From ba8ea45b3465947eb7e33c9d41f9e90771f7386d Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 31 Mar 2025 17:57:14 +0100 Subject: [PATCH 001/116] Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt --- app/build.gradle.kts | 1 - .../data/model/CurrencyEntity.java | 6 +- .../main/java/com/brainwallet/di/Module.kt | 4 +- .../presenter/activities/util/BRActivity.java | 4 +- .../tools/manager/BRApiManager.java | 317 +++++++++--------- .../currency/BackupRateFetchTests.kt | 6 +- .../java/com/brainwallet/data/BaseURLTests.kt | 19 +- .../tools/util/ProdAPIManagerTests.kt | 26 +- 8 files changed, 185 insertions(+), 198 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d20ad2c8..7922396b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -188,7 +188,6 @@ dependencies { } implementation("androidx.webkit:webkit:1.9.0") - implementation("com.squareup.moshi:moshi-kotlin:1.15.2") implementation(libs.androidx.core) implementation(libs.androidx.appcompat) implementation(libs.androidx.legacy.support) diff --git a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java index 319ed216..f0c31051 100644 --- a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java +++ b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java @@ -5,13 +5,13 @@ public class CurrencyEntity implements Serializable { //Change this after modifying the class - private static final long serialVersionUID = 7526472295622777000L; + private static final long serialVersionUID = 7526472295622776147L; public static final String TAG = CurrencyEntity.class.getName(); public String code; - public String name = ""; + public String name; public float rate; - public String symbol = ""; + public String symbol; public CurrencyEntity(String code, String name, float rate, String symbol) { this.code = code; diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index 05db629b..75a2cf5f 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -5,7 +5,7 @@ import android.content.SharedPreferences import com.brainwallet.BuildConfig import com.brainwallet.data.repository.SettingRepository import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.tools.manager.APIManager +import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.ui.screens.home.SettingsViewModel import com.brainwallet.ui.screens.inputwords.InputWordsViewModel @@ -32,7 +32,7 @@ val dataModule = module { it.initialize() } } - single { APIManager(get()) } + single { BRApiManager(get()) } single { CurrencyDataSource.getInstance(get()) } single { provideSharedPreferences(context = androidApplication()) } single { SettingRepository.Impl(get(), get()) } diff --git a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java index bd118415..6f62d97c 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java @@ -16,7 +16,7 @@ import com.brainwallet.presenter.activities.intro.RecoverActivity; import com.brainwallet.presenter.activities.intro.WriteDownActivity; import com.brainwallet.tools.animation.BRAnimator; -import com.brainwallet.tools.manager.APIManager; +import com.brainwallet.tools.manager.BRApiManager; import com.brainwallet.tools.manager.InternetManager; import com.brainwallet.tools.security.AuthManager; import com.brainwallet.tools.security.BRKeyStore; @@ -148,7 +148,7 @@ public static void init(Activity app) { if (!(app instanceof RecoverActivity || app instanceof WriteDownActivity)) { - APIManager apiManager = KoinJavaComponent.get(APIManager.class); + BRApiManager apiManager = KoinJavaComponent.get(BRApiManager.class); apiManager.startTimer(app); } diff --git a/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java b/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java index e298b178..9b7a81de 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java @@ -30,7 +30,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; -import java.util.Optional; import java.util.Set; import java.util.Timer; import java.util.TimerTask; @@ -38,164 +37,158 @@ import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; -// -//public class BRApiManager { -// private Timer timer; -// -// private TimerTask timerTask; -// -// private Handler handler; -// -// private RemoteConfigSource remoteConfigSource; -// -// public BRApiManager(RemoteConfigSource remoteConfigSource) { -// this.remoteConfigSource = remoteConfigSource; -// this.handler = new Handler(); -// } -// -// private Set getCurrencies(Activity context) { -// Set set = new LinkedHashSet<>(); -// try { -// JSONArray arr = fetchRates(context); -// FeeManager.updateFeePerKb(context); -// if (arr != null) { -// String selectedISO = BRSharedPrefs.getIsoSymbol(context); -// int length = arr.length(); -// for (int i = 0; i < length; i++) { -// CurrencyEntity tempCurrencyEntity = new CurrencyEntity(); -// try { -// JSONObject tmpJSONObj = (JSONObject) arr.get(i); -// tempCurrencyEntity.name = "no_currency_name"; -// if (tmpJSONObj.getString("name").toString() != null) { -// tempCurrencyEntity.name = tmpJSONObj.getString("name"); -// } -// tempCurrencyEntity.code = tmpJSONObj.getString("code"); -// tempCurrencyEntity.rate = (float) tmpJSONObj.getDouble("n"); -// tempCurrencyEntity.symbol = new String(""); -// if (tempCurrencyEntity.code.equalsIgnoreCase(selectedISO)) { -// BRSharedPrefs.putIso(context, tempCurrencyEntity.code); -// BRSharedPrefs.putCurrencyListPosition(context, i - 1); -// } -// set.add(tempCurrencyEntity); -// Timber.d(":::timber: CE: %s",tempCurrencyEntity.code); -// -// } catch (JSONException e) { -// ///Timber.e(e); -// // Timber.d(":::timber: ERROR: %s",e); -// } -// } -// } else { -// Timber.d("timber: getCurrencies: failed to get currencies"); -// } -// } catch (Exception e) { -// Timber.e(e); -// } -// List tempList = new ArrayList<>(set); -// Collections.reverse(tempList); -// return new LinkedHashSet<>(set); -// } -// -// -// private void initializeTimerTask(final Context context) { -// timerTask = new TimerTask() { -// public void run() { -// //use a handler to run a toast that shows the current timestamp -// handler.post(new Runnable() { -// public void run() { -// BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { -// @Override -// public void run() { -// Set tmp = getCurrencies((Activity) context); -// CurrencyDataSource.getInstance(context).putCurrencies(tmp); -// } -// }); -// } -// }); -// } -// }; -// } -// -// public void startTimer(Context context) { -// //set a new Timer -// if (timer != null) return; -// timer = new Timer(); -// -// //initialize the TimerTask's job -// initializeTimerTask(context); -// -// //schedule the timer, after the first 0ms the TimerTask will run every 60000ms -// timer.schedule(timerTask, 0, 4000); -// } -// -// public JSONArray fetchRates(Activity activity) { -// String jsonString = createGETRequestURL(activity, BW_API_PROD_HOST + "/api/v1/rates"); -// JSONArray jsonArray = null; -// if (jsonString == null) return null; -// try { -// jsonArray = new JSONArray(jsonString); -// // DEV Uncomment to view values -// // Timber.d("timber: baseUrlProd: %s", getBaseUrlProd()); -// // Timber.d("timber: JSON %s",jsonArray.toString()); -// } catch (JSONException ex) { -// Timber.e(ex); -// } -// if (jsonArray != null && !BuildConfig.DEBUG) { -// AnalyticsManager.logCustomEvent(_20250222_PAC); -// } -// return jsonArray == null ? backupFetchRates(activity) : jsonArray; -// } -// -// public JSONArray backupFetchRates(Activity activity) { -// String jsonString = createGETRequestURL(activity, BW_API_DEV_HOST + "/api/v1/rates"); -// -// JSONArray jsonArray = null; -// if (jsonString == null) return null; -// try { -// jsonArray = new JSONArray(jsonString); -// -// } catch (JSONException e) { -// Timber.e(e); -// } -// if (jsonArray != null && !BuildConfig.DEBUG) { -// AnalyticsManager.logCustomEvent(_20230113_BAC); -// } -// -// return jsonArray; -// } -// -// // createGETRequestURL -// // Creates the params and headers to make a GET Request -// private String createGETRequestURL(Context app, String myURL) { -// Request request = new Request.Builder() -// .url(myURL) -// .header("Content-Type", "application/json") -// .header("Accept", "application/json") -// .header("User-agent", Utils.getAgentString(app, "android/HttpURLConnection")) -// .get().build(); -// String response = null; -// Response resp = APIClient.getInstance(app).sendRequest(request, false, 0); -// -// try { -// if (resp == null) { -// Timber.i("timber: urlGET: %s resp is null", myURL); -// return null; -// } -// ///Set timestamp to prefs -// long timeStamp = new Date().getTime(); -// BRSharedPrefs.putSecureTime(app, timeStamp); -// -// assert resp.body() != null; -// response = resp.body().string(); -// -// } catch (IOException e) { -// Timber.e(e); -// } finally { -// if (resp != null) resp.close(); -// } -// return response; -// } -// -// public String getBaseUrlProd() { -// return BW_API_PROD_HOST; -// } -//} + +public class BRApiManager { + private Timer timer; + + private TimerTask timerTask; + + private Handler handler; + + private RemoteConfigSource remoteConfigSource; + + public BRApiManager(RemoteConfigSource remoteConfigSource) { + this.remoteConfigSource = remoteConfigSource; + this.handler = new Handler(); + } + + private Set getCurrencies(Activity context) { + Set set = new LinkedHashSet<>(); + try { + JSONArray arr = fetchRates(context); + FeeManager.updateFeePerKb(context); + if (arr != null) { + String selectedISO = BRSharedPrefs.getIsoSymbol(context); + int length = arr.length(); + for (int i = 0; i < length; i++) { + CurrencyEntity tempCurrencyEntity = new CurrencyEntity(); + try { + JSONObject tmpJSONObj = (JSONObject) arr.get(i); + tempCurrencyEntity.name = tmpJSONObj.getString("name"); + tempCurrencyEntity.code = tmpJSONObj.getString("code"); + tempCurrencyEntity.rate = (float) tmpJSONObj.getDouble("n"); + tempCurrencyEntity.symbol = new String(""); + if (tempCurrencyEntity.code.equalsIgnoreCase(selectedISO)) { + BRSharedPrefs.putIso(context, tempCurrencyEntity.code); + BRSharedPrefs.putCurrencyListPosition(context, i - 1); + } + set.add(tempCurrencyEntity); + } catch (JSONException e) { + Timber.e(e); + } + } + } else { + Timber.d("timber: getCurrencies: failed to get currencies"); + } + } catch (Exception e) { + Timber.e(e); + } + List tempList = new ArrayList<>(set); + Collections.reverse(tempList); + return new LinkedHashSet<>(set); + } + + + private void initializeTimerTask(final Context context) { + timerTask = new TimerTask() { + public void run() { + //use a handler to run a toast that shows the current timestamp + handler.post(new Runnable() { + public void run() { + BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { + @Override + public void run() { + Set tmp = getCurrencies((Activity) context); + CurrencyDataSource.getInstance(context).putCurrencies(tmp); + } + }); + } + }); + } + }; + } + + public void startTimer(Context context) { + //set a new Timer + if (timer != null) return; + timer = new Timer(); + + //initialize the TimerTask's job + initializeTimerTask(context); + + //schedule the timer, after the first 0ms the TimerTask will run every 60000ms + timer.schedule(timerTask, 0, 4000); + } + + public JSONArray fetchRates(Activity activity) { + String jsonString = createGETRequestURL(activity, BW_API_PROD_HOST + "/api/v1/rates"); + JSONArray jsonArray = null; + if (jsonString == null) return null; + try { + jsonArray = new JSONArray(jsonString); + // DEV Uncomment to view values + // Timber.d("timber: baseUrlProd: %s", getBaseUrlProd()); + // Timber.d("timber: JSON %s",jsonArray.toString()); + } catch (JSONException ex) { + Timber.e(ex); + } + if (jsonArray != null && !BuildConfig.DEBUG) { + AnalyticsManager.logCustomEvent(_20250222_PAC); + } + return jsonArray == null ? backupFetchRates(activity) : jsonArray; + } + + public JSONArray backupFetchRates(Activity activity) { + String jsonString = createGETRequestURL(activity, BW_API_DEV_HOST + "/api/v1/rates"); + + JSONArray jsonArray = null; + if (jsonString == null) return null; + try { + jsonArray = new JSONArray(jsonString); + + } catch (JSONException e) { + Timber.e(e); + } + if (jsonArray != null && !BuildConfig.DEBUG) { + AnalyticsManager.logCustomEvent(_20230113_BAC); + } + + return jsonArray; + } + + // createGETRequestURL + // Creates the params and headers to make a GET Request + private String createGETRequestURL(Context app, String myURL) { + Request request = new Request.Builder() + .url(myURL) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .header("User-agent", Utils.getAgentString(app, "android/HttpURLConnection")) + .get().build(); + String response = null; + Response resp = APIClient.getInstance(app).sendRequest(request, false, 0); + + try { + if (resp == null) { + Timber.i("timber: urlGET: %s resp is null", myURL); + return null; + } + ///Set timestamp to prefs + long timeStamp = new Date().getTime(); + BRSharedPrefs.putSecureTime(app, timeStamp); + + assert resp.body() != null; + response = resp.body().string(); + + } catch (IOException e) { + Timber.e(e); + } finally { + if (resp != null) resp.close(); + } + return response; + } + + public String getBaseUrlProd() { + return BW_API_PROD_HOST; + } +} diff --git a/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt b/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt index 4932a7fb..ba5c19ec 100644 --- a/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt +++ b/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt @@ -4,7 +4,7 @@ import android.app.Activity import android.content.Context import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.presenter.activities.util.ActivityUTILS -import com.brainwallet.tools.manager.APIManager +import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.util.BRConstants import com.brainwallet.tools.util.Utils import com.platform.APIClient @@ -22,11 +22,11 @@ import org.junit.Test class BackupRateFetchTests { private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: APIManager + private lateinit var apiManager: BRApiManager @Before fun setUp() { - apiManager = spyk(APIManager(remoteConfigSource), recordPrivateCalls = true) + apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) } @Test diff --git a/app/src/test/java/com/brainwallet/data/BaseURLTests.kt b/app/src/test/java/com/brainwallet/data/BaseURLTests.kt index fa603bf2..d0163299 100644 --- a/app/src/test/java/com/brainwallet/data/BaseURLTests.kt +++ b/app/src/test/java/com/brainwallet/data/BaseURLTests.kt @@ -1,7 +1,7 @@ package com.brainwallet.data import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.tools.manager.APIManager +import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.util.BRConstants import io.mockk.every import io.mockk.mockk @@ -13,25 +13,20 @@ import org.junit.Test class BaseURLTests { private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: APIManager + private lateinit var apiManager: BRApiManager @Before fun setUp() { - apiManager = spyk(APIManager(remoteConfigSource), recordPrivateCalls = true) + apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) } @Test - fun `invoke getPRODBaseURL with KEY_API_BASEURL_PROD_NEW_ENABLED true, then should return new getPRODBaseURL`() { + fun `invoke getBaseUrlProd with KEY_API_BASEURL_PROD_NEW_ENABLED true, then should return new baseUrlProd`() { every { remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_PROD_NEW_ENABLED) } returns true - val actual = apiManager.getPRODBaseURL() - assertEquals(BRConstants.BW_API_PROD_HOST, actual) - } - @Test - fun `invoke getDEVBaseURL with KEY_API_BASEURL_DEV_NEW_ENABLED true, then should return new getDEVBaseURL`() { - every { remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_DEV_NEW_ENABLED) } returns true - val actual = apiManager.getDEVBaseURL() - assertEquals(BRConstants.BW_API_DEV_HOST, actual) + val actual = apiManager.baseUrlProd + + assertEquals(BRConstants.BW_API_PROD_HOST, actual) } } diff --git a/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt b/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt index 75af20f7..2386d1f0 100644 --- a/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt +++ b/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt @@ -4,7 +4,7 @@ import android.app.Activity import android.content.Context import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.presenter.activities.util.ActivityUTILS -import com.brainwallet.tools.manager.APIManager +import com.brainwallet.tools.manager.BRApiManager import com.platform.APIClient import io.mockk.every import io.mockk.mockk @@ -22,11 +22,11 @@ import org.junit.Test class ProdAPIManagerTests { private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: APIManager + private lateinit var apiManager: BRApiManager @Before fun setUp() { - apiManager = spyk(APIManager(remoteConfigSource), recordPrivateCalls = true) + apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) } @Test @@ -85,17 +85,17 @@ class ProdAPIManagerTests { .body(responseString.toResponseBody()) .build() - val currencyEntityList = apiManager.fetchRates(activity) - val jsonUSD = currencyEntityList?.get(154) - val jsonEUR = currencyEntityList?.get(49) - val jsonGBP = currencyEntityList?.get(52) + val result = apiManager.fetchRates(activity) + val jsonUSD = result.getJSONObject(154) + val jsonEUR = result.getJSONObject(49) + val jsonGBP = result.getJSONObject(52) - assertEquals("USD", jsonUSD?.code) - assertEquals("US Dollar", jsonUSD?.name) - assertEquals("EUR", jsonEUR?.code) - assertEquals("Euro", jsonEUR?.name) - assertEquals("GBP", jsonGBP?.code) - assertEquals("British Pound Sterling", jsonGBP?.name) + assertEquals("USD", jsonUSD.optString("code")) + assertEquals("US Dollar", jsonUSD.optString("name")) + assertEquals("EUR", jsonEUR.optString("code")) + assertEquals("Euro", jsonEUR.optString("name")) + assertEquals("GBP", jsonGBP.optString("code")) + assertEquals("British Pound Sterling", jsonGBP.optString("name")) ///DEV: Very flaky test not enough time for the response verifyAll { From 638ce3a3b76b7114b60ef6dc8f398dc26b8e2b25 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 31 Mar 2025 19:09:11 +0100 Subject: [PATCH 002/116] Reverted the Kotlin APIManager. --- app/build.gradle.kts | 4 +- .../brainwallet/tools/manager/APIManager.kt | 119 ------------------ 2 files changed, 2 insertions(+), 121 deletions(-) delete mode 100644 app/src/main/java/com/brainwallet/tools/manager/APIManager.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7922396b..7d06d2e7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202503281 - versionName = "v4.4.1" + versionCode = 202503312 + versionName = "v4.4.3" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") diff --git a/app/src/main/java/com/brainwallet/tools/manager/APIManager.kt b/app/src/main/java/com/brainwallet/tools/manager/APIManager.kt deleted file mode 100644 index fe3b2072..00000000 --- a/app/src/main/java/com/brainwallet/tools/manager/APIManager.kt +++ /dev/null @@ -1,119 +0,0 @@ -package com.brainwallet.tools.manager - -import android.app.Activity -import android.content.Context -import com.brainwallet.data.model.CurrencyEntity -import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.presenter.entities.ServiceItems -import com.brainwallet.tools.sqlite.CurrencyDataSource -import com.brainwallet.tools.util.BRConstants.BW_API_DEV_HOST -import com.brainwallet.tools.util.BRConstants.BW_API_PROD_HOST -import com.brainwallet.tools.util.Utils -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import okhttp3.OkHttpClient -import okhttp3.Request -import com.squareup.moshi.Moshi -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.Types -import timber.log.Timber -import java.io.IOException -import java.util.* -import kotlin.collections.LinkedHashSet - -class APIManager (private val remoteConfigSource: RemoteConfigSource) { - fun getPRODBaseURL(): String = BW_API_PROD_HOST - fun getDEVBaseURL(): String = BW_API_DEV_HOST - - private var timer: Timer? = null - private var pollPeriod : Long = 5000 - - private val client = OkHttpClient() - private val moshi: Moshi = Moshi.Builder().build() - private val type = Types.newParameterizedType(List::class.java, CurrencyEntity::class.java) - private val jsonAdapter: JsonAdapter> = moshi.adapter(type) - - fun getCurrencies(context: Activity): Set { - val set = LinkedHashSet() - try { - val arr = fetchRates(context) - FeeManager.updateFeePerKb(context) - arr?.let { currencyList -> - val selectedISO = BRSharedPrefs.getIsoSymbol(context) - currencyList.forEachIndexed { i, tempCurrencyEntity -> - if (tempCurrencyEntity.code.equals(selectedISO, ignoreCase = true)) { - BRSharedPrefs.putIso(context, tempCurrencyEntity.code) - BRSharedPrefs.putCurrencyListPosition(context, i - 1) - } - set.add(tempCurrencyEntity) - } - } ?: Timber.d("timber: getCurrencies: failed to get currencies") - } catch (e: Exception) { - Timber.e(e) - } - return set.reversed().toSet() - } - - private fun initializeTimerTask(context: Context) { - timer = Timer().apply { - schedule(object : TimerTask() { - override fun run() { - CoroutineScope(Dispatchers.IO).launch { - val tmp = getCurrencies(context as Activity) - withContext(Dispatchers.Main) { - CurrencyDataSource.getInstance(context).putCurrencies(tmp) - } - } - } - }, 0, pollPeriod) - } - } - - fun startTimer(context: Context) { - if (timer != null) return - initializeTimerTask(context) - } - - fun fetchRates(activity: Activity): List? { - val jsonString = createGETRequestURL(activity, "$BW_API_PROD_HOST/api/v1/rates") - return parseJsonArray(jsonString) ?: backupFetchRates(activity) - } - - private fun backupFetchRates(activity: Activity): List? { - val jsonString = createGETRequestURL(activity, "$BW_API_DEV_HOST/api/v1/rates") - return parseJsonArray(jsonString) - } - - private fun parseJsonArray(jsonString: String?): List? { - return try { - jsonString?.let { jsonAdapter.fromJson(it) } - } catch (e: IOException) { - Timber.e(e) - null - } - } - - private fun createGETRequestURL(app: Context, url: String): String? { - val request = Request.Builder() - .url(url) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .header("User-agent", Utils.getAgentString(app, "android/HttpURLConnection")) - .header("bw-client-code", Utils.fetchServiceItem(app, ServiceItems.CLIENTCODE)) - .get() - .build() - - return try { - client.newCall(request).execute().use { response -> - response.body?.string().also { - BRSharedPrefs.putSecureTime(app, System.currentTimeMillis()) - } - } - } catch (e: IOException) { - Timber.e(e) - null - } - } -} From 5344a96a6a0c56895945e7e8d0005eee30dbfd39 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 31 Mar 2025 19:43:55 +0100 Subject: [PATCH 003/116] Add version and code to welcome screen --- .../ui/screens/welcome/WelcomeScreen.kt | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index 370b9574..4472eb38 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -41,6 +41,7 @@ import com.brainwallet.R import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect +import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.composable.BrainwalletButton import com.brainwallet.ui.composable.DarkModeToggleButton @@ -75,7 +76,7 @@ fun WelcomeScreen( val halfLeadTrailPadding = leadTrailPadding / 2 val doubleLeadTrailPadding = leadTrailPadding * 2 val rowPadding = 8 - val activeRowHeight = 70 + val activeRowHeight = 58 val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.welcomeemoji20250212)) val progress by animateLottieCompositionAsState( @@ -91,7 +92,7 @@ fun WelcomeScreen( verticalArrangement = Arrangement.SpaceBetween ) { - Spacer(modifier = Modifier.weight(0.4f)) + Spacer(modifier = Modifier.weight(0.2f)) Image( painterResource(R.drawable.brainwallet_logotype_white), @@ -125,15 +126,16 @@ fun WelcomeScreen( modifier = Modifier .fillMaxWidth() .height(activeRowHeight.dp) - .padding(horizontal = halfLeadTrailPadding.dp) + .padding(horizontal = leadTrailPadding.dp) .padding(vertical = rowPadding.dp), horizontalArrangement = Arrangement.SpaceEvenly ) { - Spacer(modifier = Modifier.weight(0.1f)) - + BrainwalletButton( - modifier = Modifier.weight(0.9f), + modifier = Modifier + .weight(1f) + .fillMaxWidth(), onClick = { viewModel.onEvent(WelcomeEvent.OnLanguageSelectorButtonClick) } @@ -145,7 +147,7 @@ fun WelcomeScreen( ) } - Spacer(modifier = Modifier.weight(0.2f)) + Spacer(modifier = Modifier.weight(0.1f)) DarkModeToggleButton( modifier = Modifier @@ -157,10 +159,12 @@ fun WelcomeScreen( } ) - Spacer(modifier = Modifier.weight(0.2f)) + Spacer(modifier = Modifier.weight(0.1f)) BrainwalletButton( - modifier = Modifier.weight(0.9f), + modifier = Modifier + .weight(1f) + .fillMaxWidth(), onClick = { viewModel.onEvent(WelcomeEvent.OnFiatButtonClick) } ) { Text( @@ -170,8 +174,6 @@ fun WelcomeScreen( ) } - Spacer(modifier = Modifier.weight(0.1f)) - } // Ready Button BorderedLargeButton( @@ -180,7 +182,7 @@ fun WelcomeScreen( }, shape = RoundedCornerShape(50), modifier = Modifier - .padding(horizontal = halfLeadTrailPadding.dp) + .padding(horizontal = leadTrailPadding.dp) .padding(vertical = rowPadding.dp) .height(activeRowHeight.dp) @@ -199,7 +201,7 @@ fun WelcomeScreen( }, shape = RoundedCornerShape(50), modifier = Modifier - .padding(horizontal = halfLeadTrailPadding.dp) + .padding(horizontal = leadTrailPadding.dp) .padding(vertical = rowPadding.dp) .height(activeRowHeight.dp) .clip(RoundedCornerShape(50)) @@ -211,6 +213,12 @@ fun WelcomeScreen( ) } + Text( modifier = Modifier + .padding(vertical = 8.dp), + text = BRConstants.APP_VERSION_NAME_CODE, + fontSize = 13.sp, + color = BrainwalletTheme.colors.content + ) Spacer(modifier = Modifier.weight(0.5f)) } From ebc3bb9a47dbb8d1e0fe9af6ddb9ee14e959a1cf Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 31 Mar 2025 19:48:18 +0100 Subject: [PATCH 004/116] reset padding --- .../com/brainwallet/ui/screens/welcome/WelcomeScreen.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index 4472eb38..f4d8ba3a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -76,6 +76,7 @@ fun WelcomeScreen( val halfLeadTrailPadding = leadTrailPadding / 2 val doubleLeadTrailPadding = leadTrailPadding * 2 val rowPadding = 8 + val versionPadding = 12 val activeRowHeight = 58 val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.welcomeemoji20250212)) @@ -131,7 +132,7 @@ fun WelcomeScreen( horizontalArrangement = Arrangement.SpaceEvenly ) { - + BrainwalletButton( modifier = Modifier .weight(1f) @@ -214,12 +215,11 @@ fun WelcomeScreen( } Text( modifier = Modifier - .padding(vertical = 8.dp), + .padding(vertical = versionPadding.dp), text = BRConstants.APP_VERSION_NAME_CODE, fontSize = 13.sp, color = BrainwalletTheme.colors.content ) - Spacer(modifier = Modifier.weight(0.5f)) } //language selector From c770f01549d7d1847a6672bbb97b247fd7ab1a40 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 31 Mar 2025 17:57:14 +0100 Subject: [PATCH 005/116] Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt --- app/build.gradle.kts | 1 - .../data/model/CurrencyEntity.java | 6 +- .../main/java/com/brainwallet/di/Module.kt | 4 +- .../presenter/activities/util/BRActivity.java | 4 +- .../tools/manager/BRApiManager.java | 317 +++++++++--------- .../currency/BackupRateFetchTests.kt | 6 +- .../java/com/brainwallet/data/BaseURLTests.kt | 19 +- .../tools/util/ProdAPIManagerTests.kt | 26 +- 8 files changed, 185 insertions(+), 198 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d20ad2c8..7922396b 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -188,7 +188,6 @@ dependencies { } implementation("androidx.webkit:webkit:1.9.0") - implementation("com.squareup.moshi:moshi-kotlin:1.15.2") implementation(libs.androidx.core) implementation(libs.androidx.appcompat) implementation(libs.androidx.legacy.support) diff --git a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java index 319ed216..f0c31051 100644 --- a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java +++ b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java @@ -5,13 +5,13 @@ public class CurrencyEntity implements Serializable { //Change this after modifying the class - private static final long serialVersionUID = 7526472295622777000L; + private static final long serialVersionUID = 7526472295622776147L; public static final String TAG = CurrencyEntity.class.getName(); public String code; - public String name = ""; + public String name; public float rate; - public String symbol = ""; + public String symbol; public CurrencyEntity(String code, String name, float rate, String symbol) { this.code = code; diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index 05db629b..75a2cf5f 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -5,7 +5,7 @@ import android.content.SharedPreferences import com.brainwallet.BuildConfig import com.brainwallet.data.repository.SettingRepository import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.tools.manager.APIManager +import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.ui.screens.home.SettingsViewModel import com.brainwallet.ui.screens.inputwords.InputWordsViewModel @@ -32,7 +32,7 @@ val dataModule = module { it.initialize() } } - single { APIManager(get()) } + single { BRApiManager(get()) } single { CurrencyDataSource.getInstance(get()) } single { provideSharedPreferences(context = androidApplication()) } single { SettingRepository.Impl(get(), get()) } diff --git a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java index bd118415..6f62d97c 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java @@ -16,7 +16,7 @@ import com.brainwallet.presenter.activities.intro.RecoverActivity; import com.brainwallet.presenter.activities.intro.WriteDownActivity; import com.brainwallet.tools.animation.BRAnimator; -import com.brainwallet.tools.manager.APIManager; +import com.brainwallet.tools.manager.BRApiManager; import com.brainwallet.tools.manager.InternetManager; import com.brainwallet.tools.security.AuthManager; import com.brainwallet.tools.security.BRKeyStore; @@ -148,7 +148,7 @@ public static void init(Activity app) { if (!(app instanceof RecoverActivity || app instanceof WriteDownActivity)) { - APIManager apiManager = KoinJavaComponent.get(APIManager.class); + BRApiManager apiManager = KoinJavaComponent.get(BRApiManager.class); apiManager.startTimer(app); } diff --git a/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java b/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java index e298b178..9b7a81de 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java @@ -30,7 +30,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Locale; -import java.util.Optional; import java.util.Set; import java.util.Timer; import java.util.TimerTask; @@ -38,164 +37,158 @@ import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; -// -//public class BRApiManager { -// private Timer timer; -// -// private TimerTask timerTask; -// -// private Handler handler; -// -// private RemoteConfigSource remoteConfigSource; -// -// public BRApiManager(RemoteConfigSource remoteConfigSource) { -// this.remoteConfigSource = remoteConfigSource; -// this.handler = new Handler(); -// } -// -// private Set getCurrencies(Activity context) { -// Set set = new LinkedHashSet<>(); -// try { -// JSONArray arr = fetchRates(context); -// FeeManager.updateFeePerKb(context); -// if (arr != null) { -// String selectedISO = BRSharedPrefs.getIsoSymbol(context); -// int length = arr.length(); -// for (int i = 0; i < length; i++) { -// CurrencyEntity tempCurrencyEntity = new CurrencyEntity(); -// try { -// JSONObject tmpJSONObj = (JSONObject) arr.get(i); -// tempCurrencyEntity.name = "no_currency_name"; -// if (tmpJSONObj.getString("name").toString() != null) { -// tempCurrencyEntity.name = tmpJSONObj.getString("name"); -// } -// tempCurrencyEntity.code = tmpJSONObj.getString("code"); -// tempCurrencyEntity.rate = (float) tmpJSONObj.getDouble("n"); -// tempCurrencyEntity.symbol = new String(""); -// if (tempCurrencyEntity.code.equalsIgnoreCase(selectedISO)) { -// BRSharedPrefs.putIso(context, tempCurrencyEntity.code); -// BRSharedPrefs.putCurrencyListPosition(context, i - 1); -// } -// set.add(tempCurrencyEntity); -// Timber.d(":::timber: CE: %s",tempCurrencyEntity.code); -// -// } catch (JSONException e) { -// ///Timber.e(e); -// // Timber.d(":::timber: ERROR: %s",e); -// } -// } -// } else { -// Timber.d("timber: getCurrencies: failed to get currencies"); -// } -// } catch (Exception e) { -// Timber.e(e); -// } -// List tempList = new ArrayList<>(set); -// Collections.reverse(tempList); -// return new LinkedHashSet<>(set); -// } -// -// -// private void initializeTimerTask(final Context context) { -// timerTask = new TimerTask() { -// public void run() { -// //use a handler to run a toast that shows the current timestamp -// handler.post(new Runnable() { -// public void run() { -// BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { -// @Override -// public void run() { -// Set tmp = getCurrencies((Activity) context); -// CurrencyDataSource.getInstance(context).putCurrencies(tmp); -// } -// }); -// } -// }); -// } -// }; -// } -// -// public void startTimer(Context context) { -// //set a new Timer -// if (timer != null) return; -// timer = new Timer(); -// -// //initialize the TimerTask's job -// initializeTimerTask(context); -// -// //schedule the timer, after the first 0ms the TimerTask will run every 60000ms -// timer.schedule(timerTask, 0, 4000); -// } -// -// public JSONArray fetchRates(Activity activity) { -// String jsonString = createGETRequestURL(activity, BW_API_PROD_HOST + "/api/v1/rates"); -// JSONArray jsonArray = null; -// if (jsonString == null) return null; -// try { -// jsonArray = new JSONArray(jsonString); -// // DEV Uncomment to view values -// // Timber.d("timber: baseUrlProd: %s", getBaseUrlProd()); -// // Timber.d("timber: JSON %s",jsonArray.toString()); -// } catch (JSONException ex) { -// Timber.e(ex); -// } -// if (jsonArray != null && !BuildConfig.DEBUG) { -// AnalyticsManager.logCustomEvent(_20250222_PAC); -// } -// return jsonArray == null ? backupFetchRates(activity) : jsonArray; -// } -// -// public JSONArray backupFetchRates(Activity activity) { -// String jsonString = createGETRequestURL(activity, BW_API_DEV_HOST + "/api/v1/rates"); -// -// JSONArray jsonArray = null; -// if (jsonString == null) return null; -// try { -// jsonArray = new JSONArray(jsonString); -// -// } catch (JSONException e) { -// Timber.e(e); -// } -// if (jsonArray != null && !BuildConfig.DEBUG) { -// AnalyticsManager.logCustomEvent(_20230113_BAC); -// } -// -// return jsonArray; -// } -// -// // createGETRequestURL -// // Creates the params and headers to make a GET Request -// private String createGETRequestURL(Context app, String myURL) { -// Request request = new Request.Builder() -// .url(myURL) -// .header("Content-Type", "application/json") -// .header("Accept", "application/json") -// .header("User-agent", Utils.getAgentString(app, "android/HttpURLConnection")) -// .get().build(); -// String response = null; -// Response resp = APIClient.getInstance(app).sendRequest(request, false, 0); -// -// try { -// if (resp == null) { -// Timber.i("timber: urlGET: %s resp is null", myURL); -// return null; -// } -// ///Set timestamp to prefs -// long timeStamp = new Date().getTime(); -// BRSharedPrefs.putSecureTime(app, timeStamp); -// -// assert resp.body() != null; -// response = resp.body().string(); -// -// } catch (IOException e) { -// Timber.e(e); -// } finally { -// if (resp != null) resp.close(); -// } -// return response; -// } -// -// public String getBaseUrlProd() { -// return BW_API_PROD_HOST; -// } -//} + +public class BRApiManager { + private Timer timer; + + private TimerTask timerTask; + + private Handler handler; + + private RemoteConfigSource remoteConfigSource; + + public BRApiManager(RemoteConfigSource remoteConfigSource) { + this.remoteConfigSource = remoteConfigSource; + this.handler = new Handler(); + } + + private Set getCurrencies(Activity context) { + Set set = new LinkedHashSet<>(); + try { + JSONArray arr = fetchRates(context); + FeeManager.updateFeePerKb(context); + if (arr != null) { + String selectedISO = BRSharedPrefs.getIsoSymbol(context); + int length = arr.length(); + for (int i = 0; i < length; i++) { + CurrencyEntity tempCurrencyEntity = new CurrencyEntity(); + try { + JSONObject tmpJSONObj = (JSONObject) arr.get(i); + tempCurrencyEntity.name = tmpJSONObj.getString("name"); + tempCurrencyEntity.code = tmpJSONObj.getString("code"); + tempCurrencyEntity.rate = (float) tmpJSONObj.getDouble("n"); + tempCurrencyEntity.symbol = new String(""); + if (tempCurrencyEntity.code.equalsIgnoreCase(selectedISO)) { + BRSharedPrefs.putIso(context, tempCurrencyEntity.code); + BRSharedPrefs.putCurrencyListPosition(context, i - 1); + } + set.add(tempCurrencyEntity); + } catch (JSONException e) { + Timber.e(e); + } + } + } else { + Timber.d("timber: getCurrencies: failed to get currencies"); + } + } catch (Exception e) { + Timber.e(e); + } + List tempList = new ArrayList<>(set); + Collections.reverse(tempList); + return new LinkedHashSet<>(set); + } + + + private void initializeTimerTask(final Context context) { + timerTask = new TimerTask() { + public void run() { + //use a handler to run a toast that shows the current timestamp + handler.post(new Runnable() { + public void run() { + BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { + @Override + public void run() { + Set tmp = getCurrencies((Activity) context); + CurrencyDataSource.getInstance(context).putCurrencies(tmp); + } + }); + } + }); + } + }; + } + + public void startTimer(Context context) { + //set a new Timer + if (timer != null) return; + timer = new Timer(); + + //initialize the TimerTask's job + initializeTimerTask(context); + + //schedule the timer, after the first 0ms the TimerTask will run every 60000ms + timer.schedule(timerTask, 0, 4000); + } + + public JSONArray fetchRates(Activity activity) { + String jsonString = createGETRequestURL(activity, BW_API_PROD_HOST + "/api/v1/rates"); + JSONArray jsonArray = null; + if (jsonString == null) return null; + try { + jsonArray = new JSONArray(jsonString); + // DEV Uncomment to view values + // Timber.d("timber: baseUrlProd: %s", getBaseUrlProd()); + // Timber.d("timber: JSON %s",jsonArray.toString()); + } catch (JSONException ex) { + Timber.e(ex); + } + if (jsonArray != null && !BuildConfig.DEBUG) { + AnalyticsManager.logCustomEvent(_20250222_PAC); + } + return jsonArray == null ? backupFetchRates(activity) : jsonArray; + } + + public JSONArray backupFetchRates(Activity activity) { + String jsonString = createGETRequestURL(activity, BW_API_DEV_HOST + "/api/v1/rates"); + + JSONArray jsonArray = null; + if (jsonString == null) return null; + try { + jsonArray = new JSONArray(jsonString); + + } catch (JSONException e) { + Timber.e(e); + } + if (jsonArray != null && !BuildConfig.DEBUG) { + AnalyticsManager.logCustomEvent(_20230113_BAC); + } + + return jsonArray; + } + + // createGETRequestURL + // Creates the params and headers to make a GET Request + private String createGETRequestURL(Context app, String myURL) { + Request request = new Request.Builder() + .url(myURL) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .header("User-agent", Utils.getAgentString(app, "android/HttpURLConnection")) + .get().build(); + String response = null; + Response resp = APIClient.getInstance(app).sendRequest(request, false, 0); + + try { + if (resp == null) { + Timber.i("timber: urlGET: %s resp is null", myURL); + return null; + } + ///Set timestamp to prefs + long timeStamp = new Date().getTime(); + BRSharedPrefs.putSecureTime(app, timeStamp); + + assert resp.body() != null; + response = resp.body().string(); + + } catch (IOException e) { + Timber.e(e); + } finally { + if (resp != null) resp.close(); + } + return response; + } + + public String getBaseUrlProd() { + return BW_API_PROD_HOST; + } +} diff --git a/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt b/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt index 4932a7fb..ba5c19ec 100644 --- a/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt +++ b/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt @@ -4,7 +4,7 @@ import android.app.Activity import android.content.Context import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.presenter.activities.util.ActivityUTILS -import com.brainwallet.tools.manager.APIManager +import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.util.BRConstants import com.brainwallet.tools.util.Utils import com.platform.APIClient @@ -22,11 +22,11 @@ import org.junit.Test class BackupRateFetchTests { private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: APIManager + private lateinit var apiManager: BRApiManager @Before fun setUp() { - apiManager = spyk(APIManager(remoteConfigSource), recordPrivateCalls = true) + apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) } @Test diff --git a/app/src/test/java/com/brainwallet/data/BaseURLTests.kt b/app/src/test/java/com/brainwallet/data/BaseURLTests.kt index fa603bf2..d0163299 100644 --- a/app/src/test/java/com/brainwallet/data/BaseURLTests.kt +++ b/app/src/test/java/com/brainwallet/data/BaseURLTests.kt @@ -1,7 +1,7 @@ package com.brainwallet.data import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.tools.manager.APIManager +import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.util.BRConstants import io.mockk.every import io.mockk.mockk @@ -13,25 +13,20 @@ import org.junit.Test class BaseURLTests { private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: APIManager + private lateinit var apiManager: BRApiManager @Before fun setUp() { - apiManager = spyk(APIManager(remoteConfigSource), recordPrivateCalls = true) + apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) } @Test - fun `invoke getPRODBaseURL with KEY_API_BASEURL_PROD_NEW_ENABLED true, then should return new getPRODBaseURL`() { + fun `invoke getBaseUrlProd with KEY_API_BASEURL_PROD_NEW_ENABLED true, then should return new baseUrlProd`() { every { remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_PROD_NEW_ENABLED) } returns true - val actual = apiManager.getPRODBaseURL() - assertEquals(BRConstants.BW_API_PROD_HOST, actual) - } - @Test - fun `invoke getDEVBaseURL with KEY_API_BASEURL_DEV_NEW_ENABLED true, then should return new getDEVBaseURL`() { - every { remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_DEV_NEW_ENABLED) } returns true - val actual = apiManager.getDEVBaseURL() - assertEquals(BRConstants.BW_API_DEV_HOST, actual) + val actual = apiManager.baseUrlProd + + assertEquals(BRConstants.BW_API_PROD_HOST, actual) } } diff --git a/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt b/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt index 75af20f7..2386d1f0 100644 --- a/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt +++ b/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt @@ -4,7 +4,7 @@ import android.app.Activity import android.content.Context import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.presenter.activities.util.ActivityUTILS -import com.brainwallet.tools.manager.APIManager +import com.brainwallet.tools.manager.BRApiManager import com.platform.APIClient import io.mockk.every import io.mockk.mockk @@ -22,11 +22,11 @@ import org.junit.Test class ProdAPIManagerTests { private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: APIManager + private lateinit var apiManager: BRApiManager @Before fun setUp() { - apiManager = spyk(APIManager(remoteConfigSource), recordPrivateCalls = true) + apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) } @Test @@ -85,17 +85,17 @@ class ProdAPIManagerTests { .body(responseString.toResponseBody()) .build() - val currencyEntityList = apiManager.fetchRates(activity) - val jsonUSD = currencyEntityList?.get(154) - val jsonEUR = currencyEntityList?.get(49) - val jsonGBP = currencyEntityList?.get(52) + val result = apiManager.fetchRates(activity) + val jsonUSD = result.getJSONObject(154) + val jsonEUR = result.getJSONObject(49) + val jsonGBP = result.getJSONObject(52) - assertEquals("USD", jsonUSD?.code) - assertEquals("US Dollar", jsonUSD?.name) - assertEquals("EUR", jsonEUR?.code) - assertEquals("Euro", jsonEUR?.name) - assertEquals("GBP", jsonGBP?.code) - assertEquals("British Pound Sterling", jsonGBP?.name) + assertEquals("USD", jsonUSD.optString("code")) + assertEquals("US Dollar", jsonUSD.optString("name")) + assertEquals("EUR", jsonEUR.optString("code")) + assertEquals("Euro", jsonEUR.optString("name")) + assertEquals("GBP", jsonGBP.optString("code")) + assertEquals("British Pound Sterling", jsonGBP.optString("name")) ///DEV: Very flaky test not enough time for the response verifyAll { From f8c1bd50ca6d4031a27060dad4c337a0660c36ea Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 31 Mar 2025 19:09:11 +0100 Subject: [PATCH 006/116] Reverted the Kotlin APIManager. --- app/build.gradle.kts | 4 +- .../brainwallet/tools/manager/APIManager.kt | 119 ------------------ 2 files changed, 2 insertions(+), 121 deletions(-) delete mode 100644 app/src/main/java/com/brainwallet/tools/manager/APIManager.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7922396b..7d06d2e7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202503281 - versionName = "v4.4.1" + versionCode = 202503312 + versionName = "v4.4.3" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") diff --git a/app/src/main/java/com/brainwallet/tools/manager/APIManager.kt b/app/src/main/java/com/brainwallet/tools/manager/APIManager.kt deleted file mode 100644 index fe3b2072..00000000 --- a/app/src/main/java/com/brainwallet/tools/manager/APIManager.kt +++ /dev/null @@ -1,119 +0,0 @@ -package com.brainwallet.tools.manager - -import android.app.Activity -import android.content.Context -import com.brainwallet.data.model.CurrencyEntity -import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.presenter.entities.ServiceItems -import com.brainwallet.tools.sqlite.CurrencyDataSource -import com.brainwallet.tools.util.BRConstants.BW_API_DEV_HOST -import com.brainwallet.tools.util.BRConstants.BW_API_PROD_HOST -import com.brainwallet.tools.util.Utils -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import okhttp3.OkHttpClient -import okhttp3.Request -import com.squareup.moshi.Moshi -import com.squareup.moshi.JsonAdapter -import com.squareup.moshi.Types -import timber.log.Timber -import java.io.IOException -import java.util.* -import kotlin.collections.LinkedHashSet - -class APIManager (private val remoteConfigSource: RemoteConfigSource) { - fun getPRODBaseURL(): String = BW_API_PROD_HOST - fun getDEVBaseURL(): String = BW_API_DEV_HOST - - private var timer: Timer? = null - private var pollPeriod : Long = 5000 - - private val client = OkHttpClient() - private val moshi: Moshi = Moshi.Builder().build() - private val type = Types.newParameterizedType(List::class.java, CurrencyEntity::class.java) - private val jsonAdapter: JsonAdapter> = moshi.adapter(type) - - fun getCurrencies(context: Activity): Set { - val set = LinkedHashSet() - try { - val arr = fetchRates(context) - FeeManager.updateFeePerKb(context) - arr?.let { currencyList -> - val selectedISO = BRSharedPrefs.getIsoSymbol(context) - currencyList.forEachIndexed { i, tempCurrencyEntity -> - if (tempCurrencyEntity.code.equals(selectedISO, ignoreCase = true)) { - BRSharedPrefs.putIso(context, tempCurrencyEntity.code) - BRSharedPrefs.putCurrencyListPosition(context, i - 1) - } - set.add(tempCurrencyEntity) - } - } ?: Timber.d("timber: getCurrencies: failed to get currencies") - } catch (e: Exception) { - Timber.e(e) - } - return set.reversed().toSet() - } - - private fun initializeTimerTask(context: Context) { - timer = Timer().apply { - schedule(object : TimerTask() { - override fun run() { - CoroutineScope(Dispatchers.IO).launch { - val tmp = getCurrencies(context as Activity) - withContext(Dispatchers.Main) { - CurrencyDataSource.getInstance(context).putCurrencies(tmp) - } - } - } - }, 0, pollPeriod) - } - } - - fun startTimer(context: Context) { - if (timer != null) return - initializeTimerTask(context) - } - - fun fetchRates(activity: Activity): List? { - val jsonString = createGETRequestURL(activity, "$BW_API_PROD_HOST/api/v1/rates") - return parseJsonArray(jsonString) ?: backupFetchRates(activity) - } - - private fun backupFetchRates(activity: Activity): List? { - val jsonString = createGETRequestURL(activity, "$BW_API_DEV_HOST/api/v1/rates") - return parseJsonArray(jsonString) - } - - private fun parseJsonArray(jsonString: String?): List? { - return try { - jsonString?.let { jsonAdapter.fromJson(it) } - } catch (e: IOException) { - Timber.e(e) - null - } - } - - private fun createGETRequestURL(app: Context, url: String): String? { - val request = Request.Builder() - .url(url) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .header("User-agent", Utils.getAgentString(app, "android/HttpURLConnection")) - .header("bw-client-code", Utils.fetchServiceItem(app, ServiceItems.CLIENTCODE)) - .get() - .build() - - return try { - client.newCall(request).execute().use { response -> - response.body?.string().also { - BRSharedPrefs.putSecureTime(app, System.currentTimeMillis()) - } - } - } catch (e: IOException) { - Timber.e(e) - null - } - } -} From ff58b57c1d2150cf791bd4a3da4fb6ec6a8ec67a Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Sat, 5 Apr 2025 00:19:01 +0700 Subject: [PATCH 007/116] fix: fix crash when FragmentSignal dismissed --- .../com/brainwallet/presenter/fragments/FragmentSignal.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java index 05bbed1e..bf936591 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java @@ -13,6 +13,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import com.brainwallet.R; @@ -20,7 +21,7 @@ import timber.log.Timber; -public class FragmentSignal extends Fragment { +public class FragmentSignal extends DialogFragment { public static final String TITLE = "title"; public static final String ICON_DESCRIPTION = "iconDescription"; public static final String RES_ID = "resId"; @@ -34,7 +35,7 @@ public class FragmentSignal extends Fragment { @Override public void run() { if (isAdded()) { - getParentFragmentManager().popBackStack(); + dismiss(); handler.postDelayed(completionRunnable, 300); } } From d64ea930d45d0adeabf2a97d4d7f7070ba15d62e Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Mon, 7 Apr 2025 10:39:48 +0700 Subject: [PATCH 008/116] fix: fix sync after wipe --- .../com/brainwallet/tools/manager/SyncManager.java | 2 +- .../ui/screens/inputwords/InputWordsViewModel.kt | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java b/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java index 924c6fc6..42e195f5 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java @@ -22,7 +22,7 @@ public class SyncManager { private static SyncManager instance; private static final long SYNC_PERIOD = TimeUnit.HOURS.toMillis(24); private static SyncProgressTask syncTask; - public boolean running; + public volatile boolean running; public static SyncManager getInstance() { if (instance == null) instance = new SyncManager(); diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt index bb2243dc..7da2b003 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt @@ -94,12 +94,12 @@ class InputWordsViewModel : BrainwalletViewModel() { return } - BRWalletManager.getInstance().run { - wipeWalletButKeystore(event.context) - wipeKeyStore(event.context) - PostAuth.getInstance().setPhraseForKeyStore(cleanPhrase) - BRSharedPrefs.putAllowSpend(event.context, false) - } + BRWalletManager.getInstance().wipeAll(event.context) + + BRSharedPrefs.putAllowSpend(event.context, false) + BRSharedPrefs.putStartHeight(event.context, 0) + + PostAuth.getInstance().setPhraseForKeyStore(cleanPhrase) viewModelScope.launch { EventBus.emit(EventBus.Event.Message(EFFECT_LEGACY_RECOVER_WALLET_AUTH)) From 9a8a20f6b636543858d5592897d61b9b86f28762 Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Tue, 8 Apr 2025 05:49:27 +0700 Subject: [PATCH 009/116] fix: fix wrong lifecycle to trigger callback at FragmentSignal --- .../presenter/fragments/FragmentSignal.java | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java index bf936591..4c136b41 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java @@ -14,13 +14,10 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.DialogFragment; -import androidx.fragment.app.Fragment; import com.brainwallet.R; import com.brainwallet.presenter.interfaces.BROnSignalCompletion; -import timber.log.Timber; - public class FragmentSignal extends DialogFragment { public static final String TITLE = "title"; public static final String ICON_DESCRIPTION = "iconDescription"; @@ -34,10 +31,8 @@ public class FragmentSignal extends DialogFragment { private final Runnable popBackStackRunnable = new Runnable() { @Override public void run() { - if (isAdded()) { - dismiss(); - handler.postDelayed(completionRunnable, 300); - } + dismiss(); + handler.postDelayed(completionRunnable, 300); } }; @@ -88,8 +83,8 @@ public void run() { }; @Override - public void onDestroyView() { - super.onDestroyView(); + public void onDestroy() { + super.onDestroy(); // Remove callbacks to prevent execution after the fragment is destroyed handler.removeCallbacks(popBackStackRunnable); handler.removeCallbacks(completionRunnable); From 832fa36a00f21e511c4cdfddfb89ccd7c8f010d9 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 8 Apr 2025 09:28:37 +0100 Subject: [PATCH 010/116] Update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dd84ea78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..bbcbbe7d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From b294cd602138cf934863c6cecdd266ed691cc54a Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 8 Apr 2025 20:52:44 +0100 Subject: [PATCH 011/116] updated core changes per @andhikayuana --- app/src/main/jni/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/jni/core b/app/src/main/jni/core index 5b9905a7..86649c2d 160000 --- a/app/src/main/jni/core +++ b/app/src/main/jni/core @@ -1 +1 @@ -Subproject commit 5b9905a72205a461e0a9935dce22f516d59e752e +Subproject commit 86649c2dd89d4c1e13fb58de4aa07567f3ac11bd From 089995ada123903b9848d0924e868558fe10c8de Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Fri, 11 Apr 2025 13:17:03 +0700 Subject: [PATCH 012/116] Rename .java to .kt --- .../data/model/{CurrencyEntity.java => CurrencyEntity.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/src/main/java/com/brainwallet/data/model/{CurrencyEntity.java => CurrencyEntity.kt} (100%) diff --git a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt similarity index 100% rename from app/src/main/java/com/brainwallet/data/model/CurrencyEntity.java rename to app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt From 7e85987bf446994eb9a648d85517d730898bf99c Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Fri, 11 Apr 2025 13:17:07 +0700 Subject: [PATCH 013/116] chore: refactor BRApiManager & APIClient --- app/build.gradle.kts | 4 +- .../brainwallet/data/model/CurrencyEntity.kt | 61 ++++-- .../data/repository/LtcRepository.kt | 40 ++++ .../data/source/RemoteApiSource.kt | 17 ++ .../main/java/com/brainwallet/di/Module.kt | 76 ++++++- .../presenter/activities/util/BRActivity.java | 11 +- .../tools/manager/BRApiManager.java | 194 ------------------ .../brainwallet/tools/manager/FeeManager.java | 1 + .../worker/CurrencyUpdateWorker.kt | 32 +++ app/src/main/java/com/platform/APIClient.java | 1 + .../currency/BackupRateFetchTests.kt | 140 ++++++------- .../java/com/brainwallet/data/BaseURLTests.kt | 34 +-- .../tools/util/ProdAPIManagerTests.kt | 170 +++++++-------- gradle/libs.versions.toml | 13 +- 14 files changed, 390 insertions(+), 404 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt create mode 100644 app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt delete mode 100644 app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java create mode 100644 app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7d06d2e7..b8f91239 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -216,7 +216,9 @@ dependencies { implementation(platform(libs.koin.bom)) implementation(libs.bundles.koin) - implementation(libs.squareup.okhttp) + implementation(platform(libs.squareup.okhttp.bom)) + implementation(libs.bundles.squareup.okhttp) + implementation(libs.bundles.squareup.retrofit) implementation(libs.jakewarthon.timber) implementation(libs.commons.io) implementation(libs.bundles.eclipse.jetty) diff --git a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt index f0c31051..1ccba70c 100644 --- a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt +++ b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt @@ -1,25 +1,42 @@ -package com.brainwallet.data.model; +package com.brainwallet.data.model -import java.io.Serializable; +import kotlinx.serialization.SerialName +import java.io.Serializable -public class CurrencyEntity implements Serializable { - - //Change this after modifying the class - private static final long serialVersionUID = 7526472295622776147L; - - public static final String TAG = CurrencyEntity.class.getName(); - public String code; - public String name; - public float rate; - public String symbol; - - public CurrencyEntity(String code, String name, float rate, String symbol) { - this.code = code; - this.name = name; - this.rate = rate; - this.symbol = symbol; - } - - public CurrencyEntity() { - } +@kotlinx.serialization.Serializable +data class CurrencyEntity( + @JvmField + var code: String ="", + @JvmField + var name: String = "", + @JvmField + @SerialName("n") + var rate: Float = 0F, + @JvmField + var symbol: String = "" +) : Serializable { +// @JvmField +// var code: String? = null +// @JvmField +// var name: String? = null +// @JvmField +// var rate: Float = 0f +// @JvmField +// var symbol: String? = null +// +// constructor(code: String?, name: String?, rate: Float, symbol: String?) { +// this.code = code +// this.name = name +// this.rate = rate +// this.symbol = symbol +// } +// +// constructor() +// +// companion object { +// //Change this after modifying the class +// private const val serialVersionUID = 7526472295622776147L +// +// val TAG: String = CurrencyEntity::class.java.name +// } } diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt new file mode 100644 index 00000000..02358b34 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -0,0 +1,40 @@ +package com.brainwallet.data.repository + +import android.content.Context +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.source.RemoteApiSource +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.manager.FeeManager +import com.brainwallet.tools.sqlite.CurrencyDataSource + +interface LtcRepository { + suspend fun fetchRates(): List + //todo + + class Impl( + private val context: Context, + private val remoteApiSource: RemoteApiSource, + private val currencyDataSource: CurrencyDataSource + ) : LtcRepository { + + //todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies + override suspend fun fetchRates(): List { + val rates = remoteApiSource.getRates() + + //legacy logic + FeeManager.updateFeePerKb(context) + val selectedISO = BRSharedPrefs.getIsoSymbol(context) + rates.forEachIndexed { index, currencyEntity -> + if (currencyEntity.code.equals(selectedISO, ignoreCase = true)) { + BRSharedPrefs.putIso(context, currencyEntity.code) + BRSharedPrefs.putCurrencyListPosition(context, index - 1) + } + } + + //save to local + currencyDataSource.putCurrencies(rates) + return rates + } + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt new file mode 100644 index 00000000..0ce3bdc8 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt @@ -0,0 +1,17 @@ +package com.brainwallet.data.source + +import com.brainwallet.data.model.CurrencyEntity +import retrofit2.http.GET + +//TODO +interface RemoteApiSource { + + @GET("api/v1/rates") + suspend fun getRates(): List + + @GET("v1/fee-per-kb") + suspend fun getFeePerKb() + +// https://prod.apigsltd.net/moonpay/buy?address=ltc1qjnsg3p9rt4r4vy7ncgvrywdykl0zwhkhcp8ue0&code=USD&idate=1742331930290&uid=ec51fa950b271ff3 +// suspend fun getMoonPayBuy() +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index 75a2cf5f..2da6b071 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -3,10 +3,12 @@ package com.brainwallet.di import android.content.Context import android.content.SharedPreferences import com.brainwallet.BuildConfig +import com.brainwallet.data.repository.LtcRepository import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.data.source.RemoteApiSource import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.sqlite.CurrencyDataSource +import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.screens.home.SettingsViewModel import com.brainwallet.ui.screens.inputwords.InputWordsViewModel import com.brainwallet.ui.screens.ready.ReadyViewModel @@ -17,25 +19,43 @@ import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel import com.brainwallet.ui.screens.yourseedwords.YourSeedWordsViewModel import com.brainwallet.util.cryptography.KeyStoreKeyGenerator import com.brainwallet.util.cryptography.KeyStoreManager +import com.brainwallet.worker.CurrencyUpdateWorker import com.google.firebase.ktx.Firebase import com.google.firebase.remoteconfig.ktx.remoteConfig +import kotlinx.serialization.json.Json +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor import org.koin.android.ext.koin.androidApplication import org.koin.core.module.dsl.viewModel import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.module +import retrofit2.Retrofit +import retrofit2.converter.kotlinx.serialization.asConverterFactory //todo module using koin as di framework here +val json = Json { + ignoreUnknownKeys = true + explicitNulls = false + prettyPrint = true +} + val dataModule = module { + factory { provideOkHttpClient() } + single { provideRetrofit(get(), BRConstants.BW_API_PROD_HOST) } + + single { provideApi(get()) } + single { RemoteConfigSource.FirebaseImpl(Firebase.remoteConfig).also { it.initialize() } } - single { BRApiManager(get()) } single { CurrencyDataSource.getInstance(get()) } single { provideSharedPreferences(context = androidApplication()) } single { SettingRepository.Impl(get(), get()) } + single { LtcRepository.Impl(get(), get(), get()) } } val viewModelModule = module { @@ -51,6 +71,7 @@ val viewModelModule = module { val appModule = module { single { KeyStoreManager(get(), KeyStoreKeyGenerator.Impl()) } + single { CurrencyUpdateWorker(get()) } } private fun provideSharedPreferences( @@ -58,4 +79,53 @@ private fun provideSharedPreferences( name: String = "${BuildConfig.APPLICATION_ID}.prefs" ): SharedPreferences { return context.getSharedPreferences(name, Context.MODE_PRIVATE) -} \ No newline at end of file +} + +private fun provideOkHttpClient(): OkHttpClient = OkHttpClient.Builder() + .addInterceptor { chain -> + val requestBuilder = chain.request() + .newBuilder() + .addHeader("Accept", "application/json") + .addHeader("Content-Type", "application/json") + .addHeader("X-Litecoin-Testnet", "false") + .addHeader("Accept-Language", "en") +// .addHeader("User-agent",) + chain.proceed(requestBuilder.build()) + } + .addInterceptor { chain -> + val request = chain.request() + runCatching { + chain.proceed(request) + }.getOrElse { + //retry using dev host + val newRequest = request.newBuilder() + .url(BRConstants.BW_API_DEV_HOST + request.url.encodedPath) + .build() + chain.proceed(newRequest) + } + } + .addInterceptor(HttpLoggingInterceptor().apply { + setLevel( + when { + BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.BODY + else -> HttpLoggingInterceptor.Level.NONE + } + ) + }) + .build() + +internal fun provideRetrofit( + okHttpClient: OkHttpClient, + baseUrl: String = BRConstants.BW_API_PROD_HOST +): Retrofit = Retrofit.Builder() + .baseUrl(baseUrl) + .client(okHttpClient) + .addConverterFactory( + json.asConverterFactory( + "application/json; charset=UTF8".toMediaType() + ) + ) + .build() + +internal fun provideApi(retrofit: Retrofit): RemoteApiSource = + retrofit.create(RemoteApiSource::class.java) \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java index 6f62d97c..df68dc39 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java @@ -16,7 +16,6 @@ import com.brainwallet.presenter.activities.intro.RecoverActivity; import com.brainwallet.presenter.activities.intro.WriteDownActivity; import com.brainwallet.tools.animation.BRAnimator; -import com.brainwallet.tools.manager.BRApiManager; import com.brainwallet.tools.manager.InternetManager; import com.brainwallet.tools.security.AuthManager; import com.brainwallet.tools.security.BRKeyStore; @@ -25,6 +24,7 @@ import com.brainwallet.tools.threads.BRExecutor; import com.brainwallet.tools.util.BRConstants; import com.brainwallet.wallet.BRWalletManager; +import com.brainwallet.worker.CurrencyUpdateWorker; import org.koin.java.KoinJavaComponent; @@ -51,11 +51,6 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); } -// @Override -// protected void attachBaseContext(Context newBase) { -// super.attachBaseContext(LocaleHelper.Companion.getInstance().setLocale(newBase)); -// } - @Override protected void onStop() { super.onStop(); @@ -148,8 +143,8 @@ public static void init(Activity app) { if (!(app instanceof RecoverActivity || app instanceof WriteDownActivity)) { - BRApiManager apiManager = KoinJavaComponent.get(BRApiManager.class); - apiManager.startTimer(app); + CurrencyUpdateWorker currencyUpdateWorker = KoinJavaComponent.get(CurrencyUpdateWorker.class); + currencyUpdateWorker.start(); } //show wallet locked if it is diff --git a/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java b/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java deleted file mode 100644 index 9b7a81de..00000000 --- a/app/src/main/java/com/brainwallet/tools/manager/BRApiManager.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.brainwallet.tools.manager; - -import static com.brainwallet.tools.util.BRConstants.BW_API_DEV_HOST; -import static com.brainwallet.tools.util.BRConstants.BW_API_PROD_HOST; -import static com.brainwallet.tools.util.BRConstants._20230113_BAC; -import static com.brainwallet.tools.util.BRConstants._20250222_PAC; - -import android.app.Activity; -import android.content.Context; -import android.os.Handler; - -import com.brainwallet.BuildConfig; -import com.brainwallet.data.model.CurrencyEntity; -import com.brainwallet.tools.sqlite.CurrencyDataSource; -import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.Utils; -import com.brainwallet.data.source.RemoteConfigSource; -import com.platform.APIClient; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; - -import okhttp3.Request; -import okhttp3.Response; -import timber.log.Timber; - -public class BRApiManager { - private Timer timer; - - private TimerTask timerTask; - - private Handler handler; - - private RemoteConfigSource remoteConfigSource; - - public BRApiManager(RemoteConfigSource remoteConfigSource) { - this.remoteConfigSource = remoteConfigSource; - this.handler = new Handler(); - } - - private Set getCurrencies(Activity context) { - Set set = new LinkedHashSet<>(); - try { - JSONArray arr = fetchRates(context); - FeeManager.updateFeePerKb(context); - if (arr != null) { - String selectedISO = BRSharedPrefs.getIsoSymbol(context); - int length = arr.length(); - for (int i = 0; i < length; i++) { - CurrencyEntity tempCurrencyEntity = new CurrencyEntity(); - try { - JSONObject tmpJSONObj = (JSONObject) arr.get(i); - tempCurrencyEntity.name = tmpJSONObj.getString("name"); - tempCurrencyEntity.code = tmpJSONObj.getString("code"); - tempCurrencyEntity.rate = (float) tmpJSONObj.getDouble("n"); - tempCurrencyEntity.symbol = new String(""); - if (tempCurrencyEntity.code.equalsIgnoreCase(selectedISO)) { - BRSharedPrefs.putIso(context, tempCurrencyEntity.code); - BRSharedPrefs.putCurrencyListPosition(context, i - 1); - } - set.add(tempCurrencyEntity); - } catch (JSONException e) { - Timber.e(e); - } - } - } else { - Timber.d("timber: getCurrencies: failed to get currencies"); - } - } catch (Exception e) { - Timber.e(e); - } - List tempList = new ArrayList<>(set); - Collections.reverse(tempList); - return new LinkedHashSet<>(set); - } - - - private void initializeTimerTask(final Context context) { - timerTask = new TimerTask() { - public void run() { - //use a handler to run a toast that shows the current timestamp - handler.post(new Runnable() { - public void run() { - BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { - @Override - public void run() { - Set tmp = getCurrencies((Activity) context); - CurrencyDataSource.getInstance(context).putCurrencies(tmp); - } - }); - } - }); - } - }; - } - - public void startTimer(Context context) { - //set a new Timer - if (timer != null) return; - timer = new Timer(); - - //initialize the TimerTask's job - initializeTimerTask(context); - - //schedule the timer, after the first 0ms the TimerTask will run every 60000ms - timer.schedule(timerTask, 0, 4000); - } - - public JSONArray fetchRates(Activity activity) { - String jsonString = createGETRequestURL(activity, BW_API_PROD_HOST + "/api/v1/rates"); - JSONArray jsonArray = null; - if (jsonString == null) return null; - try { - jsonArray = new JSONArray(jsonString); - // DEV Uncomment to view values - // Timber.d("timber: baseUrlProd: %s", getBaseUrlProd()); - // Timber.d("timber: JSON %s",jsonArray.toString()); - } catch (JSONException ex) { - Timber.e(ex); - } - if (jsonArray != null && !BuildConfig.DEBUG) { - AnalyticsManager.logCustomEvent(_20250222_PAC); - } - return jsonArray == null ? backupFetchRates(activity) : jsonArray; - } - - public JSONArray backupFetchRates(Activity activity) { - String jsonString = createGETRequestURL(activity, BW_API_DEV_HOST + "/api/v1/rates"); - - JSONArray jsonArray = null; - if (jsonString == null) return null; - try { - jsonArray = new JSONArray(jsonString); - - } catch (JSONException e) { - Timber.e(e); - } - if (jsonArray != null && !BuildConfig.DEBUG) { - AnalyticsManager.logCustomEvent(_20230113_BAC); - } - - return jsonArray; - } - - // createGETRequestURL - // Creates the params and headers to make a GET Request - private String createGETRequestURL(Context app, String myURL) { - Request request = new Request.Builder() - .url(myURL) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .header("User-agent", Utils.getAgentString(app, "android/HttpURLConnection")) - .get().build(); - String response = null; - Response resp = APIClient.getInstance(app).sendRequest(request, false, 0); - - try { - if (resp == null) { - Timber.i("timber: urlGET: %s resp is null", myURL); - return null; - } - ///Set timestamp to prefs - long timeStamp = new Date().getTime(); - BRSharedPrefs.putSecureTime(app, timeStamp); - - assert resp.body() != null; - response = resp.body().string(); - - } catch (IOException e) { - Timber.e(e); - } finally { - if (resp != null) resp.close(); - } - return response; - } - - public String getBaseUrlProd() { - return BW_API_PROD_HOST; - } -} diff --git a/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java b/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java index 3ca79a7b..91e12a9e 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java @@ -95,6 +95,7 @@ public static void updateFeePerKb(Context app) { // createGETRequestURL // Creates the params and headers to make a GET Request + @Deprecated private static String createGETRequestURL(Context app, String myURL) { Request request = new Request.Builder() .url(myURL) diff --git a/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt b/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt new file mode 100644 index 00000000..739da912 --- /dev/null +++ b/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt @@ -0,0 +1,32 @@ +package com.brainwallet.worker + +import com.brainwallet.data.repository.LtcRepository +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch + +class CurrencyUpdateWorker( + private val ltcRepository: LtcRepository +) { + private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + private var job: Job? = null + + fun start() { + if (job?.isActive == true && job != null) { + job?.cancel() + } + + job = scope.launch(Dispatchers.IO) { + while (isActive) { + ltcRepository.fetchRates() + delay(4000L) //4secs + } + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/com/platform/APIClient.java b/app/src/main/java/com/platform/APIClient.java index da333b08..d55592cf 100644 --- a/app/src/main/java/com/platform/APIClient.java +++ b/app/src/main/java/com/platform/APIClient.java @@ -35,6 +35,7 @@ import static com.brainwallet.tools.util.BRCompressor.gZipExtract; +@Deprecated public class APIClient { // proto is the transport protocol to use for talking to the API (either http or https) diff --git a/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt b/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt index ba5c19ec..9e997f57 100644 --- a/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt +++ b/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt @@ -4,7 +4,6 @@ import android.app.Activity import android.content.Context import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.presenter.activities.util.ActivityUTILS -import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.util.BRConstants import com.brainwallet.tools.util.Utils import com.platform.APIClient @@ -20,74 +19,75 @@ import okhttp3.ResponseBody.Companion.toResponseBody import org.junit.Before import org.junit.Test +//TODO: need update this test after refactor class BackupRateFetchTests { - private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: BRApiManager - - @Before - fun setUp() { - apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) - } - - @Test - fun `invoke backupFetchRates, should return success with parsed JSONArray`() { - val activity: Activity = mockk(relaxed = true) - val responseString = """ - [ - { - "code" : "CZK", - "price" : "Kč3065.541255", - "name" : "Czech Republic Koruna", - "n" : 3065.541255 - }, - { - "code" : "KRW", - "price" : "₩183797.935875", - "name" : "South Korean Won", - "n" : 183797.935875 - }, - { - "code" : "BYN", - "price" : "Br418.909259625", - "n" : 418.909259625 - }, - { - "code" : "CNY", - "price" : "CN¥927.7974375", - "name" : "Chinese Yuan", - "n" : 927.7974375 - } - ] - """.trimIndent() - mockkStatic(ActivityUTILS::class) - mockkObject(APIClient.getInstance(activity)) - every { - remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_PROD_NEW_ENABLED) - } returns false - every { - apiManager invoke "createGETRequestURL" withArguments (listOf( - activity as Context, - BRConstants.BW_API_DEV_HOST - )) - } returns responseString - every { ActivityUTILS.isMainThread() } returns false - every { APIClient.getInstance(activity).getCurrentLocale(activity) } returns "en" - - val request = Request.Builder() - .url(BRConstants.BW_API_DEV_HOST) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .header("User-agent", Utils.getAgentString(activity, "android/HttpURLConnection")) - .get().build() - every { - APIClient.getInstance(activity).sendRequest(request, false, 0) - } returns Response.Builder() - .request(request) - .protocol(Protocol.HTTP_1_1) - .code(200) - .message("OK") - .body(responseString.toResponseBody()) - .build() - - } +// private val remoteConfigSource: RemoteConfigSource = mockk() +// private lateinit var apiManager: BRApiManager +// +// @Before +// fun setUp() { +// apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) +// } +// +// @Test +// fun `invoke backupFetchRates, should return success with parsed JSONArray`() { +// val activity: Activity = mockk(relaxed = true) +// val responseString = """ +// [ +// { +// "code" : "CZK", +// "price" : "Kč3065.541255", +// "name" : "Czech Republic Koruna", +// "n" : 3065.541255 +// }, +// { +// "code" : "KRW", +// "price" : "₩183797.935875", +// "name" : "South Korean Won", +// "n" : 183797.935875 +// }, +// { +// "code" : "BYN", +// "price" : "Br418.909259625", +// "n" : 418.909259625 +// }, +// { +// "code" : "CNY", +// "price" : "CN¥927.7974375", +// "name" : "Chinese Yuan", +// "n" : 927.7974375 +// } +// ] +// """.trimIndent() +// mockkStatic(ActivityUTILS::class) +// mockkObject(APIClient.getInstance(activity)) +// every { +// remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_PROD_NEW_ENABLED) +// } returns false +// every { +// apiManager invoke "createGETRequestURL" withArguments (listOf( +// activity as Context, +// BRConstants.BW_API_DEV_HOST +// )) +// } returns responseString +// every { ActivityUTILS.isMainThread() } returns false +// every { APIClient.getInstance(activity).getCurrentLocale(activity) } returns "en" +// +// val request = Request.Builder() +// .url(BRConstants.BW_API_DEV_HOST) +// .header("Content-Type", "application/json") +// .header("Accept", "application/json") +// .header("User-agent", Utils.getAgentString(activity, "android/HttpURLConnection")) +// .get().build() +// every { +// APIClient.getInstance(activity).sendRequest(request, false, 0) +// } returns Response.Builder() +// .request(request) +// .protocol(Protocol.HTTP_1_1) +// .code(200) +// .message("OK") +// .body(responseString.toResponseBody()) +// .build() +// +// } } \ No newline at end of file diff --git a/app/src/test/java/com/brainwallet/data/BaseURLTests.kt b/app/src/test/java/com/brainwallet/data/BaseURLTests.kt index d0163299..f0423f90 100644 --- a/app/src/test/java/com/brainwallet/data/BaseURLTests.kt +++ b/app/src/test/java/com/brainwallet/data/BaseURLTests.kt @@ -1,7 +1,6 @@ package com.brainwallet.data import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.tools.manager.BRApiManager import com.brainwallet.tools.util.BRConstants import io.mockk.every import io.mockk.mockk @@ -10,24 +9,25 @@ import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test +//TODO: need update this test after refactor class BaseURLTests { - private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: BRApiManager - - @Before - fun setUp() { - apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) - } - - @Test - fun `invoke getBaseUrlProd with KEY_API_BASEURL_PROD_NEW_ENABLED true, then should return new baseUrlProd`() { - every { remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_PROD_NEW_ENABLED) } returns true - - val actual = apiManager.baseUrlProd - - assertEquals(BRConstants.BW_API_PROD_HOST, actual) - } +// private val remoteConfigSource: RemoteConfigSource = mockk() +// private lateinit var apiManager: BRApiManager +// +// @Before +// fun setUp() { +// apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) +// } +// +// @Test +// fun `invoke getBaseUrlProd with KEY_API_BASEURL_PROD_NEW_ENABLED true, then should return new baseUrlProd`() { +// every { remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_PROD_NEW_ENABLED) } returns true +// +// val actual = apiManager.baseUrlProd +// +// assertEquals(BRConstants.BW_API_PROD_HOST, actual) +// } } diff --git a/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt b/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt index 2386d1f0..1dfee111 100644 --- a/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt +++ b/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt @@ -4,7 +4,6 @@ import android.app.Activity import android.content.Context import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.presenter.activities.util.ActivityUTILS -import com.brainwallet.tools.manager.BRApiManager import com.platform.APIClient import io.mockk.every import io.mockk.mockk @@ -20,89 +19,90 @@ import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test +//TODO: need update this test after refactor class ProdAPIManagerTests { - private val remoteConfigSource: RemoteConfigSource = mockk() - private lateinit var apiManager: BRApiManager - - @Before - fun setUp() { - apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) - } - - @Test - fun `invoke fetchRates, should return success with parsed JSONArray`() { - val activity: Activity = mockk(relaxed = true) - - val responseString = """ - [ - { - "code": "USD", - "n": 416.81128312406213, - "price": "USD416.811283124062145364", - "name": "US Dollar" - }, - { - "code": "EUR", - "n": 7841.21263788453, - "price": "Af7841.212637884529266812", - "name": "Euro" - }, - { - "code": "GBP", - "n": 10592.359754930994, - "price": "ALL10592.359754930995026136", - "name": "British Pound" - } - ] - """.trimIndent() - mockkStatic(ActivityUTILS::class) - mockkObject(APIClient.getInstance(activity)) - every { - remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_PROD_NEW_ENABLED) - } returns false - every { - apiManager invoke "createGETRequestURL" withArguments (listOf( - activity as Context, - BRConstants.BW_API_PROD_HOST - )) - } returns responseString - every { ActivityUTILS.isMainThread() } returns false - every { APIClient.getInstance(activity).getCurrentLocale(activity) } returns "en" - - val request = Request.Builder() - .url(BRConstants.BW_API_PROD_HOST) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .header("User-agent", Utils.getAgentString(activity, "android/HttpURLConnection")) - .get().build() - every { - APIClient.getInstance(activity).sendRequest(request, false, 0) - } returns Response.Builder() - .request(request) - .protocol(Protocol.HTTP_1_1) - .code(200) - .message("OK") - .body(responseString.toResponseBody()) - .build() - - val result = apiManager.fetchRates(activity) - val jsonUSD = result.getJSONObject(154) - val jsonEUR = result.getJSONObject(49) - val jsonGBP = result.getJSONObject(52) - - assertEquals("USD", jsonUSD.optString("code")) - assertEquals("US Dollar", jsonUSD.optString("name")) - assertEquals("EUR", jsonEUR.optString("code")) - assertEquals("Euro", jsonEUR.optString("name")) - assertEquals("GBP", jsonGBP.optString("code")) - assertEquals("British Pound Sterling", jsonGBP.optString("name")) - - ///DEV: Very flaky test not enough time for the response - verifyAll { - ActivityUTILS.isMainThread() - APIClient.getInstance(activity).getCurrentLocale(activity) - APIClient.getInstance(activity).sendRequest(any(), any(), any()) - } - - } +// private val remoteConfigSource: RemoteConfigSource = mockk() +// private lateinit var apiManager: BRApiManager +// +// @Before +// fun setUp() { +// apiManager = spyk(BRApiManager(remoteConfigSource), recordPrivateCalls = true) +// } +// +// @Test +// fun `invoke fetchRates, should return success with parsed JSONArray`() { +// val activity: Activity = mockk(relaxed = true) +// +// val responseString = """ +// [ +// { +// "code": "USD", +// "n": 416.81128312406213, +// "price": "USD416.811283124062145364", +// "name": "US Dollar" +// }, +// { +// "code": "EUR", +// "n": 7841.21263788453, +// "price": "Af7841.212637884529266812", +// "name": "Euro" +// }, +// { +// "code": "GBP", +// "n": 10592.359754930994, +// "price": "ALL10592.359754930995026136", +// "name": "British Pound" +// } +// ] +// """.trimIndent() +// mockkStatic(ActivityUTILS::class) +// mockkObject(APIClient.getInstance(activity)) +// every { +// remoteConfigSource.getBoolean(RemoteConfigSource.KEY_API_BASEURL_PROD_NEW_ENABLED) +// } returns false +// every { +// apiManager invoke "createGETRequestURL" withArguments (listOf( +// activity as Context, +// BRConstants.BW_API_PROD_HOST +// )) +// } returns responseString +// every { ActivityUTILS.isMainThread() } returns false +// every { APIClient.getInstance(activity).getCurrentLocale(activity) } returns "en" +// +// val request = Request.Builder() +// .url(BRConstants.BW_API_PROD_HOST) +// .header("Content-Type", "application/json") +// .header("Accept", "application/json") +// .header("User-agent", Utils.getAgentString(activity, "android/HttpURLConnection")) +// .get().build() +// every { +// APIClient.getInstance(activity).sendRequest(request, false, 0) +// } returns Response.Builder() +// .request(request) +// .protocol(Protocol.HTTP_1_1) +// .code(200) +// .message("OK") +// .body(responseString.toResponseBody()) +// .build() +// +// val result = apiManager.fetchRates(activity) +// val jsonUSD = result.getJSONObject(154) +// val jsonEUR = result.getJSONObject(49) +// val jsonGBP = result.getJSONObject(52) +// +// assertEquals("USD", jsonUSD.optString("code")) +// assertEquals("US Dollar", jsonUSD.optString("name")) +// assertEquals("EUR", jsonEUR.optString("code")) +// assertEquals("Euro", jsonEUR.optString("name")) +// assertEquals("GBP", jsonGBP.optString("code")) +// assertEquals("British Pound Sterling", jsonGBP.optString("name")) +// +// ///DEV: Very flaky test not enough time for the response +// verifyAll { +// ActivityUTILS.isMainThread() +// APIClient.getInstance(activity).getCurrentLocale(activity) +// APIClient.getInstance(activity).sendRequest(any(), any(), any()) +// } +// +// } } \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f4ab271f..90f8dedd 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -23,7 +23,8 @@ google-zxing = "3.5.2" google-play-asset-delivery = "2.2.2" google-play-feature-delivery = "2.1.0" google-play-review = "2.0.1" -squareup-okhttp = "4.12.0" +squareup-okhttp-bom = "4.12.0" +squareup-retrofit = "2.11.0" firebase-bom = "32.7.1" jakewarthon-timber = "4.7.1" eclipse-jetty = "9.2.19.v20160908" @@ -68,8 +69,6 @@ androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui- androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-work = { module = "androidx.work:work-runtime-ktx", version.ref = "androidx-work" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.7.1" } -#google-dagger = { module = "com.google.dagger:dagger", version.ref = "google-dagger" } -#google-dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "google-dagger" } google-zxing = { module = "com.google.zxing:core", version.ref = "google-zxing" } google-material = { module = "com.google.android.material:material", version.ref = "google-material" } google-play-asset-delivery = { module = "com.google.android.play:asset-delivery", version.ref = "google-play-asset-delivery" } @@ -78,7 +77,11 @@ google-play-feature-delivery = { module = "com.google.android.play:feature-deliv google-play-feature-delivery-ktx = { module = "com.google.android.play:feature-delivery-ktx", version.ref = "google-play-feature-delivery" } google-play-review = { module = "com.google.android.play:review", version.ref = "google-play-review" } google-play-review-ktx = { module = "com.google.android.play:review-ktx", version.ref = "google-play-review" } -squareup-okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "squareup-okhttp" } +squareup-okhttp-bom = { module = "com.squareup.okhttp3:okhttp-bom", version.ref = "squareup-okhttp-bom" } +squareup-okhttp = { module = "com.squareup.okhttp3:okhttp" } +squareup-okhttp-logging-interceptor = { module = "com.squareup.okhttp3:logging-interceptor" } +squareup-retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "squareup-retrofit" } +squareup-retrofit-kotlinx-serialization-json = { module = "com.squareup.retrofit2:converter-kotlinx-serialization", version.ref = "squareup-retrofit" } firebase-bom = { module = "com.google.firebase:firebase-bom", version.ref = "firebase-bom" } firebase-analytics = { module = "com.google.firebase:firebase-analytics" } firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics" } @@ -123,6 +126,8 @@ eclipse-jetty = ["eclipse-jetty-webapp", "eclipse-jetty-websocket", "eclipse-jet android-test = ["androidx-test-core", "androidx-test-core-ktx", "androidx-test-rules","androidx-test-espresso-core", "androidx-test-junit-ext","androidx-test-juniext-ext-ktx", "androidx-test-runner", "androidx-test-uiautomator"] androidx-compose-ui-test = ["androidx-compose-ui-test-junit4", "androidx-compose-ui-test-manifest"] koin = ["koin-android", "koin-android-compat", "koin-compose", "koin-compose-viewmodel"] +squareup-retrofit = ["squareup-retrofit", "squareup-retrofit-kotlinx-serialization-json"] +squareup-okhttp = ["squareup-okhttp", "squareup-okhttp-logging-interceptor"] [plugins] android-application = { id = "com.android.application", version.ref = "agp" } From 0aa41e77d719adf9524f2ec5a20644722dbc560d Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Mon, 14 Apr 2025 13:25:26 +0700 Subject: [PATCH 014/116] chore: remove unused part at APIClient --- app/src/main/java/com/platform/APIClient.java | 99 +++---------------- 1 file changed, 15 insertions(+), 84 deletions(-) diff --git a/app/src/main/java/com/platform/APIClient.java b/app/src/main/java/com/platform/APIClient.java index d55592cf..90b22f68 100644 --- a/app/src/main/java/com/platform/APIClient.java +++ b/app/src/main/java/com/platform/APIClient.java @@ -1,24 +1,17 @@ package com.platform; -import android.annotation.TargetApi; +import static com.brainwallet.tools.util.BRCompressor.gZipExtract; + import android.content.Context; -import android.content.pm.ApplicationInfo; import android.net.Uri; -import android.os.Build; import android.os.NetworkOnMainThreadException; import com.brainwallet.BrainwalletApp; -import com.brainwallet.BrainwalletApp; -import com.brainwallet.BuildConfig; import com.brainwallet.presenter.activities.util.ActivityUTILS; -import com.brainwallet.tools.util.BRConstants; import com.brainwallet.tools.util.Utils; -import org.json.JSONException; -import org.json.JSONObject; - import java.io.IOException; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.concurrent.TimeUnit; @@ -30,11 +23,8 @@ import okhttp3.Response; import okhttp3.ResponseBody; import timber.log.Timber; -import com.brainwallet.tools.manager.AnalyticsManager; -import com.brainwallet.tools.util.BRConstants; - -import static com.brainwallet.tools.util.BRCompressor.gZipExtract; +//some part still used e.g. [sendRequest] @Deprecated public class APIClient { @@ -55,12 +45,12 @@ public class APIClient { private static final boolean PRINT_FILES = false; - private SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); + private final SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); - private boolean platformUpdating = false; + private final boolean platformUpdating = false; private AtomicInteger itemsLeftToUpdate = new AtomicInteger(0); - private Context ctx; + private final Context ctx; public static synchronized APIClient getInstance(Context context) { if (ourInstance == null) ourInstance = new APIClient(context); @@ -72,42 +62,14 @@ private APIClient(Context context) { itemsLeftToUpdate = new AtomicInteger(0); } - //returns the fee per kb or 0 if something went wrong - public long feePerKb() { - if (ActivityUTILS.isMainThread()) { - throw new NetworkOnMainThreadException(); - } - Response response = null; - try { - String strUtl = BASE_URL + FEE_PER_KB_URL; - Request request = new Request.Builder().url(strUtl).get().build(); - String body = null; - try { - response = sendRequest(request, false, 0); - body = response.body().string(); - Timber.d("timber: fee per kb %s",body); - } catch (IOException e) { - Timber.e(e); - AnalyticsManager.logCustomEvent(BRConstants._20200111_RNI); - } - JSONObject object = null; - object = new JSONObject(body); - return (long) object.getInt("fee_per_kb"); - } catch (JSONException e) { - Timber.e(e); - } finally { - if (response != null) response.close(); - } - return 0; - } - + // sendRequest still using, e.g. inside RemoteKVStore public Response sendRequest(Request locRequest, boolean needsAuth, int retryCount) { if (retryCount > 1) throw new RuntimeException("sendRequest: Warning retryCount is: " + retryCount); if (ActivityUTILS.isMainThread()) { throw new NetworkOnMainThreadException(); } - String lang = getCurrentLocale(ctx); + String lang = ctx.getResources().getConfiguration().locale.getLanguage(); Request request = locRequest.newBuilder() .header("X-Litecoin-Testnet", "false") .header("Accept-Language", lang) @@ -154,23 +116,15 @@ public Response sendRequest(Request locRequest, boolean needsAuth, int retryCoun Timber.d("timber: sendRequest: the content is gzip, unzipping"); byte[] decompressed = gZipExtract(data); postReqBody = ResponseBody.create(null, decompressed); - try { - if (response.code() != 200) { - Timber.d("timber: sendRequest: (%s)%s, code (%d), mess (%s), body (%s)", request.method(), - request.url(), response.code(), response.message(), new String(decompressed, "utf-8")); - } - } catch (UnsupportedEncodingException e) { - Timber.e(e); + if (response.code() != 200) { + Timber.d("timber: sendRequest: (%s)%s, code (%d), mess (%s), body (%s)", request.method(), + request.url(), response.code(), response.message(), new String(decompressed, StandardCharsets.UTF_8)); } return response.newBuilder().body(postReqBody).build(); } else { - try { - if (response.code() != 200) { - Timber.d("timber: sendRequest: (%s)%s, code (%d), mess (%s), body (%s)", request.method(), - request.url(), response.code(), response.message(), new String(data, "utf-8")); - } - } catch (UnsupportedEncodingException e) { - Timber.e(e); + if (response.code() != 200) { + Timber.d("timber: sendRequest: (%s)%s, code (%d), mess (%s), body (%s)", request.method(), + request.url(), response.code(), response.message(), new String(data, StandardCharsets.UTF_8)); } } @@ -178,27 +132,4 @@ public Response sendRequest(Request locRequest, boolean needsAuth, int retryCoun return response.newBuilder().body(postReqBody).build(); } - - public String buildUrl(String path) { - return BASE_URL + path; - } - - private void itemFinished() { - int items = itemsLeftToUpdate.incrementAndGet(); - if (items >= 4) { - Timber.d("timber: PLATFORM ALL UPDATED: %s", items); - platformUpdating = false; - itemsLeftToUpdate.set(0); - } - } - - @TargetApi(Build.VERSION_CODES.N) - public String getCurrentLocale(Context ctx) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - return ctx.getResources().getConfiguration().getLocales().get(0).getLanguage(); - } else { - //noinspection deprecation - return ctx.getResources().getConfiguration().locale.getLanguage(); - } - } } From 0cc29cbcd9ec8ffca56d5c6bb4da98dd8a0882a7 Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Mon, 14 Apr 2025 15:41:13 +0700 Subject: [PATCH 015/116] feat: wip new peer discovery --- .../repository/SelectedPeersRepository.kt | 81 +++++++++++++++++++ .../data/source/RemoteConfigSource.kt | 4 +- .../main/java/com/brainwallet/di/Module.kt | 2 + .../com/brainwallet/wallet/BRPeerManager.java | 37 ++++++++- .../brainwallet/wallet/BRWalletManager.java | 2 +- .../main/res/xml/remote_config_defaults.xml | 10 +-- 6 files changed, 121 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt diff --git a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt new file mode 100644 index 00000000..766cfb7d --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt @@ -0,0 +1,81 @@ +package com.brainwallet.data.repository + +import android.content.SharedPreferences +import androidx.core.content.edit +import com.brainwallet.di.json +import kotlinx.serialization.json.jsonObject +import okhttp3.Call +import okhttp3.Callback +import okhttp3.OkHttpClient +import okhttp3.Response +import okio.IOException +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine + +interface SelectedPeersRepository { + + suspend fun fetchSelectedPeers(): Set + + class Impl( + private val okHttpClient: OkHttpClient, + private val sharedPreferences: SharedPreferences, + ) : SelectedPeersRepository { + + private companion object { + const val PREF_KEY_SELECTED_PEERS = "selected_peers" + const val PREF_KEY_SELECTED_PEERS_CACHED_AT = "${PREF_KEY_SELECTED_PEERS}_cached_at" + } + + override suspend fun fetchSelectedPeers(): Set { + val lastUpdateTime = sharedPreferences.getLong(PREF_KEY_SELECTED_PEERS_CACHED_AT, 0) + val currentTime = System.currentTimeMillis() + val cachedPeers = sharedPreferences.getStringSet(PREF_KEY_SELECTED_PEERS, null) + + // Check if cache exists and is less than 6 hours old + if (!cachedPeers.isNullOrEmpty() && (currentTime - lastUpdateTime) < 6 * 60 * 60 * 1000) { + return cachedPeers + } + + val request = okhttp3.Request.Builder() + .url(LITECOIN_NODES_URL) + .build() + + return suspendCoroutine { continuation -> + okHttpClient.newCall(request).enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + continuation.resume(emptySet()) //just return empty if failed or need hardcoded? + } + + override fun onResponse(call: Call, response: Response) { + val jsonString = response.body?.string() + + val parsedResult = jsonString?.let { + val jsonElement = json.parseToJsonElement(it) + val dataObject = jsonElement.jsonObject["data"]?.jsonObject + val nodesObject = dataObject?.get("nodes")?.jsonObject + + //TODO: need filter criteria here? + nodesObject?.keys + ?.filter { it.endsWith(":9333") } + ?.map { it.replace(":9333", "") } + ?.toSet() + ?: emptySet() + } ?: emptySet() + + sharedPreferences.edit { + putStringSet(PREF_KEY_SELECTED_PEERS, parsedResult) + putLong(PREF_KEY_SELECTED_PEERS_CACHED_AT, currentTime) + } + + continuation.resume(parsedResult) + } + }) + } + } + + } + + companion object { + const val LITECOIN_NODES_URL = "https://api.blockchair.com/litecoin/nodes" + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt index 058d8dc9..dc5c7ff4 100644 --- a/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt @@ -13,9 +13,7 @@ interface RemoteConfigSource { companion object { const val KEY_FEATURE_MENU_HIDDEN_EXAMPLE = "feature_menu_hidden_example" - const val KEY_API_BASEURL_PROD_NEW_ENABLED = "key_api_baseurl_prod_new_enabled" - const val KEY_API_BASEURL_DEV_NEW_ENABLED = "key_api_baseurl_dev_new_enabled" - const val KEY_KEYSTORE_MANAGER_ENABLED = "key_keystore_manager_enabled" + const val KEY_FEATURE_SELECTED_PEERS_ENABLED = "feature_selected_peers_enabled" } fun initialize() diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index 2da6b071..e64e071a 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -7,6 +7,7 @@ import com.brainwallet.data.repository.LtcRepository import com.brainwallet.data.repository.SettingRepository import com.brainwallet.data.source.RemoteApiSource import com.brainwallet.data.source.RemoteConfigSource +import com.brainwallet.data.repository.SelectedPeersRepository import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.screens.home.SettingsViewModel @@ -52,6 +53,7 @@ val dataModule = module { it.initialize() } } + single { SelectedPeersRepository.Impl(get(), get()) } single { CurrencyDataSource.getInstance(get()) } single { provideSharedPreferences(context = androidApplication()) } single { SettingRepository.Impl(get(), get()) } diff --git a/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java b/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java index 0cc46e61..a27938b8 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java @@ -1,8 +1,12 @@ package com.brainwallet.wallet; +import static com.brainwallet.data.source.RemoteConfigSource.KEY_FEATURE_SELECTED_PEERS_ENABLED; + import android.content.Context; import com.brainwallet.BrainwalletApp; +import com.brainwallet.data.repository.SelectedPeersRepository; +import com.brainwallet.data.source.RemoteConfigSource; import com.brainwallet.presenter.entities.BlockEntity; import com.brainwallet.presenter.entities.PeerEntity; import com.brainwallet.tools.manager.BRSharedPrefs; @@ -12,10 +16,18 @@ import com.brainwallet.tools.threads.BRExecutor; import com.brainwallet.tools.util.TrustedNode; +import org.koin.java.KoinJavaComponent; + import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Set; +import java.util.concurrent.CompletableFuture; +import kotlin.coroutines.EmptyCoroutineContext; +import kotlinx.coroutines.CoroutineScopeKt; +import kotlinx.coroutines.CoroutineStart; +import kotlinx.coroutines.future.FutureKt; import timber.log.Timber; public class BRPeerManager { @@ -164,7 +176,7 @@ public void updateFixedPeer(Context ctx) { } else { Timber.d("timber: updateFixedPeer: succeeded"); } - connect(); + wrapConnectV2(); } public void networkChanged(boolean isOnline) { @@ -172,11 +184,21 @@ public void networkChanged(boolean isOnline) { BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { @Override public void run() { - BRPeerManager.getInstance().connect(); + wrapConnectV2(); } }); } + //wrap logic enable/disable connect with new flow + public void wrapConnectV2() { + RemoteConfigSource remoteConfigSource = KoinJavaComponent.get(RemoteConfigSource.class); + if (remoteConfigSource.getBoolean(KEY_FEATURE_SELECTED_PEERS_ENABLED)) { + fetchSelectedPeers().whenComplete((strings, throwable) -> connect()); + } else { + connect(); + } + } + public void addStatusUpdateListener(OnTxStatusUpdate listener) { if (statusUpdateListeners.contains(listener)) return; statusUpdateListeners.add(listener); @@ -186,6 +208,17 @@ public void removeListener(OnTxStatusUpdate listener) { statusUpdateListeners.remove(listener); } + public CompletableFuture> fetchSelectedPeers() { + SelectedPeersRepository selectedPeersRepository = KoinJavaComponent.get(SelectedPeersRepository.class); + + return FutureKt.future( + CoroutineScopeKt.CoroutineScope(EmptyCoroutineContext.INSTANCE), + EmptyCoroutineContext.INSTANCE, + CoroutineStart.DEFAULT, + (coroutineScope, continuation) -> selectedPeersRepository.fetchSelectedPeers(continuation) + ); + } + public static void setOnSyncFinished(OnSyncSucceeded listener) { onSyncFinished = listener; } diff --git a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java index 792fad8e..d5aee0d2 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java @@ -547,7 +547,7 @@ public void initWallet(final Context ctx) { BRPeerManager.getInstance().updateFixedPeer(ctx); } - pm.connect(); + pm.wrapConnectV2(); if (BRSharedPrefs.getStartHeight(ctx) == 0) { BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { @Override diff --git a/app/src/main/res/xml/remote_config_defaults.xml b/app/src/main/res/xml/remote_config_defaults.xml index e9f361c4..6852653a 100644 --- a/app/src/main/res/xml/remote_config_defaults.xml +++ b/app/src/main/res/xml/remote_config_defaults.xml @@ -1,15 +1,7 @@ - key_api_baseurl_prod_new_enabled - false - - - key_api_baseurl_dev_new_enabled - false - - - key_keystore_manager_enabled + feature_selected_peers_enabled true From 54d2d9ef348caf53948423c9da73ccd617504541 Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Tue, 15 Apr 2025 04:51:09 +0700 Subject: [PATCH 016/116] feat: implement selected peer ip address from cache (fetched from API) --- .../com/brainwallet/wallet/BRPeerManager.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java b/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java index a27938b8..209814e7 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Set; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import kotlin.coroutines.EmptyCoroutineContext; import kotlinx.coroutines.CoroutineScopeKt; @@ -191,14 +192,18 @@ public void run() { //wrap logic enable/disable connect with new flow public void wrapConnectV2() { - RemoteConfigSource remoteConfigSource = KoinJavaComponent.get(RemoteConfigSource.class); - if (remoteConfigSource.getBoolean(KEY_FEATURE_SELECTED_PEERS_ENABLED)) { + if (featureSelectedPeersEnabled()) { fetchSelectedPeers().whenComplete((strings, throwable) -> connect()); } else { connect(); } } + public static boolean featureSelectedPeersEnabled() { + RemoteConfigSource remoteConfigSource = KoinJavaComponent.get(RemoteConfigSource.class); + return remoteConfigSource.getBoolean(KEY_FEATURE_SELECTED_PEERS_ENABLED); + } + public void addStatusUpdateListener(OnTxStatusUpdate listener) { if (statusUpdateListeners.contains(listener)) return; statusUpdateListeners.add(listener); @@ -219,6 +224,14 @@ public CompletableFuture> fetchSelectedPeers() { ); } + public static Set fetchSelectedPeersBlocking() { + try { + return BRPeerManager.getInstance().fetchSelectedPeers().get(); + } catch (ExecutionException | InterruptedException e) { + return java.util.Collections.emptySet(); + } + } + public static void setOnSyncFinished(OnSyncSucceeded listener) { onSyncFinished = listener; } From c6923b11b89de4ee4ed48ec0b4f69aa3f01b0334 Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Tue, 15 Apr 2025 04:52:02 +0700 Subject: [PATCH 017/116] feat: implement selected peer ip address from cache (fetched from API) --- app/src/main/jni/transition/PeerManager.c | 106 +++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/app/src/main/jni/transition/PeerManager.c b/app/src/main/jni/transition/PeerManager.c index 48e50f92..4c2ce73e 100644 --- a/app/src/main/jni/transition/PeerManager.c +++ b/app/src/main/jni/transition/PeerManager.c @@ -226,6 +226,109 @@ static int networkIsReachable(void *info) { return (isNetworkOn == JNI_TRUE) ? 1 : 0; } +/** + * communicate with java to check if featureSelectedPeersEnabled is on + */ +static int featureSelectedPeersEnabled(void *info) { + __android_log_print(ANDROID_LOG_DEBUG, "Message from C: ", "featureSelectedPeersEnabled"); + + JNIEnv *env = getEnv(); + jmethodID mid; + jboolean isFeatureSelectedPeersOn; + + if (!env) return 0; + + //call java methods + mid = (*env)->GetStaticMethodID(env, _peerManagerClass, "featureSelectedPeersEnabled", "()Z"); + isFeatureSelectedPeersOn = (*env)->CallStaticBooleanMethod(env, _peerManagerClass, mid); + return (isFeatureSelectedPeersOn == JNI_TRUE) ? 1 : 0; +} + +/** + * obtain selected peers from BRPeerManager.fetchSelectedPeersBlocking + */ +static char **fetchSelectedPeers(void *info) { + __android_log_print(ANDROID_LOG_DEBUG, "Message from C: ", "fetchSelectedPeers"); + + JNIEnv *env = getEnv(); + if (!env) return NULL; + + jclass peerManagerClass = (*env)->FindClass(env, "com/brainwallet/wallet/BRPeerManager"); + if (!peerManagerClass) return NULL; + + jmethodID fetchSelectedPeersBlockingMethod = (*env)->GetStaticMethodID( + env, peerManagerClass, "fetchSelectedPeersBlocking", "()Ljava/util/Set;"); + if (!fetchSelectedPeersBlockingMethod) { + (*env)->DeleteLocalRef(env, peerManagerClass); + return NULL; + } + + jobject set = (*env)->CallStaticObjectMethod(env, peerManagerClass, fetchSelectedPeersBlockingMethod); + (*env)->DeleteLocalRef(env, peerManagerClass); + if (!set) return NULL; + + jclass setClass = (*env)->GetObjectClass(env, set); + jmethodID sizeMethod = (*env)->GetMethodID(env, setClass, "size", "()I"); + jmethodID iteratorMethod = (*env)->GetMethodID(env, setClass, "iterator", "()Ljava/util/Iterator;"); + if (!sizeMethod || !iteratorMethod) { + (*env)->DeleteLocalRef(env, setClass); + (*env)->DeleteLocalRef(env, set); + return NULL; + } + + jint size = (*env)->CallIntMethod(env, set, sizeMethod); + jobject iterator = (*env)->CallObjectMethod(env, set, iteratorMethod); + (*env)->DeleteLocalRef(env, setClass); + + if (!iterator) { + (*env)->DeleteLocalRef(env, set); + return NULL; + } + + jclass iteratorClass = (*env)->GetObjectClass(env, iterator); + jmethodID hasNextMethod = (*env)->GetMethodID(env, iteratorClass, "hasNext", "()Z"); + jmethodID nextMethod = (*env)->GetMethodID(env, iteratorClass, "next", "()Ljava/lang/Object;"); + if (!hasNextMethod || !nextMethod) { + (*env)->DeleteLocalRef(env, iteratorClass); + (*env)->DeleteLocalRef(env, iterator); + (*env)->DeleteLocalRef(env, set); + return NULL; + } + + char **ipAddresses = NULL; + if (size > 0) { + ipAddresses = (char **)calloc(size + 1, sizeof(char *)); // +1 for NULL-termination + if (!ipAddresses) { + (*env)->DeleteLocalRef(env, iteratorClass); + (*env)->DeleteLocalRef(env, iterator); + (*env)->DeleteLocalRef(env, set); + return NULL; + } + } + + size_t index = 0; + while ((*env)->CallBooleanMethod(env, iterator, hasNextMethod)) { + jstring element = (jstring)(*env)->CallObjectMethod(env, iterator, nextMethod); + if (!element) break; + const char *peerStr = (*env)->GetStringUTFChars(env, element, NULL); + if (peerStr) { + ipAddresses[index] = strdup(peerStr); + (*env)->ReleaseStringUTFChars(env, element, peerStr); + index++; + } + (*env)->DeleteLocalRef(env, element); + } + + if (ipAddresses) + ipAddresses[index] = NULL; // NULL-terminate + + (*env)->DeleteLocalRef(env, iteratorClass); + (*env)->DeleteLocalRef(env, iterator); + (*env)->DeleteLocalRef(env, set); + + return ipAddresses; +} + static void threadCleanup(void *info) { if (_jvmPM) (*_jvmPM)->DetachCurrentThread(_jvmPM); @@ -279,9 +382,10 @@ Java_com_brainwallet_wallet_BRPeerManager_create(JNIEnv *env, jobject thiz, _peerManager = BRPeerManagerNew(&BR_CHAIN_PARAMS, _wallet, (uint32_t) earliestKeyTime, _blocks, (size_t) blocksCount, _peers, (size_t) peersCount, (double) fpRate); + BRPeerManagerSetCallbacks(_peerManager, NULL, syncStarted, syncStopped, txStatusUpdate, - saveBlocks, savePeers, networkIsReachable, threadCleanup); + saveBlocks, savePeers, networkIsReachable, threadCleanup, featureSelectedPeersEnabled, fetchSelectedPeers); } if (_peerManager == NULL) { From ef4e6d2744eb29851db792604e22656477bd9bb2 Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Wed, 16 Apr 2025 05:30:37 +0700 Subject: [PATCH 018/116] feat: filter out peers with NODE_NETWORK, NODE_BLOOM --- .../data/repository/SelectedPeersRepository.kt | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt index 766cfb7d..008453a0 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt @@ -9,6 +9,7 @@ import okhttp3.Callback import okhttp3.OkHttpClient import okhttp3.Response import okio.IOException +import timber.log.Timber import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine @@ -54,12 +55,19 @@ interface SelectedPeersRepository { val dataObject = jsonElement.jsonObject["data"]?.jsonObject val nodesObject = dataObject?.get("nodes")?.jsonObject - //TODO: need filter criteria here? - nodesObject?.keys - ?.filter { it.endsWith(":9333") } - ?.map { it.replace(":9333", "") } - ?.toSet() + //filter criteria + val requiredServices = 0x01 or 0x04 // NODE_NETWORK | NODE_BLOOM + + nodesObject?.entries + ?.filter { entry -> + val flags = + entry.value.jsonObject["flags"]?.toString()?.toIntOrNull() + flags != null && (flags and requiredServices) == requiredServices + } + ?.map { it.key.replace(":9333", "") } + ?.toSet().also { Timber.d("Total Selected Peers ${it?.size}") } ?: emptySet() + } ?: emptySet() sharedPreferences.edit { From 23369394c110dc5c310efa3d01645b24c2c1ead5 Mon Sep 17 00:00:00 2001 From: andhikayuana Date: Wed, 16 Apr 2025 12:19:12 +0700 Subject: [PATCH 019/116] fix: race condition when clear shared prefs values after wipeAll --- app/src/main/java/com/brainwallet/wallet/BRWalletManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java index 792fad8e..42d460d9 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java @@ -232,12 +232,12 @@ public void wipeWalletButKeystore(final Context ctx) { @Override public void run() { Timber.d("timber: Running peerManagerFreeEverything"); + BRSharedPrefs.clearAllPrefs(ctx); BRPeerManager.getInstance().peerManagerFreeEverything(); walletFreeEverything(); TransactionDataSource.getInstance(ctx).deleteAllTransactions(); MerkleBlockDataSource.getInstance(ctx).deleteAllBlocks(); PeerDataSource.getInstance(ctx).deleteAllPeers(); - BRSharedPrefs.clearAllPrefs(ctx); } }); } From 391e319fa920ea79bf4ddf00e2f4b4a89b16d241 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 16 Apr 2025 08:21:49 +0100 Subject: [PATCH 020/116] Updating the core library from the new peer discovery (v4.2.0) --- app/src/main/jni/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/jni/core b/app/src/main/jni/core index 86649c2d..55b43a86 160000 --- a/app/src/main/jni/core +++ b/app/src/main/jni/core @@ -1 +1 @@ -Subproject commit 86649c2dd89d4c1e13fb58de4aa07567f3ac11bd +Subproject commit 55b43a869300dfc82ead7faa87e71626d580b464 From 836b6f097d8953701140c3e231cc66a22e46923f Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Fri, 25 Apr 2025 16:02:14 +0700 Subject: [PATCH 021/116] Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington --- app/build.gradle.kts | 4 +- .../brainwallet/data/model/CurrencyEntity.kt | 27 +----- .../java/com/brainwallet/data/model/Fee.kt | 37 +++++++++ .../data/repository/LtcRepository.kt | 47 +++++++---- .../repository/SelectedPeersRepository.kt | 5 ++ .../data/source/RemoteApiSource.kt | 5 +- .../main/java/com/brainwallet/di/Module.kt | 23 +++-- .../brainwallet/presenter/entities/Fee.java | 15 ---- .../tools/manager/BRSharedPrefs.java | 83 ++++++++++++------- .../brainwallet/tools/manager/FeeManager.java | 51 +++++++----- .../tools/manager/SyncManager.java | 51 ++++-------- .../brainwallet/tools/threads/BRExecutor.java | 16 ++++ .../brainwallet/tools/util/BRConstants.java | 4 +- .../com/brainwallet/ui/BrainwalletActivity.kt | 5 -- .../ui/screens/home/SettingsEvent.kt | 5 +- .../ui/screens/home/SettingsState.kt | 1 + .../ui/screens/home/SettingsViewModel.kt | 7 +- .../home/composable/HomeSettingDrawerSheet.kt | 14 +++- .../yourseedproveit/YourSeedProveItEvent.kt | 1 + .../yourseedproveit/YourSeedProveItScreen.kt | 3 +- .../yourseedproveit/YourSeedProveItState.kt | 7 +- .../YourSeedProveItViewModel.kt | 18 ++-- .../yourseedwords/YourSeedWordsEvent.kt | 2 +- .../yourseedwords/YourSeedWordsScreen.kt | 12 ++- .../yourseedwords/YourSeedWordsViewModel.kt | 11 +-- .../com/brainwallet/wallet/BRPeerManager.java | 21 +++-- app/src/main/jni/core | 2 +- app/src/main/jni/transition/PeerManager.c | 2 +- app/src/main/res/values/strings.xml | 1 + 29 files changed, 292 insertions(+), 188 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/data/model/Fee.kt delete mode 100644 app/src/main/java/com/brainwallet/presenter/entities/Fee.java diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b8f91239..3d4cb0e2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202503312 - versionName = "v4.4.3" + versionCode = 202504251 + versionName = "v4.4.7" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") diff --git a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt index 1ccba70c..a46406bc 100644 --- a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt +++ b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt @@ -14,29 +14,4 @@ data class CurrencyEntity( var rate: Float = 0F, @JvmField var symbol: String = "" -) : Serializable { -// @JvmField -// var code: String? = null -// @JvmField -// var name: String? = null -// @JvmField -// var rate: Float = 0f -// @JvmField -// var symbol: String? = null -// -// constructor(code: String?, name: String?, rate: Float, symbol: String?) { -// this.code = code -// this.name = name -// this.rate = rate -// this.symbol = symbol -// } -// -// constructor() -// -// companion object { -// //Change this after modifying the class -// private const val serialVersionUID = 7526472295622776147L -// -// val TAG: String = CurrencyEntity::class.java.name -// } -} +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/model/Fee.kt b/app/src/main/java/com/brainwallet/data/model/Fee.kt new file mode 100644 index 00000000..246100a4 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/model/Fee.kt @@ -0,0 +1,37 @@ +package com.brainwallet.data.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Fee( + @JvmField + @SerialName("fee_per_kb") + var luxury: Long, + @JvmField + @SerialName("fee_per_kb_economy") + var regular: Long, + @JvmField + @SerialName("fee_per_kb_luxury") + var economy: Long, + var timestamp: Long +) { + companion object { + //from legacy + // this is the default that matches the mobile-api if the server is unavailable + private const val defaultEconomyFeePerKB: Long = + 2500L // From legacy minimum. default min is 1000 as Litecoin Core version v0.17.1 + private const val defaultRegularFeePerKB: Long = 25000L + private const val defaultLuxuryFeePerKB: Long = 66746L + private const val defaultTimestamp: Long = 1583015199122L + + @JvmStatic + val Default = Fee( + defaultLuxuryFeePerKB, + defaultRegularFeePerKB, + defaultEconomyFeePerKB, + defaultTimestamp + ) + + } +} diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index 02358b34..31c05e30 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -2,6 +2,7 @@ package com.brainwallet.data.repository import android.content.Context import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.Fee import com.brainwallet.data.source.RemoteApiSource import com.brainwallet.tools.manager.BRSharedPrefs import com.brainwallet.tools.manager.FeeManager @@ -9,7 +10,8 @@ import com.brainwallet.tools.sqlite.CurrencyDataSource interface LtcRepository { suspend fun fetchRates(): List - //todo + + suspend fun fetchFeePerKb(): Fee class Impl( private val context: Context, @@ -19,22 +21,39 @@ interface LtcRepository { //todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies override suspend fun fetchRates(): List { - val rates = remoteApiSource.getRates() - - //legacy logic - FeeManager.updateFeePerKb(context) - val selectedISO = BRSharedPrefs.getIsoSymbol(context) - rates.forEachIndexed { index, currencyEntity -> - if (currencyEntity.code.equals(selectedISO, ignoreCase = true)) { - BRSharedPrefs.putIso(context, currencyEntity.code) - BRSharedPrefs.putCurrencyListPosition(context, index - 1) + return runCatching { + val rates = remoteApiSource.getRates() + + //legacy logic + FeeManager.updateFeePerKb(context) + val selectedISO = BRSharedPrefs.getIsoSymbol(context) + rates.forEachIndexed { index, currencyEntity -> + if (currencyEntity.code.equals(selectedISO, ignoreCase = true)) { + BRSharedPrefs.putIso(context, currencyEntity.code) + BRSharedPrefs.putCurrencyListPosition(context, index - 1) + } } - } - //save to local - currencyDataSource.putCurrencies(rates) - return rates + //save to local + currencyDataSource.putCurrencies(rates) + return rates + }.getOrElse { currencyDataSource.getAllCurrencies(true) } + + } + + override suspend fun fetchFeePerKb(): Fee { + return runCatching { + val fee = remoteApiSource.getFeePerKb() + + //todo: cache + + return fee + }.getOrElse { Fee.Default } } } + + companion object { + + } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt index 008453a0..0275d542 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt @@ -50,6 +50,11 @@ interface SelectedPeersRepository { override fun onResponse(call: Call, response: Response) { val jsonString = response.body?.string() + if (response.isSuccessful.not()) { + continuation.resume(cachedPeers ?: emptySet()) + return + } + val parsedResult = jsonString?.let { val jsonElement = json.parseToJsonElement(it) val dataObject = jsonElement.jsonObject["data"]?.jsonObject diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt index 0ce3bdc8..60c865e2 100644 --- a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt @@ -1,16 +1,17 @@ package com.brainwallet.data.source import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.Fee import retrofit2.http.GET //TODO interface RemoteApiSource { - @GET("api/v1/rates") + @GET("v1/rates") suspend fun getRates(): List @GET("v1/fee-per-kb") - suspend fun getFeePerKb() + suspend fun getFeePerKb(): Fee // https://prod.apigsltd.net/moonpay/buy?address=ltc1qjnsg3p9rt4r4vy7ncgvrywdykl0zwhkhcp8ue0&code=USD&idate=1742331930290&uid=ec51fa950b271ff3 // suspend fun getMoonPayBuy() diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index e64e071a..4dce30f1 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -4,10 +4,10 @@ import android.content.Context import android.content.SharedPreferences import com.brainwallet.BuildConfig import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.data.repository.SelectedPeersRepository import com.brainwallet.data.repository.SettingRepository import com.brainwallet.data.source.RemoteApiSource import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.data.repository.SelectedPeersRepository import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.screens.home.SettingsViewModel @@ -31,6 +31,7 @@ import org.koin.android.ext.koin.androidApplication import org.koin.core.module.dsl.viewModel import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.module +import retrofit2.HttpException import retrofit2.Retrofit import retrofit2.converter.kotlinx.serialization.asConverterFactory @@ -46,7 +47,7 @@ val dataModule = module { factory { provideOkHttpClient() } single { provideRetrofit(get(), BRConstants.BW_API_PROD_HOST) } - single { provideApi(get()) } + single { provideApi(get()) } single { RemoteConfigSource.FirebaseImpl(Firebase.remoteConfig).also { @@ -91,17 +92,25 @@ private fun provideOkHttpClient(): OkHttpClient = OkHttpClient.Builder() .addHeader("Content-Type", "application/json") .addHeader("X-Litecoin-Testnet", "false") .addHeader("Accept-Language", "en") -// .addHeader("User-agent",) chain.proceed(requestBuilder.build()) } .addInterceptor { chain -> val request = chain.request() runCatching { - chain.proceed(request) + val result = chain.proceed(request) + if (result.isSuccessful.not()) { + throw HttpException( + retrofit2.Response.error( + result.code, + result.body ?: result.peekBody(Long.MAX_VALUE) + ) + ) + } + result }.getOrElse { //retry using dev host val newRequest = request.newBuilder() - .url(BRConstants.BW_API_DEV_HOST + request.url.encodedPath) + .url("${BRConstants.LEGACY_BW_API_DEV_HOST}/api${request.url.encodedPath}") //legacy dev api need prefix path /api .build() chain.proceed(newRequest) } @@ -129,5 +138,5 @@ internal fun provideRetrofit( ) .build() -internal fun provideApi(retrofit: Retrofit): RemoteApiSource = - retrofit.create(RemoteApiSource::class.java) \ No newline at end of file +internal inline fun provideApi(retrofit: Retrofit): T = + retrofit.create(T::class.java) \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/presenter/entities/Fee.java b/app/src/main/java/com/brainwallet/presenter/entities/Fee.java deleted file mode 100644 index bbe80465..00000000 --- a/app/src/main/java/com/brainwallet/presenter/entities/Fee.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.brainwallet.presenter.entities; - -public class Fee { - public final long luxury; - public final long regular; - public final long economy; - public final long timestamp; - - public Fee(long luxury, long regular, long economy, long timestamp) { - this.luxury = luxury; - this.regular = regular; - this.economy = economy; - this.timestamp = timestamp; - } -} diff --git a/app/src/main/java/com/brainwallet/tools/manager/BRSharedPrefs.java b/app/src/main/java/com/brainwallet/tools/manager/BRSharedPrefs.java index a3edc499..6fd054b9 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/BRSharedPrefs.java +++ b/app/src/main/java/com/brainwallet/tools/manager/BRSharedPrefs.java @@ -3,15 +3,17 @@ import android.content.Context; import android.content.SharedPreferences; -import com.brainwallet.BrainwalletApp; +import android.util.Log; + import com.brainwallet.data.repository.SettingRepository; import com.brainwallet.tools.util.BRConstants; import org.koin.java.KoinJavaComponent; -import org.koin.mp.KoinPlatformTools_jvmKt; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Currency; +import java.util.Date; import java.util.List; import java.util.Locale; @@ -45,16 +47,14 @@ public static String getIsoSymbol(Context context) { try { if (defaultLanguage == "ru") { defIso = Currency.getInstance(new Locale("ru", "RU")).getCurrencyCode(); - } - else if (defaultLanguage == "en") { + } else if (defaultLanguage == "en") { defIso = Currency.getInstance(Locale.US).getCurrencyCode(); - } - else { + } else { defIso = Currency.getInstance(Locale.getDefault()).getCurrencyCode(); } } catch (IllegalArgumentException e) { Timber.e(e); - defIso = Currency.getInstance(Locale.US).getCurrencyCode(); + defIso = Currency.getInstance(Locale.US).getCurrencyCode(); } return settingsToGet.getString(SettingRepository.KEY_FIAT_CURRENCY_CODE, defIso); //using new shared prefs used by setting repository } @@ -74,38 +74,64 @@ public static void notifyIsoChanged(String iso) { } } - ////////////////////////////////////////////////////////////////////////////// - //////////////////// Active Shared Preferences /////////////////////////////// - public static void putLastSyncTimestamp(Context activity, long time) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + /// /////////////////////////////////////////////////////////////////////////// + /// ///////////////// Active Shared Preferences /////////////////////////////// + + public static void putStartSyncTimestamp(Context context, long time) { + if (context == null) { + Log.e("BRSharedPrefs", "Context is null in putStartSyncTimestamp!"); + return; + } + SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); - editor.putLong("lastSyncTime", time); + editor.putLong("startSyncTime", time); editor.apply(); } - public static long getLastSyncTimestamp(Context activity) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return prefs.getLong("lastSyncTime", 0L); + + public static long getStartSyncTimestamp(Context context) { + if (context == null) { + Log.e("BRSharedPrefs", "Context is null in getStartSyncTimestamp!"); + } + SharedPreferences startSyncTime = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + return startSyncTime.getLong("startSyncTime", System.currentTimeMillis()); } - public static void putStartSyncTimestamp(Context activity, long time) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + + public static void putEndSyncTimestamp(Context context, long time) { + + if (context == null) { + Log.e("BRSharedPrefs", "Context is null in putEndSyncTimestamp!"); + return; + } + + SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); - editor.putLong("startSyncTime", time); + editor.putLong("endSyncTime", time); editor.apply(); } - public static long getStartSyncTimestamp(Context activity) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return prefs.getLong("startSyncTime", 0L); + + public static String getSyncMetadata(Context context) { + SharedPreferences syncMetadata = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + return syncMetadata.getString("syncMetadata", " No Sync Duration metadata"); } - public static void putSyncTimeElapsed(Context activity, long time) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + public static void putSyncMetadata(Context activity, long startSyncTime, long endSyncTime) { + SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, 0); SharedPreferences.Editor editor = prefs.edit(); - editor.putLong("syncTimeElapsed", time); + + double syncDuration = (double) (endSyncTime - startSyncTime) / 1_000.0 / 60.0; + + SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm"); + Date startDate = new Date(startSyncTime); + Date endDate = new Date(endSyncTime); + + String formattedMetadata = String.format("Duration: %3.2f mins\nStarted: %d (%s)\nEnded: %d (%s)", syncDuration, startSyncTime, sdf.format(startDate), endSyncTime, sdf.format(endDate)); + editor.putString("syncMetadata", formattedMetadata); editor.apply(); } - public static long getSyncTimeElapsed(Context activity) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return prefs.getLong("syncTimeElapsed", 0L); + + public static long getEndSyncTimestamp(Context context) { + SharedPreferences endSyncTime = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + return endSyncTime.getLong("endSyncTime", System.currentTimeMillis()); } public static boolean getPhraseWroteDown(Context context) { @@ -232,9 +258,10 @@ public static void putUseFingerprint(Context activity, boolean use) { editor.putBoolean("useFingerprint", use); editor.apply(); } + public static int getStartHeight(Context context) { SharedPreferences settingsToGet = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); - return settingsToGet.getInt(BRConstants.START_HEIGHT, 0); + return settingsToGet.getInt(BRConstants.START_HEIGHT, 0); } public static void putStartHeight(Context context, int startHeight) { diff --git a/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java b/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java index 91e12a9e..963a56af 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java @@ -4,13 +4,14 @@ import androidx.annotation.StringDef; +import com.brainwallet.data.repository.LtcRepository; import com.brainwallet.presenter.entities.ServiceItems; +import com.brainwallet.tools.threads.BRExecutor; import com.brainwallet.tools.util.Utils; -import com.brainwallet.presenter.entities.Fee; +import com.brainwallet.data.model.Fee; import com.platform.APIClient; -import org.json.JSONException; -import org.json.JSONObject; +import org.koin.java.KoinJavaComponent; import java.io.IOException; import java.lang.annotation.Retention; @@ -24,16 +25,9 @@ import okhttp3.Response; import timber.log.Timber; - +//we are still using this, maybe in the future will deprecate? public final class FeeManager { - // this is the default that matches the mobile-api if the server is unavailable - private static final long defaultEconomyFeePerKB = 2_500L; // From legacy minimum. default min is 1000 as Litecoin Core version v0.17.1 - private static final long defaultRegularFeePerKB = 2_5000L; - private static final long defaultLuxuryFeePerKB = 66_746L; - private static final long defaultTimestamp = 1583015199122L; - - private Fee defaultValues = new Fee(defaultLuxuryFeePerKB, defaultRegularFeePerKB, defaultEconomyFeePerKB, defaultTimestamp); private static final FeeManager instance; @@ -50,7 +44,7 @@ public static FeeManager getInstance() { } private void initWithDefaultValues() { - currentFees = defaultValues; + currentFees = Fee.getDefault(); feeType = REGULAR; } @@ -75,22 +69,33 @@ public boolean isRegularFee() { public void setFees(long luxuryFee, long regularFee, long economyFee) { // TODO: to be implemented when feePerKB API will be ready + currentFees = new Fee(luxuryFee, regularFee, economyFee, System.currentTimeMillis()); } public static void updateFeePerKb(Context app) { - String jsonString = "{'fee_per_kb': 10000, 'fee_per_kb_economy': 2500, 'fee_per_kb_luxury': 66746}"; - try { - JSONObject obj = new JSONObject(jsonString); - // TODO: Refactor when mobile-api v0.4.0 is in prod - long regularFee = obj.optLong("fee_per_kb"); - long economyFee = obj.optLong("fee_per_kb_economy"); - long luxuryFee = obj.optLong("fee_per_kb_luxury"); - FeeManager.getInstance().setFees(luxuryFee, regularFee, economyFee); +// String jsonString = "{'fee_per_kb': 10000, 'fee_per_kb_economy': 2500, 'fee_per_kb_luxury': 66746}"; +// try { +// JSONObject obj = new JSONObject(jsonString); +// // TODO: Refactor when mobile-api v0.4.0 is in prod +// long regularFee = obj.optLong("fee_per_kb"); +// long economyFee = obj.optLong("fee_per_kb_economy"); +// long luxuryFee = obj.optLong("fee_per_kb_luxury"); +// FeeManager.getInstance().setFees(luxuryFee, regularFee, economyFee); +// BRSharedPrefs.putFeeTime(app, System.currentTimeMillis()); //store the time of the last successful fee fetch +// } catch (JSONException e) { +// Timber.e(new IllegalArgumentException("updateFeePerKb: FAILED: " + jsonString, e)); +// } + + LtcRepository ltcRepository = KoinJavaComponent.get(LtcRepository.class); + BRExecutor.getInstance().executeSuspend( + (coroutineScope, continuation) -> ltcRepository.fetchFeePerKb(continuation) + ).whenComplete((fee, throwable) -> { + + //legacy logic + FeeManager.getInstance().setFees(fee.luxury, fee.regular, fee.economy); BRSharedPrefs.putFeeTime(app, System.currentTimeMillis()); //store the time of the last successful fee fetch - } catch (JSONException e) { - Timber.e(new IllegalArgumentException("updateFeePerKb: FAILED: " + jsonString, e)); - } + }); } // createGETRequestURL diff --git a/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java b/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java index 42e195f5..ace9dcc1 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java @@ -1,5 +1,7 @@ package com.brainwallet.tools.manager; +import static com.brainwallet.tools.manager.BRSharedPrefs.putSyncMetadata; + import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; @@ -44,8 +46,6 @@ public synchronized void startSyncingProgressThread(Context app) { } syncTask = new SyncProgressTask(); syncTask.start(); - BRSharedPrefs.putStartSyncTimestamp(app, System.currentTimeMillis()); - BRSharedPrefs.putSyncTimeElapsed(app, 0L); updateStartSyncData(app); } catch (IllegalThreadStateException ex) { Timber.e(ex); @@ -54,41 +54,11 @@ public synchronized void startSyncingProgressThread(Context app) { private synchronized void updateStartSyncData(Context app) { final double progress = BRPeerManager.syncProgress(BRSharedPrefs.getStartHeight(app)); - long startSync = BRSharedPrefs.getStartSyncTimestamp(app); - long lastSync = BRSharedPrefs.getLastSyncTimestamp(app); - long elapsed = BRSharedPrefs.getSyncTimeElapsed(app); - - if (elapsed > 0L) { - elapsed = (System.currentTimeMillis() - lastSync) + elapsed; - } - else { - elapsed = 1L; - } - BRSharedPrefs.putLastSyncTimestamp(app, System.currentTimeMillis()); - BRSharedPrefs.putSyncTimeElapsed(app, elapsed); - double minutesValue = ((double) elapsed / 1_000.0 / 60.0); - String minutesString = String.format( "%3.2f mins", minutesValue); - String millisecString = String.format( "%5d msec", elapsed); - Timber.d("timber: ||\nprogress: %s\nThread: %s\nrunning lastSyncingTime: %s\nelapsed: %s | %s", String.format( "%.2f", progress * 100.00),Thread.currentThread().getName(),String.valueOf(BRSharedPrefs.getLastSyncTimestamp(app)), millisecString, minutesString); - } private synchronized void markFinishedSyncData(Context app) { - Timber.d("timber: || markFinish threadname:%s", Thread.currentThread().getName()); + Timber.d("timber: || SYNC ELAPSE markFinish threadname:%s", Thread.currentThread().getName()); final double progress = BRPeerManager.syncProgress(BRSharedPrefs.getStartHeight(app)); - long startSync = BRSharedPrefs.getStartSyncTimestamp(app); - long lastSync = BRSharedPrefs.getLastSyncTimestamp(app); - long elapsed = BRSharedPrefs.getSyncTimeElapsed(app); - double minutesValue = ((double) elapsed / 1_000.0 / 60.0); - String minutesString = String.format( "%3.2f mins", minutesValue); - String millisecString = String.format( "%5d msec", elapsed); - Timber.d("timber: ||\ncompletedprogress: %s\nstartSyncTime: %s\nlastSyncingTime: %s\ntotalTimeelapsed: %s | %s", String.format( "%.2f", progress * 100.00),String.valueOf(startSync),String.valueOf(lastSync), millisecString, minutesString); - - Bundle params = new Bundle(); - params.putDouble("sync_time_elapsed", minutesValue); - params.putLong("sync_start_timestamp", startSync); - params.putLong("sync_last_timestamp", lastSync); - AnalyticsManager.logCustomEventWithParams(BRConstants._20230407_DCS, params); } public synchronized void stopSyncingProgressThread(Context app) { @@ -139,7 +109,10 @@ public void run() { app = BreadActivity.getApp(); progressStatus = 0; running = true; - Timber.d("timber: run: starting: %s", progressStatus); + long runTimeStamp = System.currentTimeMillis(); + Timber.d("timber: run: starting: %s date: %d", progressStatus, runTimeStamp); + ///Set StartSync + BRSharedPrefs.putStartSyncTimestamp(app, runTimeStamp); if (app != null) { final long lastBlockTimeStamp = BRPeerManager.getInstance().getLastBlockTimestamp() * 1000; @@ -162,6 +135,16 @@ public void run() { progressStatus = BRPeerManager.syncProgress(startHeight); if (progressStatus == 1) { running = false; + /// Record sync time + long startTimeStamp = BRSharedPrefs.getStartSyncTimestamp(app); + long endSyncTimeStamp = System.currentTimeMillis(); + BRSharedPrefs.putEndSyncTimestamp(app, endSyncTimeStamp); + + double syncDuration = (double) (endSyncTimeStamp - startTimeStamp) / 1_000.0 / 60.0; + /// only update if the sync duration is longer than 2 mins + if (syncDuration > 2.0) { + putSyncMetadata(app, startTimeStamp, endSyncTimeStamp); + } continue; } final long lastBlockTimeStamp = BRPeerManager.getInstance().getLastBlockTimestamp() * 1000; diff --git a/app/src/main/java/com/brainwallet/tools/threads/BRExecutor.java b/app/src/main/java/com/brainwallet/tools/threads/BRExecutor.java index ec127999..b1b21255 100644 --- a/app/src/main/java/com/brainwallet/tools/threads/BRExecutor.java +++ b/app/src/main/java/com/brainwallet/tools/threads/BRExecutor.java @@ -1,5 +1,6 @@ package com.brainwallet.tools.threads; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionHandler; @@ -7,6 +8,12 @@ import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import kotlin.coroutines.Continuation; +import kotlin.coroutines.EmptyCoroutineContext; +import kotlinx.coroutines.CoroutineScope; +import kotlinx.coroutines.CoroutineScopeKt; +import kotlinx.coroutines.CoroutineStart; +import kotlinx.coroutines.future.FutureKt; import timber.log.Timber; /* @@ -130,4 +137,13 @@ public Executor forMainThreadTasks() { public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { Timber.d("timber: rejectedExecution: "); } + + public CompletableFuture executeSuspend(kotlin.jvm.functions.Function2, ? extends Object> paramToExec) { + return FutureKt.future( + CoroutineScopeKt.CoroutineScope(EmptyCoroutineContext.INSTANCE), + EmptyCoroutineContext.INSTANCE, + CoroutineStart.DEFAULT, + paramToExec + ); + } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/tools/util/BRConstants.java b/app/src/main/java/com/brainwallet/tools/util/BRConstants.java index 5788f6de..1c4d4a53 100644 --- a/app/src/main/java/com/brainwallet/tools/util/BRConstants.java +++ b/app/src/main/java/com/brainwallet/tools/util/BRConstants.java @@ -106,8 +106,8 @@ private BRConstants() { /** * API Hosts */ - public static final String BW_API_PROD_HOST = "https://prod.apigsltd.net"; - public static final String BW_API_DEV_HOST = "https://dev.apigsltd.net"; + public static final String BW_API_PROD_HOST = "https://api.grunt.ltd"; + public static final String LEGACY_BW_API_DEV_HOST = "https://dev.apigsltd.net"; public static final String BLOCK_EXPLORER_BASE_URL = "https://blockchair.com/litecoin/transaction/"; diff --git a/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt b/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt index 34608ffd..8ef9dfda 100644 --- a/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt +++ b/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt @@ -32,7 +32,6 @@ import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGAC import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGACY_DIALOG_WIPE_ALERT import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGACY_EFFECT_RESET_PIN import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel.Companion.LEGACY_EFFECT_ON_PAPERKEY_PROVED -import com.brainwallet.ui.screens.yourseedwords.YourSeedWordsViewModel.Companion.LEGACY_EFFECT_ON_SAVED_PAPERKEY import com.brainwallet.ui.theme.BrainwalletAppTheme import com.brainwallet.util.EventBus import com.brainwallet.wallet.BRWalletManager @@ -114,10 +113,6 @@ class BrainwalletActivity : BRActivity() { } } - LEGACY_EFFECT_ON_SAVED_PAPERKEY -> { - PostAuth.getInstance().onPhraseProveAuth(this, false) - } - LEGACY_EFFECT_ON_PAPERKEY_PROVED -> { BRSharedPrefs.putPhraseWroteDown(this@BrainwalletActivity, true) LegacyNavigation.startBreadActivity( diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt index 531305b6..48e0750a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt @@ -4,7 +4,10 @@ import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Language sealed class SettingsEvent { - data class OnLoad(val shareAnalyticsDataEnabled: Boolean = false) : SettingsEvent() + data class OnLoad( + val shareAnalyticsDataEnabled: Boolean = false, + val lastSyncMetadata: String? = null, + ) : SettingsEvent() object OnSecurityUpdatePinClick : SettingsEvent() object OnSecuritySeedPhraseClick : SettingsEvent() object OnSecurityShareAnalyticsDataClick : SettingsEvent() diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt index 3efe10a7..9f924c3c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt @@ -14,4 +14,5 @@ data class SettingsState( val languageSelectorBottomSheetVisible: Boolean = false, val fiatSelectorBottomSheetVisible: Boolean = false, val shareAnalyticsDataEnabled: Boolean = false, + val lastSyncMetadata: String? = null, ) \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt index 7ec71f98..e9515ce8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt @@ -47,7 +47,12 @@ class SettingsViewModel( override fun onEvent(event: SettingsEvent) { when (event) { is SettingsEvent.OnLoad -> viewModelScope.launch { - _state.update { it.copy(shareAnalyticsDataEnabled = event.shareAnalyticsDataEnabled) } + _state.update { + it.copy( + shareAnalyticsDataEnabled = event.shareAnalyticsDataEnabled, + lastSyncMetadata = event.lastSyncMetadata + ) + } } SettingsEvent.OnToggleDarkMode -> viewModelScope.launch { diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index 497770f8..42b370a8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -6,6 +6,7 @@ import android.util.AttributeSet import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.LazyColumn @@ -57,7 +58,10 @@ fun HomeSettingDrawerSheet( val context = LocalContext.current LaunchedEffect(Unit) { - viewModel.onEvent(SettingsEvent.OnLoad(BRSharedPrefs.getShareData(context))) //currently just load analytics share data here + viewModel.onEvent(SettingsEvent.OnLoad( + shareAnalyticsDataEnabled = BRSharedPrefs.getShareData(context), //currently just load analytics share data here + lastSyncMetadata = BRSharedPrefs.getSyncMetadata(context) //currently just load sync metadata here + )) } /// Layout values @@ -173,6 +177,14 @@ fun HomeSettingDrawerSheet( ) } + item { + SettingRowItem( + modifier = Modifier.height(100.dp), + title = stringResource(R.string.settings_title_sync_metadata), + description = state.lastSyncMetadata ?: "No sync metadata" + ) + } + item { SettingRowItem( title = stringResource(R.string.settings_title_app_version), diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt index d9f530b0..68816d6a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt @@ -6,6 +6,7 @@ sealed class YourSeedProveItEvent { ) : YourSeedProveItEvent() data class OnDropSeedWordItem( + val index: Int, val expectedWord: String, val actualWord: String ) : YourSeedProveItEvent() diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt index 3e793c6a..171186ab 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt @@ -147,7 +147,7 @@ fun YourSeedProveItScreen( verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), maxItemsInEachRow = maxItemsPerRow ) { - state.correctSeedWords.entries.forEachIndexed { index, (expectedWord, actualWord) -> + state.correctSeedWords.values.forEachIndexed { index, (expectedWord, actualWord) -> val label = if (expectedWord != actualWord && actualWord.isEmpty()) { "${index + 1}" @@ -173,6 +173,7 @@ fun YourSeedProveItScreen( viewModel.onEvent( YourSeedProveItEvent.OnDropSeedWordItem( + index = index, expectedWord = expectedWord, actualWord = text.toString() ) diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt index 991763a2..1da5cc92 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt @@ -1,7 +1,12 @@ package com.brainwallet.ui.screens.yourseedproveit data class YourSeedProveItState( - val correctSeedWords: Map = mapOf(), + val correctSeedWords: Map = emptyMap(), val shuffledSeedWords: List = emptyList(), val orderCorrected: Boolean = false, ) + +data class SeedWordItem( + val expected: String, + val actual: String = "" +) \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt index 99af1398..6f4d19c4 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt @@ -18,25 +18,31 @@ class YourSeedProveItViewModel : BrainwalletViewModel() { when (event) { is YourSeedProveItEvent.OnLoad -> _state.update { it.copy( - correctSeedWords = event.seedWords.associateWith { "" }, + correctSeedWords = event.seedWords.mapIndexed { index, word -> + index to SeedWordItem(expected = word) + }.toMap(), shuffledSeedWords = event.seedWords.shuffled() ) } is YourSeedProveItEvent.OnDropSeedWordItem -> _state.update { - val correctSeedWords = it.correctSeedWords.toMutableMap().apply { - this[event.expectedWord] = event.actualWord - } + val correctSeedWords = it.correctSeedWords.map { (index, seedWordItem) -> + if (index == event.index && seedWordItem.expected == event.expectedWord) { + index to seedWordItem.copy(actual = event.actualWord) + } else { + index to seedWordItem + } + }.toMap() it.copy( correctSeedWords = correctSeedWords, - orderCorrected = correctSeedWords.all { (expectedWord, actualWord) -> expectedWord == actualWord } + orderCorrected = correctSeedWords.all { (_, seedWordItem) -> seedWordItem.expected == seedWordItem.actual } ) } YourSeedProveItEvent.OnClear -> _state.update { it.copy( - correctSeedWords = it.correctSeedWords.mapValues { "" } + correctSeedWords = it.correctSeedWords.mapValues { SeedWordItem(expected = it.value.expected) } ) } diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsEvent.kt index 9f9db09b..ba2cbde0 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsEvent.kt @@ -1,5 +1,5 @@ package com.brainwallet.ui.screens.yourseedwords sealed class YourSeedWordsEvent { - object OnSavedItClick : YourSeedWordsEvent() + data class OnSavedItClick(val seedWords: List) : YourSeedWordsEvent() } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt index bd2e5119..c541f588 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt @@ -21,6 +21,7 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -51,6 +52,15 @@ fun YourSeedWordsScreen( val leadingCopyPadding = 16 val detailLineHeight = 28 + LaunchedEffect(Unit) { + viewModel.uiEffect.collect { effect -> + when (effect) { + is UiEffect.Navigate -> onNavigate.invoke(effect) + else -> Unit + } + } + } + BrainwalletScaffold( topBar = { BrainwalletTopAppBar( @@ -122,7 +132,7 @@ fun YourSeedWordsScreen( LargeButton( onClick = { - viewModel.onEvent(YourSeedWordsEvent.OnSavedItClick) + viewModel.onEvent(YourSeedWordsEvent.OnSavedItClick(seedWords)) }, ) { Text( diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt index 650a4381..562b8b97 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt @@ -1,21 +1,18 @@ package com.brainwallet.ui.screens.yourseedwords import androidx.lifecycle.viewModelScope +import com.brainwallet.navigation.Route +import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.BrainwalletViewModel -import com.brainwallet.util.EventBus import kotlinx.coroutines.launch class YourSeedWordsViewModel : BrainwalletViewModel() { override fun onEvent(event: YourSeedWordsEvent) { when (event) { - YourSeedWordsEvent.OnSavedItClick -> viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_SAVED_PAPERKEY)) + is YourSeedWordsEvent.OnSavedItClick -> viewModelScope.launch { + sendUiEffect(UiEffect.Navigate(destinationRoute = Route.YourSeedProveIt(event.seedWords))) } } } - - companion object { - const val LEGACY_EFFECT_ON_SAVED_PAPERKEY = "onSavedPaperKey" - } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java b/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java index 209814e7..6f591402 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java @@ -72,7 +72,6 @@ public static void syncStarted() { public static void syncSucceeded() { Context ctx = BrainwalletApp.getBreadContext(); if (ctx == null) return; - BRSharedPrefs.putLastSyncTimestamp(ctx, System.currentTimeMillis()); SyncManager.getInstance().updateAlarms(ctx); BRSharedPrefs.putAllowSpend(ctx, true); SyncManager.getInstance().stopSyncingProgressThread(ctx); @@ -99,9 +98,12 @@ public static void syncFailed() { public static void txStatusUpdate() { Timber.d("timber: txStatusUpdate"); - for (OnTxStatusUpdate listener : statusUpdateListeners) { - if (listener != null) listener.onStatusUpdate(); + synchronized (statusUpdateListeners) { + for (OnTxStatusUpdate listener : statusUpdateListeners) { + if (listener != null) listener.onStatusUpdate(); + } } + BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { @Override public void run() { @@ -192,11 +194,14 @@ public void run() { //wrap logic enable/disable connect with new flow public void wrapConnectV2() { - if (featureSelectedPeersEnabled()) { - fetchSelectedPeers().whenComplete((strings, throwable) -> connect()); - } else { - connect(); - } +// if (featureSelectedPeersEnabled()) { +// fetchSelectedPeers().whenComplete((strings, throwable) -> connect()); +// } else { +// connect(); +// } + //currently we are just using connect(), since the core using hardcoded peers + //https://github.com/gruntsoftware/core/commit/0b7f85feac840c7667338c340c808dfccde4251a + connect(); } public static boolean featureSelectedPeersEnabled() { diff --git a/app/src/main/jni/core b/app/src/main/jni/core index 55b43a86..28d7d31a 160000 --- a/app/src/main/jni/core +++ b/app/src/main/jni/core @@ -1 +1 @@ -Subproject commit 55b43a869300dfc82ead7faa87e71626d580b464 +Subproject commit 28d7d31ae057bdde33b1d19e6b7af3ba07710c89 diff --git a/app/src/main/jni/transition/PeerManager.c b/app/src/main/jni/transition/PeerManager.c index 4c2ce73e..8d249725 100644 --- a/app/src/main/jni/transition/PeerManager.c +++ b/app/src/main/jni/transition/PeerManager.c @@ -385,7 +385,7 @@ Java_com_brainwallet_wallet_BRPeerManager_create(JNIEnv *env, jobject thiz, BRPeerManagerSetCallbacks(_peerManager, NULL, syncStarted, syncStopped, txStatusUpdate, - saveBlocks, savePeers, networkIsReachable, threadCleanup, featureSelectedPeersEnabled, fetchSelectedPeers); + saveBlocks, savePeers, networkIsReachable, threadCleanup); } if (_peerManager == NULL) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d4d2d53f..1b2f4e52 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -825,6 +825,7 @@ Unlock Theme App version: + Sync metadata: Sync Sync duration: >20 minutes Game %1$d: From 3caa1a7702878a54fa87f326523197797a5fbdb0 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Tue, 29 Apr 2025 12:33:29 +0700 Subject: [PATCH 022/116] feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) --- app/src/main/AndroidManifest.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ffbd7a0e..dd68f40a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -96,11 +96,6 @@ android:exported="true" android:launchMode="singleTask" android:screenOrientation="portrait" /> - Date: Fri, 2 May 2025 13:23:05 +0700 Subject: [PATCH 023/116] fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) --- app/src/main/java/com/brainwallet/di/Module.kt | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index 4dce30f1..3b666d1f 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -97,16 +97,17 @@ private fun provideOkHttpClient(): OkHttpClient = OkHttpClient.Builder() .addInterceptor { chain -> val request = chain.request() runCatching { - val result = chain.proceed(request) - if (result.isSuccessful.not()) { - throw HttpException( - retrofit2.Response.error( - result.code, - result.body ?: result.peekBody(Long.MAX_VALUE) + chain.proceed(request).use { response -> + if (response.isSuccessful.not()) { + throw HttpException( + retrofit2.Response.error( + response.code, + response.body ?: response.peekBody(Long.MAX_VALUE) + ) ) - ) + } + response } - result }.getOrElse { //retry using dev host val newRequest = request.newBuilder() From 1f9c5d03496b86e16e90db38fc88ee376040f357 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Fri, 2 May 2025 08:05:53 +0100 Subject: [PATCH 024/116] code bump --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3d4cb0e2..80cc7aec 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,7 +20,7 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202504251 + versionCode = 202505021 versionName = "v4.4.7" multiDexEnabled = true From 7ca17d3615b80a71d0d004dc2e5eb45377e67196 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Mon, 5 May 2025 20:52:16 +0700 Subject: [PATCH 025/116] Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code --- .../java/com/brainwallet/data/model/Fee.kt | 58 +++- .../data/repository/LtcRepository.kt | 30 +- .../main/java/com/brainwallet/di/Module.kt | 2 +- .../presenter/fragments/FragmentSend.kt | 296 +++++++++++------- .../brainwallet/tools/manager/FeeManager.java | 85 +---- .../ui/screens/home/SettingsState.kt | 5 + .../ui/screens/home/SettingsViewModel.kt | 8 +- .../home/composable/HomeSettingDrawerSheet.kt | 4 +- .../settingsrows/LitecoinBlockchainDetail.kt | 112 ++++++- .../brainwallet/wallet/BRWalletManager.java | 6 +- app/src/main/res/layout/fragment_send.xml | 94 +----- app/src/main/res/values-ar/strings.xml | 4 + app/src/main/res/values-de/strings.xml | 4 + app/src/main/res/values-es/strings.xml | 8 +- app/src/main/res/values-fr/strings.xml | 4 + app/src/main/res/values-hi/strings.xml | 4 + app/src/main/res/values-in/strings.xml | 4 + app/src/main/res/values-it/strings.xml | 4 + app/src/main/res/values-ja/strings.xml | 4 + app/src/main/res/values-ko/strings.xml | 4 + app/src/main/res/values-pt/strings.xml | 4 + app/src/main/res/values-ru/strings.xml | 4 + app/src/main/res/values-sv/strings.xml | 4 + app/src/main/res/values-tr/strings.xml | 4 + app/src/main/res/values-uk/strings.xml | 4 + app/src/main/res/values-zh-rCN/strings.xml | 6 +- app/src/main/res/values-zh-rTW/strings.xml | 4 + app/src/main/res/values/strings.xml | 7 +- 28 files changed, 462 insertions(+), 315 deletions(-) diff --git a/app/src/main/java/com/brainwallet/data/model/Fee.kt b/app/src/main/java/com/brainwallet/data/model/Fee.kt index 246100a4..0ea99667 100644 --- a/app/src/main/java/com/brainwallet/data/model/Fee.kt +++ b/app/src/main/java/com/brainwallet/data/model/Fee.kt @@ -1,20 +1,27 @@ package com.brainwallet.data.model +import android.annotation.SuppressLint +import com.brainwallet.R +import com.brainwallet.tools.manager.FeeManager.ECONOMY +import com.brainwallet.tools.manager.FeeManager.FeeType +import com.brainwallet.tools.manager.FeeManager.LUXURY +import com.brainwallet.tools.manager.FeeManager.REGULAR import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlin.math.ceil +import kotlin.math.round @Serializable data class Fee( @JvmField - @SerialName("fee_per_kb") + @SerialName("fee_per_kb_luxury") var luxury: Long, @JvmField - @SerialName("fee_per_kb_economy") + @SerialName("fee_per_kb") var regular: Long, @JvmField - @SerialName("fee_per_kb_luxury") + @SerialName("fee_per_kb_economy") var economy: Long, - var timestamp: Long ) { companion object { //from legacy @@ -25,13 +32,52 @@ data class Fee( private const val defaultLuxuryFeePerKB: Long = 66746L private const val defaultTimestamp: Long = 1583015199122L +// {"fee_per_kb":5289,"fee_per_kb_economy":2645,"fee_per_kb_luxury":10578} + @JvmStatic val Default = Fee( defaultLuxuryFeePerKB, defaultRegularFeePerKB, defaultEconomyFeePerKB, - defaultTimestamp ) - } } + + +data class FeeOption( + @FeeType + val type: String, + val feePerKb: Long, + val labelStringId: Int, +) + +fun Fee.toFeeOptions(): List = listOf( + FeeOption( + type = ECONOMY, + feePerKb = economy, + labelStringId = R.string.network_fee_options_low + ), + FeeOption( + type = REGULAR, + feePerKb = regular, + labelStringId = R.string.network_fee_options_medium + ), + FeeOption( + type = LUXURY, + feePerKb = luxury, + labelStringId = R.string.network_fee_options_top + ), +) + +fun FeeOption.getFiat(currencyEntity: CurrencyEntity): Float { + val satoshisPerLtc = 100_000_000.0 + val feeInLtc = feePerKb / satoshisPerLtc + return (feeInLtc * currencyEntity.rate).toFloat() +} + +@SuppressLint("DefaultLocale") +fun FeeOption.getFiatFormatted(currencyEntity: CurrencyEntity): String { + val fiatValue = getFiat(currencyEntity) + val formatted = String.format("%.3f", fiatValue) + return "${currencyEntity.symbol}$formatted" +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index 31c05e30..38b325fd 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -1,12 +1,16 @@ package com.brainwallet.data.repository import android.content.Context +import android.content.SharedPreferences +import androidx.core.content.edit import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Fee import com.brainwallet.data.source.RemoteApiSource +import com.brainwallet.di.json import com.brainwallet.tools.manager.BRSharedPrefs import com.brainwallet.tools.manager.FeeManager import com.brainwallet.tools.sqlite.CurrencyDataSource +import kotlinx.serialization.encodeToString interface LtcRepository { suspend fun fetchRates(): List @@ -16,7 +20,8 @@ interface LtcRepository { class Impl( private val context: Context, private val remoteApiSource: RemoteApiSource, - private val currencyDataSource: CurrencyDataSource + private val currencyDataSource: CurrencyDataSource, + private val sharedPreferences: SharedPreferences, ) : LtcRepository { //todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies @@ -42,18 +47,33 @@ interface LtcRepository { } override suspend fun fetchFeePerKb(): Fee { + val lastUpdateTime = sharedPreferences.getLong(PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT, 0) + val currentTime = System.currentTimeMillis() + val cachedFee = sharedPreferences.getString(PREF_KEY_NETWORK_FEE_PER_KB, null) + ?.let { json.decodeFromString(it) } + return runCatching { - val fee = remoteApiSource.getFeePerKb() + // Check if cache exists and is less than 6 hours old + if (cachedFee != null && (currentTime - lastUpdateTime) < 6 * 60 * 60 * 1000) { + return cachedFee + } - //todo: cache + val fee = remoteApiSource.getFeePerKb() + sharedPreferences.edit { + putString(PREF_KEY_NETWORK_FEE_PER_KB, json.encodeToString(fee)) + putLong(PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT, currentTime) + } return fee - }.getOrElse { Fee.Default } + }.getOrElse { + cachedFee ?: Fee.Default + } } } companion object { - + const val PREF_KEY_NETWORK_FEE_PER_KB = "network_fee_per_kb" + const val PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT = "${PREF_KEY_NETWORK_FEE_PER_KB}_cached_at" } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index 3b666d1f..8dcfb909 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -58,7 +58,7 @@ val dataModule = module { single { CurrencyDataSource.getInstance(get()) } single { provideSharedPreferences(context = androidApplication()) } single { SettingRepository.Impl(get(), get()) } - single { LtcRepository.Impl(get(), get(), get()) } + single { LtcRepository.Impl(get(), get(), get(), get()) } } val viewModelModule = module { diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt index 1f4af687..9b47690e 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt @@ -11,9 +11,12 @@ import android.view.ViewGroup import android.view.ViewTreeObserver.OnGlobalLayoutListener import android.view.animation.OvershootInterpolator import android.view.inputmethod.EditorInfo -import android.widget.* -import androidx.annotation.ColorRes -import androidx.annotation.StringRes +import android.widget.Button +import android.widget.EditText +import android.widget.ImageButton +import android.widget.LinearLayout +import android.widget.ScrollView +import android.widget.TextView import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintSet import androidx.fragment.app.Fragment @@ -22,38 +25,53 @@ import androidx.transition.Transition import androidx.transition.TransitionManager import com.brainwallet.R import com.brainwallet.presenter.customviews.BRKeyboard -import com.brainwallet.presenter.customviews.BRLinearLayoutWithCaret import com.brainwallet.presenter.entities.ServiceItems import com.brainwallet.presenter.entities.TransactionItem import com.brainwallet.tools.animation.BRAnimator import com.brainwallet.tools.animation.BRDialog import com.brainwallet.tools.animation.SlideDetector import com.brainwallet.tools.animation.SpringAnimator -import com.brainwallet.tools.manager.* +import com.brainwallet.tools.manager.AnalyticsManager +import com.brainwallet.tools.manager.BRClipboardManager +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.manager.FeeManager import com.brainwallet.tools.security.BRSender import com.brainwallet.tools.security.BitcoinUrlHandler import com.brainwallet.tools.threads.BRExecutor -import com.brainwallet.tools.util.* +import com.brainwallet.tools.util.BRConstants +import com.brainwallet.tools.util.BRCurrency +import com.brainwallet.tools.util.BRExchange +import com.brainwallet.tools.util.Utils import com.brainwallet.wallet.BRWalletManager -import com.google.common.math.Quantiles.scale import timber.log.Timber import java.math.BigDecimal import java.math.RoundingMode import java.util.regex.Pattern +//TODO: make sure remove unused after refactor network fee move to HomeSettingDrawerSheet class FragmentSend : Fragment() { - private lateinit var signalLayout: LinearLayout; private lateinit var keyboardLayout: LinearLayout - private lateinit var scanButton: Button; private lateinit var pasteButton: Button; private lateinit var sendButton: Button; private lateinit var isoCurrencySymbolButton: Button - private lateinit var commentEdit: EditText; private lateinit var addressEdit: EditText;private lateinit var amountEdit: EditText - private lateinit var isoCurrencySymbolText: TextView; private lateinit var balanceText: TextView; private lateinit var feeText: TextView; private lateinit var feeDescription: TextView; private lateinit var warningText: TextView - private var amountLabelOn = true; private var ignoreCleanup = false; private var feeButtonsShown = false - private lateinit var edit: ImageView + private lateinit var signalLayout: LinearLayout; + private lateinit var keyboardLayout: LinearLayout + private lateinit var scanButton: Button; + private lateinit var pasteButton: Button; + private lateinit var sendButton: Button; + private lateinit var isoCurrencySymbolButton: Button + private lateinit var commentEdit: EditText; + private lateinit var addressEdit: EditText; + private lateinit var amountEdit: EditText + private lateinit var isoCurrencySymbolText: TextView; + private lateinit var balanceText: TextView; + private lateinit var feeText: TextView; + private lateinit var feeDescription: TextView; + private lateinit var warningText: TextView + private var amountLabelOn = true; + private var ignoreCleanup = false; + private var feeButtonsShown = false private var currentBalance: Long = 0 private var keyboardIndex = 0 private lateinit var keyboard: BRKeyboard private lateinit var closeButton: ImageButton private lateinit var amountLayout: ConstraintLayout - private lateinit var feeLayout: BRLinearLayoutWithCaret private var selectedIsoCurrencySymbol: String? = null private lateinit var backgroundLayout: ScrollView private lateinit var amountBuilder: StringBuilder @@ -78,16 +96,17 @@ class FragmentSend : Fragment() { amountEdit = rootView.findViewById(R.id.amount_edit) as EditText balanceText = rootView.findViewById(R.id.balance_text) as TextView feeText = rootView.findViewById(R.id.fee_text) as TextView - edit = rootView.findViewById(R.id.edit) as ImageView isoCurrencySymbolButton = rootView.findViewById(R.id.iso_button) as Button keyboardLayout = rootView.findViewById(R.id.keyboard_layout) as LinearLayout amountLayout = rootView.findViewById(R.id.amount_layout) as ConstraintLayout - feeLayout = rootView.findViewById(R.id.fee_buttons_layout) as BRLinearLayoutWithCaret - feeDescription = rootView.findViewById(R.id.fee_description) as TextView - warningText = rootView.findViewById(R.id.warning_text) as TextView +// feeLayout = rootView.findViewById(R.id.fee_buttons_layout) as BRLinearLayoutWithCaret +// feeDescription = rootView.findViewById(R.id.fee_description) as TextView +// warningText = rootView.findViewById(R.id.warning_text) as TextView closeButton = rootView.findViewById(R.id.close_button) as ImageButton selectedIsoCurrencySymbol = - if (BRSharedPrefs.getPreferredLTC(context)) "LTC" else BRSharedPrefs.getIsoSymbol(context) + if (BRSharedPrefs.getPreferredLTC(context)) "LTC" else BRSharedPrefs.getIsoSymbol( + context + ) amountBuilder = StringBuilder(0) setListeners() @@ -102,18 +121,20 @@ class FragmentSend : Fragment() { signalLayout.setOnTouchListener(SlideDetector(signalLayout) { animateClose() }) AnalyticsManager.logCustomEvent(BRConstants._20191105_VSC) - setupFeesSelector(rootView) - showFeeSelectionButtons(feeButtonsShown) - edit.setOnClickListener { - feeButtonsShown = !feeButtonsShown - showFeeSelectionButtons(feeButtonsShown) - } +// setupFeesSelector(rootView) +// showFeeSelectionButtons(feeButtonsShown) +// edit.setOnClickListener { +// feeButtonsShown = !feeButtonsShown +// showFeeSelectionButtons(feeButtonsShown) +// } keyboardIndex = signalLayout.indexOfChild(keyboardLayout) // TODO: all views are using the layout of this button. Views should be refactored without it // Hiding until layouts are built. showKeyboard(false) signalLayout.layoutTransition = BRAnimator.getDefaultTransition() - + + updateText() + return rootView } @@ -121,62 +142,62 @@ class FragmentSend : Fragment() { super.onActivityCreated(savedInstanceState) } - private fun setupFeesSelector(rootView: View) { - val feesSegment = rootView.findViewById(R.id.fees_segment) - feesSegment.setOnCheckedChangeListener { _, checkedTypeId -> onFeeTypeSelected(checkedTypeId) } - onFeeTypeSelected(R.id.regular_fee_but) - } - - private fun onFeeTypeSelected(checkedTypeId: Int) { - val feeManager = FeeManager.getInstance() - when (checkedTypeId) { - R.id.regular_fee_but -> { - feeManager.setFeeType(FeeManager.REGULAR) - BRWalletManager.getInstance().setFeePerKb(feeManager.currentFees.regular) - setFeeInformation(R.string.FeeSelector_regularTime, 0, 0, View.GONE) - } - R.id.economy_fee_but -> { - feeManager.setFeeType(FeeManager.ECONOMY) - BRWalletManager.getInstance().setFeePerKb(feeManager.currentFees.economy) - setFeeInformation( - R.string.FeeSelector_economyTime, - R.string.FeeSelector_economyWarning, - R.color.chili, - View.VISIBLE, - ) - } - R.id.luxury_fee_but -> { - feeManager.setFeeType(FeeManager.LUXURY) - BRWalletManager.getInstance().setFeePerKb(feeManager.currentFees.luxury) - setFeeInformation( - R.string.FeeSelector_luxuryTime, - R.string.FeeSelector_luxuryMessage, - R.color.cheddar, - View.VISIBLE, - ) - } - else -> { - } - } - updateText() - } - - private fun setFeeInformation( - @StringRes deliveryTime: Int, - @StringRes warningStringId: Int, - @ColorRes warningColorId: Int, - visibility: Int, - ) { - feeDescription.text = - getString(R.string.FeeSelector_estimatedDeliver, getString(deliveryTime)) - if (warningStringId != 0) { - warningText.setText(warningStringId) - } - if (warningColorId != 0) { - warningText.setTextColor(resources.getColor(warningColorId, null)) - } - warningText.visibility = visibility - } +// private fun setupFeesSelector(rootView: View) { +// val feesSegment = rootView.findViewById(R.id.fees_segment) +// feesSegment.setOnCheckedChangeListener { _, checkedTypeId -> onFeeTypeSelected(checkedTypeId) } +// onFeeTypeSelected(R.id.regular_fee_but) +// } + +// private fun onFeeTypeSelected(checkedTypeId: Int) { +// val feeManager = FeeManager.getInstance() +// when (checkedTypeId) { +// R.id.regular_fee_but -> { +// feeManager.setFeeType(FeeManager.REGULAR) +// BRWalletManager.getInstance().setFeePerKb(feeManager.currentFeeOptions.regular) +// setFeeInformation(R.string.FeeSelector_regularTime, 0, 0, View.GONE) +// } +// R.id.economy_fee_but -> { +// feeManager.setFeeType(FeeManager.ECONOMY) +// BRWalletManager.getInstance().setFeePerKb(feeManager.currentFeeOptions.economy) +// setFeeInformation( +// R.string.FeeSelector_economyTime, +// R.string.FeeSelector_economyWarning, +// R.color.chili, +// View.VISIBLE, +// ) +// } +// R.id.luxury_fee_but -> { +// feeManager.setFeeType(FeeManager.LUXURY) +// BRWalletManager.getInstance().setFeePerKb(feeManager.currentFeeOptions.luxury) +// setFeeInformation( +// R.string.FeeSelector_luxuryTime, +// R.string.FeeSelector_luxuryMessage, +// R.color.cheddar, +// View.VISIBLE, +// ) +// } +// else -> { +// } +// } +// updateText() +// } + +// private fun setFeeInformation( +// @StringRes deliveryTime: Int, +// @StringRes warningStringId: Int, +// @ColorRes warningColorId: Int, +// visibility: Int, +// ) { +// feeDescription.text = +// getString(R.string.FeeSelector_estimatedDeliver, getString(deliveryTime)) +// if (warningStringId != 0) { +// warningText.setText(warningStringId) +// } +// if (warningColorId != 0) { +// warningText.setTextColor(resources.getColor(warningColorId, null)) +// } +// warningText.visibility = visibility +// } private fun setListeners() { amountEdit.setOnClickListener { @@ -187,8 +208,9 @@ class FragmentSend : Fragment() { amountEdit.textSize = 24f balanceText.visibility = View.VISIBLE feeText.visibility = View.VISIBLE - edit.visibility = View.VISIBLE - isoCurrencySymbolText.text = BRCurrency.getSymbolByIso(activity, selectedIsoCurrencySymbol) +// edit.visibility = View.VISIBLE + isoCurrencySymbolText.text = + BRCurrency.getSymbolByIso(activity, selectedIsoCurrencySymbol) isoCurrencySymbolText.textSize = 28f val scaleX = amountEdit.scaleX amountEdit.scaleX = 0f @@ -242,7 +264,13 @@ class FragmentSend : Fragment() { ConstraintSet.TOP, px4, ) - set.connect(isoCurrencySymbolText.id, ConstraintSet.BOTTOM, -1, ConstraintSet.TOP, -1) + set.connect( + isoCurrencySymbolText.id, + ConstraintSet.BOTTOM, + -1, + ConstraintSet.TOP, + -1 + ) set.applyTo(amountLayout) } } @@ -328,7 +356,11 @@ class FragmentSend : Fragment() { ) isoCurrencySymbolButton.setOnClickListener { selectedIsoCurrencySymbol = - if (selectedIsoCurrencySymbol.equals(BRSharedPrefs.getIsoSymbol(context), ignoreCase = true)) { + if (selectedIsoCurrencySymbol.equals( + BRSharedPrefs.getIsoSymbol(context), + ignoreCase = true + ) + ) { "LTC" } else { BRSharedPrefs.getIsoSymbol(context) @@ -372,7 +404,8 @@ class FragmentSend : Fragment() { if (allFilled) { BRSender.getInstance().sendTransaction( context, - TransactionItem(sendAddress, + TransactionItem( + sendAddress, Utils.fetchServiceItem(context, ServiceItems.WALLETOPS), null, litoshiAmount.toLong(), @@ -490,9 +523,11 @@ class FragmentSend : Fragment() { key.isEmpty() -> { handleDeleteClick() } + Character.isDigit(key[0]) -> { handleDigitClick(key.substring(0, 1).toInt()) } + key[0] == '.' -> { handleSeparatorClick() } @@ -537,7 +572,7 @@ class FragmentSend : Fragment() { private fun updateText() { if (activity == null) return var tempDoubleAmountValue = 0.0 - if (amountBuilder.toString() != "" && amountBuilder.toString() != "." ) { + if (amountBuilder.toString() != "" && amountBuilder.toString() != ".") { tempDoubleAmountValue = amountBuilder.toString().toDouble() } val scaleValue = 4 @@ -547,42 +582,68 @@ class FragmentSend : Fragment() { val selectedISOSymbol = selectedIsoCurrencySymbol val currencySymbol = BRCurrency.getSymbolByIso(activity, selectedIsoCurrencySymbol) if (!amountLabelOn) isoCurrencySymbolText.text = currencySymbol - isoCurrencySymbolButton.text = String.format("%s(%s)", - BRCurrency.getCurrencyName(activity, selectedIsoCurrencySymbol), - currencySymbol) + isoCurrencySymbolButton.text = String.format( + "%s(%s)", + BRCurrency.getCurrencyName(activity, selectedIsoCurrencySymbol), + currencySymbol + ) // Balance depending on ISOSymbol currentBalance = BRWalletManager.getInstance().getBalance(activity) - val balanceForISOSymbol = BRExchange.getAmountFromLitoshis(activity, selectedISOSymbol, BigDecimal(currentBalance)) - val formattedBalance = BRCurrency.getFormattedCurrencyString(activity, selectedISOSymbol, balanceForISOSymbol) + val balanceForISOSymbol = BRExchange.getAmountFromLitoshis( + activity, + selectedISOSymbol, + BigDecimal(currentBalance) + ) + val formattedBalance = + BRCurrency.getFormattedCurrencyString(activity, selectedISOSymbol, balanceForISOSymbol) // Current amount depending on ISOSymbol val currentAmountInLitoshis = if (selectedIsoCurrencySymbol.equals("LTC", ignoreCase = true)) { BRExchange.convertltcsToLitoshis(tempDoubleAmountValue).toLong() } else { - BRExchange.getLitoshisFromAmount(activity,selectedIsoCurrencySymbol,BigDecimal(tempDoubleAmountValue)).toLong() + BRExchange.getLitoshisFromAmount( + activity, + selectedIsoCurrencySymbol, + BigDecimal(tempDoubleAmountValue) + ).toLong() } - Timber.d("timber: updateText: currentAmountInLitoshis %d",currentAmountInLitoshis) + Timber.d("timber: updateText: currentAmountInLitoshis %d", currentAmountInLitoshis) // Network Fee depending on ISOSymbol - var networkFee = if(currentAmountInLitoshis > 0) { BRWalletManager.getInstance().feeForTransactionAmount(currentAmountInLitoshis) } - else { 0 } //Amount is zero so network fee is also zero + var networkFee = if (currentAmountInLitoshis > 0) { + BRWalletManager.getInstance().feeForTransactionAmount(currentAmountInLitoshis) + } else { + 0 + } //Amount is zero so network fee is also zero val networkFeeForISOSymbol = - BRExchange.getAmountFromLitoshis(activity,selectedISOSymbol, BigDecimal(networkFee)).setScale(scaleValue, RoundingMode.HALF_UP) - val formattedNetworkFee = BRCurrency.getFormattedCurrencyString(activity, selectedISOSymbol, networkFeeForISOSymbol) + BRExchange.getAmountFromLitoshis(activity, selectedISOSymbol, BigDecimal(networkFee)) + .setScale(scaleValue, RoundingMode.HALF_UP) + val formattedNetworkFee = BRCurrency.getFormattedCurrencyString( + activity, + selectedISOSymbol, + networkFeeForISOSymbol + ) // Service Fee depending on ISOSymbol var serviceFee = Utils.tieredOpsFee(activity, currentAmountInLitoshis) val serviceFeeForISOSymbol = - BRExchange.getAmountFromLitoshis(activity,selectedISOSymbol,BigDecimal(serviceFee)).setScale(scaleValue, RoundingMode.HALF_UP) - val formattedServiceFee = BRCurrency.getFormattedCurrencyString(activity, selectedISOSymbol, serviceFeeForISOSymbol) + BRExchange.getAmountFromLitoshis(activity, selectedISOSymbol, BigDecimal(serviceFee)) + .setScale(scaleValue, RoundingMode.HALF_UP) + val formattedServiceFee = BRCurrency.getFormattedCurrencyString( + activity, + selectedISOSymbol, + serviceFeeForISOSymbol + ) // Total Fees depending on ISOSymbol val totalFees = networkFee + serviceFee val totalFeeForISOSymbol = - BRExchange.getAmountFromLitoshis( activity,selectedISOSymbol,BigDecimal(totalFees)).setScale(scaleValue, RoundingMode.HALF_UP) - val formattedTotalFees = BRCurrency.getFormattedCurrencyString(activity, selectedISOSymbol, totalFeeForISOSymbol) + BRExchange.getAmountFromLitoshis(activity, selectedISOSymbol, BigDecimal(totalFees)) + .setScale(scaleValue, RoundingMode.HALF_UP) + val formattedTotalFees = + BRCurrency.getFormattedCurrencyString(activity, selectedISOSymbol, totalFeeForISOSymbol) // Update UI with alert red when over balance if (BigDecimal(currentAmountInLitoshis).toDouble() > currentBalance.toDouble()) { @@ -590,8 +651,7 @@ class FragmentSend : Fragment() { feeText.setTextColor(requireContext().getColor(R.color.chili)) amountEdit.setTextColor(requireContext().getColor(R.color.chili)) if (!amountLabelOn) isoCurrencySymbolText.setTextColor(requireContext().getColor(R.color.chili)) - } - else { + } else { balanceText.setTextColor(requireContext().getColor(R.color.cheddar)) feeText.setTextColor(requireContext().getColor(R.color.cheddar)) amountEdit.setTextColor(requireContext().getColor(R.color.cheddar)) @@ -599,12 +659,14 @@ class FragmentSend : Fragment() { } balanceText.text = getString(R.string.Send_balance, formattedBalance) - feeText.text = String.format("(%s + %s): %s + %s = %s", + feeText.text = String.format( + "(%s + %s): %s + %s = %s", getString(R.string.Network_feeLabel), getString(R.string.Fees_Service), formattedNetworkFee, formattedServiceFee, - formattedTotalFees) + formattedTotalFees + ) amountLayout.requestLayout() } @@ -627,13 +689,13 @@ class FragmentSend : Fragment() { } } - private fun showFeeSelectionButtons(b: Boolean) { - if (!b) { - signalLayout.removeView(feeLayout) - } else { - signalLayout.addView(feeLayout, signalLayout.indexOfChild(amountLayout) + 1) - } - } +// private fun showFeeSelectionButtons(b: Boolean) { +// if (!b) { +// signalLayout.removeView(feeLayout) +// } else { +// signalLayout.addView(feeLayout, signalLayout.indexOfChild(amountLayout) + 1) +// } +// } private fun setAmount() { val tmpAmount = amountBuilder.toString() @@ -648,7 +710,7 @@ class FragmentSend : Fragment() { newAmount.append(",") } } - + amountEdit.setText(newAmount.toString()) } @@ -680,7 +742,8 @@ class FragmentSend : Fragment() { private fun loadMetaData() { ignoreCleanup = false if (!Utils.isNullOrEmpty(savedMemo)) commentEdit.setText(savedMemo) - if (!Utils.isNullOrEmpty(savedIsoCurrencySymbol)) selectedIsoCurrencySymbol = savedIsoCurrencySymbol + if (!Utils.isNullOrEmpty(savedIsoCurrencySymbol)) selectedIsoCurrencySymbol = + savedIsoCurrencySymbol if (!Utils.isNullOrEmpty(savedAmount)) { amountBuilder = StringBuilder(savedAmount!!) Handler().postDelayed({ @@ -709,7 +772,6 @@ class FragmentSend : Fragment() { } - ///DEV WIP // val approximateNetworkFee = BRCurrency.getFormattedCurrencyString(activity, selectedISOSymbol, feeForISOSymbol) diff --git a/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java b/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java index 963a56af..f9457baa 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java @@ -5,34 +5,23 @@ import androidx.annotation.StringDef; import com.brainwallet.data.repository.LtcRepository; -import com.brainwallet.presenter.entities.ServiceItems; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.Utils; import com.brainwallet.data.model.Fee; -import com.platform.APIClient; import org.koin.java.KoinJavaComponent; -import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - -import okhttp3.Request; -import okhttp3.Response; -import timber.log.Timber; //we are still using this, maybe in the future will deprecate? +@Deprecated public final class FeeManager { private static final FeeManager instance; private String feeType; - public Fee currentFees; + public Fee currentFeeOptions; public static FeeManager getInstance() { return instance; @@ -44,8 +33,8 @@ public static FeeManager getInstance() { } private void initWithDefaultValues() { - currentFees = Fee.getDefault(); - feeType = REGULAR; + currentFeeOptions = Fee.getDefault(); + feeType = LUXURY; } private FeeManager() { @@ -56,37 +45,22 @@ public void setFeeType(@FeeType String feeType) { } public void resetFeeType() { - this.feeType = REGULAR; + this.feeType = LUXURY; } - public boolean isRegularFee() { - return feeType.equals(REGULAR); + public boolean isLuxuryFee() { + return feeType.equals(LUXURY); } - public static final String LUXURY = "luxury"; - public static final String REGULAR = "regular"; - public static final String ECONOMY = "economy"; + public static final String LUXURY = "luxury";//top + public static final String REGULAR = "regular";//medium + public static final String ECONOMY = "economy";//low public void setFees(long luxuryFee, long regularFee, long economyFee) { - // TODO: to be implemented when feePerKB API will be ready - currentFees = new Fee(luxuryFee, regularFee, economyFee, System.currentTimeMillis()); + currentFeeOptions = new Fee(luxuryFee, regularFee, economyFee); } public static void updateFeePerKb(Context app) { - -// String jsonString = "{'fee_per_kb': 10000, 'fee_per_kb_economy': 2500, 'fee_per_kb_luxury': 66746}"; -// try { -// JSONObject obj = new JSONObject(jsonString); -// // TODO: Refactor when mobile-api v0.4.0 is in prod -// long regularFee = obj.optLong("fee_per_kb"); -// long economyFee = obj.optLong("fee_per_kb_economy"); -// long luxuryFee = obj.optLong("fee_per_kb_luxury"); -// FeeManager.getInstance().setFees(luxuryFee, regularFee, economyFee); -// BRSharedPrefs.putFeeTime(app, System.currentTimeMillis()); //store the time of the last successful fee fetch -// } catch (JSONException e) { -// Timber.e(new IllegalArgumentException("updateFeePerKb: FAILED: " + jsonString, e)); -// } - LtcRepository ltcRepository = KoinJavaComponent.get(LtcRepository.class); BRExecutor.getInstance().executeSuspend( (coroutineScope, continuation) -> ltcRepository.fetchFeePerKb(continuation) @@ -98,43 +72,6 @@ public static void updateFeePerKb(Context app) { }); } - // createGETRequestURL - // Creates the params and headers to make a GET Request - @Deprecated - private static String createGETRequestURL(Context app, String myURL) { - Request request = new Request.Builder() - .url(myURL) - .header("Content-Type", "application/json") - .header("Accept", "application/json") - .header("User-agent", Utils.getAgentString(app, "android/HttpURLConnection")) - .header("BW-client-code", Utils.fetchServiceItem(app, ServiceItems.CLIENTCODE)) - .get().build(); - String response = null; - Response resp = APIClient.getInstance(app).sendRequest(request, false, 0); - - try { - if (resp == null) { - Timber.i("timber: urlGET: %s resp is null", myURL); - return null; - } - response = resp.body().string(); - String strDate = resp.header("date"); - if (strDate == null) { - Timber.i("timber: urlGET: strDate is null!"); - return response; - } - SimpleDateFormat formatter = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); - Date date = formatter.parse(strDate); - long timeStamp = date.getTime(); - BRSharedPrefs.putSecureTime(app, timeStamp); - } catch (ParseException | IOException e) { - Timber.e(e); - } finally { - if (resp != null) resp.close(); - } - return response; - } - @Retention(RetentionPolicy.SOURCE) @StringDef({LUXURY, REGULAR, ECONOMY}) public @interface FeeType { diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt index 9f924c3c..60a209bd 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt @@ -1,6 +1,10 @@ package com.brainwallet.ui.screens.home + import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.Fee +import com.brainwallet.data.model.FeeOption import com.brainwallet.data.model.Language +import com.brainwallet.data.model.toFeeOptions data class SettingsState( val darkMode: Boolean = true, @@ -15,4 +19,5 @@ data class SettingsState( val fiatSelectorBottomSheetVisible: Boolean = false, val shareAnalyticsDataEnabled: Boolean = false, val lastSyncMetadata: String? = null, + val currentFeeOptions: List = Fee.Default.toFeeOptions(), ) \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt index e9515ce8..8859d395 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt @@ -5,6 +5,8 @@ import androidx.core.os.LocaleListCompat import androidx.lifecycle.viewModelScope import com.brainwallet.data.model.AppSetting import com.brainwallet.data.model.Language +import com.brainwallet.data.model.toFeeOptions +import com.brainwallet.data.repository.LtcRepository import com.brainwallet.data.repository.SettingRepository import com.brainwallet.ui.BrainwalletViewModel import com.brainwallet.util.EventBus @@ -21,7 +23,8 @@ import kotlinx.coroutines.launch class SettingsViewModel( - private val settingRepository: SettingRepository + private val settingRepository: SettingRepository, + private val ltcRepository: LtcRepository ) : BrainwalletViewModel() { private val _state = MutableStateFlow(SettingsState()) @@ -50,7 +53,8 @@ class SettingsViewModel( _state.update { it.copy( shareAnalyticsDataEnabled = event.shareAnalyticsDataEnabled, - lastSyncMetadata = event.lastSyncMetadata + lastSyncMetadata = event.lastSyncMetadata, + currentFeeOptions = ltcRepository.fetchFeePerKb().toFeeOptions() ) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index 42b370a8..5c0c6a9c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -60,7 +60,7 @@ fun HomeSettingDrawerSheet( LaunchedEffect(Unit) { viewModel.onEvent(SettingsEvent.OnLoad( shareAnalyticsDataEnabled = BRSharedPrefs.getShareData(context), //currently just load analytics share data here - lastSyncMetadata = BRSharedPrefs.getSyncMetadata(context) //currently just load sync metadata here + lastSyncMetadata = BRSharedPrefs.getSyncMetadata(context), //currently just load sync metadata here )) } @@ -134,6 +134,8 @@ fun HomeSettingDrawerSheet( modifier = Modifier .fillMaxSize() .wrapContentHeight(), + selectedCurrency = state.selectedCurrency, + feeOptions = state.currentFeeOptions, onEvent = { viewModel.onEvent(it) } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt index 339584cd..138ab31c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt @@ -1,26 +1,50 @@ package com.brainwallet.ui.screens.home.composable.settingsrows +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material3.Button +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.SegmentedButton +import androidx.compose.material3.SegmentedButtonDefaults +import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import com.brainwallet.R +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.Fee +import com.brainwallet.data.model.FeeOption +import com.brainwallet.data.model.getFiatFormatted +import com.brainwallet.data.model.toFeeOptions +import com.brainwallet.tools.manager.FeeManager import com.brainwallet.ui.screens.home.SettingsEvent +import com.brainwallet.ui.theme.BrainwalletTheme +import com.brainwallet.wallet.BRWalletManager //TODO @Composable fun LitecoinBlockchainDetail( modifier: Modifier = Modifier, + selectedCurrency: CurrencyEntity, + feeOptions: List, onEvent: (SettingsEvent) -> Unit, ) { + var feeOptionsState by remember { mutableIntStateOf(2) } //2 -> index of top, since we have [low,medium,top] + /// Layout values val contentHeight = 60 val horizontalPadding = 14 @@ -35,19 +59,89 @@ fun LitecoinBlockchainDetail( ) { Row( - modifier = Modifier - .height(contentHeight.dp), + modifier = Modifier.height(contentHeight.dp), verticalAlignment = Alignment.CenterVertically ) { - Text(stringResource(R.string.settings_blockchain_litecoin_description)) - Spacer(modifier = Modifier.weight(1f)) - Button(onClick = { - onEvent.invoke(SettingsEvent.OnBlockchainSyncClick) - }) { + Text( + text = stringResource(R.string.settings_blockchain_litecoin_description), + modifier = Modifier.weight(1.3f) + ) + Button( + modifier = Modifier.weight(.7f), + onClick = { + onEvent.invoke(SettingsEvent.OnBlockchainSyncClick) + } + ) { Text(stringResource(R.string.settings_blockchain_litecoin_button)) } } + HorizontalDivider(color = BrainwalletTheme.colors.content) + + NetworkFeeSelector( + selectedCurrency = selectedCurrency, + feeOptions = feeOptions, + selectedIndex = feeOptionsState + ) { newSelectedIndex -> + feeOptionsState = newSelectedIndex + + //just update inside BRWalletManager.setFeePerKb + BRWalletManager.getInstance().setFeePerKb(feeOptions[newSelectedIndex].feePerKb) + } + + } + } +} + +@Composable +private fun NetworkFeeSelector( + selectedCurrency: CurrencyEntity, + feeOptions: List, + selectedIndex: Int, + onSelectedChange: (Int) -> Unit +) { + Column( + modifier = Modifier.padding(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + Text( + text = stringResource(R.string.network_fee_options_desc), + fontSize = 12.sp, + ) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween + ) { + feeOptions.forEachIndexed { index, feeOption -> + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Text( + text = "${feeOption.feePerKb}", + fontWeight = FontWeight.Bold + ) + Text( + text = feeOptions[index].getFiatFormatted(selectedCurrency), //fiat? + fontSize = 12.sp + ) + } + } + } + + SingleChoiceSegmentedButtonRow { + feeOptions.forEachIndexed { index, feeOption -> + SegmentedButton( + shape = SegmentedButtonDefaults.itemShape( + index = index, + count = feeOptions.size, + baseShape = MaterialTheme.shapes.extraLarge + ), + onClick = { onSelectedChange.invoke(index) }, + selected = index == selectedIndex, + label = { Text(stringResource(feeOption.labelStringId)) } + ) + } } + + } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java index 7a37d9cd..507a5125 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java @@ -514,9 +514,9 @@ public void initWallet(final Context ctx) { String firstAddress = BRWalletManager.getFirstAddress(pubkeyEncoded); BRSharedPrefs.putFirstAddress(ctx, firstAddress); FeeManager feeManager = FeeManager.getInstance(); - if (feeManager.isRegularFee()) { - feeManager.updateFeePerKb(ctx); - BRWalletManager.getInstance().setFeePerKb(feeManager.currentFees.regular); + if (feeManager.isLuxuryFee()) { + FeeManager.updateFeePerKb(ctx); + BRWalletManager.getInstance().setFeePerKb(feeManager.currentFeeOptions.luxury); } } diff --git a/app/src/main/res/layout/fragment_send.xml b/app/src/main/res/layout/fragment_send.xml index c60707bd..742ea48f 100644 --- a/app/src/main/res/layout/fragment_send.xml +++ b/app/src/main/res/layout/fragment_send.xml @@ -216,105 +216,15 @@ android:textSize="18sp" app:buttonType="2" app:isBreadButton="true" - app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" - app:layout_constraintVertical_bias="0.0" /> - - - - - - - - - - - - - - - - - - - - + - مشاركة بيانات التحليلات تحديث الرقم السري عرض + رسوم الشبكة (لكل كيلو بايت): القيمة الأعلى تعني اكتمال المعاملة في وقت أقرب + قمة + واسطة + قليل diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 4d0e68ac..6d272928 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -796,4 +796,8 @@ Analyse-Daten teilen PIN aktualisieren Anzeigen + Netzwerkgebühr (pro KB): Ein höherer Wert bedeutet, dass die Transaktion früher abgeschlossen wird + Spitze + Medium + Niedrig diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 9f12f07d..24bf3fc0 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -169,9 +169,9 @@ Ignorar - SEGURIDAD DEL DISPOSITIVO COMPROMETIDA\nCualquier aplicación \"jailbreak\" puede acceder a los datos del llavero de Loaf y robar tus Litecoins. Borra esta cartera de inmediato y restáurala en un dispositivo seguro. + SEGURIDAD DEL DISPOSITIVO COMPROMETIDA\nCualquier aplicación "jailbreak" puede acceder a los datos del llavero de Loaf y robar tus Litecoins. Borra esta cartera de inmediato y restáurala en un dispositivo seguro. - SEGURIDAD DEL DISPOSITIVO COMPROMETIDA\nCualquier aplicación \"jailbreak\" puede acceder a los datos del llavero de Loaf y robar tus Litecoins. Usa Loaf únicamente en un dispositivo sin jailbreak. + SEGURIDAD DEL DISPOSITIVO COMPROMETIDA\nCualquier aplicación "jailbreak" puede acceder a los datos del llavero de Loaf y robar tus Litecoins. Usa Loaf únicamente en un dispositivo sin jailbreak. AVISO @@ -795,4 +795,8 @@ Compartir datos analíticos Actualizar PIN Mostrar + Tarifa de red (por kb): un valor más alto significa que la transacción se completa antes + Arriba + Medio + Bajo diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 93928b67..1571dd93 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -796,4 +796,8 @@ Partager les données analytiques Mettre à jour le code PIN Afficher + Frais de réseau (par Ko): une valeur plus élevée signifie que la transaction se termine plus tôt + Haut + Moyen + Faible diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 8a0158a5..a03d849c 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -434,4 +434,8 @@ विश्लेषण डेटा साझा करें पिन अपडेट करें दिखाएं + नेटवर्क शुल्क (प्रति केबी): उच्च मूल्य का मतलब है कि लेनदेन जल्दी पूरा हो जाएगा + शीर्ष + मध्यम + कम diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 7899cb2d..d3bb43e0 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -798,4 +798,8 @@ Bagikan data analitik Perbarui PIN Tampilkan + Biaya Jaringan (per kb): Nilai yang lebih tinggi berarti transaksi selesai lebih cepat + Atas + Sedang + Rendah diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 6641145b..592ebba1 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -796,4 +796,8 @@ Condividere i dati analitici Aggiorna PIN Mostra + Tariffa di rete (per kb): un valore più elevato significa che la transazione viene completata prima + Superiore + Medio + Basso diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 523cd7f2..c6ffb20c 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -796,4 +796,8 @@ 分析データを共有 PIN を更新 表示 + ネットワーク料金 (kb あたり): 値が高いほど、トランザクションが早く完了することを意味します + トップ + 中くらい + 低い diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 3deda254..8ec4b384 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -796,4 +796,8 @@ 분석 데이터 공유 PIN 업데이트 표시 + 네트워크 수수료(kb당): 값이 높을수록 거래가 더 빨리 완료됨을 의미합니다. + 맨 위 + 중간 + 낮은 diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 48a2dc0b..27b64935 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -795,4 +795,8 @@ Compartilhar dados analíticos Atualizar PIN Mostrar + Taxa de rede (por kb): valor mais alto significa que a transação é concluída mais cedo + Principal + Médio + Baixo diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 22df2082..4df74670 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -796,4 +796,8 @@ Делиться аналитическими данными Обновить PIN Показать + Сетевая плата (за КБ): более высокое значение означает, что транзакция завершится раньше. + Вершина + Середина + Низкий diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 12d62935..78b503fd 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -434,4 +434,8 @@ Dela analysdata Uppdatera PIN Visa + Nätverksavgift (per kb): Högre värde innebär att transaktionen slutförs tidigare + Bästa + Medium + Låg diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index d1e3c107..a526c60c 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -819,4 +819,8 @@ Analitik verileri paylaş PIN güncelle Göster + Ağ Ücreti (kb başına): Daha yüksek değer, işlemin daha erken tamamlanacağı anlamına gelir + Tepe + Orta + Düşük diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 3f7aca4a..b5d20546 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -802,4 +802,8 @@ Ділитися аналітичними даними Оновити PIN Показати + Плата за мережу (за кб): вищий показник означає, що транзакція завершується швидше + Топ + Середній + Низький diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b25903f6..b1517637 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -764,7 +764,7 @@ 你可以从开始的地方返回 恢复我的脑钱包 清除 - 不要猜测。\n\n这将需要你 \n5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000 次尝试 + 不要猜测。\n\n这将需要你 \n5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000,000 次尝试 确认 你没有忘记吧?再次输入。或者,返回重新开始。 准备好 @@ -796,4 +796,8 @@ 分享分析数据 更新 PIN 显示 + 网络费用(每 kb):值越高意味着交易完成得越快 + 顶部 + 中等的 + 低的 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 13e6b9cc..69514c55 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -796,4 +796,8 @@ 分享分析數據 更新 PIN 顯示 + 網路費用(每 kb):數值越高代表交易完成越快 + 頂部 + 中等的 + 低的 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1b2f4e52..3e6f5bbe 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -805,7 +805,7 @@ You can get back from where you started Restore my Brainwallet Clear - Don’t guess.\n\nIt would take you \n5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000 tries + Don’t guess.\n\nIt would take you \n5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000,000 tries Confirm You didn’t forget did you? Enter it again. Or, go back to start over. Ready @@ -839,5 +839,8 @@ Share analytics data Update PIN Show - + Network Fee (per kb): Higher value mean the transaction completes sooner + Top + Medium + Low From e7fb2b7873f4ddb5a9c511a0c0b91efe9041b77a Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Wed, 7 May 2025 12:45:38 +0700 Subject: [PATCH 026/116] fix: fix dismiss allow state loss (#76) --- .../com/brainwallet/presenter/fragments/FragmentSignal.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java index 4c136b41..5757a798 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSignal.java @@ -31,7 +31,7 @@ public class FragmentSignal extends DialogFragment { private final Runnable popBackStackRunnable = new Runnable() { @Override public void run() { - dismiss(); + dismissAllowingStateLoss(); handler.postDelayed(completionRunnable, 300); } }; From 3d8ef981879bbcab1d1fa8cab54c2b08edfd29e0 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Wed, 7 May 2025 12:46:41 +0700 Subject: [PATCH 027/116] fix: fix typo at strings.xml (#75) --- app/src/main/res/values-zh-rCN/strings.xml | 2 +- app/src/main/res/values/strings.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b1517637..53cd941f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -764,7 +764,7 @@ 你可以从开始的地方返回 恢复我的脑钱包 清除 - 不要猜测。\n\n这将需要你 \n5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000,000 次尝试 + 不要猜测。\n\n这将需要你 \n5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000 次尝试 确认 你没有忘记吧?再次输入。或者,返回重新开始。 准备好 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3e6f5bbe..d107536c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -805,7 +805,7 @@ You can get back from where you started Restore my Brainwallet Clear - Don’t guess.\n\nIt would take you \n5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000,000 tries + Don’t guess.\n\nIt would take you \n5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000 tries Confirm You didn’t forget did you? Enter it again. Or, go back to start over. Ready From 25be1a85f036e502811c3e093398feee996dfe77 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Mon, 12 May 2025 18:59:29 +0700 Subject: [PATCH 028/116] feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent --- .../data/model/MoonpayCurrencyLimit.kt | 24 + .../data/model/QuickFiatAmountOption.kt | 11 + .../data/repository/LtcRepository.kt | 65 +- .../data/source/LocalCacheSource.kt | 45 ++ .../data/source/RemoteApiSource.kt | 22 +- .../response/GetMoonpayBuyQuoteResponse.kt | 17 + .../response/GetMoonpaySignUrlResponse.kt | 8 + .../main/java/com/brainwallet/di/Module.kt | 36 +- .../navigation/LegacyNavigation.kt | 61 ++ .../com/brainwallet/navigation/MainNav.kt | 5 + .../java/com/brainwallet/navigation/Route.kt | 3 + .../presenter/activities/BreadActivity.java | 23 +- .../com/brainwallet/tools/qrcode/QRUtils.java | 15 + .../tools/sqlite/CurrencyDataSource.java | 51 +- .../brainwallet/ui/BrainwalletViewModel.kt | 19 + .../brainwallet/ui/composable/Foundation.kt | 18 +- .../brainwallet/ui/composable/LargeButton.kt | 5 +- .../ui/composable/LoadingDialog.kt | 55 ++ .../ui/composable/MoonpayBuyButton.kt | 66 ++ .../ui/composable/MoonpayBuyWidget.kt | 56 ++ .../brainwallet/ui/composable/WheelPicker.kt | 634 ++++++++++++++++++ .../screens/buylitecoin/BuyLitecoinEvent.kt | 11 + .../screens/buylitecoin/BuyLitecoinScreen.kt | 167 +++++ .../screens/buylitecoin/BuyLitecoinState.kt | 19 + .../buylitecoin/BuyLitecoinViewModel.kt | 128 ++++ .../ui/screens/home/buy/BuyScreen.kt | 10 - .../ui/screens/home/receive/ReceiveDialog.kt | 452 +++++++++++++ .../home/receive/ReceiveDialogEvent.kt | 21 + .../home/receive/ReceiveDialogState.kt | 61 ++ .../home/receive/ReceiveDialogViewModel.kt | 179 +++++ .../ui/screens/topup/TopUpScreen.kt | 182 ++--- .../YourSeedProveItViewModel.kt | 4 +- .../java/com/brainwallet/ui/theme/Theme.kt | 4 + app/src/main/res/drawable/ic_copy.xml | 9 + app/src/main/res/drawable/ic_import.xml | 19 + app/src/main/res/menu/bottom_nav_menu.xml | 10 +- app/src/main/res/menu/bottom_nav_menu_us.xml | 23 +- app/src/main/res/values-ar/strings.xml | 11 + app/src/main/res/values-de/strings.xml | 11 + app/src/main/res/values-es/strings.xml | 11 + app/src/main/res/values-fr/strings.xml | 11 + app/src/main/res/values-hi/strings.xml | 11 + app/src/main/res/values-in/strings.xml | 11 + app/src/main/res/values-it/strings.xml | 11 + app/src/main/res/values-ja/strings.xml | 11 + app/src/main/res/values-ko/strings.xml | 11 + app/src/main/res/values-pt/strings.xml | 11 + app/src/main/res/values-ru/strings.xml | 11 + app/src/main/res/values-sv/strings.xml | 11 + app/src/main/res/values-tr/strings.xml | 12 + app/src/main/res/values-uk/strings.xml | 12 + app/src/main/res/values-zh-rCN/strings.xml | 11 + app/src/main/res/values-zh-rTW/strings.xml | 11 + app/src/main/res/values/strings.xml | 14 +- 54 files changed, 2479 insertions(+), 251 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt create mode 100644 app/src/main/java/com/brainwallet/data/model/QuickFiatAmountOption.kt create mode 100644 app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt create mode 100644 app/src/main/java/com/brainwallet/data/source/response/GetMoonpayBuyQuoteResponse.kt create mode 100644 app/src/main/java/com/brainwallet/data/source/response/GetMoonpaySignUrlResponse.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyWidget.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/screens/home/buy/BuyScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt create mode 100644 app/src/main/res/drawable/ic_copy.xml create mode 100644 app/src/main/res/drawable/ic_import.xml diff --git a/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt b/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt new file mode 100644 index 00000000..d8344438 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt @@ -0,0 +1,24 @@ +package com.brainwallet.data.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class MoonpayCurrencyLimit( + @SerialName("data") val data: Data = Data() +) { + @Serializable + data class Data( + @SerialName("paymentMethod") val paymentMethod: String = "", + @SerialName("quoteCurrency") val quoteCurrency: CurrencyLimit = CurrencyLimit(), + @SerialName("baseCurrency") val baseCurrency: CurrencyLimit = CurrencyLimit(), + @SerialName("areFeesIncluded") val areFeesIncluded: Boolean = false + ) + + @Serializable + data class CurrencyLimit( + val code: String = "usd", + @SerialName("minBuyAmount") val min: Float = 21f, + @SerialName("maxBuyAmount") val max: Float = 29849f + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/model/QuickFiatAmountOption.kt b/app/src/main/java/com/brainwallet/data/model/QuickFiatAmountOption.kt new file mode 100644 index 00000000..20dc3368 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/model/QuickFiatAmountOption.kt @@ -0,0 +1,11 @@ +package com.brainwallet.data.model + + +data class QuickFiatAmountOption( + val symbol: String = "custom", + val value: Float = -1f +) + +fun QuickFiatAmountOption.isCustom(): Boolean = symbol == "custom" && value == -1f + +fun QuickFiatAmountOption.getFormattedText(): String = "${symbol}${value.toInt()}" \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index 38b325fd..365bbc0d 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -2,21 +2,29 @@ package com.brainwallet.data.repository import android.content.Context import android.content.SharedPreferences -import androidx.core.content.edit +import androidx.core.net.toUri +import com.brainwallet.BuildConfig import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Fee +import com.brainwallet.data.model.MoonpayCurrencyLimit import com.brainwallet.data.source.RemoteApiSource -import com.brainwallet.di.json +import com.brainwallet.data.source.fetchWithCache +import com.brainwallet.data.source.response.GetMoonpayBuyQuoteResponse import com.brainwallet.tools.manager.BRSharedPrefs import com.brainwallet.tools.manager.FeeManager import com.brainwallet.tools.sqlite.CurrencyDataSource -import kotlinx.serialization.encodeToString interface LtcRepository { suspend fun fetchRates(): List suspend fun fetchFeePerKb(): Fee + suspend fun fetchLimits(baseCurrencyCode: String): MoonpayCurrencyLimit + + suspend fun fetchBuyQuote(params: Map): GetMoonpayBuyQuoteResponse + + suspend fun fetchMoonpaySignedUrl(params: Map): String + class Impl( private val context: Context, private val remoteApiSource: RemoteApiSource, @@ -47,27 +55,42 @@ interface LtcRepository { } override suspend fun fetchFeePerKb(): Fee { - val lastUpdateTime = sharedPreferences.getLong(PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT, 0) - val currentTime = System.currentTimeMillis() - val cachedFee = sharedPreferences.getString(PREF_KEY_NETWORK_FEE_PER_KB, null) - ?.let { json.decodeFromString(it) } + return sharedPreferences.fetchWithCache( + key = PREF_KEY_NETWORK_FEE_PER_KB, + cachedAtKey = PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT, + cacheTimeMs = 6 * 60 * 60 * 1000, + fetchData = { + remoteApiSource.getFeePerKb() + }, + defaultValue = Fee.Default + ) + } - return runCatching { - // Check if cache exists and is less than 6 hours old - if (cachedFee != null && (currentTime - lastUpdateTime) < 6 * 60 * 60 * 1000) { - return cachedFee + override suspend fun fetchLimits(baseCurrencyCode: String): MoonpayCurrencyLimit { + return sharedPreferences.fetchWithCache( + key = "${PREF_KEY_BUY_LIMITS_PREFIX}${baseCurrencyCode.lowercase()}", + cachedAtKey = "${PREF_KEY_BUY_LIMITS_PREFIX_CACHED_AT}${baseCurrencyCode.lowercase()}", + cacheTimeMs = 5 * 60 * 1000, //5 minutes + fetchData = { + remoteApiSource.getMoonpayCurrencyLimit(baseCurrencyCode) } + ) + } - val fee = remoteApiSource.getFeePerKb() - sharedPreferences.edit { - putString(PREF_KEY_NETWORK_FEE_PER_KB, json.encodeToString(fee)) - putLong(PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT, currentTime) - } + override suspend fun fetchBuyQuote(params: Map): GetMoonpayBuyQuoteResponse = + remoteApiSource.getBuyQuote(params) - return fee - }.getOrElse { - cachedFee ?: Fee.Default - } + override suspend fun fetchMoonpaySignedUrl(params: Map): String { + return remoteApiSource.getMoonpaySignedUrl(params) + .signedUrl.toUri() + .buildUpon() + .apply { + if (BuildConfig.DEBUG) { + authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com + } + } + .build() + .toString() } } @@ -75,5 +98,7 @@ interface LtcRepository { companion object { const val PREF_KEY_NETWORK_FEE_PER_KB = "network_fee_per_kb" const val PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT = "${PREF_KEY_NETWORK_FEE_PER_KB}_cached_at" + const val PREF_KEY_BUY_LIMITS_PREFIX = "buy_limits:" //e.g. buy_limits:usd + const val PREF_KEY_BUY_LIMITS_PREFIX_CACHED_AT = "buy_limits_cached_at:" } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt b/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt new file mode 100644 index 00000000..d86d312d --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt @@ -0,0 +1,45 @@ +package com.brainwallet.data.source + +import android.content.SharedPreferences +import androidx.core.content.edit +import com.brainwallet.di.json +import kotlinx.serialization.encodeToString + +/** + * Generic function to handle caching data in shared preferences + * @param key The key to store the data under + * @param cachedAtKey The key to store the timestamp under + * @param cacheTimeMs How long the cache should be valid in milliseconds + * @param fetchData Suspending function to fetch new data + * @return The data, either from cache or freshly fetched + */ +suspend inline fun SharedPreferences.fetchWithCache( + key: String, + cachedAtKey: String, + cacheTimeMs: Long, + crossinline fetchData: suspend () -> T, + defaultValue: T? = null +): T { + val lastUpdateTime = getLong(cachedAtKey, 0) + val currentTime = System.currentTimeMillis() + val cached = getString(key, null) + ?.let { runCatching { json.decodeFromString(it) }.getOrNull() } + + // Return cached value if it exists and is not expired + if (cached != null && (currentTime - lastUpdateTime) < cacheTimeMs) { + return cached + } + + return runCatching { + // Fetch fresh data + val result = fetchData() + // Save to cache + edit { + putString(key, json.encodeToString(result)) + putLong(cachedAtKey, currentTime) + } + result + }.getOrElse { + cached ?: (defaultValue ?: throw it) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt index 60c865e2..4e0a1c02 100644 --- a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt @@ -2,7 +2,12 @@ package com.brainwallet.data.source import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Fee +import com.brainwallet.data.model.MoonpayCurrencyLimit +import com.brainwallet.data.source.response.GetMoonpayBuyQuoteResponse +import com.brainwallet.data.source.response.GetMoonpaySignUrlResponse import retrofit2.http.GET +import retrofit2.http.Query +import retrofit2.http.QueryMap //TODO interface RemoteApiSource { @@ -13,6 +18,19 @@ interface RemoteApiSource { @GET("v1/fee-per-kb") suspend fun getFeePerKb(): Fee -// https://prod.apigsltd.net/moonpay/buy?address=ltc1qjnsg3p9rt4r4vy7ncgvrywdykl0zwhkhcp8ue0&code=USD&idate=1742331930290&uid=ec51fa950b271ff3 -// suspend fun getMoonPayBuy() + @GET("v1/moonpay/ltc-to-fiat-limits") + suspend fun getMoonpayCurrencyLimit( + @Query("baseCurrencyCode") baseCurrencyCode: String + ): MoonpayCurrencyLimit + + @GET("v1/moonpay/sign-url") + suspend fun getMoonpaySignedUrl( + @QueryMap params: Map + ): GetMoonpaySignUrlResponse + + @GET("v1/moonpay/buy-quote") + suspend fun getBuyQuote( + @QueryMap params: Map + ): GetMoonpayBuyQuoteResponse + } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/source/response/GetMoonpayBuyQuoteResponse.kt b/app/src/main/java/com/brainwallet/data/source/response/GetMoonpayBuyQuoteResponse.kt new file mode 100644 index 00000000..848732a9 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/source/response/GetMoonpayBuyQuoteResponse.kt @@ -0,0 +1,17 @@ +package com.brainwallet.data.source.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class GetMoonpayBuyQuoteResponse( + @SerialName("data") val data: Data = Data() + +) { + @Serializable + data class Data( + val totalAmount: Float = 0f, + val baseCurrencyCode: String = "usd", + val quoteCurrencyAmount: Float = 0f, + ) +} diff --git a/app/src/main/java/com/brainwallet/data/source/response/GetMoonpaySignUrlResponse.kt b/app/src/main/java/com/brainwallet/data/source/response/GetMoonpaySignUrlResponse.kt new file mode 100644 index 00000000..51e316cc --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/source/response/GetMoonpaySignUrlResponse.kt @@ -0,0 +1,8 @@ +package com.brainwallet.data.source.response + +import kotlinx.serialization.Serializable + +@Serializable +data class GetMoonpaySignUrlResponse( + val signedUrl: String +) diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index 8dcfb909..b95bbeec 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -10,7 +10,9 @@ import com.brainwallet.data.source.RemoteApiSource import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.tools.util.BRConstants +import com.brainwallet.ui.screens.buylitecoin.BuyLitecoinViewModel import com.brainwallet.ui.screens.home.SettingsViewModel +import com.brainwallet.ui.screens.home.receive.ReceiveDialogViewModel import com.brainwallet.ui.screens.inputwords.InputWordsViewModel import com.brainwallet.ui.screens.ready.ReadyViewModel import com.brainwallet.ui.screens.setpasscode.SetPasscodeViewModel @@ -28,6 +30,8 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import org.koin.android.ext.koin.androidApplication +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject import org.koin.core.module.dsl.viewModel import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.module @@ -70,6 +74,8 @@ val viewModelModule = module { viewModel { UnLockViewModel() } viewModel { YourSeedProveItViewModel() } viewModel { YourSeedWordsViewModel() } + viewModel { ReceiveDialogViewModel(get(), get()) } + viewModel { BuyLitecoinViewModel(get(), get()) } } val appModule = module { @@ -94,28 +100,6 @@ private fun provideOkHttpClient(): OkHttpClient = OkHttpClient.Builder() .addHeader("Accept-Language", "en") chain.proceed(requestBuilder.build()) } - .addInterceptor { chain -> - val request = chain.request() - runCatching { - chain.proceed(request).use { response -> - if (response.isSuccessful.not()) { - throw HttpException( - retrofit2.Response.error( - response.code, - response.body ?: response.peekBody(Long.MAX_VALUE) - ) - ) - } - response - } - }.getOrElse { - //retry using dev host - val newRequest = request.newBuilder() - .url("${BRConstants.LEGACY_BW_API_DEV_HOST}/api${request.url.encodedPath}") //legacy dev api need prefix path /api - .build() - chain.proceed(newRequest) - } - } .addInterceptor(HttpLoggingInterceptor().apply { setLevel( when { @@ -140,4 +124,10 @@ internal fun provideRetrofit( .build() internal inline fun provideApi(retrofit: Retrofit): T = - retrofit.create(T::class.java) \ No newline at end of file + retrofit.create(T::class.java) + +inline fun getKoinInstance(): T { + return object : KoinComponent { + val value: T by inject() + }.value +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt index b50bef17..d38eaeb9 100644 --- a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt +++ b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt @@ -1,11 +1,22 @@ package com.brainwallet.navigation import android.app.Activity +import android.app.ProgressDialog import android.content.Context import android.content.Intent +import android.widget.Toast +import androidx.browser.customtabs.CustomTabsIntent +import androidx.core.net.toUri +import com.brainwallet.BuildConfig import com.brainwallet.R +import com.brainwallet.data.source.RemoteApiSource +import com.brainwallet.di.getKoinInstance import com.brainwallet.presenter.activities.BreadActivity import com.brainwallet.ui.BrainwalletActivity +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import timber.log.Timber @@ -55,4 +66,54 @@ object LegacyNavigation { context.startActivity(it) } + @JvmStatic + fun showMoonPayWidget( + context: Context, + params: Map = mapOf(), + isDarkMode: Boolean = true, + ) { + val remoteApiSource: RemoteApiSource = getKoinInstance() + + val progressDialog = ProgressDialog(context).apply { + setMessage(context.getString(R.string.loading)) + setCancelable(false) + show() + } + + CoroutineScope(Dispatchers.Main).launch { + try { + val result = withContext(Dispatchers.IO) { + remoteApiSource.getMoonpaySignedUrl( + params = params.toMutableMap().apply { + put("defaultCurrencyCode", "ltc") + put("currencyCode", "ltc") + put("themeId", "main-v1.0.0") + put("theme", if (isDarkMode) "dark" else "light") + } + ) + } + + val widgetUri = result.signedUrl.toUri().buildUpon() + .apply { + if (BuildConfig.DEBUG) { + authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com + } + } + .build() + val intent = CustomTabsIntent.Builder() + .setColorScheme(if (isDarkMode) CustomTabsIntent.COLOR_SCHEME_DARK else CustomTabsIntent.COLOR_SCHEME_LIGHT) + .build() + intent.launchUrl(context, widgetUri) + } catch (e: Exception) { + Toast.makeText( + context, + "Failed to load: ${e.message}, please try again later", + Toast.LENGTH_LONG + ).show() + } finally { + progressDialog.dismiss() + } + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/navigation/MainNav.kt b/app/src/main/java/com/brainwallet/navigation/MainNav.kt index f6e2e091..ec2a8a06 100644 --- a/app/src/main/java/com/brainwallet/navigation/MainNav.kt +++ b/app/src/main/java/com/brainwallet/navigation/MainNav.kt @@ -7,6 +7,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.toRoute +import com.brainwallet.ui.screens.buylitecoin.BuyLitecoinScreen import com.brainwallet.ui.screens.inputwords.InputWordsScreen import com.brainwallet.ui.screens.ready.ReadyScreen import com.brainwallet.ui.screens.setpasscode.SetPasscodeScreen @@ -113,6 +114,10 @@ fun NavGraphBuilder.mainNavGraph( UnLockScreen(onNavigate = onNavigate, isUpdatePin = route.isUpdatePin) } + composable { navBackStackEntry -> + BuyLitecoinScreen(onNavigate = onNavigate) + } + //todo add more composable screens } diff --git a/app/src/main/java/com/brainwallet/navigation/Route.kt b/app/src/main/java/com/brainwallet/navigation/Route.kt index 2e0e71a8..16f16dcf 100644 --- a/app/src/main/java/com/brainwallet/navigation/Route.kt +++ b/app/src/main/java/com/brainwallet/navigation/Route.kt @@ -45,4 +45,7 @@ sealed class Route : JavaSerializable { @Serializable data class UnLock(val isUpdatePin: Boolean = false) : Route() + @Serializable + object BuyLitecoin : Route() + } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java index aec322e1..b210395c 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java @@ -25,6 +25,7 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; +import androidx.browser.customtabs.CustomTabsIntent; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import androidx.core.app.ActivityCompat; @@ -61,6 +62,8 @@ import com.brainwallet.ui.BrainwalletActivity; import com.brainwallet.ui.screens.home.SettingsViewModel; import com.brainwallet.ui.screens.home.composable.HomeSettingDrawerComposeView; +import com.brainwallet.ui.screens.home.receive.ReceiveDialogFragment; +import com.brainwallet.ui.screens.home.receive.ReceiveDialogKt; import com.brainwallet.util.PermissionUtil; import com.brainwallet.wallet.BRPeerManager; import com.brainwallet.wallet.BRWalletManager; @@ -252,16 +255,22 @@ public boolean handleNavigationItemSelected(int menuItemId) { mSelectedBottomNavItem = 0; } else if (menuItemId == R.id.nav_receive) { if (BRAnimator.isClickAllowed()) { - BRAnimator.showReceiveFragment(BreadActivity.this, true); - } - mSelectedBottomNavItem = 0; - } - else if (menuItemId == R.id.nav_buy) { - if (BRAnimator.isClickAllowed()) { - BRAnimator.showMoonpayFragment(BreadActivity.this); +// BRAnimator.showReceiveFragment(BreadActivity.this, true); + //todo + ReceiveDialogFragment.show(getSupportFragmentManager()); } mSelectedBottomNavItem = 0; } +// else if (menuItemId == R.id.nav_buy) { +// if (BRAnimator.isClickAllowed()) { +//// BRAnimator.showMoonpayFragment(BreadActivity.this); +// } +// +// +// +// +// mSelectedBottomNavItem = 0; +// } return true; } diff --git a/app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java b/app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java index 5728657c..a0e9fd5f 100644 --- a/app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java +++ b/app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java @@ -83,6 +83,21 @@ public static boolean generateQR(Context ctx, String bitcoinURL, ImageView qrcod return true; } + public static Bitmap generateQR(Context ctx, String litecoinUrl) { + if (litecoinUrl == null || litecoinUrl.isEmpty()) return null; + WindowManager manager = (WindowManager) ctx.getSystemService(Activity.WINDOW_SERVICE); + Display display = manager.getDefaultDisplay(); + Point point = new Point(); + display.getSize(point); + int width = point.x; + int height = point.y; + int smallerDimension = Math.min(width, height); + smallerDimension = (int) (smallerDimension * 0.45f); + Bitmap bitmap = null; + bitmap = QRUtils.encodeAsBitmap(litecoinUrl, smallerDimension); + return bitmap; + } + private static String guessAppropriateEncoding(CharSequence contents) { // Very crude at the moment for (int i = 0; i < contents.length(); i++) { diff --git a/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java b/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java index 40ad36b1..7c15df6d 100644 --- a/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java +++ b/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java @@ -16,6 +16,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import timber.log.Timber; @@ -31,6 +32,27 @@ public class CurrencyDataSource implements BRDataSourceInterface { BRSQLiteHelper.CURRENCY_RATE }; + /// Set the most popular fiats + /// Hack: Database needs a symbol column. This is injected here. + private final HashMap codeSymbolsMap = new HashMap() {{ + put("USD","$"); + put("EUR","€"); + put("GBP","£"); + put("SGD","$"); + put("CAD","$"); + put("AUD","$"); + put("RUB","₽"); + put("KRW","₩"); + put("MXN","$"); + put("SAR","﷼"); + put("UAH","₴"); + put("NGN","₦"); + put("JPY","¥"); + put("CNY","¥"); + put("IDR","Rp"); + put("TRY","₺"); + }}; + private static CurrencyDataSource instance; public static CurrencyDataSource getInstance(Context context) { @@ -71,26 +93,6 @@ public List getAllCurrencies(Boolean shouldBeFiltered) { List currencies = new ArrayList<>(); - /// Set the most popular fiats - /// Hack: Database needs a symbol column. This is injected here. - HashMap codeSymbolsMap = new HashMap(); - codeSymbolsMap.put("USD","$"); - codeSymbolsMap.put("EUR","€"); - codeSymbolsMap.put("GBP","£"); - codeSymbolsMap.put("SGD","$"); - codeSymbolsMap.put("CAD","$"); - codeSymbolsMap.put("AUD","$"); - codeSymbolsMap.put("RUB","₽"); - codeSymbolsMap.put("KRW","₩"); - codeSymbolsMap.put("MXN","$"); - codeSymbolsMap.put("SAR","﷼"); - codeSymbolsMap.put("UAH","₴"); - codeSymbolsMap.put("NGN","₦"); - codeSymbolsMap.put("JPY","¥"); - codeSymbolsMap.put("CNY","¥"); - codeSymbolsMap.put("IDR","Rp"); - codeSymbolsMap.put("TRY","₺"); - /// Set the most popular fiats List filteredFiatCodes = Arrays.asList("USD","EUR","GBP", "SGD","CAD","AUD","RUB","KRW","MXN","SAR","UAH","NGN","JPY","CNY","IDR","TRY"); @@ -125,7 +127,7 @@ public List getAllCurrencies(Boolean shouldBeFiltered) { List completeCurrencyEntities = new ArrayList<>(); for(int i=0;i : ViewModel() { protected fun handleError(t: Throwable) { val errorMessage = t.message ?: "Oops, something went wrong" //todo more error handler + + if (t is retrofit2.HttpException) { + val message = t.response()?.errorBody()?.string()?.let { + runCatching { + json.decodeFromString(it)["message"]?.toString() + }.getOrNull() + } ?: "Oops, something went wrong" + + sendUiEffect( + UiEffect.ShowMessage( + type = UiEffect.ShowMessage.Type.Error, + message = message + ) + ) + return + } + sendUiEffect( UiEffect.ShowMessage( type = UiEffect.ShowMessage.Type.Error, diff --git a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt index 2fabe5ae..f72137f5 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.BottomSheetDefaults import androidx.compose.material3.Button +import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet @@ -18,6 +19,7 @@ import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp import com.brainwallet.ui.theme.BrainwalletTheme @@ -75,17 +77,21 @@ fun BrainwalletBottomSheet( fun BrainwalletButton( onClick: () -> Unit, modifier: Modifier = Modifier, + enabled: Boolean = true, + shape: Shape = CircleShape, + colors: ButtonColors = ButtonDefaults.buttonColors( + containerColor = BrainwalletTheme.colors.surface, + contentColor = BrainwalletTheme.colors.content + ), content: @Composable RowScope.() -> Unit ) { Button( onClick = onClick, - shape = CircleShape, - colors = ButtonDefaults.buttonColors( - containerColor = BrainwalletTheme.colors.surface, - contentColor = BrainwalletTheme.colors.content - ), + enabled = enabled, + shape = shape, + colors = colors, modifier = modifier - .border(1.dp, BrainwalletTheme.colors.border, CircleShape) + .border(1.dp, BrainwalletTheme.colors.border, shape) .height(50.dp), content = content ) diff --git a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt index a6f63965..48721758 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt @@ -10,16 +10,14 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.FilledTonalButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.graphics.drawscope.ContentDrawScope import androidx.compose.ui.unit.dp -import com.brainwallet.ui.theme.BrainwalletColors import com.brainwallet.ui.theme.BrainwalletTheme @Composable fun LargeButton( modifier: Modifier = Modifier, + enabled: Boolean = true, onClick: () -> Unit, colors: ButtonColors = ButtonDefaults.buttonColors( containerColor = BrainwalletTheme.colors.background, @@ -32,6 +30,7 @@ fun LargeButton( modifier = modifier .fillMaxWidth() .height(56.dp), + enabled = enabled, onClick = onClick, colors = colors, shape = shape, diff --git a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt new file mode 100644 index 00000000..8c6270ad --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt @@ -0,0 +1,55 @@ +package com.brainwallet.ui.composable + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.brainwallet.R +import com.brainwallet.ui.theme.BrainwalletTheme + +@Composable +fun LoadingDialog( + text: String = stringResource(R.string.loading), + onDismissRequest: () -> Unit = {}, +) { + Dialog( + onDismissRequest = onDismissRequest, + properties = DialogProperties( + dismissOnClickOutside = false, + dismissOnBackPress = false + ) + ) { + Card( + shape = BrainwalletTheme.shapes.medium, + modifier = Modifier + .fillMaxWidth(0.8f) + .wrapContentHeight(), + ) { + Column( + modifier = Modifier + .padding(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text( + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center, + text = text, + style = BrainwalletTheme.typography.bodyLarge + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt new file mode 100644 index 00000000..e3513194 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt @@ -0,0 +1,66 @@ +package com.brainwallet.ui.composable + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.ui.theme.BrainwalletTheme +import com.brainwallet.ui.theme.lavender +import com.brainwallet.ui.theme.nearBlack + +@Composable +fun MoonpayBuyButton( + modifier: Modifier = Modifier, + enabled: Boolean = true, + onClick: () -> Unit, +) { + Button( + modifier = modifier, + shape = BrainwalletTheme.shapes.large, + colors = ButtonDefaults.buttonColors( + containerColor = lavender, + contentColor = nearBlack + ), + enabled = enabled, + onClick = onClick, + ) { + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = stringResource(R.string.buy_ltc).uppercase(), + style = BrainwalletTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold) + ) + Row( + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = stringResource(R.string.powered_by_moonpay).uppercase(), + style = BrainwalletTheme.typography.labelSmall.copy(fontSize = 8.sp) + ) + Image( + modifier = Modifier.size(16.dp), + painter = painterResource(R.drawable.ic_moonpay_logo), + contentDescription = "moonpay" + ) + } + } + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyWidget.kt b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyWidget.kt new file mode 100644 index 00000000..006e45bf --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyWidget.kt @@ -0,0 +1,56 @@ +package com.brainwallet.ui.composable + + +import android.annotation.SuppressLint +import android.graphics.Bitmap +import android.view.ViewGroup +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.viewinterop.AndroidView + +//TODO: wip here + +@SuppressLint("SetJavaScriptEnabled") +@Composable +fun MoonpayBuyWidget( + modifier: Modifier = Modifier, + signedUrl: String = "https://buy.moonpay.com", +) { + AndroidView( + modifier = modifier.clip(MaterialTheme.shapes.large), + factory = { ctx -> + WebView(ctx).apply { + layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT + ) + + setBackgroundColor(0) + + settings.javaScriptEnabled = true + settings.domStorageEnabled = true + settings.useWideViewPort = true + + webViewClient = object : WebViewClient() { + + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + super.onPageStarted(view, url, favicon) + } + + override fun onPageFinished(view: WebView?, url: String?) { + super.onPageFinished(view, url) + } + } + + } + }, + update = { + it.loadUrl(signedUrl) + } + ) + +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt b/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt new file mode 100644 index 00000000..27e9ce40 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt @@ -0,0 +1,634 @@ +package com.brainwallet.ui.composable + +import android.util.Log +import androidx.compose.animation.core.DecayAnimationSpec +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.calculateTargetValue +import androidx.compose.animation.core.exponentialDecay +import androidx.compose.foundation.background +import androidx.compose.foundation.interaction.InteractionSource +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListItemInfo +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.saveable.listSaver +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.input.nestedscroll.NestedScrollConnection +import androidx.compose.ui.input.nestedscroll.NestedScrollSource +import androidx.compose.ui.input.nestedscroll.nestedScroll +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.Velocity +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.CancellableContinuation +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.coroutines.resume +import kotlin.math.absoluteValue + +interface WheelPickerContentScope { + val state: WheelPickerState +} + +interface WheelPickerDisplayScope : WheelPickerContentScope { + @Composable + fun Content(index: Int) +} + +@Composable +fun VerticalWheelPicker( + modifier: Modifier = Modifier, + count: Int, + state: WheelPickerState = rememberWheelPickerState(), + key: ((index: Int) -> Any)? = null, + itemHeight: Dp = 35.dp, + unfocusedCount: Int = 2, + userScrollEnabled: Boolean = true, + reverseLayout: Boolean = false, + debug: Boolean = false, + focus: @Composable () -> Unit = { WheelPickerFocusVertical() }, + display: @Composable WheelPickerDisplayScope.(index: Int) -> Unit = { + DefaultWheelPickerDisplay( + it + ) + }, + content: @Composable WheelPickerContentScope.(index: Int) -> Unit, +) { + WheelPicker( + modifier = modifier, + isVertical = true, + count = count, + state = state, + key = key, + itemSize = itemHeight, + unfocusedCount = unfocusedCount, + userScrollEnabled = userScrollEnabled, + reverseLayout = reverseLayout, + debug = debug, + focus = focus, + display = display, + content = content, + ) +} + + +@Composable +private fun WheelPicker( + modifier: Modifier, + isVertical: Boolean, + count: Int, + state: WheelPickerState, + key: ((index: Int) -> Any)?, + itemSize: Dp, + unfocusedCount: Int, + userScrollEnabled: Boolean, + reverseLayout: Boolean, + debug: Boolean, + focus: @Composable () -> Unit, + display: @Composable WheelPickerDisplayScope.(index: Int) -> Unit, + content: @Composable WheelPickerContentScope.(index: Int) -> Unit, +) { + require(count >= 0) { "Require count >= 0" } + require(unfocusedCount >= 0) { "Require unfocusedCount >= 0" } + require(itemSize > 0.dp) { "Require itemSize > 0.dp" } + + SafeBox( + modifier = modifier, + isVertical = isVertical, + itemSize = itemSize, + unfocusedCount = unfocusedCount, + ) { safeUnfocusedCount -> + InternalWheelPicker( + isVertical = isVertical, + count = count, + state = state, + key = key, + itemSize = itemSize, + unfocusedCount = safeUnfocusedCount, + userScrollEnabled = userScrollEnabled, + reverseLayout = reverseLayout, + debug = debug, + focus = focus, + display = display, + content = content, + ) + + if (debug && unfocusedCount != safeUnfocusedCount) { + LaunchedEffect(unfocusedCount, safeUnfocusedCount) { + logMsg(true) { "unfocusedCount $unfocusedCount -> $safeUnfocusedCount" } + } + } + } +} + +@Composable +private fun InternalWheelPicker( + isVertical: Boolean, + count: Int, + state: WheelPickerState, + key: ((index: Int) -> Any)?, + itemSize: Dp, + unfocusedCount: Int, + userScrollEnabled: Boolean, + reverseLayout: Boolean, + debug: Boolean, + focus: @Composable () -> Unit, + display: @Composable WheelPickerDisplayScope.(index: Int) -> Unit, + content: @Composable WheelPickerContentScope.(index: Int) -> Unit, +) { + state.debug = debug + LaunchedEffect(state, count) { + state.updateCount(count) + } + + val nestedScrollConnection = remember(state) { + WheelPickerNestedScrollConnection(state) + }.apply { + this.isVertical = isVertical + this.itemSizePx = with(LocalDensity.current) { itemSize.roundToPx() } + this.reverseLayout = reverseLayout + } + + val totalSize = remember(itemSize, unfocusedCount) { + itemSize * (unfocusedCount * 2 + 1) + } + + val displayScope = remember(state) { + WheelPickerDisplayScopeImpl(state) + }.apply { + this.content = content + } + + Box( + modifier = Modifier + .nestedScroll(nestedScrollConnection) + .graphicsLayer { + this.alpha = if (state.isReady) 1f else 0f + } + .run { + if (totalSize > 0.dp) { + if (isVertical) { + height(totalSize).widthIn(40.dp) + } else { + width(totalSize).heightIn(40.dp) + } + } else { + this + } + }, + contentAlignment = Alignment.Center, + ) { + + val lazyListScope: LazyListScope.() -> Unit = { + + repeat(unfocusedCount) { + item(contentType = "placeholder") { + ItemSizeBox( + isVertical = isVertical, + itemSize = itemSize, + ) + } + } + + items( + count = count, + key = key, + ) { index -> + ItemSizeBox( + isVertical = isVertical, + itemSize = itemSize, + ) { + displayScope.display(index) + } + } + + repeat(unfocusedCount) { + item(contentType = "placeholder") { + ItemSizeBox( + isVertical = isVertical, + itemSize = itemSize, + ) + } + } + } + + if (isVertical) { + LazyColumn( + state = state.lazyListState, + horizontalAlignment = Alignment.CenterHorizontally, + reverseLayout = reverseLayout, + userScrollEnabled = userScrollEnabled && state.isReady, + modifier = Modifier.matchParentSize(), + content = lazyListScope, + ) + } else { + LazyRow( + state = state.lazyListState, + verticalAlignment = Alignment.CenterVertically, + reverseLayout = reverseLayout, + userScrollEnabled = userScrollEnabled && state.isReady, + modifier = Modifier.matchParentSize(), + content = lazyListScope, + ) + } + + ItemSizeBox( + modifier = Modifier.align(Alignment.Center), + isVertical = isVertical, + itemSize = itemSize, + ) { + focus() + } + } +} + +@Composable +private fun SafeBox( + modifier: Modifier = Modifier, + isVertical: Boolean, + itemSize: Dp, + unfocusedCount: Int, + content: @Composable (safeUnfocusedCount: Int) -> Unit, +) { + BoxWithConstraints( + modifier = modifier, + contentAlignment = Alignment.Center, + ) { + val maxSize = if (isVertical) maxHeight else maxWidth + val result = remember(maxSize, itemSize, unfocusedCount) { + val totalSize = itemSize * (unfocusedCount * 2 + 1) + if (totalSize <= maxSize) { + unfocusedCount + } else { + (((maxSize - itemSize) / 2f) / itemSize).toInt().coerceAtLeast(0) + } + } + content(result) + } +} + +@Composable +private fun ItemSizeBox( + modifier: Modifier = Modifier, + isVertical: Boolean, + itemSize: Dp, + content: @Composable () -> Unit = { }, +) { + Box( + modifier + .run { + if (isVertical) { + height(itemSize) + } else { + width(itemSize) + } + }, + contentAlignment = Alignment.Center, + ) { + content() + } +} + +private class WheelPickerNestedScrollConnection( + private val state: WheelPickerState, +) : NestedScrollConnection { + var isVertical: Boolean = true + var itemSizePx: Int = 0 + var reverseLayout: Boolean = false + + override fun onPostScroll( + consumed: Offset, + available: Offset, + source: NestedScrollSource + ): Offset { + state.synchronizeCurrentIndexSnapshot() + return super.onPostScroll(consumed, available, source) + } + + override suspend fun onPreFling(available: Velocity): Velocity { + val currentIndex = state.synchronizeCurrentIndexSnapshot() + return if (currentIndex >= 0) { + available.flingItemCount( + isVertical = isVertical, + itemSize = itemSizePx, + decay = exponentialDecay(2f), + reverseLayout = reverseLayout, + ).let { flingItemCount -> + if (flingItemCount == 0) { + state.animateScrollToIndex(currentIndex) + } else { + state.animateScrollToIndex(currentIndex - flingItemCount) + } + } + available + } else { + super.onPreFling(available) + } + } +} + +private fun Velocity.flingItemCount( + isVertical: Boolean, + itemSize: Int, + decay: DecayAnimationSpec, + reverseLayout: Boolean, +): Int { + if (itemSize <= 0) return 0 + val velocity = if (isVertical) y else x + val targetValue = decay.calculateTargetValue(0f, velocity) + val flingItemCount = (targetValue / itemSize).toInt() + return if (reverseLayout) -flingItemCount else flingItemCount +} + +private class WheelPickerDisplayScopeImpl( + override val state: WheelPickerState, +) : WheelPickerDisplayScope { + + var content: @Composable WheelPickerContentScope.(index: Int) -> Unit by mutableStateOf({}) + + @Composable + override fun Content(index: Int) { + content(index) + } +} + +internal inline fun logMsg(debug: Boolean, block: () -> String) { + if (debug) { + Log.i("WheelPicker", block()) + } +} + +//default +/** + * The default implementation of focus view in vertical. + */ +@Composable +fun WheelPickerFocusVertical( + modifier: Modifier = Modifier, + dividerSize: Dp = 1.dp, + dividerColor: Color = DefaultDividerColor, +) { + Box( + modifier = modifier.fillMaxSize() + ) { + Box( + modifier = Modifier + .background(dividerColor) + .height(dividerSize) + .fillMaxWidth() + .align(Alignment.TopCenter), + ) + Box( + modifier = Modifier + .background(dividerColor) + .height(dividerSize) + .fillMaxWidth() + .align(Alignment.BottomCenter), + ) + } +} + +/** + * Default divider color. + */ +private val DefaultDividerColor: Color + @Composable + get() { + val color = if (isSystemInDarkTheme()) Color.White else Color.Black + return color.copy(alpha = 0.2f) + } + +/** + * Default display. + */ +@Composable +fun WheelPickerDisplayScope.DefaultWheelPickerDisplay( + index: Int, +) { + val focused = index == state.currentIndexSnapshot + val animateScale by animateFloatAsState( + targetValue = if (focused) 1.0f else 0.8f, + label = "Wheel picker item scale", + ) + Box( + modifier = Modifier.graphicsLayer { + this.alpha = if (focused) 1.0f else 0.3f + this.scaleX = animateScale + this.scaleY = animateScale + } + ) { + Content(index) + } +} + +//state +@Composable +fun rememberWheelPickerState( + initialIndex: Int = 0, +): WheelPickerState { + return rememberSaveable(saver = WheelPickerState.Saver) { + WheelPickerState( + initialIndex = initialIndex, + ) + } +} + +@Composable +fun WheelPickerState.CurrentIndex( + block: suspend (Int) -> Unit, +) { + val blockUpdated by rememberUpdatedState(block) + LaunchedEffect(this) { + snapshotFlow { currentIndex } + .collect { blockUpdated(it) } + } +} + +class WheelPickerState internal constructor( + initialIndex: Int, +) { + internal var debug = false + internal val lazyListState = LazyListState() + internal var isReady by mutableStateOf(false) + + private var _count = 0 + private var _currentIndex by mutableIntStateOf(-1) + private var _currentIndexSnapshot by mutableIntStateOf(-1) + + private var _pendingIndex: Int? = initialIndex.coerceAtLeast(0) + private var _pendingIndexContinuation: CancellableContinuation? = null + set(value) { + field = value + if (value == null) _pendingIndex = null + } + + /** + * Index of picker when it is idle, -1 means that there is no data. + * + * Note that this property is observable and if you use it in the composable function + * it will be recomposed on every change. + */ + val currentIndex: Int get() = _currentIndex + + /** + * Index of picker when it is idle or drag but not fling, -1 means that there is no data. + * + * Note that this property is observable and if you use it in the composable function + * it will be recomposed on every change. + */ + val currentIndexSnapshot: Int get() = _currentIndexSnapshot + + /** + * [LazyListState.interactionSource] + */ + val interactionSource: InteractionSource get() = lazyListState.interactionSource + + /** + * [LazyListState.isScrollInProgress] + */ + val isScrollInProgress: Boolean get() = lazyListState.isScrollInProgress + + suspend fun animateScrollToIndex(index: Int) { + logMsg(debug) { "animateScrollToIndex index:$index count:$_count" } + @Suppress("NAME_SHADOWING") + val index = index.coerceAtLeast(0) + lazyListState.animateScrollToItem(index) + synchronizeCurrentIndex() + } + + suspend fun scrollToIndex(index: Int) { + logMsg(debug) { "scrollToIndex index:$index count:$_count" } + @Suppress("NAME_SHADOWING") + val index = index.coerceAtLeast(0) + + // Always cancel last continuation. + _pendingIndexContinuation?.let { + logMsg(debug) { "cancelAwaitIndex" } + _pendingIndexContinuation = null + it.cancel() + } + + awaitIndex(index) + + lazyListState.scrollToItem(index) + synchronizeCurrentIndex() + } + + private suspend fun awaitIndex(index: Int) { + if (_count > 0) return + logMsg(debug) { "awaitIndex:$index start" } + suspendCancellableCoroutine { cont -> + _pendingIndex = index + _pendingIndexContinuation = cont + cont.invokeOnCancellation { + logMsg(debug) { "awaitIndex:$index canceled" } + _pendingIndexContinuation = null + } + } + logMsg(debug) { "awaitIndex:$index finish" } + } + + internal suspend fun updateCount(count: Int) { + logMsg(debug) { "updateCount count:$count currentIndex:$_currentIndex" } + + // Update count + _count = count + + val maxIndex = count - 1 + if (maxIndex < _currentIndex) { + if (count > 0) { + scrollToIndex(maxIndex) + } else { + synchronizeCurrentIndex() + } + } + + if (count > 0) { + val pendingIndex = _pendingIndex + if (pendingIndex != null) { + logMsg(debug) { "Found pendingIndex:$pendingIndex pendingIndexContinuation:$_pendingIndexContinuation" } + val continuation = _pendingIndexContinuation + _pendingIndexContinuation = null + + if (continuation?.isActive == true) { + logMsg(debug) { "resume pendingIndexContinuation" } + continuation.resume(Unit) + } else { + scrollToIndex(pendingIndex) + } + } else { + if (_currentIndex < 0) { + synchronizeCurrentIndex() + } + } + } + + isReady = count > 0 + } + + private fun synchronizeCurrentIndex() { + val index = synchronizeCurrentIndexSnapshot() + if (_currentIndex != index) { + logMsg(debug) { "setCurrentIndex:$index" } + _currentIndex = index + _currentIndexSnapshot = index + } + } + + internal fun synchronizeCurrentIndexSnapshot(): Int { + return (mostStartItemInfo()?.index ?: -1).also { + _currentIndexSnapshot = it + } + } + + /** + * The item closest to the viewport start. + */ + private fun mostStartItemInfo(): LazyListItemInfo? { + if (_count <= 0) return null + + val layoutInfo = lazyListState.layoutInfo + val listInfo = layoutInfo.visibleItemsInfo + + if (listInfo.isEmpty()) return null + if (listInfo.size == 1) return listInfo.first() + + val firstItem = listInfo.first() + val firstOffsetDelta = (firstItem.offset - layoutInfo.viewportStartOffset).absoluteValue + return if (firstOffsetDelta < firstItem.size / 2) { + firstItem + } else { + listInfo[1] + } + } + + companion object { + val Saver = listSaver( + save = { listOf(it.currentIndex) }, + restore = { WheelPickerState(initialIndex = it[0]) }, + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt new file mode 100644 index 00000000..31e528fe --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt @@ -0,0 +1,11 @@ +package com.brainwallet.ui.screens.buylitecoin + +import android.content.Context + +sealed class BuyLitecoinEvent { + data class OnLoad(val context: Context) : BuyLitecoinEvent() + data class OnFiatAmountChange( + val fiatAmount: Float, + val needFetch: Boolean = true + ) : BuyLitecoinEvent() +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt new file mode 100644 index 00000000..97260328 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt @@ -0,0 +1,167 @@ +package com.brainwallet.ui.screens.buylitecoin + +import android.widget.Toast +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Done +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.unit.dp +import com.brainwallet.R +import com.brainwallet.navigation.LegacyNavigation +import com.brainwallet.navigation.OnNavigate +import com.brainwallet.navigation.UiEffect +import com.brainwallet.ui.composable.BrainwalletScaffold +import com.brainwallet.ui.composable.BrainwalletTopAppBar +import com.brainwallet.ui.composable.LargeButton +import com.brainwallet.ui.composable.LoadingDialog +import com.brainwallet.ui.screens.home.receive.ReceiveDialogEvent +import com.brainwallet.ui.theme.BrainwalletTheme +import org.koin.compose.koinInject + +//TODO: wip +@Composable +fun BuyLitecoinScreen( + onNavigate: OnNavigate, + viewModel: BuyLitecoinViewModel = koinInject() +) { + val state by viewModel.state.collectAsState() + val loadingState by viewModel.loadingState.collectAsState() + val appSetting by viewModel.appSetting.collectAsState() + val context = LocalContext.current + + LaunchedEffect(Unit) { + viewModel.onEvent(BuyLitecoinEvent.OnLoad(context)) + viewModel.uiEffect.collect { effect -> + when (effect) { + is UiEffect.ShowMessage -> + Toast.makeText(context, effect.message, Toast.LENGTH_SHORT).show() + + else -> Unit + } + } + } + + BrainwalletScaffold( + topBar = { + BrainwalletTopAppBar( + navigationIcon = { + IconButton( + onClick = { onNavigate.invoke(UiEffect.Navigate.Back()) }, + ) { + Icon( + imageVector = Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(R.string.back), + ) + } + } + ) + } + ) { paddingValues -> + + Box( + modifier = Modifier + .padding(paddingValues) + .padding(16.dp) + .fillMaxSize(), + contentAlignment = Alignment.TopCenter + ) { + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(24.dp) + ) { + Text( + text = stringResource(R.string.buy_litecoin_title), + style = MaterialTheme.typography.titleLarge, + ) + + OutlinedTextField( + enabled = loadingState.visible.not(), + prefix = { + Text( + text = appSetting.currency.symbol, + style = BrainwalletTheme.typography.titleLarge.copy(color = BrainwalletTheme.colors.content) + ) + }, + textStyle = BrainwalletTheme.typography.titleLarge.copy(color = BrainwalletTheme.colors.content), + value = "${if (state.fiatAmount < 1) "" else state.fiatAmount.toInt()}", + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), + onValueChange = { input -> + val amount = input.toFloatOrNull() ?: 0f + viewModel.onEvent(BuyLitecoinEvent.OnFiatAmountChange(amount, false)) + }, + shape = BrainwalletTheme.shapes.extraLarge, + isError = state.isValid().not(), + supportingText = { + state.errorFiatAmountStringId?.let { + Text(stringResource(it, state.fiatAmount)) + } + } + ) + + Text( + text = state.getLtcAmountFormatted(loadingState.visible), + style = MaterialTheme.typography.titleLarge.copy( + color = BrainwalletTheme.colors.content.copy( + 0.7f + ) + ), + ) + + Text( + text = stringResource(R.string.buy_litecoin_desc), + style = MaterialTheme.typography.titleMedium + ) + + Text( + text = state.address, + style = MaterialTheme.typography.titleMedium.copy( + color = BrainwalletTheme.colors.content.copy( + 0.7f + ) + ) + ) + + } + + + LargeButton( + modifier = Modifier.align(Alignment.BottomCenter), + enabled = loadingState.visible.not(), + onClick = { + LegacyNavigation.showMoonPayWidget( + context = context, + params = mapOf( + "baseCurrencyCode" to appSetting.currency.code, + "baseCurrencyAmount" to state.fiatAmount.toString(), + "language" to appSetting.languageCode, + "walletAddress" to state.address + ) + ) + } + ) { + Text(stringResource(R.string.buy_litecoin_button_moonpay)) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinState.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinState.kt new file mode 100644 index 00000000..628d6f0c --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinState.kt @@ -0,0 +1,19 @@ +package com.brainwallet.ui.screens.buylitecoin + +import com.brainwallet.data.model.MoonpayCurrencyLimit +import timber.log.Timber + +data class BuyLitecoinState( + val moonpayCurrencyLimit: MoonpayCurrencyLimit = MoonpayCurrencyLimit(), + val fiatAmount: Float = moonpayCurrencyLimit.data.baseCurrency.min, + val ltcAmount: Float = 0f, + val address: String = "", + val errorFiatAmountStringId: Int? = null +) + +fun BuyLitecoinState.isValid(): Boolean = errorFiatAmountStringId == null + +fun BuyLitecoinState.getLtcAmountFormatted(isLoading: Boolean): String = + (if (isLoading || ltcAmount < 0f) "x.xxxŁ" else "%.3fŁ".format(ltcAmount)).also { + Timber.d("TImber: ltcamount $ltcAmount") + } diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt new file mode 100644 index 00000000..5e6e6316 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt @@ -0,0 +1,128 @@ +package com.brainwallet.ui.screens.buylitecoin + +import android.util.Log +import androidx.lifecycle.viewModelScope +import com.brainwallet.R +import com.brainwallet.data.model.AppSetting +import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.ui.BrainwalletViewModel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.getAndUpdate +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch + +class BuyLitecoinViewModel( + private val settingRepository: SettingRepository, + private val ltcRepository: LtcRepository +) : BrainwalletViewModel() { + + private val _state = MutableStateFlow(BuyLitecoinState()) + val state: StateFlow = _state.asStateFlow() + + val appSetting = settingRepository.settings + .distinctUntilChanged() + .stateIn( + viewModelScope, + SharingStarted.Eagerly, + AppSetting() + ) + + init { + viewModelScope.launch { + state.map { it.fiatAmount } + .debounce(1000) + .distinctUntilChanged() + .filter { + val (_, min, max) = state.value.moonpayCurrencyLimit.data.baseCurrency + it in min..max + } + .collect { + onEvent(BuyLitecoinEvent.OnFiatAmountChange(it)) + } + } + + } + + override fun onEvent(event: BuyLitecoinEvent) { + when (event) { + is BuyLitecoinEvent.OnLoad -> viewModelScope.launch { + delay(500) + _state.update { it.copy(address = BRSharedPrefs.getReceiveAddress(event.context)) } + try { + onLoading(true) + + _state.getAndUpdate { + val limitResult = ltcRepository.fetchLimits( + baseCurrencyCode = appSetting.value.currency.code + ) + + it.copy( + moonpayCurrencyLimit = limitResult, + fiatAmount = limitResult.data.baseCurrency.min, + ) + } + } catch (e: Exception) { + handleError(e) + } finally { + onLoading(false) + } + + } + + is BuyLitecoinEvent.OnFiatAmountChange -> viewModelScope.launch { + //do validation + val (_, min, max) = state.value.moonpayCurrencyLimit.data.baseCurrency + val errorStringId = when { + event.fiatAmount < min -> R.string.buy_litecoin_fiat_amount_validation_min + event.fiatAmount > max -> R.string.buy_litecoin_fiat_amount_validation_max + else -> null + } + _state.update { + it.copy( + errorFiatAmountStringId = errorStringId, + fiatAmount = event.fiatAmount + ) + } + + if (event.needFetch.not()) { + return@launch + } + + try { + onLoading(true) + + _state.update { + val result = ltcRepository.fetchBuyQuote( + mapOf( + "currencyCode" to "ltc", + "baseCurrencyCode" to appSetting.value.currency.code, + "baseCurrencyAmount" to event.fiatAmount.toString(), + ) + ) + + it.copy( + ltcAmount = result.data.quoteCurrencyAmount, + ) + } + + } catch (e: Exception) { + handleError(e) + } finally { + onLoading(false) + } + } + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/buy/BuyScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/home/buy/BuyScreen.kt deleted file mode 100644 index 2e974ad2..00000000 --- a/app/src/main/java/com/brainwallet/ui/screens/home/buy/BuyScreen.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.brainwallet.ui.screens.home.buy - -import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.Composable - -//TODO: wip -@Composable -fun BuyScreen() { - Box {} -} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt new file mode 100644 index 00000000..291015e2 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt @@ -0,0 +1,452 @@ +@file:OptIn(ExperimentalMaterial3Api::class, FlowPreview::class) + +package com.brainwallet.ui.screens.home.receive + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material.icons.filled.Check +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.filled.Done +import androidx.compose.material3.AssistChip +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.IconButtonDefaults +import androidx.compose.material3.OutlinedIconButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager +import com.brainwallet.R +import com.brainwallet.data.model.getFormattedText +import com.brainwallet.data.model.isCustom +import com.brainwallet.navigation.LegacyNavigation +import com.brainwallet.navigation.UiEffect +import com.brainwallet.ui.composable.MoonpayBuyButton +import com.brainwallet.ui.composable.VerticalWheelPicker +import com.brainwallet.ui.composable.WheelPickerFocusVertical +import com.brainwallet.ui.composable.rememberWheelPickerState +import com.brainwallet.ui.theme.BrainwalletAppTheme +import com.brainwallet.ui.theme.BrainwalletTheme +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter +import org.koin.android.ext.android.inject +import org.koin.compose.koinInject +import timber.log.Timber + +@Composable +fun ReceiveDialog( + onDismissRequest: () -> Unit, + viewModel: ReceiveDialogViewModel = koinInject() +) { + val state by viewModel.state.collectAsState() + val loadingState by viewModel.loadingState.collectAsState() + val appSetting by viewModel.appSetting.collectAsState() + val context = LocalContext.current + val wheelPickerFiatCurrencyState = rememberWheelPickerState(0) + + LaunchedEffect(Unit) { + viewModel.onEvent(ReceiveDialogEvent.OnLoad(context)) + viewModel.uiEffect.collect { effect -> + when (effect) { + is UiEffect.ShowMessage -> Toast.makeText( + context, + effect.message, + Toast.LENGTH_SHORT + ).show() + + else -> Unit + } + } + } + + LaunchedEffect(Unit) { + delay(500) + wheelPickerFiatCurrencyState.scrollToIndex(state.getSelectedFiatCurrencyIndex()) + } + + LaunchedEffect(wheelPickerFiatCurrencyState) { + snapshotFlow { wheelPickerFiatCurrencyState.currentIndex } + .filter { it > -1 } + .distinctUntilChanged() + .debounce(700) + .collect { + Timber.i("wheelPickerFiatCurrencyState: currentIndex $it") + + viewModel.onEvent(ReceiveDialogEvent.OnFiatCurrencyChange(state.fiatCurrencies[it])) + } + } + + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + CenterAlignedTopAppBar( + colors = TopAppBarDefaults.centerAlignedTopAppBarColors( + containerColor = BrainwalletTheme.colors.content //invert surface + ), + expandedHeight = 56.dp, + title = { + Text( + text = stringResource(R.string.bottom_nav_item_buy_receive_title).uppercase(), + style = BrainwalletTheme.typography.titleSmall + ) + }, + navigationIcon = { + if (state.moonpayWidgetVisible()) { + IconButton(onClick = { + viewModel.onEvent(ReceiveDialogEvent.OnSignedUrlClear) + }) { + Icon( + Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(R.string.back) + ) + } + } + }, + actions = { + IconButton(onClick = onDismissRequest) { + Icon( + Icons.Default.Close, + contentDescription = stringResource(R.string.AccessibilityLabels_close), + tint = BrainwalletTheme.colors.surface + ) + } + } + ) + + //moonpay widget + //todo: revisit this later +// AnimatedVisibility(visible = state.moonpayWidgetVisible()) { +// state.moonpayBuySignedUrl?.let { signedUrl -> +// MoonpayBuyWidget( +// modifier = Modifier.height(500.dp), +// signedUrl = signedUrl +// ) +// } +// } + + + //buy / receive +// AnimatedVisibility(visible = state.moonpayWidgetVisible().not()) { + Column { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + state.qrBitmap?.asImageBitmap()?.let { imageBitmap -> + Image( + modifier = Modifier + .weight(1f), + bitmap = imageBitmap, + contentDescription = "address" + ) + } ?: Box( + modifier = Modifier + .weight(1f) + .height(180.dp) + .background(Color.Gray) + ) + + Column( + modifier = Modifier + .weight(1f), + verticalArrangement = Arrangement.spacedBy(8.dp) + ) { + Text( + text = state.address, + style = BrainwalletTheme.typography.bodyLarge.copy( + fontWeight = FontWeight.Bold, + color = BrainwalletTheme.colors.surface + ), + maxLines = 4, + overflow = TextOverflow.Ellipsis + ) + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp) + ) { + Text( + text = stringResource(R.string.new_address).uppercase(), + style = BrainwalletTheme.typography.bodySmall.copy( + color = BrainwalletTheme.colors.surface, + ), + modifier = Modifier.weight(1f) + ) + OutlinedIconButton( + modifier = Modifier.size(32.dp), + onClick = { + viewModel.onEvent(ReceiveDialogEvent.OnCopyClick(context)) + Toast.makeText( + context, + R.string.Receive_copied, + Toast.LENGTH_SHORT + ) + .show() + }, + colors = IconButtonDefaults.outlinedIconButtonColors( + containerColor = BrainwalletTheme.colors.content.copy(alpha = 0.5f) + ), + ) { + Icon( + painter = androidx.compose.ui.res.painterResource(id = R.drawable.ic_copy), + contentDescription = stringResource(R.string.URLHandling_copy), + tint = BrainwalletTheme.colors.surface + ) + } + } + } + } + + HorizontalDivider() + + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center + ) { + VerticalWheelPicker( + modifier = Modifier.weight(1f), + focus = { + WheelPickerFocusVertical( + dividerColor = BrainwalletTheme.colors.surface.copy( + alpha = 0.5f + ) + ) + }, + unfocusedCount = 1, + count = state.fiatCurrencies.size, + state = wheelPickerFiatCurrencyState, + ) { index -> + Text( + text = state.fiatCurrencies[index].code, + fontWeight = FontWeight.Bold, + color = BrainwalletTheme.colors.surface + ) + } + + Column( + modifier = Modifier.weight(1f), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = state.getLtcAmountFormatted(loadingState.visible), + style = BrainwalletTheme.typography.titleLarge.copy( + fontWeight = FontWeight.Bold, + color = BrainwalletTheme.colors.surface + ) + ) + Text( + text = state.getRatesUpdatedAtFormatted(), + style = BrainwalletTheme.typography.bodySmall.copy( + color = BrainwalletTheme.colors.surface + ) + ) + } + } + + LazyRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + itemsIndexed(items = state.getQuickFiatAmountOptions()) { index, quickFiatAmountOption -> + AssistChip( + enabled = loadingState.visible.not(), + onClick = { + viewModel.onEvent( + ReceiveDialogEvent.OnFiatAmountOptionIndexChange( + index, + quickFiatAmountOption + ) + ) + }, + label = { + Text( + text = if (quickFiatAmountOption.isCustom()) + stringResource(R.string.custom) + else quickFiatAmountOption.getFormattedText() + ) + }, + leadingIcon = { + if (index == state.selectedQuickFiatAmountOptionIndex) { + Icon(Icons.Default.Check, contentDescription = null) + } + } + ) + } + } + + + AnimatedVisibility(visible = state.isQuickFiatAmountOptionCustom()) { + OutlinedTextField( + modifier = Modifier.fillMaxWidth(), + prefix = { + Text( + text = state.selectedFiatCurrency.symbol, + style = BrainwalletTheme.typography.bodyMedium.copy(color = BrainwalletTheme.colors.surface) + ) + }, + trailingIcon = { + IconButton(onClick = { + viewModel.onEvent(ReceiveDialogEvent.OnFiatAmountChange(state.fiatAmount)) + }) { + Icon(Icons.Default.Done, contentDescription = null) + } + }, + textStyle = BrainwalletTheme.typography.bodyMedium.copy(color = BrainwalletTheme.colors.surface), + value = "${if (state.fiatAmount < 1) "" else state.fiatAmount}", + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), + onValueChange = { input -> + val amount = input.toFloatOrNull() ?: 0f + viewModel.onEvent(ReceiveDialogEvent.OnFiatAmountChange(amount, false)) + }, + shape = BrainwalletTheme.shapes.large, + isError = state.errorFiatAmountStringId != null, + supportingText = { + state.errorFiatAmountStringId?.let { + Text(stringResource(it, state.fiatAmount)) + } + } + ) + } + + MoonpayBuyButton( + modifier = Modifier.fillMaxWidth(), + enabled = loadingState.visible.not(), + onClick = { + + //todo: revisit this later + //viewModel.onEvent(ReceiveDialogEvent.OnMoonpayButtonClick) + + LegacyNavigation.showMoonPayWidget( + context = context, + params = mapOf( + "baseCurrencyCode" to state.selectedFiatCurrency.code, + "baseCurrencyAmount" to state.fiatAmount.toString(), + "language" to appSetting.languageCode, + "walletAddress" to state.address, + ), + isDarkMode = appSetting.isDarkMode + ) + onDismissRequest.invoke() + }, + ) + +// } + } + + + } +} + +/** + * describe [ReceiveDialogFragment] for backward compat, + * since we are still using [com.brainwallet.presenter.activities.BreadActivity] + */ +class ReceiveDialogFragment : DialogFragment() { + + private val viewModel: ReceiveDialogViewModel by inject() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return ComposeView(requireContext()).apply { + setContent { + val appSetting by viewModel.appSetting.collectAsState() + /** + * we need this theme inside this fragment, + * because we are still using fragment to display ReceiveDialog composable + * pls check BreadActivity.handleNavigationItemSelected + */ + BrainwalletAppTheme(appSetting = appSetting) { + Box( + modifier = Modifier + .padding(12.dp) + .background( + BrainwalletTheme.colors.content, + shape = BrainwalletTheme.shapes.large + ) + .border( + width = 1.dp, + color = BrainwalletTheme.colors.surface, + shape = BrainwalletTheme.shapes.large + ) + .padding(12.dp), + ) { + ReceiveDialog( + viewModel = viewModel, + onDismissRequest = { dismiss() } + ) + } + } + } + } + } + + override fun onStart() { + super.onStart() + dialog?.window?.setLayout( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + dialog?.window?.setBackgroundDrawableResource(android.R.color.transparent) + isCancelable = false + } + + companion object { + @JvmStatic + fun show(manager: FragmentManager) { + ReceiveDialogFragment().show(manager, "ReceiveDialogFragment") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt new file mode 100644 index 00000000..f1968756 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt @@ -0,0 +1,21 @@ +package com.brainwallet.ui.screens.home.receive + +import android.content.Context +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.QuickFiatAmountOption + +sealed class ReceiveDialogEvent { + data class OnLoad(val context: Context) : ReceiveDialogEvent() + data class OnCopyClick(val context: Context) : ReceiveDialogEvent() + data class OnFiatAmountChange(val fiatAmount: Float, val needFetch: Boolean = true) : + ReceiveDialogEvent() + + data class OnFiatCurrencyChange(val fiatCurrency: CurrencyEntity) : ReceiveDialogEvent() + data class OnFiatAmountOptionIndexChange( + val index: Int, + val quickFiatAmountOption: QuickFiatAmountOption + ) : ReceiveDialogEvent() + + object OnMoonpayButtonClick : ReceiveDialogEvent() + object OnSignedUrlClear : ReceiveDialogEvent() +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt new file mode 100644 index 00000000..745d172a --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt @@ -0,0 +1,61 @@ +package com.brainwallet.ui.screens.home.receive + +import android.graphics.Bitmap +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.MoonpayCurrencyLimit +import com.brainwallet.data.model.QuickFiatAmountOption +import timber.log.Timber +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + + +data class ReceiveDialogState( + val address: String = "", + val qrBitmap: Bitmap? = null, + val fiatCurrencies: List = listOf(), + val selectedFiatCurrency: CurrencyEntity = CurrencyEntity( + "USD", + "US Dollar", + -1f, + "$" + ), // default from shared prefs then the user can override using picker wheel at [ReceiveDialog] + val moonpayCurrencyLimit: MoonpayCurrencyLimit = MoonpayCurrencyLimit(), + val fiatAmount: Float = 0f, + val ltcAmount: Float = 0f, + val ratesUpdatedAt: Long = System.currentTimeMillis(), + val selectedQuickFiatAmountOptionIndex: Int = 1, //default is 10X, other [min, 10x, max, custom] + val errorFiatAmountStringId: Int? = null, + val moonpayBuySignedUrl: String? = null, +) + +fun ReceiveDialogState.getSelectedFiatCurrencyIndex(): Int = fiatCurrencies + .indexOfFirst { it.code.lowercase() == selectedFiatCurrency.code.lowercase() } + +fun ReceiveDialogState.getDefaultFiatAmount(): Float { + val (_, min, max) = moonpayCurrencyLimit.data.baseCurrency + return min * 10 //default is 10X +} + +fun ReceiveDialogState.getRatesUpdatedAtFormatted(): String { + val date = Date(ratesUpdatedAt) + val format = SimpleDateFormat("d MMM yyyy HH:mm:ss", Locale.ENGLISH) + return format.format(date).uppercase() +} + +fun ReceiveDialogState.getLtcAmountFormatted(isLoading: Boolean): String = + (if (isLoading || ltcAmount < 0f) "x.xxxŁ" else "%.3fŁ".format(ltcAmount)).also { + Timber.d("TImber: ltcamount $ltcAmount") + } + +fun ReceiveDialogState.getQuickFiatAmountOptions(): List { + val selectedFiatSymbol = selectedFiatCurrency.symbol + val (_, min, max) = moonpayCurrencyLimit.data.baseCurrency + return listOf(min, min * 10, max) + .map { QuickFiatAmountOption(symbol = selectedFiatSymbol, it) } + QuickFiatAmountOption() +} + +fun ReceiveDialogState.isQuickFiatAmountOptionCustom(): Boolean = + selectedQuickFiatAmountOptionIndex == 3 //3 will be custom + +fun ReceiveDialogState.moonpayWidgetVisible(): Boolean = moonpayBuySignedUrl != null \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt new file mode 100644 index 00000000..80ab1984 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt @@ -0,0 +1,179 @@ +package com.brainwallet.ui.screens.home.receive + +import androidx.lifecycle.viewModelScope +import com.brainwallet.R +import com.brainwallet.data.model.AppSetting +import com.brainwallet.data.model.isCustom +import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.tools.manager.BRClipboardManager +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.qrcode.QRUtils +import com.brainwallet.tools.sqlite.CurrencyDataSource +import com.brainwallet.ui.BrainwalletViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.stateIn +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.flow.updateAndGet +import kotlinx.coroutines.launch + +//todo: wip +class ReceiveDialogViewModel( + private val settingRepository: SettingRepository, + private val ltcRepository: LtcRepository, +) : BrainwalletViewModel() { + + private val _state = MutableStateFlow(ReceiveDialogState()) + val state: StateFlow = _state.asStateFlow() + + val appSetting = settingRepository.settings + .distinctUntilChanged() + .onEach { setting -> + onEvent(ReceiveDialogEvent.OnFiatCurrencyChange(setting.currency)) + } + .stateIn( + viewModelScope, + SharingStarted.Eagerly, + AppSetting() + ) + + override fun onEvent(event: ReceiveDialogEvent) { + when (event) { + is ReceiveDialogEvent.OnLoad -> _state.update { + val address = BRSharedPrefs.getReceiveAddress(event.context) + it.copy( + address = address, + qrBitmap = QRUtils.generateQR(event.context, "litecoin:${address}"), + fiatCurrencies = CurrencyDataSource.getInstance(event.context) + .getAllCurrencies(true), + ) + } + + is ReceiveDialogEvent.OnCopyClick -> BRClipboardManager.putClipboard( + event.context, + state.value.address + ) + + is ReceiveDialogEvent.OnFiatAmountChange -> viewModelScope.launch { + //do validation + val (_, min, max) = state.value.moonpayCurrencyLimit.data.baseCurrency + val errorStringId = when { + event.fiatAmount < min -> R.string.buy_litecoin_fiat_amount_validation_min + event.fiatAmount > max -> R.string.buy_litecoin_fiat_amount_validation_max + else -> null + } + _state.update { + it.copy( + errorFiatAmountStringId = errorStringId, + fiatAmount = event.fiatAmount + ) + } + + if (event.needFetch.not()) { + return@launch + } + + try { + onLoading(true) + + _state.update { + val result = ltcRepository.fetchBuyQuote( + mapOf( + "currencyCode" to "ltc", + "baseCurrencyCode" to it.selectedFiatCurrency.code, + "baseCurrencyAmount" to event.fiatAmount.toString(), + ) + ) + + it.copy( + ltcAmount = result.data.quoteCurrencyAmount, + ) + } + + } catch (e: Exception) { + handleError(e) + } finally { + onLoading(false) + } + + } + + is ReceiveDialogEvent.OnFiatCurrencyChange -> viewModelScope.launch { + try { + onLoading(true) + val currencyLimit = ltcRepository.fetchLimits(event.fiatCurrency.code) + + _state.updateAndGet { + it.copy( + selectedFiatCurrency = event.fiatCurrency, + moonpayCurrencyLimit = currencyLimit, + selectedQuickFiatAmountOptionIndex = 1, //default to 10X + fiatAmount = it.getDefaultFiatAmount(), + ) + }.let { + onEvent( + ReceiveDialogEvent.OnFiatAmountOptionIndexChange( + index = it.selectedQuickFiatAmountOptionIndex, + quickFiatAmountOption = it.getQuickFiatAmountOptions()[it.selectedQuickFiatAmountOptionIndex] + ) + ) + } + + } catch (e: Exception) { + handleError(e) + } finally { + onLoading(false) + } + } + + is ReceiveDialogEvent.OnFiatAmountOptionIndexChange -> _state.updateAndGet { + it.copy( + selectedQuickFiatAmountOptionIndex = event.index, + fiatAmount = if (event.quickFiatAmountOption.isCustom()) it.fiatAmount + else event.quickFiatAmountOption.value + ) + }.let { + if (event.quickFiatAmountOption.isCustom().not()) { + onEvent(ReceiveDialogEvent.OnFiatAmountChange(it.fiatAmount)) + } + } + + ReceiveDialogEvent.OnMoonpayButtonClick -> viewModelScope.launch { + try { + onLoading(true) + + val currentState = state.value + val signedUrl = ltcRepository.fetchMoonpaySignedUrl( + mapOf( + "baseCurrencyCode" to currentState.selectedFiatCurrency.code, + "baseCurrencyAmount" to currentState.fiatAmount.toString(), + "language" to appSetting.value.languageCode, + "walletAddress" to currentState.address, + "defaultCurrencyCode" to "ltc", + "currencyCode" to "ltc", + "themeId" to "main-v1.0.0", + "theme" to if (appSetting.value.isDarkMode) "dark" else "light" + ) + ) + + _state.update { it.copy(moonpayBuySignedUrl = signedUrl) } + + } catch (e: Exception) { + handleError(e) + } finally { + + onLoading(false) + + } + + } + + ReceiveDialogEvent.OnSignedUrlClear -> _state.update { it.copy(moonpayBuySignedUrl = null) } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt index ddc14ded..22f5722d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt @@ -3,10 +3,6 @@ package com.brainwallet.ui.screens.topup -import android.graphics.Bitmap -import android.view.ViewGroup -import android.webkit.WebView -import android.webkit.WebViewClient import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -15,7 +11,6 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowForward @@ -25,12 +20,6 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate @@ -39,27 +28,25 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.viewmodel.compose.viewModel import com.brainwallet.R import com.brainwallet.navigation.OnNavigate +import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect import com.brainwallet.tools.manager.AnalyticsManager import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar -import com.brainwallet.ui.composable.MediumTextButton import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItEvent import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel -import kotlinx.coroutines.delay @Composable fun TopUpScreen( onNavigate: OnNavigate, viewModel: YourSeedProveItViewModel = viewModel() ) { - val state by viewModel.state.collectAsState() + val context = LocalContext.current /// Layout values @@ -69,13 +56,6 @@ fun TopUpScreen( val spacerHeight = 90 val skipButtonWidth = 100 - var shouldShowWebView by remember { mutableStateOf(false) } - var backEnabled by remember { mutableStateOf(false) } - var shouldSkipBeVisible by remember { mutableStateOf(false) } - - LaunchedEffect(Unit) { - } - BrainwalletScaffold( topBar = { BrainwalletTopAppBar( @@ -93,7 +73,6 @@ fun TopUpScreen( } ) { paddingValues -> - Spacer(modifier = Modifier.height(spacerHeight.dp)) Column( modifier = Modifier @@ -103,129 +82,54 @@ fun TopUpScreen( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), ) { - - if (!shouldShowWebView) { + Spacer(modifier = Modifier.weight(1f)) + Row { + Icon( + Icons.AutoMirrored.Filled.ArrowForward, + contentDescription = stringResource(R.string.down_left_arrow), + modifier = Modifier + .rotate(45f) + .graphicsLayer( + scaleX = 2f, + scaleY = 2f + ) + ) Spacer(modifier = Modifier.weight(1f)) - Row { - Icon( - Icons.AutoMirrored.Filled.ArrowForward, - contentDescription = stringResource(R.string.down_left_arrow), - modifier = Modifier - .rotate(45f) - .graphicsLayer( - scaleX = 2f, - scaleY = 2f - ) - ) - Spacer(modifier = Modifier.weight(1f)) - } + } - Text( - text = stringResource(R.string.top_up_title), - style = MaterialTheme.typography.displaySmall.copy(textAlign = TextAlign.Left), - modifier = Modifier.fillMaxWidth() - ) + Text( + text = stringResource(R.string.top_up_title), + style = MaterialTheme.typography.displaySmall.copy(textAlign = TextAlign.Left), + modifier = Modifier.fillMaxWidth() + ) + + Text( + text = stringResource(R.string.top_up_detail_1), + style = MaterialTheme.typography.bodyLarge, + modifier = Modifier.fillMaxWidth() + ) + BorderedLargeButton( + onClick = { onNavigate.invoke(UiEffect.Navigate(destinationRoute = Route.BuyLitecoin)) }, + modifier = Modifier.fillMaxWidth() + ) { Text( - text = stringResource(R.string.top_up_detail_1), - style = MaterialTheme.typography.bodyLarge, - modifier = Modifier.fillMaxWidth() + text = stringResource(R.string.top_up_button_1), + style = MaterialTheme.typography.bodyLarge ) } - if (shouldShowWebView) { - AndroidView( - factory = { - WebView(it).apply { - setInitialScale(99) - setLayerType(ViewGroup.LAYER_TYPE_SOFTWARE, null) - settings.apply { - javaScriptEnabled = true - useWideViewPort = true - loadWithOverviewMode = true - builtInZoomControls = true - domStorageEnabled = true - allowContentAccess = true - } - webViewClient = object : WebViewClient() { - override fun onPageStarted(view: WebView, url: String?, favicon: Bitmap?) { - backEnabled = view.canGoBack() - } - } - webViewClient = object : WebViewClient() { - override fun onPageFinished(view: WebView?, url: String?) { - shouldSkipBeVisible = true - } - } - - layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT) - - } - }, - update = { - it.loadUrl(BRConstants.MOBILE_MP_LINK) - }, - modifier = Modifier - .height(600.dp) - .weight(1f) + BorderedLargeButton( + onClick = { + viewModel.onEvent(YourSeedProveItEvent.OnGameAndSync) + AnalyticsManager.logCustomEvent(BRConstants._20250303_DSTU) + }, + modifier = Modifier.fillMaxWidth() + + ) { + Text( + text = stringResource(R.string.top_up_button_2), + style = MaterialTheme.typography.bodyMedium ) - Row( - modifier = Modifier - .fillMaxWidth() - .height(buttonRowHeight.dp), - - ){ - Spacer(modifier = Modifier.weight(1f)) - if(shouldSkipBeVisible) { - MediumTextButton( - onClick = { - viewModel.onEvent(YourSeedProveItEvent.OnGameAndSync) - AnalyticsManager.logCustomEvent(BRConstants._20250303_DSTU) - }, - modifier = Modifier - .width(skipButtonWidth.dp) - .padding(vertical = horizontalVerticalSpacing.dp), - - ) { - - Text( - text = stringResource(R.string.top_up_button_3), - style = MaterialTheme.typography.bodyMedium, - textAlign = TextAlign.Right - ) - } - } - } - - } - if (!shouldShowWebView) { - BorderedLargeButton( - onClick = { - shouldShowWebView = true - }, - modifier = Modifier.fillMaxWidth() - - ) { - Text( - text = stringResource(R.string.top_up_button_1), - style = MaterialTheme.typography.bodyLarge - ) - } - BorderedLargeButton( - onClick = { - viewModel.onEvent(YourSeedProveItEvent.OnGameAndSync) - AnalyticsManager.logCustomEvent(BRConstants._20250303_DSTU) - }, - modifier = Modifier.fillMaxWidth() - - ) { - Text( - text = stringResource(R.string.top_up_button_2), - style = MaterialTheme.typography.bodyMedium - ) - } - } Spacer(modifier = Modifier.weight(0.05f)) diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt index 6f4d19c4..998ddb00 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt @@ -18,8 +18,8 @@ class YourSeedProveItViewModel : BrainwalletViewModel() { when (event) { is YourSeedProveItEvent.OnLoad -> _state.update { it.copy( - correctSeedWords = event.seedWords.mapIndexed { index, word -> - index to SeedWordItem(expected = word) + correctSeedWords = event.seedWords.mapIndexed { index, word -> + index to SeedWordItem(expected = word) }.toMap(), shuffledSeedWords = event.seedWords.shuffled() ) diff --git a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt index 819eb43e..36afabbe 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt @@ -1,6 +1,7 @@ package com.brainwallet.ui.theme import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Shapes import androidx.compose.material3.Typography import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -84,6 +85,9 @@ object BrainwalletTheme { val typography: Typography @Composable @ReadOnlyComposable get() = MaterialTheme.typography + val shapes: Shapes + @Composable @ReadOnlyComposable get() = MaterialTheme.shapes + //todo: add typography, shape? for the design system } diff --git a/app/src/main/res/drawable/ic_copy.xml b/app/src/main/res/drawable/ic_copy.xml new file mode 100644 index 00000000..6a0293ec --- /dev/null +++ b/app/src/main/res/drawable/ic_copy.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_import.xml b/app/src/main/res/drawable/ic_import.xml new file mode 100644 index 00000000..33f6260c --- /dev/null +++ b/app/src/main/res/drawable/ic_import.xml @@ -0,0 +1,19 @@ + + + + diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml index 0d1f4a90..dc0df45e 100644 --- a/app/src/main/res/menu/bottom_nav_menu.xml +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -19,10 +19,10 @@ android:icon="@drawable/ic_nav_receive" android:title="@string/Button.receive" /> - + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu_us.xml b/app/src/main/res/menu/bottom_nav_menu_us.xml index 2d26a165..187ac237 100644 --- a/app/src/main/res/menu/bottom_nav_menu_us.xml +++ b/app/src/main/res/menu/bottom_nav_menu_us.xml @@ -1,27 +1,28 @@ + + - + android:title="@string/bottom_nav_item_buy_receive_title" /> - + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 8a3ee8f0..cf9095d7 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -439,4 +439,15 @@ قمة واسطة قليل + مزامنة البيانات التعريفية: + شراء لايتكوين + مدعوم من مونباي + تحميل... + المبلغ أقل من الحد الأدنى (%1$f) + يتجاوز المبلغ الحد الأقصى (%1$f) + شراء لايتكوين + يتم إيداعها في عنوان LTC الخاص بك: + الشراء باستخدام Moonpay + العنوان الجديد + شراء / تلقي diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 6d272928..a07b7400 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -800,4 +800,15 @@ Spitze Medium Niedrig + Metadaten synchronisieren: + Kaufen Sie LTC + Unterstützt von Moonpay + Laden... + Betrag liegt unter dem Mindestlimit (%1$f) + Betrag überschreitet Höchstgrenze (%1$f) + Litecoin kaufen + Bitte überweisen Sie es an Ihre LTC-Adresse: + Kaufen Sie mit Moonpay + Neue Adresse + Kaufen / Empfangen diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 24bf3fc0..1a918843 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -799,4 +799,15 @@ Arriba Medio Bajo + Sincronizar metadatos: + Comprar LTC + Desarrollado por Moonpay + Cargando... + El monto está por debajo del límite mínimo (%1$f) + El importe supera el límite máximo (%1$f) + Comprar Litecoin + Se depositará en su dirección LTC: + Compra con Moonpay + Nueva dirección + Comprar / Recibir diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 1571dd93..b0e92d08 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -800,4 +800,15 @@ Haut Moyen Faible + Synchroniser les métadonnées : + Acheter des SLD + Propulsé par Moonpay + Chargement... + Le montant est inférieur à la limite minimale (%1$f) + Le montant dépasse la limite maximale (%1$f) + Acheter du Litecoin + Soyez déposé à votre adresse LTC : + Acheter avec Moonpay + Nouvelle adresse + Acheter / Recevoir diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index a03d849c..3c263e70 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -438,4 +438,15 @@ शीर्ष मध्यम कम + मेटाडेटा सिंक करें: + एलटीसी खरीदें + मूनपे द्वारा संचालित + लोड हो रहा है... + राशि न्यूनतम सीमा से कम है (%1$f) + राशि अधिकतम सीमा से अधिक है (%1$f) + लाइटकॉइन खरीदें + अपने एलटीसी पते पर जमा करें: + मूनपे से खरीदें + नया पता + खरीदें/प्राप्त करें diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index d3bb43e0..371a07fa 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -802,4 +802,15 @@ Atas Sedang Rendah + Sinkronkan metadata: + Beli LTC + Didukung oleh Moonpay + Memuat... + Jumlahnya di bawah batas minimum (%1$f) + Jumlah melebihi batas maksimum (%1$f) + Beli Litecoin + Disetorkan ke Alamat LTC Anda: + Beli dengan Moonpay + Alamat Baru + Beli / Terima diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 592ebba1..0246634a 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -800,4 +800,15 @@ Superiore Medio Basso + Sincronizza i metadati: + Acquista LTC + Alimentato da Moonpay + Caricamento... + L\'importo è inferiore al limite minimo (%1$f) + L\'importo supera il limite massimo (%1$f) + Acquista Litecoin + Essere depositato al tuo indirizzo LTC: + Acquista con Moonpay + Nuovo indirizzo + Acquista/Ricevi diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index c6ffb20c..9523482b 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -800,4 +800,15 @@ トップ 中くらい 低い + メタデータを同期する: + LTCを購入する + ムーンペイ提供 + 読み込み中... + 金額が下限値 (%1$f) を下回っています + 量が上限を超えています (%1$f) + ライトコインを購入する + LTCアドレスに入金してください: + Moonpay で購入する + 新しい住所 + 買う/受け取る diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 8ec4b384..0f409eb0 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -800,4 +800,15 @@ 맨 위 중간 낮은 + 메타데이터 동기화: + 라이트코인 구매 + 문페이 제공 + 로드 중... + 금액이 최소 한도(%1$f)보다 낮습니다. + 금액이 최대 한도(%1$f)를 초과했습니다. + 라이트코인 구매 + LTC 주소로 입금하세요: + 문페이로 구매하세요 + 새 주소 + 구매 / 받기 diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 27b64935..535904d3 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -799,4 +799,15 @@ Principal Médio Baixo + Sincronizar metadados: + Comprar LTC + Desenvolvido por Moonpay + Carregando... + O valor está abaixo do limite mínimo (%1$f) + O valor excede o limite máximo (%1$f) + Comprar Litecoin + Seja depositado em seu endereço LTC: + Compre com Moonpay + Novo endereço + Comprar / Receber diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 4df74670..5434b353 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -800,4 +800,15 @@ Вершина Середина Низкий + Синхронизировать метаданные: + Купить LTC + При поддержке Moonpay + Загрузка... + Сумма ниже минимального лимита (%1$f) + Сумма превышает максимальный лимит (%1$f) + Купить Лайткоин + Депонируйте на свой адрес LTC: + Купить с помощью Moonpay + Новый адрес + Купить/получить diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 78b503fd..eef96cac 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -438,4 +438,15 @@ Bästa Medium Låg + Synkronisera metadata: + Köp LTC + Drivs av Moonpay + Belastning... + Beloppet är under minimigränsen (%1$f) + Beloppet överskrider maxgränsen (%1$f) + Köp Litecoin + Sätt in till din LTC-adress: + Köp med Moonpay + Ny adress + Köp/ta emot diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index a526c60c..b67506d4 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -823,4 +823,16 @@ Tepe Orta Düşük + + Meta verileri senkronize et: + LTC satın al + Moonpay tarafından desteklenmektedir + Yükleniyor... + Tutar minimum sınırın altında (%1$f) + Tutar maksimum sınırı aşıyor (%1$f) + Litecoin satın al + LTC Adresinize yatırın: + Moonpay ile satın alın + Yeni Adres + Satın Al / Al diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index b5d20546..f8899d68 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -806,4 +806,16 @@ Топ Середній Низький + + Синхронізувати метадані: + Купити LTC + На основі Moonpay + Завантаження... + Сума нижче мінімального ліміту (%1$f) + Сума перевищує максимальний ліміт (%1$f) + Купуйте Litecoin + Зробіть депозит на свою адресу LTC: + Купуйте за допомогою Moonpay + Нова адреса + Купити / Отримати diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 53cd941f..763288ac 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -800,4 +800,15 @@ 顶部 中等的 低的 + 同步元数据: + 购买莱特币 + 由 月付 提供支持 + 加载中... + 金额低于最低限额 (%1$f) + 金额超过最大限制 (%1$f) + 购买莱特币 + 请存入您的 LTC 地址: + 使用 Moonpay 购买 + 新地址 + 购买/接收 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 69514c55..fe1abc56 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -800,4 +800,15 @@ 頂部 中等的 低的 + 同步元資料: + 購買萊特幣 + 由 月付 提供支持 + 載入中... + 金額低於最低限額 (%1$f) + 金額超過最大限制 (%1$f) + 購買萊特幣 + 請存入您的 LTC 地址: + 使用 Moonpay 購買 + 新地址 + 購買/接收 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d107536c..f7c7deb0 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,7 +74,7 @@ receive - send + Send Settings @@ -839,8 +839,20 @@ Share analytics data Update PIN Show + Buy LTC + Powered by Moonpay + Loading... Network Fee (per kb): Higher value mean the transaction completes sooner Top Medium Low + Amount is below minimum limit (%f) + Amount exceeds maximum limit (%f) + Buy Litecoin + Do be deposited to your LTC Address: + Buy with Moonpay + New Address + + Buy / Receive + Custom From 18eda469fb568e492d9f7a6f3a5b95d240872478 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 12 May 2025 13:29:20 +0100 Subject: [PATCH 029/116] version and code bump --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 80cc7aec..172a0a87 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202505021 - versionName = "v4.4.7" + versionCode = 202505121 + versionName = "v4.5.0" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") From dbb6a5fee697fa6d29f0fdd32e77f378029b4a7a Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 19 May 2025 01:22:10 -0700 Subject: [PATCH 030/116] Added support url (#81) - changed the language - code bump --- app/build.gradle.kts | 2 +- app/src/main/java/com/brainwallet/tools/util/BRConstants.java | 1 + .../ui/screens/home/composable/HomeSettingDrawerSheet.kt | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 172a0a87..8add0963 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,7 +20,7 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202505121 + versionCode = 202505141 versionName = "v4.5.0" multiDexEnabled = true diff --git a/app/src/main/java/com/brainwallet/tools/util/BRConstants.java b/app/src/main/java/com/brainwallet/tools/util/BRConstants.java index 1c4d4a53..7c989533 100644 --- a/app/src/main/java/com/brainwallet/tools/util/BRConstants.java +++ b/app/src/main/java/com/brainwallet/tools/util/BRConstants.java @@ -98,6 +98,7 @@ private BRConstants() { public static final String TWITTER_LINK = "https://twitter.com/Brainwallet_App"; public static final String INSTAGRAM_LINK = "https://www.instagram.com/brainwalletapp"; public static final String WEB_LINK = "https://brainwallet.co"; + public static final String SUPPORT_WEB_LINK = "https://brainwallet.co/support.html"; public static final String TOS_LINK = "https://brainwallet.co/privacy-policy.html"; public static final String MOBILE_MP_LINK = "https://brainwallet.co/mobile-top-up.html"; public static String BITREFILL_AFFILIATE_LINK = "https://www.bitrefill.com/"; diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index 5c0c6a9c..1daa4b33 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -144,11 +144,11 @@ fun HomeSettingDrawerSheet( item { SettingRowItem( title = stringResource(R.string.settings_title_support), - description = "brainwallet.co", + description = "brainwallet.co/support.html", onClick = { val builder = CustomTabsIntent.Builder() val customTabsIntent = builder.build() - customTabsIntent.launchUrl(context, Uri.parse(BRConstants.WEB_LINK)) + customTabsIntent.launchUrl(context, Uri.parse(BRConstants.SUPPORT_WEB_LINK)) } ) } From c82a5e3316282bc3d7d31d3c5e8d7ebb5774f521 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 19 May 2025 09:26:16 +0100 Subject: [PATCH 031/116] version and code bump --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8add0963..290ed2dd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202505141 - versionName = "v4.5.0" + versionCode = 202505191 + versionName = "v4.5.3" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") From 2981ec62d3974cbbc12ad70617612588b181135b Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Sun, 25 May 2025 19:32:34 +0700 Subject: [PATCH 032/116] Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington --- .../java/com/brainwallet/data/model/Fee.kt | 27 ++++++++---- .../data/repository/LtcRepository.kt | 18 ++++---- .../data/repository/SettingRepository.kt | 17 ++++++++ .../presenter/fragments/FragmentSend.kt | 32 ++++++++------- .../brainwallet/tools/manager/FeeManager.java | 27 +++++++++--- .../tools/manager/PromptManager.java | 2 + .../brainwallet/tools/util/BRConstants.java | 6 +-- .../brainwallet/tools/util/BRExchange.java | 12 ++++-- .../com/brainwallet/tools/util/Utils.java | 41 ++++++++----------- .../ui/screens/home/SettingsEvent.kt | 2 + .../ui/screens/home/SettingsState.kt | 2 + .../ui/screens/home/SettingsViewModel.kt | 28 ++++++++++++- .../home/composable/HomeSettingDrawerSheet.kt | 1 + .../settingsrows/LitecoinBlockchainDetail.kt | 18 ++------ .../brainwallet/wallet/BRWalletManager.java | 17 +++++--- .../tools/database/DatabaseTests.kt | 1 - .../brainwallet/tools/util/BRConstantsTest.kt | 2 - 17 files changed, 160 insertions(+), 93 deletions(-) diff --git a/app/src/main/java/com/brainwallet/data/model/Fee.kt b/app/src/main/java/com/brainwallet/data/model/Fee.kt index 0ea99667..b1d086ae 100644 --- a/app/src/main/java/com/brainwallet/data/model/Fee.kt +++ b/app/src/main/java/com/brainwallet/data/model/Fee.kt @@ -8,8 +8,6 @@ import com.brainwallet.tools.manager.FeeManager.LUXURY import com.brainwallet.tools.manager.FeeManager.REGULAR import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import kotlin.math.ceil -import kotlin.math.round @Serializable data class Fee( @@ -22,23 +20,31 @@ data class Fee( @JvmField @SerialName("fee_per_kb_economy") var economy: Long, + var timestamp: Long ) { companion object { - //from legacy - // this is the default that matches the mobile-api if the server is unavailable - private const val defaultEconomyFeePerKB: Long = - 2500L // From legacy minimum. default min is 1000 as Litecoin Core version v0.17.1 + /** + * Default value for economy fee rate per kilobyte. + * Used as a fallback when fee rate cannot be determined dynamically. + * + * Previous value: 2500L (2.5 satoshis per byte). From legacy minimum. default min is 1000 as Litecoin Core version v0.17.1 + * Updated economy to 8000L (8 satoshis per byte) on 2023-11-16 (same as iOS) + */ + private const val defaultEconomyFeePerKB: Long = 8000L private const val defaultRegularFeePerKB: Long = 25000L private const val defaultLuxuryFeePerKB: Long = 66746L private const val defaultTimestamp: Long = 1583015199122L -// {"fee_per_kb":5289,"fee_per_kb_economy":2645,"fee_per_kb_luxury":10578} - + /** + * currently we are using this static [Default] for our fee + * maybe we need to update core if we need dynamic fee? + */ @JvmStatic val Default = Fee( defaultLuxuryFeePerKB, defaultRegularFeePerKB, defaultEconomyFeePerKB, + defaultTimestamp ) } } @@ -80,4 +86,9 @@ fun FeeOption.getFiatFormatted(currencyEntity: CurrencyEntity): String { val fiatValue = getFiat(currencyEntity) val formatted = String.format("%.3f", fiatValue) return "${currencyEntity.symbol}$formatted" +} + +fun List.getSelectedIndex(selectedFeeType: String): Int { + return indexOfFirst { it.type == selectedFeeType }.takeIf { it >= 0 } + ?: 2 //2 -> index of top, since we have [low,medium,top] } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index 365bbc0d..962602f7 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -54,17 +54,13 @@ interface LtcRepository { } - override suspend fun fetchFeePerKb(): Fee { - return sharedPreferences.fetchWithCache( - key = PREF_KEY_NETWORK_FEE_PER_KB, - cachedAtKey = PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT, - cacheTimeMs = 6 * 60 * 60 * 1000, - fetchData = { - remoteApiSource.getFeePerKb() - }, - defaultValue = Fee.Default - ) - } + /** + * for now we just using [Fee.Default] + * will move to [RemoteApiSource.getFeePerKb] after fix the calculation when we do send + * + * maybe need updaete core if we need to use dynamic fee? + */ + override suspend fun fetchFeePerKb(): Fee = Fee.Default //using static fee override suspend fun fetchLimits(baseCurrencyCode: String): MoonpayCurrencyLimit { return sharedPreferences.fetchWithCache( diff --git a/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt index 2e4b3388..3f217918 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt @@ -5,6 +5,7 @@ import androidx.core.content.edit import com.brainwallet.data.model.AppSetting import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Language +import com.brainwallet.tools.manager.FeeManager import com.brainwallet.tools.sqlite.CurrencyDataSource import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -36,6 +37,10 @@ interface SettingRepository { fun toggleDarkMode(isDarkMode: Boolean) + fun putSelectedFeeType(feeType: String) + + fun getSelectedFeeType(): String + class Impl( private val sharedPreferences: SharedPreferences, private val currencyDataSource: CurrencyDataSource @@ -77,6 +82,17 @@ interface SettingRepository { _state.update { it.copy(isDarkMode = isDarkMode) } } + override fun putSelectedFeeType(feeType: String) { + sharedPreferences.edit { + putString(KEY_SELECTED_FEE_TYPE, feeType) + } + } + + override fun getSelectedFeeType(): String = + sharedPreferences.getString(KEY_SELECTED_FEE_TYPE, FeeManager.REGULAR) + ?: FeeManager.REGULAR + + private fun load(): AppSetting { return AppSetting( isDarkMode = sharedPreferences.getBoolean(KEY_IS_DARK_MODE, true), @@ -100,5 +116,6 @@ interface SettingRepository { const val KEY_IS_DARK_MODE = "is_dark_mode" const val KEY_LANGUAGE_CODE = "language_code" const val KEY_FIAT_CURRENCY_CODE = "fiat_currency_code" + const val KEY_SELECTED_FEE_TYPE = "selected_fee_type" } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt index 9b47690e..83d08dcb 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt @@ -135,6 +135,9 @@ class FragmentSend : Fragment() { updateText() + //update fee + BRWalletManager.getInstance().setFeePerKb(FeeManager.getInstance().currentFeeValue) + return rootView } @@ -496,7 +499,6 @@ class FragmentSend : Fragment() { override fun onStop() { super.onStop() - FeeManager.getInstance().resetFeeType() } override fun onResume() { @@ -611,9 +613,22 @@ class FragmentSend : Fragment() { } Timber.d("timber: updateText: currentAmountInLitoshis %d", currentAmountInLitoshis) + // Service Fee depending on ISOSymbol + var serviceFee = Utils.tieredOpsFee(activity, currentAmountInLitoshis) + val serviceFeeForISOSymbol = + BRExchange.getAmountFromLitoshis(activity, selectedISOSymbol, BigDecimal(serviceFee)) + .setScale(scaleValue, RoundingMode.HALF_UP) + val formattedServiceFee = BRCurrency.getFormattedCurrencyString( + activity, + selectedISOSymbol, + serviceFeeForISOSymbol + ) + + val totalAmountToCalculateFees = currentAmountInLitoshis + serviceFee + // Network Fee depending on ISOSymbol - var networkFee = if (currentAmountInLitoshis > 0) { - BRWalletManager.getInstance().feeForTransactionAmount(currentAmountInLitoshis) + var networkFee = if (totalAmountToCalculateFees > 0) { + BRWalletManager.getInstance().feeForTransactionAmount(totalAmountToCalculateFees) } else { 0 } //Amount is zero so network fee is also zero @@ -626,17 +641,6 @@ class FragmentSend : Fragment() { networkFeeForISOSymbol ) - // Service Fee depending on ISOSymbol - var serviceFee = Utils.tieredOpsFee(activity, currentAmountInLitoshis) - val serviceFeeForISOSymbol = - BRExchange.getAmountFromLitoshis(activity, selectedISOSymbol, BigDecimal(serviceFee)) - .setScale(scaleValue, RoundingMode.HALF_UP) - val formattedServiceFee = BRCurrency.getFormattedCurrencyString( - activity, - selectedISOSymbol, - serviceFeeForISOSymbol - ) - // Total Fees depending on ISOSymbol val totalFees = networkFee + serviceFee val totalFeeForISOSymbol = diff --git a/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java b/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java index f9457baa..bf927976 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/FeeManager.java @@ -4,9 +4,10 @@ import androidx.annotation.StringDef; +import com.brainwallet.data.model.Fee; import com.brainwallet.data.repository.LtcRepository; +import com.brainwallet.data.repository.SettingRepository; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.data.model.Fee; import org.koin.java.KoinJavaComponent; @@ -14,7 +15,6 @@ import java.lang.annotation.RetentionPolicy; //we are still using this, maybe in the future will deprecate? -@Deprecated public final class FeeManager { @@ -56,8 +56,24 @@ public boolean isLuxuryFee() { public static final String REGULAR = "regular";//medium public static final String ECONOMY = "economy";//low - public void setFees(long luxuryFee, long regularFee, long economyFee) { - currentFeeOptions = new Fee(luxuryFee, regularFee, economyFee); + public void setFees(Fee fee) { + currentFeeOptions = fee; + } + + public long getCurrentFeeValue() { + SettingRepository settingRepository = KoinJavaComponent.get(SettingRepository.class); + String feeType = settingRepository.getSelectedFeeType(); + + switch (feeType) { + case LUXURY: + return currentFeeOptions.luxury; + case REGULAR: + return currentFeeOptions.regular; + case ECONOMY: + return currentFeeOptions.economy; + default: + return currentFeeOptions.regular; // Default to regular fee + } } public static void updateFeePerKb(Context app) { @@ -66,8 +82,7 @@ public static void updateFeePerKb(Context app) { (coroutineScope, continuation) -> ltcRepository.fetchFeePerKb(continuation) ).whenComplete((fee, throwable) -> { - //legacy logic - FeeManager.getInstance().setFees(fee.luxury, fee.regular, fee.economy); + FeeManager.getInstance().setFees(fee); BRSharedPrefs.putFeeTime(app, System.currentTimeMillis()); //store the time of the last successful fee fetch }); } diff --git a/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java b/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java index e6c9a029..a716d7f7 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java @@ -9,6 +9,7 @@ import android.content.Intent; import android.view.View; +import com.brainwallet.presenter.activities.settings.SyncBlockchainActivity; import com.brainwallet.tools.security.BRKeyStore; import com.brainwallet.tools.threads.BRExecutor; import com.brainwallet.R; @@ -88,6 +89,7 @@ public void run() { BRSharedPrefs.putStartHeight(app, 0); BRPeerManager.getInstance().rescan(); BRSharedPrefs.putScanRecommended(app, false); + BRSharedPrefs.putAllowSpend(app, false); } }); } diff --git a/app/src/main/java/com/brainwallet/tools/util/BRConstants.java b/app/src/main/java/com/brainwallet/tools/util/BRConstants.java index 7c989533..bd8f810b 100644 --- a/app/src/main/java/com/brainwallet/tools/util/BRConstants.java +++ b/app/src/main/java/com/brainwallet/tools/util/BRConstants.java @@ -129,7 +129,6 @@ private BRConstants() { public static final String _20201118_DTGS = "did_tap_get_support"; public static final String _20200217_DUWP = "did_unlock_with_pin"; public static final String _20200217_DUWB = "did_unlock_with_biometrics"; - public static final String _20200301_DUDFPK = "did_use_default_fee_per_kb"; public static final String _20201121_SIL = "started_IFPS_lookup"; public static final String _20201121_DRIA = "did_resolve_IPFS_address"; public static final String _20201121_FRIA = "failed_resolve_IPFS_address"; @@ -137,6 +136,7 @@ private BRConstants() { public static final String _20230407_DCS = "did_complete_sync"; public static final String _20250303_DSTU = "did_skip_top_up"; + public static final String _20250517_WCINFO = "wallet_callback_info"; ///Dev: These events not yet used public static final String _20200207_DTHB = "did_tap_header_balance"; @@ -170,7 +170,6 @@ private BRConstants() { _20201118_DTGS, _20200217_DUWP, _20200217_DUWB, - _20200301_DUDFPK, _20201121_SIL, _20201121_DRIA, _20201121_FRIA, @@ -187,7 +186,8 @@ private BRConstants() { _20241006_UCR, _HOME_OPEN, _20250222_PAC, - _20250303_DSTU + _20250303_DSTU, + _20250517_WCINFO }) public @interface Event { } diff --git a/app/src/main/java/com/brainwallet/tools/util/BRExchange.java b/app/src/main/java/com/brainwallet/tools/util/BRExchange.java index 52b6df6b..c199b115 100644 --- a/app/src/main/java/com/brainwallet/tools/util/BRExchange.java +++ b/app/src/main/java/com/brainwallet/tools/util/BRExchange.java @@ -102,11 +102,17 @@ public static BigDecimal getLitoshisFromAmount(Context app, String iso, BigDecim if (iso.equalsIgnoreCase("LTC")) { result = BRExchange.getLitoshisForLitecoin(app, amount); } else { - //multiply by 100 because core function localAmount accepts the smallest amount e.g. cents CurrencyEntity ent = CurrencyDataSource.getInstance(app).getCurrencyByIso(iso); if (ent == null) return new BigDecimal(0); - BigDecimal rate = new BigDecimal(ent.rate).multiply(new BigDecimal(100)); - result = new BigDecimal(BRWalletManager.getInstance().bitcoinAmount(amount.multiply(new BigDecimal(100)).longValue(), rate.doubleValue())); + + // Get the exchange rate + BigDecimal rate = new BigDecimal(ent.rate); + + result = amount.divide(rate, 8, BRConstants.ROUNDING_MODE) + .multiply(new BigDecimal("100000000")); + + // Round to a whole number of litoshis + result = result.setScale(0, BRConstants.ROUNDING_MODE); } return result; } diff --git a/app/src/main/java/com/brainwallet/tools/util/Utils.java b/app/src/main/java/com/brainwallet/tools/util/Utils.java index 8e7e6062..fb03d0c3 100644 --- a/app/src/main/java/com/brainwallet/tools/util/Utils.java +++ b/app/src/main/java/com/brainwallet/tools/util/Utils.java @@ -267,38 +267,29 @@ else if (name == ServiceItems.CLIENTCODE) { } /// Description: 1715876807 public static long tieredOpsFee(Context app, long sendAmount) { - - double doubleRate = 83.000; - double sendAmountDouble = new Double(String.valueOf(sendAmount)); - String usIso = Currency.getInstance(new Locale("en", "US")).getCurrencyCode(); - CurrencyEntity currency = CurrencyDataSource.getInstance(app).getCurrencyByIso(usIso); - if (currency != null) { - doubleRate = currency.rate; + if (sendAmount < 1_398_000) { + return 69900; } - double usdInLTC = sendAmountDouble * doubleRate / 100_000_000.0; - usdInLTC = Math.floor(usdInLTC * 100) / 100; - - if (isBetween(usdInLTC, 0.00, 20.00)) { - double lowRate = usdInLTC * 0.01; - return (long) ((lowRate / doubleRate) * 100_000_000.0); + else if (sendAmount < 6_991_000) { + return 111_910; + } + else if (sendAmount < 27_965_000) { + return 279_700; } - else if (isBetween(usdInLTC, 20.00, 50.00)) { - return (long) ((0.30 / doubleRate) * 100_000_000.0); + else if (sendAmount < 139_820_000) { + return 699_540; } - else if (isBetween(usdInLTC, 50.00, 100.00)) { - return (long) ((1.00 / doubleRate) * 100_000_000.0); - } - else if (isBetween(usdInLTC, 100.00, 500.00)) { - return (long) ((2.00 / doubleRate) * 100_000_000.0); + else if (sendAmount < 279_653_600) { + return 1_049_300; } - else if (isBetween(usdInLTC, 500.00, 1000.00)) { - return (long) ((2.50 / doubleRate) * 100_000_000.0); + else if (sendAmount < 699_220_000) { + return 1_398_800; } - else if ( usdInLTC > 1000.00) { - return (long) ((3.00 / doubleRate) * 100_000_000.0); + else if (sendAmount < 1_398_440_000) { + return 2_797_600; } else { - return (long) ((3.00 / doubleRate) * 100_000_000.0); + return 2_797_600; } } private static boolean isBetween(double x, double lower, double upper) { diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt index 48e0750a..61a8ced4 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt @@ -8,6 +8,7 @@ sealed class SettingsEvent { val shareAnalyticsDataEnabled: Boolean = false, val lastSyncMetadata: String? = null, ) : SettingsEvent() + object OnSecurityUpdatePinClick : SettingsEvent() object OnSecuritySeedPhraseClick : SettingsEvent() object OnSecurityShareAnalyticsDataClick : SettingsEvent() @@ -20,4 +21,5 @@ sealed class SettingsEvent { object OnFiatSelectorDismiss : SettingsEvent() data class OnFiatChange(val currency: CurrencyEntity) : SettingsEvent() object OnBlockchainSyncClick : SettingsEvent() + data class OnFeeTypeChange(val feeType: String) : SettingsEvent() } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt index 60a209bd..d0336bff 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt @@ -5,6 +5,7 @@ import com.brainwallet.data.model.Fee import com.brainwallet.data.model.FeeOption import com.brainwallet.data.model.Language import com.brainwallet.data.model.toFeeOptions +import com.brainwallet.tools.manager.FeeManager data class SettingsState( val darkMode: Boolean = true, @@ -20,4 +21,5 @@ data class SettingsState( val shareAnalyticsDataEnabled: Boolean = false, val lastSyncMetadata: String? = null, val currentFeeOptions: List = Fee.Default.toFeeOptions(), + val selectedFeeType: String = FeeManager.LUXURY ) \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt index 8859d395..738af4be 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt @@ -8,8 +8,10 @@ import com.brainwallet.data.model.Language import com.brainwallet.data.model.toFeeOptions import com.brainwallet.data.repository.LtcRepository import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.tools.manager.FeeManager import com.brainwallet.ui.BrainwalletViewModel import com.brainwallet.util.EventBus +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -47,6 +49,25 @@ class SettingsViewModel( AppSetting() ) + init { + viewModelScope.launch { + while (true) { + /** + * need update fee options every 4s, since we are fetching every 4s + * pls check at + * - [CurrencyUpdateWorker] + * - [LtcRepository.fetchRates] + * - [LtcRepository.fetchFeePerKb] + */ + + _state.update { + it.copy(currentFeeOptions = FeeManager.getInstance().currentFeeOptions.toFeeOptions()) + } + delay(4000) + } + } + } + override fun onEvent(event: SettingsEvent) { when (event) { is SettingsEvent.OnLoad -> viewModelScope.launch { @@ -54,7 +75,7 @@ class SettingsViewModel( it.copy( shareAnalyticsDataEnabled = event.shareAnalyticsDataEnabled, lastSyncMetadata = event.lastSyncMetadata, - currentFeeOptions = ltcRepository.fetchFeePerKb().toFeeOptions() + selectedFeeType = settingRepository.getSelectedFeeType() ) } } @@ -143,6 +164,11 @@ class SettingsViewModel( EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_SHARE_ANALYTICS_DATA_TOGGLE)) } + + is SettingsEvent.OnFeeTypeChange -> _state.update { + settingRepository.putSelectedFeeType(event.feeType) + it.copy(selectedFeeType = event.feeType) + } } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index 1daa4b33..b3559014 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -135,6 +135,7 @@ fun HomeSettingDrawerSheet( .fillMaxSize() .wrapContentHeight(), selectedCurrency = state.selectedCurrency, + selectedFeeType = state.selectedFeeType, feeOptions = state.currentFeeOptions, onEvent = { viewModel.onEvent(it) diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt index 138ab31c..f964e418 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt @@ -14,10 +14,6 @@ import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -26,24 +22,21 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.brainwallet.R import com.brainwallet.data.model.CurrencyEntity -import com.brainwallet.data.model.Fee import com.brainwallet.data.model.FeeOption import com.brainwallet.data.model.getFiatFormatted -import com.brainwallet.data.model.toFeeOptions -import com.brainwallet.tools.manager.FeeManager +import com.brainwallet.data.model.getSelectedIndex import com.brainwallet.ui.screens.home.SettingsEvent import com.brainwallet.ui.theme.BrainwalletTheme -import com.brainwallet.wallet.BRWalletManager //TODO @Composable fun LitecoinBlockchainDetail( modifier: Modifier = Modifier, selectedCurrency: CurrencyEntity, + selectedFeeType: String, feeOptions: List, onEvent: (SettingsEvent) -> Unit, ) { - var feeOptionsState by remember { mutableIntStateOf(2) } //2 -> index of top, since we have [low,medium,top] /// Layout values val contentHeight = 60 @@ -81,12 +74,9 @@ fun LitecoinBlockchainDetail( NetworkFeeSelector( selectedCurrency = selectedCurrency, feeOptions = feeOptions, - selectedIndex = feeOptionsState + selectedIndex = feeOptions.getSelectedIndex(selectedFeeType) ) { newSelectedIndex -> - feeOptionsState = newSelectedIndex - - //just update inside BRWalletManager.setFeePerKb - BRWalletManager.getInstance().setFeePerKb(feeOptions[newSelectedIndex].feePerKb) + onEvent.invoke(SettingsEvent.OnFeeTypeChange(feeOptions[newSelectedIndex].type)) } } diff --git a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java index 507a5125..59aaed33 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java @@ -9,6 +9,7 @@ import android.media.MediaPlayer; import android.net.ConnectivityManager; import android.net.NetworkInfo; +import android.os.Bundle; import android.os.Handler; import android.os.NetworkOnMainThreadException; import android.os.SystemClock; @@ -334,6 +335,14 @@ public void onClick(DialogInterface dialog, int which) { */ public static void publishCallback(final String message, final int error, byte[] txHash) { Timber.d("timber: publishCallback: " + message + ", err:" + error + ", txHash: " + Arrays.toString(txHash)); + + Bundle params = new Bundle(); + params.putString("function", "BRWalletManager.publishCallback"); + params.putString("message", message); + params.putInt("error", error); + params.putString("txHash", Arrays.toString(txHash)); + AnalyticsManager.logCustomEventWithParams(BRConstants._20250517_WCINFO, params); + final Context app = BrainwalletApp.getBreadContext(); BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() { @Override @@ -440,6 +449,7 @@ public static void onTxDeleted(String hash, int notifyUser, final int recommendR final Context ctx = BrainwalletApp.getBreadContext(); if (ctx != null) { BRSharedPrefs.putScanRecommended(ctx, true); + TransactionDataSource.getInstance(ctx).deleteTxByHash(hash); } else { Timber.i("timber: onTxDeleted: Failed! ctx is null"); } @@ -513,11 +523,8 @@ public void initWallet(final Context ctx) { m.createWallet(transactionsCount, pubkeyEncoded); String firstAddress = BRWalletManager.getFirstAddress(pubkeyEncoded); BRSharedPrefs.putFirstAddress(ctx, firstAddress); - FeeManager feeManager = FeeManager.getInstance(); - if (feeManager.isLuxuryFee()) { - FeeManager.updateFeePerKb(ctx); - BRWalletManager.getInstance().setFeePerKb(feeManager.currentFeeOptions.luxury); - } + //set fee here + BRWalletManager.getInstance().setFeePerKb(FeeManager.getInstance().getCurrentFeeValue()); } if (!pm.isCreated()) { diff --git a/app/src/test/java/com/brainwallet/tools/database/DatabaseTests.kt b/app/src/test/java/com/brainwallet/tools/database/DatabaseTests.kt index 9a3a7d4f..3b8821d0 100644 --- a/app/src/test/java/com/brainwallet/tools/database/DatabaseTests.kt +++ b/app/src/test/java/com/brainwallet/tools/database/DatabaseTests.kt @@ -68,7 +68,6 @@ class DatabaseTests { // Assert.assertSame(BRConstants._20201118_DTGS,"did_tap_get_support"); // Assert.assertSame(BRConstants._20200217_DUWP,"did_unlock_with_pin"); // Assert.assertSame(BRConstants._20200217_DUWB,"did_unlock_with_biometrics"); -// Assert.assertSame(BRConstants._20200301_DUDFPK,"did_use_default_fee_per_kb"); // Assert.assertSame(BRConstants._20201121_SIL,"started_IFPS_lookup"); // Assert.assertSame(BRConstants._20201121_DRIA,"did_resolve_IPFS_address"); // Assert.assertSame(BRConstants._20201121_FRIA,"failed_resolve_IPFS_address"); diff --git a/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt b/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt index 82eabe93..5779b8df 100644 --- a/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt +++ b/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt @@ -43,7 +43,6 @@ class BRConstantsTest { assertSame(BRConstants._20201118_DTGS,"did_tap_get_support"); assertSame(BRConstants._20200217_DUWP,"did_unlock_with_pin"); assertSame(BRConstants._20200217_DUWB,"did_unlock_with_biometrics"); - assertSame(BRConstants._20200301_DUDFPK,"did_use_default_fee_per_kb"); assertSame(BRConstants._20201121_SIL,"started_IFPS_lookup"); assertSame(BRConstants._20201121_DRIA,"did_resolve_IPFS_address"); assertSame(BRConstants._20201121_FRIA,"failed_resolve_IPFS_address"); @@ -128,7 +127,6 @@ class BRConstantsTest { // Assert.assertSame(BRConstants._20201118_DTGS,"did_tap_get_support"); // Assert.assertSame(BRConstants._20200217_DUWP,"did_unlock_with_pin"); // Assert.assertSame(BRConstants._20200217_DUWB,"did_unlock_with_biometrics"); -// Assert.assertSame(BRConstants._20200301_DUDFPK,"did_use_default_fee_per_kb"); // Assert.assertSame(BRConstants._20201121_SIL,"started_IFPS_lookup"); // Assert.assertSame(BRConstants._20201121_DRIA,"did_resolve_IPFS_address"); // Assert.assertSame(BRConstants._20201121_FRIA,"failed_resolve_IPFS_address"); From c161fedb924a437b22b6b905ada4303a0ed51011 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 25 May 2025 15:48:06 +0100 Subject: [PATCH 033/116] build bump --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 290ed2dd..bfc2e94d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202505191 - versionName = "v4.5.3" + versionCode = 202505251 + versionName = "v4.5.4" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") From 63d7494d3e476e60fe645523b954fd004276638a Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Mon, 26 May 2025 17:04:48 +0700 Subject: [PATCH 034/116] chore: open bread activity first then open moonpay widget (#88) --- .../com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt index 97260328..89fd9473 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt @@ -149,6 +149,8 @@ fun BuyLitecoinScreen( modifier = Modifier.align(Alignment.BottomCenter), enabled = loadingState.visible.not(), onClick = { + //open bread activity first then open moonpay widget + LegacyNavigation.restartBreadActivity(context) LegacyNavigation.showMoonPayWidget( context = context, params = mapOf( From f09eb286c60f23ad52f1400ef7f29118f27c7c99 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Thu, 29 May 2025 14:16:53 +0700 Subject: [PATCH 035/116] Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test --- .circleci/config.yml | 139 ++++++++++-- Gemfile.lock | 2 + .../flow/RecoverWalletScreenGrabsTest.kt | 205 ++++++++++++------ .../java/com/brainwallet/BrainwalletApp.kt | 4 +- .../ui/composable/PasscodeKeypad.kt | 3 +- .../home/composable/HomeSettingDrawerSheet.kt | 13 +- .../settingsrows/LockSettingRowItem.kt | 3 + .../ui/screens/home/receive/ReceiveDialog.kt | 6 +- .../ui/screens/welcome/WelcomeScreen.kt | 2 + app/src/main/res/menu/bottom_nav_menu.xml | 12 +- .../brainwallet/BrainwalletScreengrabApp.kt | 26 ++- fastlane/Fastfile | 6 +- 12 files changed, 317 insertions(+), 104 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1ad5baa3..c074e195 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,60 @@ version: 2.1 orbs: - android: circleci/android@3.0.2 + android: circleci/android@3.1.0 + ruby: circleci/ruby@2.5.3 + +# Define reusable commands +commands: + setup_environment: + description: "Sets up the basic environment for all jobs (checkout, credentials, submodules)" + steps: + - checkout + - run: + name: "Setup environment..." + command: "echo Setting up environment for brainwallet-android!" + - run: + name: "Create google-services.json from env" + command: | + mkdir -p app + echo "$GOOGLE_SERVICES_JSON" | base64 --decode > app/google-services.json + ls -la app/google-services.json + - run: + name: "create service-data.json from env" + command: | + mkdir -p app/src/main/assets + echo "$SERVICE_DATA_JSON" | base64 --decode > app/src/main/assets/service-data.json + ls -la app/src/main/assets/service-data.json + - run: + name: "Create keystore files from env" + command: | + echo "$DEBUG_STORE_FILE" | base64 --decode > debug.keystore + echo "$RELEASE_STORE_FILE" | base64 --decode > release.keystore + ls -la *.keystore + - run: + name: "Create local.properties file" + command: | + cat > local.properties \<< EOL + #adjust with your location + DEBUG_STORE_FILE=${CIRCLE_WORKING_DIRECTORY}/debug.keystore + DEBUG_STORE_PASSWORD=${DEBUG_STORE_PASSWORD} + DEBUG_KEY_ALIAS=${DEBUG_KEY_ALIAS} + DEBUG_KEY_PASSWORD=${DEBUG_KEY_PASSWORD} + + #adjust with your location + RELEASE_STORE_FILE=${CIRCLE_WORKING_DIRECTORY}/release.keystore + RELEASE_STORE_PASSWORD=${RELEASE_STORE_PASSWORD} + RELEASE_KEY_ALIAS=${RELEASE_KEY_ALIAS} + RELEASE_KEY_PASSWORD=${RELEASE_KEY_PASSWORD} + + # screengrab paperkey + SCREENGRAB_PAPERKEY=${SCREENGRAB_PAPERKEY} + EOL + ls && cat local.properties + - run: + name: "Initialize submodule" + command: "git submodule init && git submodule update --init --recursive" + - android/restore_gradle_cache # Define a job to be invoked later in a workflow. # See: https://circleci.com/docs/2.0/configuration-reference/#jobs @@ -14,23 +67,7 @@ jobs: resource_class: large tag: 2024.07.1-ndk steps: - - checkout - - run: - name: "brainwallet-android unit test setup..." - command: "echo Building tests for brainwallet-android! && ls" - - run: - name: "Default for gradle.properties" - command: "echo \"RELEASE_STORE_FILE=/\nRELEASE_STORE_PASSWORD=\nRELEASE_KEY_ALIAS=\nRELEASE_KEY_PASSWORD=\nandroid.useAndroidX=true\nandroid.enableJetifier=true\" >> gradle.properties && ls && cat gradle.properties" - - run: - name: "Initialize submodule" - command: "git submodule init && git submodule update --init --recursive" - - run: - name: "Export google-services.json to env" - command: echo 'export $GOOGLE_SERVICES_JSON="$GOOGLE_SERVICES_JSON"' >> $BASH_ENV - - run: - name: "decode $GOOGLE_SERVICES_JSON to google-services.json" - command: echo "$GOOGLE_SERVICES_JSON" | base64 --decode > app/google-services.json - - android/restore_gradle_cache + - setup_environment - run: name: "Execute Unit Test" command: ./gradlew testBrainwalletDebugUnitTest @@ -46,6 +83,57 @@ jobs: - store_artifacts: path: ~/test-results/junit + screengrab: + executor: + name: android/android_machine + resource_class: large + tag: default + steps: + - setup_environment + - ruby/install: + version: '3.2.0' + - ruby/install-deps + - run: + name: "Install fastlane" + command: | + gem install bundler + bundle install + - android/create_avd: + avd_name: bw_avd + install: true + system_image: system-images;android-34;google_apis;x86_64 + additional_args: '-d "pixel_7_pro"' + - android/start_emulator: + avd_name: bw_avd + no_window: true + memory: 4096 + delay_adb: true + run_logcat: true + # additional_args: "-skin 1080x1920 -memory 2048" + post_emulator_launch_assemble_command: | + # bundle exec fastlane android build_and_screengrab + echo "skipping assemble command, as we only need the emulator running for screengrab" + - run: + name: "Wait for emulator to boot and set PIN" + command: | + echo "Waiting for emulator to boot..." + timeout 300 sh -c 'until adb shell getprop sys.boot_completed | grep -m 1 "1"; do sleep 5; done' + echo "Emulator is ready!" + adb shell svc power stayon true + adb shell locksettings set-pin 123456 + adb shell input keyevent 82 + sleep 5 + - run: + name: "Run Screengrab" + command: | + bundle exec fastlane android build_and_screengrab + - run: + name: "List fastlane android contents" + command: ls -R fastlane/android/ + - android/save_gradle_cache + - store_artifacts: + path: fastlane/metadata/android/ + destination: android-screenshots # Invoke jobs via workflows # See: https://circleci.com/docs/2.0/configuration-reference/#workflows @@ -53,3 +141,18 @@ workflows: test-and-build: jobs: - unit-test +# - screengrab: +# requires: +# - unit-test + + # Daily scheduled screengrab workflow + # daily-screengrab: + # triggers: + # - schedule: + # cron: "0 0 * * *" # Run at midnight UTC every day + # filters: + # branches: + # only: + # - develop # Adjust to your main branch name + # jobs: + # - screengrab diff --git a/Gemfile.lock b/Gemfile.lock index f322ed56..03d4f21e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -214,6 +214,8 @@ GEM PLATFORMS arm64-darwin-23 arm64-darwin-24 + x86-linux + x86_64-linux DEPENDENCIES fastlane diff --git a/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt b/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt index 30060516..56e381e6 100644 --- a/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt +++ b/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt @@ -1,33 +1,46 @@ package flow import android.Manifest +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.hasTestTag import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onChild import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.performClick +import androidx.compose.ui.test.performScrollTo +import androidx.compose.ui.test.performScrollToNode import androidx.compose.ui.test.performTextInput import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions.click import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.espresso.matcher.ViewMatchers.withText import androidx.test.filters.LargeTest import androidx.test.platform.app.InstrumentationRegistry import androidx.test.rule.GrantPermissionRule import androidx.test.uiautomator.UiDevice -import com.brainwallet.BuildConfig import com.brainwallet.R +import com.brainwallet.test.BuildConfig import com.brainwallet.ui.BrainwalletActivity +import org.junit.After +import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 +import timber.log.Timber import tools.fastlane.screengrab.FalconScreenshotStrategy import tools.fastlane.screengrab.Screengrab +import tools.fastlane.screengrab.cleanstatusbar.BluetoothState +import tools.fastlane.screengrab.cleanstatusbar.CleanStatusBar +import tools.fastlane.screengrab.cleanstatusbar.IconVisibility +import tools.fastlane.screengrab.cleanstatusbar.MobileDataType import tools.fastlane.screengrab.locale.LocaleTestRule /** * TODO: revisit this, since breaking with new navigation + * + * this will require pixel 7 pro */ @RunWith(JUnit4::class) @LargeTest @@ -47,23 +60,47 @@ class RecoverWalletScreenGrabsTest { @get:Rule val composeTestRule = createAndroidComposeRule() + private val uiDevice + get() = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + + @Before + fun setUp() { + CleanStatusBar() + .setBluetoothState(BluetoothState.DISCONNECTED) + .setMobileNetworkDataType(MobileDataType.LTE) + .setWifiVisibility(IconVisibility.HIDE) + .setShowNotifications(false) + .setClock("0900") + .setBatteryLevel(100) + .enable() + } + + @After + fun tearDown() { + CleanStatusBar.disable() + } + + + @OptIn(ExperimentalTestApi::class) @Test fun onRecoverFlowSuccess() { + composeTestRule.activityRule.scenario.onActivity { Screengrab.setDefaultScreenshotStrategy(FalconScreenshotStrategy(it)) } - val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) + waitUntilReady() - Screengrab.screenshot("1_intro_screen") + uiDevice.waitForIdle(60_000) + composeTestRule.waitForIdle() - onView(withId(R.id.button_recover_wallet)).perform(click()) + Screengrab.screenshot("1_welcome_screen") - Screengrab.screenshot("2_recover_screen") + composeTestRule.onNode(hasTestTag("buttonRestore")).performClick() - onView(withId(R.id.send_button)).perform(click()) //actually next button + uiDevice.waitForIdle() - Screengrab.screenshot("3_input_paperkey_screen") + Screengrab.screenshot("2_input_words_screen") //seed words input val editTextTags = (0..11).map { index -> "textFieldSeedWord$index" } @@ -71,123 +108,159 @@ class RecoverWalletScreenGrabsTest { val paperKey = BuildConfig.SCREENGRAB_PAPERKEY editTextTags.zip(paperKey).forEachIndexed { index, (textFieldTag, value) -> - device.waitForIdle(100) + uiDevice.waitForIdle() val textForTyping = value.dropLast(1) composeTestRule.onNodeWithTag(textFieldTag).onChild().performTextInput(textForTyping) composeTestRule.onNodeWithText(value).performClick() - } - composeTestRule.onNodeWithTag("buttonRestore").performClick() + Screengrab.screenshot("3_input_words_screen_2") - device.waitForIdle(300) + composeTestRule.onNodeWithTag("buttonRestore").performScrollTo() + composeTestRule.onNodeWithTag("buttonRestore").assertExists() + composeTestRule.onNodeWithTag("buttonRestore").performClick() - Screengrab.screenshot("4_input_paperkey_screen_2") + uiDevice.waitForIdle() - Screengrab.screenshot("5_setpin_screen") + composeTestRule.waitUntilAtLeastOneExists(hasTestTag("keypad1")) - repeat(6) { - onView(withId(R.id.num1)).perform(click()) + repeat(4) { + uiDevice.waitForIdle() + composeTestRule.onNodeWithTag("keypad1").assertExists() + composeTestRule.onNodeWithTag("keypad1").performClick() } - Screengrab.screenshot("6_setpin_confirm_screen") + Screengrab.screenshot("4_set_passcode_screen") - repeat(6) { - onView(withId(R.id.num1)).perform(click()) - } + composeTestRule.waitUntilAtLeastOneExists(hasTestTag("keypad1")) - device.waitForIdle(3000) + repeat(4) { + uiDevice.waitForIdle() + composeTestRule.onNodeWithTag("keypad1").assertExists() + composeTestRule.onNodeWithTag("keypad1").performClick() + } - Screengrab.screenshot("7_main_screen") + Screengrab.screenshot("5_set_passcode_confirm_screen") - onView(withId(R.id.menuBut)).perform(click()) + uiDevice.waitForIdle() - Screengrab.screenshot("8_menu_bottom_sheet") + Thread.sleep(1000) - onView(withText(R.string.MenuButton_security)).perform(click()) + Screengrab.screenshot("6_main_screen") - Screengrab.screenshot("9_security_center_screen") + //setting drawer + onView(withId(R.id.menuBut)).perform(click()) - onView(withId(R.id.close_button)).perform(click()) + Screengrab.screenshot("7_setting_drawer_open") - onView(withId(R.id.menuBut)).perform(click()) + composeTestRule.onNodeWithTag("settingSecurity").assertExists() + composeTestRule.onNodeWithTag("settingSecurity").performClick() - onView(withText(R.string.MenuButton_settings)).perform(click()) + composeTestRule.waitForIdle() - Screengrab.screenshot("10_settings_screen") + Screengrab.screenshot("8_setting_drawer_open_security") - onView(withText(R.string.settings_show_seed)).perform(click()) + composeTestRule.waitForIdle() - onView(withId(R.id.show_seed_button)).perform(click()) + composeTestRule.onNodeWithTag("settingLanguage").assertExists() + composeTestRule.onNodeWithTag("settingLanguage").performClick() - Screengrab.screenshot("11_settings_seed_phrase") + composeTestRule.waitForIdle() - device.pressBack() + Screengrab.screenshot("9_setting_drawer_open_language") - onView(withText(R.string.Settings_wipe)).perform(click()) + composeTestRule.waitForIdle() - Screengrab.screenshot("12_settings_recover_another_wallet") + composeTestRule.onNodeWithTag("settingCurrency").assertExists() + composeTestRule.onNodeWithTag("settingCurrency").performClick() - onView(withId(R.id.close_button)).perform(click()) + composeTestRule.waitForIdle() - onView(withText(R.string.Settings_languages)).perform(click()) + Screengrab.screenshot("10_setting_drawer_open_currency") - Screengrab.screenshot("13_settings_language") + composeTestRule.waitForIdle() - device.pressBack() + composeTestRule.onNodeWithTag("settingGames").assertExists() + composeTestRule.onNodeWithTag("settingGames").performClick() - onView(withText(R.string.Settings_currency)).perform(click()) + composeTestRule.waitForIdle() - Screengrab.screenshot("14_settings_currency") + Screengrab.screenshot("11_setting_drawer_open_games") - device.pressBack() + composeTestRule.waitForIdle() - onView(withText(R.string.Settings_sync)).perform(click()) + composeTestRule.onNodeWithTag("lazyColumnSetting").performScrollToNode(hasTestTag("settingBlockchain")) + composeTestRule.onNodeWithTag("settingBlockchain").assertExists() + composeTestRule.onNodeWithTag("settingBlockchain").performClick() - Screengrab.screenshot("15_settings_sync") + composeTestRule.waitForIdle() - device.pressBack() + Screengrab.screenshot("12_setting_drawer_open_blockchain") - onView(withText(R.string.Settings_shareData)).perform(click()) + composeTestRule.waitForIdle() - Screengrab.screenshot("16_settings_share_anonymous_data") + composeTestRule.onNodeWithTag("lazyColumnSetting").performScrollToNode(hasTestTag("settingLock")) + composeTestRule.onNodeWithTag("settingLock").assertExists() + composeTestRule.onNodeWithTag("settingLock").performClick() - device.pressBack() + composeTestRule.waitForIdle() - onView(withText(R.string.Settings_about)).perform(click()) + Screengrab.screenshot("13_setting_drawer_lock") - Screengrab.screenshot("17_settings_about") + repeat(4) { + uiDevice.waitForIdle() + composeTestRule.onNodeWithTag("keypad1").assertExists() + composeTestRule.onNodeWithTag("keypad1").performClick() + } - device.pressBack() + uiDevice.waitForIdle() + Thread.sleep(1000) - device.pressBack() + //tx send ui onView(withId(R.id.nav_send)).perform(click()) onView(withId(R.id.amount_edit)).perform(click()) - Screengrab.screenshot("18_transaction_send") + Screengrab.screenshot("14_transaction_send") onView(withId(R.id.close_button)).perform(click()) - onView(withId(R.id.nav_receive)).perform(click()) - - Screengrab.screenshot("19_transaction_receive") - onView(withId(R.id.close_button)).perform(click()) - - onView(withId(R.id.nav_buy)).perform(click()) - - Screengrab.screenshot("20_transaction_buy") + //tx buy/receive ui + onView(withId(R.id.nav_receive)).perform(click()) - onView(withId(R.id.nav_history)).perform(click()) + Screengrab.screenshot("15_transaction_buy_receive") - onView(withId(R.id.menuBut)).perform(click()) + composeTestRule.onNodeWithTag("buttonClose").performClick() - onView(withText(R.string.MenuButton_lock)).perform(click()) + uiDevice.waitForIdle() - Screengrab.screenshot("21_lock_screen") + } + private fun waitUntilReady() { + var attempts = 0 + val maxAttempts = 5 + + while (attempts < maxAttempts) { + try { + composeTestRule.waitUntil(timeoutMillis = 60_000) { + try { + composeTestRule.onRoot().fetchSemanticsNode() + true + } catch (e: Exception) { + Timber.e("[waitForComposeHierarchy] Error1 : ${e.message}", e) + false + } + } + return + } catch (e: Exception) { + Timber.e("[waitForComposeHierarchy] Error2 : ${e.message}", e) + attempts++ + if (attempts >= maxAttempts) throw e + Thread.sleep(1000) + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/BrainwalletApp.kt b/app/src/main/java/com/brainwallet/BrainwalletApp.kt index 237bf5a1..03fd029e 100644 --- a/app/src/main/java/com/brainwallet/BrainwalletApp.kt +++ b/app/src/main/java/com/brainwallet/BrainwalletApp.kt @@ -31,7 +31,7 @@ import java.util.Timer import java.util.TimerTask import java.util.concurrent.atomic.AtomicInteger -class BrainwalletApp : Application() { +open class BrainwalletApp : Application() { override fun onCreate() { super.onCreate() @@ -73,7 +73,7 @@ class BrainwalletApp : Application() { appsFlyerLib.start(this) } - protected fun initializeModule() { + protected open fun initializeModule() { startKoin { androidLogger(if (BuildConfig.DEBUG) Level.DEBUG else Level.ERROR) androidContext(this@BrainwalletApp) diff --git a/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt b/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt index 4fac2149..a0607cbc 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt @@ -17,6 +17,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp @Composable @@ -34,7 +35,7 @@ fun PasscodeKeypad( repeat(9) { index -> val number = index + 1 CircleButton( - modifier = modifierCircleButton, + modifier = modifierCircleButton.testTag("keypad$number"), onClick = { onEvent.invoke(PasscodeKeypadEvent.OnPressed(number)) }, diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index b3559014..d96cda42 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.AbstractComposeView import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.coroutineScope @@ -76,6 +77,7 @@ fun HomeSettingDrawerSheet( ) { LazyColumn( modifier = Modifier + .testTag("lazyColumnSetting") .weight(1f) .padding(top = headerPadding.dp) .wrapContentHeight(align = Alignment.Top) @@ -83,6 +85,7 @@ fun HomeSettingDrawerSheet( item { SecurityDetail( modifier = Modifier + .testTag("settingSecurity") .fillMaxSize() .wrapContentHeight(), shareAnalyticsDataEnabled = state.shareAnalyticsDataEnabled, @@ -94,6 +97,7 @@ fun HomeSettingDrawerSheet( item { LanguageDetail( modifier = Modifier + .testTag("settingLanguage") .fillMaxSize() .wrapContentHeight(), selectedLanguage = state.selectedLanguage, @@ -110,6 +114,7 @@ fun HomeSettingDrawerSheet( item { CurrencyDetail( modifier = Modifier + .testTag("settingCurrency") .fillMaxSize() .wrapContentHeight(), selectedCurrency = state.selectedCurrency, @@ -125,6 +130,7 @@ fun HomeSettingDrawerSheet( item { GamesDetail( modifier = Modifier + .testTag("settingGames") .fillMaxSize() .wrapContentHeight() ) @@ -132,6 +138,7 @@ fun HomeSettingDrawerSheet( item { LitecoinBlockchainDetail( modifier = Modifier + .testTag("settingBlockchain") .fillMaxSize() .wrapContentHeight(), selectedCurrency = state.selectedCurrency, @@ -144,6 +151,7 @@ fun HomeSettingDrawerSheet( } item { SettingRowItem( + modifier = Modifier.testTag("settingSupport"), title = stringResource(R.string.settings_title_support), description = "brainwallet.co/support.html", onClick = { @@ -155,6 +163,7 @@ fun HomeSettingDrawerSheet( } item { SettingRowItem( + modifier = Modifier.testTag("settingSocialMedia"), title = stringResource(R.string.settings_title_social_media), description = "linktr.ee/brainwallet", onClick = { @@ -166,7 +175,9 @@ fun HomeSettingDrawerSheet( } item { // Lock / Unlock - LockSettingRowItem { + LockSettingRowItem( + modifier = Modifier.testTag("settingLock"), + ) { viewModel.onEvent(SettingsEvent.OnToggleLock) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt index 8f0ab2eb..871b466f 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt @@ -4,14 +4,17 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Lock import androidx.compose.material3.Icon import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.brainwallet.R @Composable fun LockSettingRowItem( + modifier: Modifier = Modifier, onClick: () -> Unit, ) { SettingRowItem( + modifier = modifier, title = stringResource(R.string.settings_title_lock), onClick = onClick ) { diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt index 291015e2..8292904c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt @@ -52,6 +52,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType @@ -152,7 +153,10 @@ fun ReceiveDialog( } }, actions = { - IconButton(onClick = onDismissRequest) { + IconButton( + modifier = Modifier.testTag("buttonClose"), + onClick = onDismissRequest + ) { Icon( Icons.Default.Close, contentDescription = stringResource(R.string.AccessibilityLabels_close), diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index f4d8ba3a..b0370f4b 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -26,6 +26,7 @@ import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight @@ -202,6 +203,7 @@ fun WelcomeScreen( }, shape = RoundedCornerShape(50), modifier = Modifier + .testTag("buttonRestore") .padding(horizontal = leadTrailPadding.dp) .padding(vertical = rowPadding.dp) .height(activeRowHeight.dp) diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml index dc0df45e..947c8a79 100644 --- a/app/src/main/res/menu/bottom_nav_menu.xml +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -1,18 +1,18 @@ - - + + Date: Thu, 29 May 2025 15:45:24 +0700 Subject: [PATCH 036/116] fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated --- .../ui/screens/welcome/WelcomeScreen.kt | 212 +++++++++--------- 1 file changed, 110 insertions(+), 102 deletions(-) diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index b0370f4b..f7c32e61 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -3,6 +3,7 @@ package com.brainwallet.ui.screens.welcome import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -10,10 +11,12 @@ import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Card +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -26,6 +29,7 @@ import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource @@ -61,7 +65,8 @@ fun WelcomeScreen( val configuration = LocalConfiguration.current val screenHeight = configuration.screenHeightDp - var mainBoxFactor = 0.5 + val density = LocalDensity.current.density + val mainBoxFactor = if (density > 2) 0.5 else 0.4 val thirdOfScreenHeight = (screenHeight * mainBoxFactor).toInt() LaunchedEffect(Unit) { @@ -73,11 +78,11 @@ fun WelcomeScreen( val buttonFontSize = 24 val thinButtonFontSize = 22 val toggleButtonSize = 45 - val leadTrailPadding = 18 + val leadTrailPadding = 8 val halfLeadTrailPadding = leadTrailPadding / 2 val doubleLeadTrailPadding = leadTrailPadding * 2 val rowPadding = 8 - val versionPadding = 12 + val versionPadding = 8 val activeRowHeight = 58 val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.welcomeemoji20250212)) @@ -86,16 +91,12 @@ fun WelcomeScreen( iterations = LottieConstants.IterateForever ) - Column( + Box( modifier = Modifier .fillMaxSize() - .background(BrainwalletTheme.colors.surface), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.SpaceBetween + .background(BrainwalletTheme.colors.surface) + .verticalScroll(rememberScrollState()), ) { - - Spacer(modifier = Modifier.weight(0.2f)) - Image( painterResource(R.drawable.brainwallet_logotype_white), contentDescription = "brainwallet_logotype_white", @@ -104,124 +105,131 @@ fun WelcomeScreen( BrainwalletTheme.colors.content, ), modifier = Modifier + .align(Alignment.TopCenter) .fillMaxWidth() .padding(doubleLeadTrailPadding.dp) ) // Animation Placeholder - Card( + LottieAnimation( modifier = Modifier + .offset(y = 120.dp) .fillMaxWidth() - .height(thirdOfScreenHeight.dp) .padding(leadTrailPadding.dp) - ) { - - LottieAnimation( - modifier = Modifier.background(BrainwalletTheme.colors.surface), - composition = composition, - contentScale = ContentScale.Fit, - progress = { progress } - ) - } - // TODO: implement later, for now just comment this - Row( - modifier = Modifier - .fillMaxWidth() - .height(activeRowHeight.dp) - .padding(horizontal = leadTrailPadding.dp) - .padding(vertical = rowPadding.dp), - horizontalArrangement = Arrangement.SpaceEvenly + .background( + BrainwalletTheme.colors.surface, + BrainwalletTheme.shapes.large + ) + .height(thirdOfScreenHeight.dp) + .clip(BrainwalletTheme.shapes.large), + composition = composition, + contentScale = ContentScale.FillWidth, + alignment = Alignment.Center, + progress = { progress } + ) + Column( + modifier = Modifier.align(Alignment.BottomCenter), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(8.dp) ) { - - BrainwalletButton( + Row( modifier = Modifier - .weight(1f) - .fillMaxWidth(), - onClick = { - viewModel.onEvent(WelcomeEvent.OnLanguageSelectorButtonClick) - } + .fillMaxWidth() + .height(activeRowHeight.dp) + .padding(horizontal = leadTrailPadding.dp) + .padding(vertical = rowPadding.dp), + horizontalArrangement = Arrangement.SpaceEvenly + ) { - Text( - text = state.selectedLanguage.title, - fontSize = 14.sp, - color = BrainwalletTheme.colors.content + + BrainwalletButton( + modifier = Modifier + .weight(1f) + .fillMaxWidth(), + onClick = { + viewModel.onEvent(WelcomeEvent.OnLanguageSelectorButtonClick) + } + ) { + Text( + text = state.selectedLanguage.title, + fontSize = 14.sp, + color = BrainwalletTheme.colors.content + ) + } + + Spacer(modifier = Modifier.weight(0.1f)) + + DarkModeToggleButton( + modifier = Modifier + .width(toggleButtonSize.dp) + .aspectRatio(1f), + checked = state.darkMode, + onCheckedChange = { + viewModel.onEvent(WelcomeEvent.OnToggleDarkMode) + } ) - } - Spacer(modifier = Modifier.weight(0.1f)) + Spacer(modifier = Modifier.weight(0.1f)) - DarkModeToggleButton( - modifier = Modifier - .width(toggleButtonSize.dp) - .aspectRatio(1f), - checked = state.darkMode, - onCheckedChange = { - viewModel.onEvent(WelcomeEvent.OnToggleDarkMode) + BrainwalletButton( + modifier = Modifier + .weight(1f) + .fillMaxWidth(), + onClick = { viewModel.onEvent(WelcomeEvent.OnFiatButtonClick) } + ) { + Text( + text = state.selectedCurrency.name, + fontSize = 14.sp, + color = BrainwalletTheme.colors.content + ) } - ) - - Spacer(modifier = Modifier.weight(0.1f)) - BrainwalletButton( + } + // Ready Button + BorderedLargeButton( + onClick = { + onNavigate.invoke(UiEffect.Navigate(Route.Ready)) + }, + shape = RoundedCornerShape(50), modifier = Modifier - .weight(1f) - .fillMaxWidth(), - onClick = { viewModel.onEvent(WelcomeEvent.OnFiatButtonClick) } + .padding(horizontal = leadTrailPadding.dp) + .height(activeRowHeight.dp) + ) { Text( - text = state.selectedCurrency.name, - fontSize = 14.sp, - color = BrainwalletTheme.colors.content + text = stringResource(R.string.ready), + fontSize = buttonFontSize.sp, + fontWeight = FontWeight.SemiBold, ) } - } - // Ready Button - BorderedLargeButton( - onClick = { - onNavigate.invoke(UiEffect.Navigate(Route.Ready)) - }, - shape = RoundedCornerShape(50), - modifier = Modifier - .padding(horizontal = leadTrailPadding.dp) - .padding(vertical = rowPadding.dp) - .height(activeRowHeight.dp) - - ) { - Text( - text = stringResource(R.string.ready), - fontSize = buttonFontSize.sp, - fontWeight = FontWeight.SemiBold, - ) - } + // Restore Button + BorderedLargeButton( + onClick = { + onNavigate.invoke(UiEffect.Navigate(Route.InputWords())) + }, + shape = RoundedCornerShape(50), + modifier = Modifier + .testTag("buttonRestore") + .padding(horizontal = leadTrailPadding.dp) + .height(activeRowHeight.dp) + .clip(RoundedCornerShape(50)) + ) { + Text( + text = stringResource(R.string.restore), + fontSize = thinButtonFontSize.sp, + fontWeight = FontWeight.Thin, + ) + } - // Restore Button - BorderedLargeButton( - onClick = { - onNavigate.invoke(UiEffect.Navigate(Route.InputWords())) - }, - shape = RoundedCornerShape(50), - modifier = Modifier - .testTag("buttonRestore") - .padding(horizontal = leadTrailPadding.dp) - .padding(vertical = rowPadding.dp) - .height(activeRowHeight.dp) - .clip(RoundedCornerShape(50)) - ) { Text( - text = stringResource(R.string.restore), - fontSize = thinButtonFontSize.sp, - fontWeight = FontWeight.Thin, + modifier = Modifier.padding(vertical = versionPadding.dp), + text = BRConstants.APP_VERSION_NAME_CODE, + fontSize = 13.sp, + color = BrainwalletTheme.colors.content ) } - - Text( modifier = Modifier - .padding(vertical = versionPadding.dp), - text = BRConstants.APP_VERSION_NAME_CODE, - fontSize = 13.sp, - color = BrainwalletTheme.colors.content - ) } //language selector From a9c4a63d604a8c7e6252757766a7c26168fd5db5 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Thu, 29 May 2025 17:35:10 +0700 Subject: [PATCH 037/116] fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout --- .../brainwallet/ui/composable/SeedWordItem.kt | 18 ++-- .../ui/composable/SeedWordsLayout.kt | 27 ++++++ .../yourseedproveit/YourSeedProveItScreen.kt | 83 ++++++++----------- .../yourseedwords/YourSeedWordsScreen.kt | 31 +++---- app/src/main/res/values/strings.xml | 1 + 5 files changed, 82 insertions(+), 78 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/ui/composable/SeedWordsLayout.kt diff --git a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt index 040457fd..202f21f8 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions @@ -22,7 +21,6 @@ import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text -import androidx.compose.material3.Typography import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -32,18 +30,12 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.compose.ui.window.PopupProperties -import com.brainwallet.ui.screens.welcome.WelcomeScreen import com.brainwallet.ui.theme.BrainwalletTheme import com.brainwallet.ui.theme.chilli @@ -56,10 +48,14 @@ fun SeedWordItem( ) { SeedWordItemBox(modifier = modifier) { Text( - modifier = Modifier.padding(vertical = 12.dp), + modifier = Modifier + .padding(vertical = 12.dp) + .weight(1f), text = label, style = MaterialTheme.typography.bodyMedium, - color = if (isError) chilli else BrainwalletTheme.colors.content + color = if (isError) chilli else BrainwalletTheme.colors.content, + overflow = TextOverflow.Ellipsis, + maxLines = 1 ) trailingIcon?.let { icon -> Spacer(modifier = Modifier.width(8.dp)) diff --git a/app/src/main/java/com/brainwallet/ui/composable/SeedWordsLayout.kt b/app/src/main/java/com/brainwallet/ui/composable/SeedWordsLayout.kt new file mode 100644 index 00000000..a8f3d98c --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/SeedWordsLayout.kt @@ -0,0 +1,27 @@ +package com.brainwallet.ui.composable + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyGridScope +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@Composable +fun SeedWordsLayout( + modifier: Modifier = Modifier, + content: LazyGridScope.() -> Unit +) { + LazyVerticalGrid( + modifier = modifier + .height(220.dp), + columns = GridCells.Fixed(3), //fixed 3 + contentPadding = PaddingValues(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + horizontalArrangement = Arrangement.spacedBy(8.dp), + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt index 171186ab..214982a7 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt @@ -9,27 +9,24 @@ import android.content.ClipData import android.content.ClipDescription import android.media.MediaPlayer import android.view.View -import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.draganddrop.dragAndDropSource import androidx.compose.foundation.draganddrop.dragAndDropTarget import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi -import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.filled.Clear import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -60,6 +57,7 @@ import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.LargeButton import com.brainwallet.ui.composable.SeedWordItem +import com.brainwallet.ui.composable.SeedWordsLayout import org.koin.compose.koinInject @Composable @@ -72,7 +70,7 @@ fun YourSeedProveItScreen( val context = LocalContext.current /// Layout values - val columnPadding = 18 + val columnPadding = 12 val horizontalVerticalSpacing = 8 val spacerHeight = 48 val maxItemsPerRow = 3 @@ -104,23 +102,12 @@ fun YourSeedProveItScreen( } }) }, - floatingActionButton = { - if (state.orderCorrected.not()) { - FloatingActionButton( - onClick = { - viewModel.onEvent(YourSeedProveItEvent.OnClear) - } - ) { - Icon(Icons.Default.Clear, contentDescription = null) - } - } - } ) { paddingValues -> Column( modifier = Modifier + .fillMaxSize() .padding(paddingValues) .padding(columnPadding.dp) - .fillMaxSize() .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), @@ -138,17 +125,10 @@ fun YourSeedProveItScreen( ) ) - Spacer(modifier = Modifier.height(spacerHeight.dp)) - - FlowRow( - modifier = Modifier - .fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), - verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), - maxItemsInEachRow = maxItemsPerRow - ) { - state.correctSeedWords.values.forEachIndexed { index, (expectedWord, actualWord) -> + Spacer(modifier = Modifier.weight(0.1f)) + SeedWordsLayout { + itemsIndexed(items = state.correctSeedWords.values.toList()) { index: Int, (expectedWord, actualWord): SeedWordItem -> val label = if (expectedWord != actualWord && actualWord.isEmpty()) { "${index + 1}" } else { @@ -158,7 +138,6 @@ fun YourSeedProveItScreen( SeedWordItem( modifier = Modifier .fillMaxWidth() - .weight(1f) .dragAndDropTarget( shouldStartDragAndDrop = { event -> event @@ -195,17 +174,20 @@ fun YourSeedProveItScreen( Spacer(modifier = Modifier.weight(1f)) - AnimatedVisibility(visible = state.orderCorrected.not()) { - FlowRow( - modifier = Modifier - .fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), - verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), - maxItemsInEachRow = maxItemsPerRow - ) { - state.shuffledSeedWords.forEachIndexed { index, word -> + SeedWordsLayout { + itemsIndexed(items = state.shuffledSeedWords) { index, word -> + + val isWordUsedCorrectly = + state.correctSeedWords.values.any { (expectedWord, actualWord) -> + expectedWord == word && actualWord == word + } + + if (isWordUsedCorrectly) { + Box(modifier = Modifier.fillMaxWidth()) + } else { SeedWordItem( modifier = Modifier + .fillMaxWidth() .dragAndDropSource { detectTapGestures( onLongPress = { @@ -230,20 +212,25 @@ fun YourSeedProveItScreen( } ) } + + } } - AnimatedVisibility(visible = state.orderCorrected) { - LargeButton( - onClick = { + + LargeButton( + onClick = { + if (state.orderCorrected) { onNavigate.invoke(UiEffect.Navigate(Route.TopUp)) - }, - ) { - Text( - text = stringResource(R.string.game_and_sync), - style = MaterialTheme.typography.labelLarge - ) - } + } else { + viewModel.onEvent(YourSeedProveItEvent.OnClear) + } + }, + ) { + Text( + text = stringResource(if (state.orderCorrected) R.string.game_and_sync else R.string.reset_start_over).uppercase(), + style = MaterialTheme.typography.labelLarge + ) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt index c541f588..17bdaf18 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt @@ -5,12 +5,11 @@ package com.brainwallet.ui.screens.yourseedwords import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi -import androidx.compose.foundation.layout.FlowRow import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.grid.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons @@ -36,6 +35,7 @@ import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.LargeButton import com.brainwallet.ui.composable.SeedWordItem +import com.brainwallet.ui.composable.SeedWordsLayout import org.koin.compose.koinInject @Composable @@ -45,12 +45,11 @@ fun YourSeedWordsScreen( viewModel: YourSeedWordsViewModel = koinInject() ) { /// Layout values - val columnPadding = 16 + val columnPadding = 12 val horizontalVerticalSpacing = 8 - val spacerHeight = 48 - val maxItemsPerRow = 3 - val leadingCopyPadding = 16 - val detailLineHeight = 28 + val spacerHeight = 36 + val leadingCopyPadding = 8 + val detailLineHeight = 24 LaunchedEffect(Unit) { viewModel.uiEffect.collect { effect -> @@ -78,9 +77,9 @@ fun YourSeedWordsScreen( ) { paddingValues -> Column( modifier = Modifier + .fillMaxSize() .padding(paddingValues) .padding(columnPadding.dp) - .fillMaxSize() .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), @@ -102,16 +101,10 @@ fun YourSeedWordsScreen( ) ) - Spacer(modifier = Modifier.height(spacerHeight.dp)) + Spacer(modifier = Modifier.weight(0.1f)) - FlowRow( - modifier = Modifier - .fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), - verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), - maxItemsInEachRow = maxItemsPerRow - ) { - seedWords.forEachIndexed { index, word -> + SeedWordsLayout(modifier = Modifier.weight(1f)) { + itemsIndexed(items = seedWords) { index, word -> SeedWordItem( modifier = Modifier .fillMaxWidth() @@ -121,14 +114,14 @@ fun YourSeedWordsScreen( } } - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(0.1f)) Text( text = stringResource(R.string.blockchain_litecoin), style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.Center) ) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(0.2f)) LargeButton( onClick = { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f7c7deb0..12fca16d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -855,4 +855,5 @@ Buy / Receive Custom + Reset / Start Over From d8f08adf506c7166f1c930dc7c9da923c3e714d3 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 29 May 2025 04:29:26 -0700 Subject: [PATCH 038/116] tiny resizing (#94) --- .../java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index f7c32e61..845a9073 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -79,8 +79,6 @@ fun WelcomeScreen( val thinButtonFontSize = 22 val toggleButtonSize = 45 val leadTrailPadding = 8 - val halfLeadTrailPadding = leadTrailPadding / 2 - val doubleLeadTrailPadding = leadTrailPadding * 2 val rowPadding = 8 val versionPadding = 8 val activeRowHeight = 58 @@ -107,7 +105,8 @@ fun WelcomeScreen( modifier = Modifier .align(Alignment.TopCenter) .fillMaxWidth() - .padding(doubleLeadTrailPadding.dp) + .padding(horizontal = 55.dp) + .padding(vertical = 30.dp) ) // Animation Placeholder From ef935858b84faa6723120b009b0f7b58128c8a62 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 29 May 2025 12:32:00 +0100 Subject: [PATCH 039/116] code and version bump --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bfc2e94d..08429835 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202505251 - versionName = "v4.5.4" + versionCode = 202505291 + versionName = "v4.5.5" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") From 174d612e80724d5d4c1cc6f9bb03c8752ef39b72 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Fri, 30 May 2025 14:14:02 -0700 Subject: [PATCH 040/116] change break (#97) adds a android user agent and externalID --- .../main/java/com/brainwallet/navigation/LegacyNavigation.kt | 5 ++++- app/src/main/java/com/brainwallet/tools/util/Utils.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt index d38eaeb9..08bb8258 100644 --- a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt +++ b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt @@ -12,6 +12,7 @@ import com.brainwallet.R import com.brainwallet.data.source.RemoteApiSource import com.brainwallet.di.getKoinInstance import com.brainwallet.presenter.activities.BreadActivity +import com.brainwallet.tools.util.Utils import com.brainwallet.ui.BrainwalletActivity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -66,6 +67,7 @@ object LegacyNavigation { context.startActivity(it) } + @JvmOverloads @JvmStatic fun showMoonPayWidget( context: Context, @@ -73,7 +75,7 @@ object LegacyNavigation { isDarkMode: Boolean = true, ) { val remoteApiSource: RemoteApiSource = getKoinInstance() - + val agentString = Utils.getAgentString(context, "android/HttpURLConnection") val progressDialog = ProgressDialog(context).apply { setMessage(context.getString(R.string.loading)) setCancelable(false) @@ -86,6 +88,7 @@ object LegacyNavigation { remoteApiSource.getMoonpaySignedUrl( params = params.toMutableMap().apply { put("defaultCurrencyCode", "ltc") + put("externalTransactionId", agentString) put("currencyCode", "ltc") put("themeId", "main-v1.0.0") put("theme", if (isDarkMode) "dark" else "light") diff --git a/app/src/main/java/com/brainwallet/tools/util/Utils.java b/app/src/main/java/com/brainwallet/tools/util/Utils.java index fb03d0c3..21b556dd 100644 --- a/app/src/main/java/com/brainwallet/tools/util/Utils.java +++ b/app/src/main/java/com/brainwallet/tools/util/Utils.java @@ -171,6 +171,9 @@ public static void hideKeyboard(Context app) { public static String getAgentString(Context app, String cfnetwork) { int versionNumber = 0; + String deviceCode = Build.MANUFACTURER + "-|-" + Build.MODEL; + + if (app != null) { try { PackageInfo pInfo = app.getPackageManager().getPackageInfo(app.getPackageName(), 0); @@ -179,7 +182,7 @@ public static String getAgentString(Context app, String cfnetwork) { Timber.e(e); } } - return String.format(Locale.ENGLISH, "%s/%d %s Android/%s", "Brainwallet", versionNumber, cfnetwork, Build.VERSION.RELEASE); + return String.format(Locale.ENGLISH, "%s/%d %s Android/%s Device/%s", "Brainwallet", versionNumber, cfnetwork, Build.VERSION.RELEASE, deviceCode); } public static String reverseHex(String hex) { From a4521d7028495031bb2ad208323b7a1b35517590 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Sat, 31 May 2025 13:19:07 +0700 Subject: [PATCH 041/116] build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) --- app/build.gradle.kts | 2 +- .../presenter/activities/BreadActivity.java | 7 +---- app/src/main/res/layout/activity_bread.xml | 2 +- app/src/main/res/menu/bottom_nav_menu.xml | 8 +----- app/src/main/res/menu/bottom_nav_menu_us.xml | 28 ------------------- 5 files changed, 4 insertions(+), 43 deletions(-) delete mode 100644 app/src/main/res/menu/bottom_nav_menu_us.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 08429835..326d7062 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,7 +20,7 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202505291 + versionCode = 202505311 versionName = "v4.5.5" multiDexEnabled = true diff --git a/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java index b210395c..2fd05ab0 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java @@ -421,7 +421,7 @@ private void initializeViews() { bottomNav = findViewById(R.id.bottomNav); bottomNav.getMenu().clear(); - bottomNav.inflateMenu(isInUsa() ? R.menu.bottom_nav_menu_us : R.menu.bottom_nav_menu); + bottomNav.inflateMenu(R.menu.bottom_nav_menu); balanceTxtV = findViewById(R.id.balanceTxtV); primaryPrice = findViewById(R.id.primary_price); @@ -447,11 +447,6 @@ public void onGlobalLayout() { balanceTxtV.append(":"); } - private boolean isInUsa() { - TelephonyManager telManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); - return "us".equals(telManager.getSimCountryIso()); - } - @Override public void onBalanceChanged(final long balance) { updateUI(); diff --git a/app/src/main/res/layout/activity_bread.xml b/app/src/main/res/layout/activity_bread.xml index 7ad85ca9..e17e37f7 100644 --- a/app/src/main/res/layout/activity_bread.xml +++ b/app/src/main/res/layout/activity_bread.xml @@ -146,7 +146,7 @@ android:layout_height="64dp" android:layout_alignParentBottom="true" app:labelVisibilityMode="labeled" - tools:menu="@menu/bottom_nav_menu_us" /> + tools:menu="@menu/bottom_nav_menu" /> diff --git a/app/src/main/res/menu/bottom_nav_menu.xml b/app/src/main/res/menu/bottom_nav_menu.xml index 947c8a79..e5323f61 100644 --- a/app/src/main/res/menu/bottom_nav_menu.xml +++ b/app/src/main/res/menu/bottom_nav_menu.xml @@ -17,12 +17,6 @@ android:id="@+id/nav_receive" android:enabled="true" android:icon="@drawable/ic_nav_receive" - android:title="@string/Button.receive" /> - - - - - - + android:title="@string/bottom_nav_item_buy_receive_title" /> \ No newline at end of file diff --git a/app/src/main/res/menu/bottom_nav_menu_us.xml b/app/src/main/res/menu/bottom_nav_menu_us.xml deleted file mode 100644 index 187ac237..00000000 --- a/app/src/main/res/menu/bottom_nav_menu_us.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file From 6fec1e25e9cf1f35d4737112351cac4b59f7e05e Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Mon, 2 Jun 2025 13:04:59 +0700 Subject: [PATCH 042/116] fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) --- .../tools/sqlite/CurrencyDataSource.java | 20 +++++++++++++++++++ .../home/receive/ReceiveDialogViewModel.kt | 3 +-- .../com/brainwallet/currency/CurrencyTests.kt | 7 +++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java b/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java index 7c15df6d..6640916f 100644 --- a/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java +++ b/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java @@ -89,6 +89,26 @@ public void putCurrencies(Collection currencyEntities) { } } + public List getCurrenciesForBuy() { + List supportedFiatCodes = Arrays.asList( + "AUD", + "BRL", + "CAD", + "CHF", + "EUR", + "GBP", + "IDR", + "MXN", + "NGN", + "TRY", + "USD", + "ZAR" + ); + return getAllCurrencies(true).stream() + .filter(currencyEntity -> supportedFiatCodes.contains(currencyEntity.code)) + .collect(Collectors.toList()); + } + public List getAllCurrencies(Boolean shouldBeFiltered) { List currencies = new ArrayList<>(); diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt index 80ab1984..ea6df431 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt @@ -49,8 +49,7 @@ class ReceiveDialogViewModel( it.copy( address = address, qrBitmap = QRUtils.generateQR(event.context, "litecoin:${address}"), - fiatCurrencies = CurrencyDataSource.getInstance(event.context) - .getAllCurrencies(true), + fiatCurrencies = CurrencyDataSource.getInstance(event.context).getCurrenciesForBuy(), ) } diff --git a/app/src/test/java/com/brainwallet/currency/CurrencyTests.kt b/app/src/test/java/com/brainwallet/currency/CurrencyTests.kt index 37b7e46a..6be7752e 100644 --- a/app/src/test/java/com/brainwallet/currency/CurrencyTests.kt +++ b/app/src/test/java/com/brainwallet/currency/CurrencyTests.kt @@ -50,6 +50,13 @@ class CurrencyTests { assertEquals(currencyDataSource?.getAllCurrencies(true)?.count(), 0) } + @Test + fun `invoke CurrencyDataSource instance and Brainwallet filtered Fiats for Buy, should return the correct number of supported currencies (moonpay)`() { + //The actual number of BW currencies is 16. The 0 is a placeholder and needs to be replaced with a db query. + mockCursorDataFromDatabase() + assertEquals(currencyDataSource?.currenciesForBuy?.count(), 0) + } + @Test fun `invoke CurrencyDataSource instance and open database, then should validate database was not null`() { val database = currencyDataSource?.openDatabase() From c8fdf8d73be2753e5f772be5d38ee0ec169afde4 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 2 Jun 2025 20:38:32 +0100 Subject: [PATCH 043/116] Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana --- .../brainwallet/data/repository/LtcRepository.kt | 10 +++++++++- .../com/brainwallet/navigation/LegacyNavigation.kt | 13 ++++--------- .../screens/home/receive/ReceiveDialogViewModel.kt | 6 ++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index 962602f7..b5983c3c 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -13,6 +13,7 @@ import com.brainwallet.data.source.response.GetMoonpayBuyQuoteResponse import com.brainwallet.tools.manager.BRSharedPrefs import com.brainwallet.tools.manager.FeeManager import com.brainwallet.tools.sqlite.CurrencyDataSource +import com.brainwallet.tools.util.Utils interface LtcRepository { suspend fun fetchRates(): List @@ -77,7 +78,14 @@ interface LtcRepository { remoteApiSource.getBuyQuote(params) override suspend fun fetchMoonpaySignedUrl(params: Map): String { - return remoteApiSource.getMoonpaySignedUrl(params) + val agentString = Utils.getAgentString(context, "android/HttpURLConnection") + val finalParams = params + mapOf( + "defaultCurrencyCode" to "ltc", + "externalTransactionId" to agentString, + "currencyCode" to "ltc", + "themeId" to "main-v1.0.0", + ) + return remoteApiSource.getMoonpaySignedUrl(finalParams) .signedUrl.toUri() .buildUpon() .apply { diff --git a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt index 08bb8258..26e1b5dc 100644 --- a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt +++ b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt @@ -9,10 +9,10 @@ import androidx.browser.customtabs.CustomTabsIntent import androidx.core.net.toUri import com.brainwallet.BuildConfig import com.brainwallet.R +import com.brainwallet.data.repository.LtcRepository import com.brainwallet.data.source.RemoteApiSource import com.brainwallet.di.getKoinInstance import com.brainwallet.presenter.activities.BreadActivity -import com.brainwallet.tools.util.Utils import com.brainwallet.ui.BrainwalletActivity import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -74,8 +74,7 @@ object LegacyNavigation { params: Map = mapOf(), isDarkMode: Boolean = true, ) { - val remoteApiSource: RemoteApiSource = getKoinInstance() - val agentString = Utils.getAgentString(context, "android/HttpURLConnection") + val ltcRepository: LtcRepository = getKoinInstance() val progressDialog = ProgressDialog(context).apply { setMessage(context.getString(R.string.loading)) setCancelable(false) @@ -85,18 +84,14 @@ object LegacyNavigation { CoroutineScope(Dispatchers.Main).launch { try { val result = withContext(Dispatchers.IO) { - remoteApiSource.getMoonpaySignedUrl( + ltcRepository.fetchMoonpaySignedUrl( params = params.toMutableMap().apply { - put("defaultCurrencyCode", "ltc") - put("externalTransactionId", agentString) - put("currencyCode", "ltc") - put("themeId", "main-v1.0.0") put("theme", if (isDarkMode) "dark" else "light") } ) } - val widgetUri = result.signedUrl.toUri().buildUpon() + val widgetUri = result.toUri().buildUpon() .apply { if (BuildConfig.DEBUG) { authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt index ea6df431..f6b2ba8a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt @@ -49,7 +49,8 @@ class ReceiveDialogViewModel( it.copy( address = address, qrBitmap = QRUtils.generateQR(event.context, "litecoin:${address}"), - fiatCurrencies = CurrencyDataSource.getInstance(event.context).getCurrenciesForBuy(), + fiatCurrencies = CurrencyDataSource.getInstance(event.context) + .getCurrenciesForBuy(), ) } @@ -153,9 +154,6 @@ class ReceiveDialogViewModel( "baseCurrencyAmount" to currentState.fiatAmount.toString(), "language" to appSetting.value.languageCode, "walletAddress" to currentState.address, - "defaultCurrencyCode" to "ltc", - "currencyCode" to "ltc", - "themeId" to "main-v1.0.0", "theme" to if (appSetting.value.isDarkMode) "dark" else "light" ) ) From 3f646dfc8c46619597ae52a6fb01460b3f5e0c47 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 14 Jun 2025 22:15:17 +0100 Subject: [PATCH 044/116] Add agent string obfuscation (#103) --- .../data/repository/LtcRepository.kt | 4 +- .../presenter/entities/ServiceItems.kt | 1 + .../com/brainwallet/tools/util/Utils.java | 114 ++++++++++++++++-- 3 files changed, 104 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index b5983c3c..39542354 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -78,10 +78,10 @@ interface LtcRepository { remoteApiSource.getBuyQuote(params) override suspend fun fetchMoonpaySignedUrl(params: Map): String { - val agentString = Utils.getAgentString(context, "android/HttpURLConnection") + val externalTransactionID = Utils.getEncryptedAgentString(context) val finalParams = params + mapOf( "defaultCurrencyCode" to "ltc", - "externalTransactionId" to agentString, + "externalTransactionId" to externalTransactionID, "currencyCode" to "ltc", "themeId" to "main-v1.0.0", ) diff --git a/app/src/main/java/com/brainwallet/presenter/entities/ServiceItems.kt b/app/src/main/java/com/brainwallet/presenter/entities/ServiceItems.kt index 1a8b7a4d..fc9b1983 100644 --- a/app/src/main/java/com/brainwallet/presenter/entities/ServiceItems.kt +++ b/app/src/main/java/com/brainwallet/presenter/entities/ServiceItems.kt @@ -6,4 +6,5 @@ enum class ServiceItems(val key: String) { WALLETSTART("start-date"), AFDEVID("af-dev-id"), CLIENTCODE("client-code"), + AGENTPUBKEY("agent-base64-pubkey") } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/tools/util/Utils.java b/app/src/main/java/com/brainwallet/tools/util/Utils.java index 21b556dd..1596c5c5 100644 --- a/app/src/main/java/com/brainwallet/tools/util/Utils.java +++ b/app/src/main/java/com/brainwallet/tools/util/Utils.java @@ -3,8 +3,6 @@ import android.app.Activity; import android.content.Context; import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; import android.content.res.AssetManager; import android.net.Uri; import android.os.Build; @@ -15,10 +13,21 @@ import android.view.inputmethod.InputMethodManager; import com.brainwallet.tools.manager.AnalyticsManager; -import com.brainwallet.tools.sqlite.CurrencyDataSource; -import com.brainwallet.data.model.CurrencyEntity; import com.brainwallet.presenter.entities.ServiceItems; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -33,7 +42,6 @@ import java.util.Calendar; import java.util.Collection; import java.util.Collections; -import java.util.Currency; import java.util.HashSet; import java.util.List; import java.util.Locale; @@ -168,21 +176,98 @@ public static void hideKeyboard(Context app) { } } - public static String getAgentString(Context app, String cfnetwork) { - int versionNumber = 0; + String deviceCode = Build.MANUFACTURER + "-|-" + Build.MODEL; + String appVersion = BRConstants.APP_VERSION_NAME_CODE; + return String.format(Locale.ENGLISH, "%s/%d %s Android/%s Device/%s", "Brainwallet", + appVersion, cfnetwork, Build.VERSION.RELEASE, deviceCode); + } + public static String getEncryptedAgentString(Context app) { + String deviceCode = Build.MANUFACTURER; + String deviceType = Build.DEVICE; + String deviceModel = Build.MODEL; + String appVersion = BRConstants.APP_VERSION_NAME_CODE; + String formattedAgentString = String.format(Locale.ENGLISH, "brainwallet-android,%s,%s-%s-%s", + appVersion, deviceCode,deviceType,deviceModel); + + try { + + // Convert base64 public key string to PublicKey object + byte[] keyBytes; + try { + String pubkey = Utils.fetchServiceItem(app, ServiceItems.AGENTPUBKEY).toString(); + keyBytes = Base64.getDecoder().decode(pubkey); + + // Decode the base64 to get the PEM string + byte[] pemBytes = Base64.getDecoder().decode(pubkey); + String pemString = new String(pemBytes, "UTF-8"); + + // Extract just the key data (remove PEM headers and whitespace) + String keyData = pemString + .replace("-----BEGIN PUBLIC KEY-----", "") + .replace("-----END PUBLIC KEY-----", "") + .replaceAll("\\s+", ""); + + // Decode the clean base64 key data + keyBytes = Base64.getDecoder().decode(keyData); + } catch (IllegalArgumentException e) { + Timber.d("Invalid base64 public key format: %s", e.toString()); + return "ERROR-CANNOT-KEYBYTES-DO-CONVERSION"; + } + KeyFactory keyFactory; + try { + keyFactory = KeyFactory.getInstance("RSA"); + } catch (NoSuchAlgorithmException e) { + Timber.d("RSA algorithm not available: %s", e.toString()); + return "ERROR-CANNOT-NOSUCHALGO"; + } - if (app != null) { + // Generate PublicKey object + PublicKey publicKey; try { - PackageInfo pInfo = app.getPackageManager().getPackageInfo(app.getPackageName(), 0); - versionNumber = pInfo.versionCode; - } catch (PackageManager.NameNotFoundException e) { - Timber.e(e); + publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(keyBytes)); + } catch (InvalidKeySpecException e) { + Timber.d("Invalid public key specification: %s", e.toString()); + return "ERROR-CANNOT-INVALID-PUBLIC-KEY-SPEC"; } + + // Initialize cipher for encryption + Cipher cipher; + try { + cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); + } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { + Timber.d("RSA cipher algorithm/padding not available: %s", e.toString()); + return "ERROR-RSA-CIPHER-NA"; + } + + try { + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + } catch (InvalidKeyException e) { + Timber.d("Invalid public key for encryption: %s", e.toString()); + return "ERROR-CANNOT-INVALID-PUBLIC-KEY-ENCRYPTION"; + } + + // Encrypt the agent string + byte[] encryptedBytes; + try { + encryptedBytes = cipher.doFinal(formattedAgentString.getBytes()); + } catch (IllegalBlockSizeException e) { + Timber.d("Agent string too large for RSA encryption. Consider using hybrid encryption.: %s", e.toString()); + return "ERROR-ILLEGAL-BLOCK-SIZE"; + } catch (BadPaddingException e) { + Timber.d("Padding error during encryption: %s", e.toString()); + return "ERROR-BAD-PADDING-EXCEPTION"; + } + + return Base64.getEncoder().encodeToString(encryptedBytes); + + } catch (Exception e) { + // Catch any unexpected exceptions + Timber.d("Unexpected error during encryption: %s", e.toString()); + return "ERROR-UNEXPECTED-DURING-ENCRYPTION"; } - return String.format(Locale.ENGLISH, "%s/%d %s Android/%s Device/%s", "Brainwallet", versionNumber, cfnetwork, Build.VERSION.RELEASE, deviceCode); } public static String reverseHex(String hex) { @@ -245,6 +330,9 @@ else if (name == ServiceItems.OPSALL) { else if (name == ServiceItems.AFDEVID) { return keyObject.optString(name.getKey()); } + else if (name == ServiceItems.AGENTPUBKEY) { + return keyObject.optString(name.getKey()); + } else if (name == ServiceItems.CLIENTCODE) { return keyObject.optString(name.getKey()); } From 642f9e6ea00637cdc5de29196cbe3e7a826dc214 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 24 Jun 2025 09:09:05 +0100 Subject: [PATCH 045/116] updated metadata (#105) --- app/build.gradle.kts | 4 ++-- app/src/main/java/com/brainwallet/tools/util/Utils.java | 7 +++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 326d7062..be73cab7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202505311 - versionName = "v4.5.5" + versionCode = 202506231 + versionName = "v4.6.1" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") diff --git a/app/src/main/java/com/brainwallet/tools/util/Utils.java b/app/src/main/java/com/brainwallet/tools/util/Utils.java index 1596c5c5..5a346596 100644 --- a/app/src/main/java/com/brainwallet/tools/util/Utils.java +++ b/app/src/main/java/com/brainwallet/tools/util/Utils.java @@ -46,8 +46,10 @@ import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; +import kotlin.uuid.Uuid; import timber.log.Timber; public class Utils { @@ -187,9 +189,10 @@ public static String getEncryptedAgentString(Context app) { String deviceCode = Build.MANUFACTURER; String deviceType = Build.DEVICE; String deviceModel = Build.MODEL; + String udidString = String.valueOf(UUID.randomUUID()); String appVersion = BRConstants.APP_VERSION_NAME_CODE; - String formattedAgentString = String.format(Locale.ENGLISH, "brainwallet-android,%s,%s-%s-%s", - appVersion, deviceCode,deviceType,deviceModel); + String formattedAgentString = String.format(Locale.ENGLISH, "brainwallet-android,%s,%s-%s-%s,%s", + appVersion, deviceCode,deviceType,deviceModel,udidString); try { From 50f44de142f3673d1e0be13ad0d35488b98f7d40 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Tue, 24 Jun 2025 15:10:19 +0700 Subject: [PATCH 046/116] chore: remove screen lock detection (#106) --- .../brainwallet/wallet/BRWalletManager.java | 23 +++---------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java index 59aaed33..b1031ea8 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java @@ -457,27 +457,10 @@ public static void onTxDeleted(String hash, int notifyUser, final int recommendR public void startTheWalletIfExists(final Activity app) { final BRWalletManager m = BRWalletManager.getInstance(); - if (!m.isPasscodeEnabled(app)) { - //Device passcode/password should be enabled for the app to work - BRDialog.showCustomDialog(app, app.getString(R.string.JailbreakWarnings_title), app.getString(R.string.Prompts_NoScreenLock_body_android), - app.getString(R.string.AccessibilityLabels_close), null, new BRDialogView.BROnClickListener() { - @Override - public void onClick(BRDialogView brDialogView) { - app.finish(); - } - }, null, new DialogInterface.OnDismissListener() { - @Override - public void onDismiss(DialogInterface dialog) { - app.finish(); - } - }, 0); - } else { - if (!m.noWallet(app) && BRSharedPrefs.getPhraseWroteDown(app)) { - BRAnimator.startBreadActivity(app, true); - } - //else just sit in the intro screen - + if (!m.noWallet(app) && BRSharedPrefs.getPhraseWroteDown(app)) { + BRAnimator.startBreadActivity(app, true); } + //else just sit in the intro screen } @WorkerThread From ea154239e367ee6cea42ccbb7b145c70527309c5 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 25 Jun 2025 16:57:17 +0100 Subject: [PATCH 047/116] =?UTF-8?q?=F0=9F=A7=B0=20=20Fx/seed=20words=20UI?= =?UTF-8?q?=20polish=20(#108)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound --- app/build.gradle.kts | 4 ++-- .../yourseedproveit/YourSeedProveItScreen.kt | 20 ++++++++++++++---- app/src/main/res/raw/clickseedword.m4a | Bin 3866 -> 0 bytes app/src/main/res/raw/clickseedword.mp3 | Bin 0 -> 3829 bytes app/src/main/res/raw/errorsound.mp3 | Bin 0 -> 41086 bytes app/src/main/res/values-ar/strings.xml | 1 + app/src/main/res/values-de/strings.xml | 1 + app/src/main/res/values-es/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values-hi/strings.xml | 1 + app/src/main/res/values-in/strings.xml | 1 + app/src/main/res/values-it/strings.xml | 1 + app/src/main/res/values-ja/strings.xml | 1 + app/src/main/res/values-ko/strings.xml | 1 + app/src/main/res/values-pt/strings.xml | 1 + app/src/main/res/values-ru/strings.xml | 1 + app/src/main/res/values-sv/strings.xml | 1 + app/src/main/res/values-tr/strings.xml | 1 + app/src/main/res/values-uk/strings.xml | 1 + app/src/main/res/values-zh-rCN/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values/strings.xml | 4 +++- 22 files changed, 37 insertions(+), 7 deletions(-) delete mode 100644 app/src/main/res/raw/clickseedword.m4a create mode 100644 app/src/main/res/raw/clickseedword.mp3 create mode 100644 app/src/main/res/raw/errorsound.mp3 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index be73cab7..fc08272e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,8 +20,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202506231 - versionName = "v4.6.1" + versionCode = 202506251 + versionName = "v4.6.2" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt index 214982a7..04fcf6f2 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt @@ -76,6 +76,7 @@ fun YourSeedProveItScreen( val maxItemsPerRow = 3 val clickAudioPlayer = remember { MediaPlayer.create(context, R.raw.clickseedword) } + val errorAudioPlayer = remember { MediaPlayer.create(context, R.raw.errorsound) } val coinAudioPlayer = remember { MediaPlayer.create(context, R.raw.coinflip) } LaunchedEffect(Unit) { @@ -156,10 +157,13 @@ fun YourSeedProveItScreen( expectedWord = expectedWord, actualWord = text.toString() ) - ) - if (expectedWord == actualWord) { - clickAudioPlayer.start() + ) + if (text.toString() == expectedWord) { + clickAudioPlayer.start() // Success sound + } + else { + errorAudioPlayer.start() // Success sound } return true } @@ -173,6 +177,14 @@ fun YourSeedProveItScreen( } Spacer(modifier = Modifier.weight(1f)) + Text( + text = stringResource(if (state.orderCorrected) R.string.empty_string else R.string.tap_drag_a_word), + style = MaterialTheme.typography.bodyMedium.copy( + textAlign = TextAlign.Center, + color = Color.Gray + ) + ) + Spacer(modifier = Modifier.weight(0.1f)) SeedWordsLayout { itemsIndexed(items = state.shuffledSeedWords) { index, word -> @@ -190,7 +202,7 @@ fun YourSeedProveItScreen( .fillMaxWidth() .dragAndDropSource { detectTapGestures( - onLongPress = { + onPress = { startTransfer( DragAndDropTransferData( clipData = ClipData.newPlainText( diff --git a/app/src/main/res/raw/clickseedword.m4a b/app/src/main/res/raw/clickseedword.m4a deleted file mode 100644 index 53758e26a756a36bbab8c9882e19fd9be5e4c567..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3866 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سهم لأسفل لليسار شعار تبديل الوضع المظلم + اضغط على كلمة واسحبها إلى مكانها اشحن رصيدك؟\n عقلك فارغ الآن.. احصل على عملة اللايتكوين في 5 دقائق diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a07b7400..31708d56 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -773,6 +773,7 @@ Pfeil nach unten links Logo Dunkelmodus umschalten + Tippen Sie auf ein Wort und ziehen Sie es an die richtige Stelle Nachfüllen? Im Moment ist dein Gehirn leer... Holen Sie sich Litecoin in 5 Minuten diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 1a918843..3eaded9b 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -772,6 +772,7 @@ flecha abajo-izquierda logo alternar-modo-oscuro + Toca una palabra y arrástrala a su lugar ¿Completar? Ahora mismo tu cerebro está vacío... Obtén Litecoin en 5 minutos diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b0e92d08..2d0343e3 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -773,6 +773,7 @@ flèche bas-gauche logo basculer en mode sombre + Appuyez sur un mot et faites-le glisser en place Recharger ? En ce moment, votre cerveau est vide... Obtenez du Litecoin en 5 minutes diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 3c263e70..cb889a37 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -411,6 +411,7 @@ नीचे-बाएँ-तीर प्रतीक चिन्ह टॉगल-डार्क-मोड + एक शब्द पर टैप करें और इसे सही जगह खींचें लबालब भरना? अभी तो तुम्हारा दिमाग खाली है... 5 मिनट में लाइटकॉइन प्राप्त करें diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 371a07fa..73f60f4d 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -775,6 +775,7 @@ panah kiri bawah logo beralih-mode gelap + Ketuk kata dan seret ke tempatnya Isi ulang? Saat ini otakmu kosong... Dapatkan Litecoin dalam 5 menit diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 0246634a..69116bf1 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -773,6 +773,7 @@ freccia giù a sinistra logo attiva/disattiva la modalità oscura + Tocca una parola e trascinala al posto giusto Ricaricare? In questo momento il tuo cervello è vuoto... Ottieni Litecoin in 5 minuti diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 9523482b..5550e8f1 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -773,6 +773,7 @@ 左下矢印 ロゴ ダークモードの切り替え + 単語をタップしてドラッグして配置してください 補充しますか? 今、あなたの脳は空っぽです... 5分でライトコインをゲット diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 0f409eb0..693a92ae 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -773,6 +773,7 @@ 아래쪽 왼쪽 화살표 심벌 마크 토글 다크 모드 + 단어를 탭하고 제자리로 드래그하세요 충전하시겠습니까? 지금 당신의 뇌는 비어있습니다... 5분 안에 라이트코인을 받으세요 diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 535904d3..1e68ec84 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -772,6 +772,7 @@ seta para baixo à esquerda logotipo alternar modo escuro + Toque em uma palavra e arraste-a para o lugar Recarregar? Neste momento seu cérebro está vazio... Obtenha Litecoin em 5 minutos diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 5434b353..183a5c30 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -773,6 +773,7 @@ стрелка вниз-влево логотип переключить темный режим + Нажмите на слово и перетащите его на место Пополнить? Сейчас в твоем мозгу пусто... Получите Litecoin за 5 минут diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index eef96cac..1e7f0342 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -411,6 +411,7 @@ ned-vänster-pil logotyp växla mellan mörkt läge + Tryck på ett ord och dra det på plats Fylla på? Just nu är din hjärna tom... Få Litecoin på 5 minuter diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index b67506d4..cd3a9eaf 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -795,6 +795,7 @@ sol aşağı ok logo karanlık moda geçiş + Bir kelimeye dokunun ve yerine sürükleyin Tamamlansın mı?\n Tamamlansın mı?\n Tamamlansın mı? diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index f8899d68..cd63237d 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -779,6 +779,7 @@ стрілка вниз-ліворуч логотип перемикати темний режим + Торкніться слова і перетягніть його на місце Поповнити? Зараз ваш мозок порожній... Отримайте Litecoin за 5 хвилин diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 763288ac..4f28b512 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -773,6 +773,7 @@ 左下箭头 标识 切换暗模式 + 点击单词并拖拽到位 充值? 现在你的大脑一片空白…… 5 分钟内获得莱特币 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index fe1abc56..378bc1aa 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -772,6 +772,7 @@ 左下箭頭 標識 切換暗模式 + 點擊單詞並拖拽到位 儲值? 現在你的大腦一片空白… 5 分鐘內獲得萊特幣 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 12fca16d..8323d2ac 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -776,13 +776,14 @@ + Back Your seed words "Just for you. \n It is the private key that lets you send." Blockchain: Litecoin I saved it on paper or metal You saved it, right? - Prove it!\nDrag thƒe words in the correct order. + Prove it!\nDrag the words in the correct order. Game & Sync Ready? Do this for you. Please do it @@ -795,6 +796,7 @@ Use biometrics You saved your keys. Crush the next level. + Tap a word and drag it in place Top up? Right now your brain is empty... Get Litecoin in 5 minutes From 5b6dff30504257d908bf56db047dd7b723081901 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Fri, 27 Jun 2025 23:46:23 +0100 Subject: [PATCH 048/116] =?UTF-8?q?=E2=9D=87=EF=B8=8F=20Feat/add=20polish?= =?UTF-8?q?=20punjabi=20farsi=20(#109)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump --- app/build.gradle.kts | 4 +- .../data/model/IntroLanguageResource.kt | 142 --- .../com/brainwallet/data/model/Language.kt | 4 + app/src/main/res/raw/arabic.mp3 | Bin 5184 -> 0 bytes app/src/main/res/raw/bahasaindonesia.mp3 | Bin 8928 -> 0 bytes app/src/main/res/raw/deutsch.mp3 | Bin 3936 -> 0 bytes app/src/main/res/raw/english.mp3 | Bin 3936 -> 0 bytes app/src/main/res/raw/french.mp3 | Bin 3648 -> 0 bytes app/src/main/res/raw/hindi.mp3 | Bin 6912 -> 0 bytes app/src/main/res/raw/italiano.mp3 | Bin 4416 -> 0 bytes app/src/main/res/raw/japanese.mp3 | Bin 4320 -> 0 bytes app/src/main/res/raw/korean.mp3 | Bin 4416 -> 0 bytes app/src/main/res/raw/portugues.mp3 | Bin 5280 -> 0 bytes app/src/main/res/raw/russian.mp3 | Bin 4224 -> 0 bytes app/src/main/res/raw/simplifiedchinese.mp3 | Bin 5088 -> 0 bytes app/src/main/res/raw/spanish.mp3 | Bin 4032 -> 0 bytes app/src/main/res/raw/traditionalchinese.mp3 | Bin 5088 -> 0 bytes app/src/main/res/raw/turkish.mp3 | Bin 3552 -> 0 bytes app/src/main/res/raw/ukrainian.mp3 | Bin 5184 -> 0 bytes app/src/main/res/values-fa/strings.xml | 852 ++++++++++++++++++ app/src/main/res/values-pa/strings.xml | 846 +++++++++++++++++ app/src/main/res/values-pl/strings.xml | 841 +++++++++++++++++ .../tools/util/LocaleHelperTest.kt | 26 +- fast_follow_asset_pack_01/.DS_Store | Bin 6148 -> 0 bytes fast_follow_asset_pack_01/build.gradle.kts | 10 - .../src/main/assets/audio/arabic.mp3 | Bin 5184 -> 0 bytes .../src/main/assets/audio/bahasaindonesia.mp3 | Bin 8928 -> 0 bytes .../src/main/assets/audio/coinflip.mp3 | Bin 23680 -> 0 bytes .../src/main/assets/audio/deutsch.mp3 | Bin 3936 -> 0 bytes .../src/main/assets/audio/english.mp3 | Bin 3936 -> 0 bytes .../src/main/assets/audio/french.mp3 | Bin 3648 -> 0 bytes .../src/main/assets/audio/hindi.mp3 | Bin 6912 -> 0 bytes .../src/main/assets/audio/italiano.mp3 | Bin 4416 -> 0 bytes .../src/main/assets/audio/japanese.mp3 | Bin 4320 -> 0 bytes .../src/main/assets/audio/korean.mp3 | Bin 4416 -> 0 bytes .../src/main/assets/audio/portugues.mp3 | Bin 5280 -> 0 bytes .../src/main/assets/audio/russian.mp3 | Bin 4224 -> 0 bytes .../main/assets/audio/simplifiedchinese.mp3 | Bin 5088 -> 0 bytes .../src/main/assets/audio/spanish.mp3 | Bin 4032 -> 0 bytes .../main/assets/audio/traditionalchinese.mp3 | Bin 5088 -> 0 bytes .../src/main/assets/audio/turkish.mp3 | Bin 3552 -> 0 bytes .../src/main/assets/audio/ukrainian.mp3 | Bin 5184 -> 0 bytes settings.gradle.kts | 1 - 43 files changed, 2552 insertions(+), 174 deletions(-) delete mode 100644 app/src/main/java/com/brainwallet/data/model/IntroLanguageResource.kt delete mode 100644 app/src/main/res/raw/arabic.mp3 delete mode 100644 app/src/main/res/raw/bahasaindonesia.mp3 delete mode 100644 app/src/main/res/raw/deutsch.mp3 delete mode 100644 app/src/main/res/raw/english.mp3 delete mode 100644 app/src/main/res/raw/french.mp3 delete mode 100644 app/src/main/res/raw/hindi.mp3 delete mode 100644 app/src/main/res/raw/italiano.mp3 delete mode 100644 app/src/main/res/raw/japanese.mp3 delete mode 100644 app/src/main/res/raw/korean.mp3 delete mode 100644 app/src/main/res/raw/portugues.mp3 delete mode 100644 app/src/main/res/raw/russian.mp3 delete mode 100644 app/src/main/res/raw/simplifiedchinese.mp3 delete mode 100644 app/src/main/res/raw/spanish.mp3 delete mode 100644 app/src/main/res/raw/traditionalchinese.mp3 delete mode 100644 app/src/main/res/raw/turkish.mp3 delete mode 100644 app/src/main/res/raw/ukrainian.mp3 create mode 100644 app/src/main/res/values-fa/strings.xml create mode 100644 app/src/main/res/values-pa/strings.xml create mode 100644 app/src/main/res/values-pl/strings.xml delete mode 100644 fast_follow_asset_pack_01/.DS_Store delete mode 100644 fast_follow_asset_pack_01/build.gradle.kts delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/arabic.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/bahasaindonesia.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/coinflip.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/deutsch.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/english.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/french.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/hindi.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/italiano.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/japanese.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/korean.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/portugues.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/russian.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/simplifiedchinese.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/spanish.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/traditionalchinese.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/turkish.mp3 delete mode 100644 fast_follow_asset_pack_01/src/main/assets/audio/ukrainian.mp3 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index fc08272e..802fe2e6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -20,7 +20,7 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 34 - versionCode = 202506251 + versionCode = 202506271 versionName = "v4.6.2" multiDexEnabled = true @@ -40,7 +40,7 @@ android { } } - assetPacks.addAll(setOf(":install_time_asset_pack", ":fast_follow_asset_pack_01")) + assetPacks.addAll(setOf(":install_time_asset_pack")) signingConfigs { getByName("debug") { diff --git a/app/src/main/java/com/brainwallet/data/model/IntroLanguageResource.kt b/app/src/main/java/com/brainwallet/data/model/IntroLanguageResource.kt deleted file mode 100644 index f1399dc1..00000000 --- a/app/src/main/java/com/brainwallet/data/model/IntroLanguageResource.kt +++ /dev/null @@ -1,142 +0,0 @@ -package com.brainwallet.data.model - -import com.brainwallet.R - -class IntroLanguageResource { - fun loadResources(): Array { - return arrayOf( - IntroLanguage( - Language.ENGLISH.code, - Language.ENGLISH.title, - "The most fun thing to do with your Litecoin!", - R.raw.english, - "Are you sure you want to change the language to English?", - Language.ENGLISH - ), - IntroLanguage( - Language.SPANISH.code, - Language.SPANISH.title, - "¡Lo más divertido que puedes hacer con tus Litecoin!", - R.raw.spanish, - "¿Estás seguro de que quieres cambiar el idioma a español?", - Language.SPANISH, - ), - IntroLanguage( - Language.INDONESIAN.code, - Language.INDONESIAN.title, - "Hal paling menyenangkan untuk dilakukan dengan Litecoin Anda!", - R.raw.bahasaindonesia, - "Yakin ingin mengubah bahasanya ke bahasa Indonesia?", - Language.INDONESIAN - ), - IntroLanguage( - Language.ARABIC.code, - Language.ARABIC.title, - "الشيء الأكثر متعة يمكنك القيام به مع Litecoin الخاص بك!", - R.raw.arabic, - "هل أنت متأكد أنك تريد تغيير اللغة إلى الإندونيسية؟", - Language.ARABIC - ), - IntroLanguage( - Language.UKRAINIAN.code, - Language.UKRAINIAN.title, - "Найцікавіша річ, яку можна зробити зі своїм Litecoin!", - R.raw.ukrainian, - "Ви впевнені, що хочете змінити мову на українську?", - Language.UKRAINIAN - ), - IntroLanguage( - Language.RUSSIAN.code, - Language.RUSSIAN.title, - "Самое веселое занятие с вашими Litecoin!", - R.raw.russian, - "Вы уверены, что хотите сменить язык на русский?", - Language.RUSSIAN - ), - IntroLanguage( - Language.PORTUGUESE.code, - Language.PORTUGUESE.title, - "A coisa mais divertida para fazer com seu Litecoin!", - R.raw.portugues, - "Tem certeza de que deseja alterar o idioma para português?", - Language.PORTUGUESE - ), - IntroLanguage( - Language.KOREAN.code, - Language.KOREAN.title, - "라이트코인으로 할 수 있는 가장 재밌는 일!", - R.raw.korean, - "언어를 한국어로 변경하시겠습니까?", - Language.KOREAN - ), - IntroLanguage( - Language.FRENCH.code, - Language.FRENCH.title, - "La chose la plus amusante à faire avec votre Litecoin!", - R.raw.french, - "Êtes-vous sûr de vouloir changer la langue en français ?", - Language.FRENCH - ), - IntroLanguage( - Language.CHINESE_TRADITIONAL.code, - Language.CHINESE_TRADITIONAL.title, - "用萊特幣做的最有趣的事!", - R.raw.traditionalchinese, - "您確定要將語言改為中文嗎?", - Language.CHINESE_TRADITIONAL - ), - IntroLanguage( - Language.TURKISH.code, - Language.TURKISH.title, - "Litecoin'inizle yapabileceğiniz en eğlenceli şey!", - R.raw.turkish, - "Dili türkçeye değiştirmek istediğinizden emin misiniz?", - Language.TURKISH - ), - IntroLanguage( - Language.JAPANESE.code, - Language.JAPANESE.title, - "ライトコインでできる最も楽しいこと!", - R.raw.japanese, - "言語を日本語に変更してもよろしいですか?", - Language.JAPANESE - ), - IntroLanguage( - Language.GERMAN.code, - Language.GERMAN.title, - "Das macht am meisten Spaß, was Sie mit Ihrem Litecoin machen können!", - R.raw.deutsch, - "Sind Sie sicher, dass Sie die Sprache auf Deutsch ändern möchten?", - Language.GERMAN - ), - IntroLanguage( - Language.CHINESE_SIMPLIFIED.code, - Language.CHINESE_SIMPLIFIED.title, - "用使用萊特幣可以做的最有趣的事情!", - R.raw.simplifiedchinese, - "您確定要將語言改為中文嗎?", - Language.CHINESE_SIMPLIFIED - ), - IntroLanguage( - Language.HINDI.code, - Language.HINDI.title, - "अपने लाइटकॉइन के साथ करने के लिए सबसे मज़ेदार चीज़!", - R.raw.hindi, - "您確定要將語言改為中文嗎?", - Language.HINDI - ), - IntroLanguage( - Language.ITALIAN.code, - Language.ITALIAN.title, - "La cosa più divertente da fare con i tuoi Litecoin!", - R.raw.italiano, - "Sei sicuro di voler cambiare la lingua in italiano?", - Language.ITALIAN - ), - ) - } - - fun findLanguageIndex(language: Language): Int { - return loadResources().map { intro -> intro.lang }.indexOf(language) - } -} diff --git a/app/src/main/java/com/brainwallet/data/model/Language.kt b/app/src/main/java/com/brainwallet/data/model/Language.kt index 340af45b..9a9d6c8c 100644 --- a/app/src/main/java/com/brainwallet/data/model/Language.kt +++ b/app/src/main/java/com/brainwallet/data/model/Language.kt @@ -23,6 +23,9 @@ enum class Language ( PORTUGUESE("pt", "Português", "Selecione o idioma"), HINDI("hi", "हिंदी", "भाषा चुने"), GERMAN("de", "Deutsch", "Sprache auswählen"), + PERSIAN("fa", "فارسی", "زبان را انتخاب کنید"), + PUNJABI("pa", "پنجابی", "زبان دا انتخاب کرو"), + POLISH("pl", "Polski", "Wybierz język"), KOREAN("ko", "한국어", "언어 선택"), FRENCH("fr", "Français", "Sélectionner la langue"), CHINESE_TRADITIONAL("zh-TW", "繁體字", "選擇語言"), @@ -30,6 +33,7 @@ enum class Language ( JAPANESE("ja", "日本語", "言語を選択する"), CHINESE_SIMPLIFIED("zh-CN", "简化字", "选择语言"), ITALIAN("it", "Italiano", "Seleziona la lingua"), + SWEDISH("sv", "Svenska", "Välj språk") ; companion object { diff --git a/app/src/main/res/raw/arabic.mp3 b/app/src/main/res/raw/arabic.mp3 deleted file mode 100644 index 65e0112eb5652104577cf2ef357343de135eaf24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5184 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 R{x9SE-)8yW|KtC+{~v%HY3%?2 diff --git a/app/src/main/res/raw/deutsch.mp3 b/app/src/main/res/raw/deutsch.mp3 deleted file mode 100644 index 868409d093b4b4a67adbed42bca46d1c292c97fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3936 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 C1S38G diff --git a/app/src/main/res/raw/hindi.mp3 b/app/src/main/res/raw/hindi.mp3 deleted file mode 100644 index 7ba1ad66b8a76602c541525030faaaa6cf72a0ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6912 zcmeI%XD}RIy8!TAExL_P5WSbx1^;NPtWK;5!Rl7;AtWRbU36K!x7B+mMDLwo38F^? zK@j%-_udchydUrT&Ye4V=02a!nKS2{-#lN=^UT4Vh4umd4+rMI{J0uGMF0S!uL^h^ z1tPjN>`T(#R=N8LhIl#4^VoLS+yjiBh_mecL{Yz;lErY5M38=lFByp5vMVNw6eBNK zHZ9~Jq=-9tUY?JDb3$)eeALjxGc_IUjE1Nu_%(eet^R??;2Sd~g32k8Ox8FR8g6sG zv%yA83mpw>)nPRaDd)$c%t!61`r&2^SE; zNfv(lU9g1`F_ip>udjlb_e)k3P3b#j8v-!7(rmVA=-0QnAmJ2_&050 zkgVsRi&G7~{?eZ!8gRiCmP`jNvzKg(KOUsad9aoiwfHUN}~% z5!@&SRS3sy+X4;$XE9HI(l;ak(Ebdc)jMBqUu@ap2Hg-Mp}dHF zuSX@#9$vTyTJrfGkM)Z~GmC_rv}fxQniAe>0KdAY$S_V_bJ|}OV&)kF6wLQ(t zf_zD}dwy2Vw4vBhp}&Rovx|(ThX4X+Iu#;|B~3q*T+tuPA6r-@XumP^Mf}baF3^y{ zgLkvXYrXf}(;bNtD@g}!k!A6hJWbpe8XFmVwh$8oBBG`TyeBj-B>b5T9roQc)VZSM zH)qS=1%^3|Y zz$am0;%WEe0h+n6+-!@3o5_q1Qv^3Mm0e#@VO)(i%J<*Jgpxw7Poh+SWTX^_>sUVx z-waCxVA&#V4o8fz6inT;S+B7l2C5cBg$;^%w*}o5RX(7>Ne*%4K^SBQrWY*mjt={C zjwn&sGPn%9xfp&gud_>BS{?nz|K%}tcKk(H%_ENanlC9&n-G<^Hgp|2mx+rYj^#-P zR=pQ5Aq&JYudm5kqf8fX0;(SFx{my5$6)Ski#BCinp(Yw5*98wvV(HZrTR|`?oLnx zV<=O8PHPL>{*xtcmroQxZ4bz~`c?1e?|qpP96M=PKdX?|atvT)0d3%XEEDH?IkRh# z8tJk*MvwN$G%5nO#1PfeP}hFoEXCPzYb`SpNao#m{Xt$N+%<;s=!pLsZzV;y!cbHi zqzG4{kK0d*SLId9*Budh$-qBu;50s~qt;os6bv5S4Z~n)PN*I-pHNgE-bDVe6vSk= zY*ks`L>I2-1pL0yd2x4n!{kfyigN%4;bRA&($zgoUL=JeRPlydMFi@&Rpx z^oA``l&n7b$Z#_(iuE%Kzgvy~?10b{BQRt2-`irdkGky46#kSyFxqOkVJf&Lo7 zA?vaB``ulfz)z+|$8YkrU*q!J$CCx$fVN-l=v7Ye_dVj!Pxt^& zxEpNh#HcOoX|#h_IwFE?vbK572mJ?KjX7DoR;zb7!eDNMyn{xhI`yc|Jp;K`37?_( zy&L3b$_+b3mX72@*=e+R`g)|)T`MWh3Jc!BT6#h!Cn2sI&FMN{!9<T6 z@I16gBrkvR<$?1-&SQ!RE3Meu-g{%bCXerbA(Dmgq!u%Hw^2k{YnnXNEn9a!r^8rc zFt;KL=aZf%-IDS;MzN*U7P4CwugxgZQMSu&na0R)B0T4Z)GjBJ99zZ-54tdi2T`!V zwCE!;dRiXlQra{@;kUp%I1>&IzRD+Y%De;B|IELT+@=rUa0;CQPR@L3JzvqGHcNeM z$>5x#Q{=8?+}h5J=o%VyJ^S4sk$+W#Cey@MW!BAlWTbOMs&Dq8^!f?gKw|lDhw_4R z#iB{0=eeUeSQG3hNue@5E>ZBf`oi++IK}ihEAXxz6TN$LoXsJb_3WARhwdZi^97Nz z?wq#y0Mi`=nb@tZe{CDR{!nC}sDYnonti)utl$0D(&|+{E0+vzNYaquJdGDfmJt0Z zfa3lL+?aryJ_PH3AVAIT0yxu0lfR!%pMom_hP&2Q;)ngTOKEov1voV|Yz@ZM8Zaq&b@DUdhSvzAqN+-=bF6U&3Xz(; zf0))-8!PtNNe8x?#hQx)=ER?c;Mjx30Qc!}=?dwA+&I?6@KvC@3f9lYKgRBe^&d(; zHUF%KLd0$GSg?z=cM&h)LgE_xZ z9q}zr1TMk7IiDL(-{tky(@YUj45lJjVtM_{a!hZLC2{=3)Md2+HFGx0x%lU>!V|Wa zletrgbHY^fi;Y^{j)v){aOva+UE2FE!s_Xc84D|5@K`RRFdQlz?XA3@;sBgHMe}@h zZ82%ZUODcdZDQ_LzN57wXD&u4*3ZlLV8jt{sE>~G)|~T@)>roMC{YqC%<}SpYVbCc zEvJDKRB3XfG-b9#*+-qsjV-z>VVwSqkwlUyhDXO+R|o#P)pyt7cY!x|cXHKn+eOwE zk9SfVuFel+HXW+y0;i=iFr8a1sUUcLyuP3?M<~Z9PZwq~MtE8N^pN7s`{1SHK# zbQ09KNJTOR?!)W?QTiWrNC+XFc?weBm5f5;0eD^;h(AxJg)t3CKJOzw!zXIW+yuPd z#QLRp1Ziyn2NUR7AK{Y@LuReUW9PDWxo!Mkvl<7A&JEG)my;Nb0`Ck<)i`3f+P!3Q zy5z5mqZ@Slje--GPksK=n?+Y&+i9xw3eSOzM|O6qXj0< z`p)id_o_1=Ngv6q>sJ})2RYZrn6{l?%hfwav-!>{UtWrQk9j-XXnas`9v@$U`o@+qN}$|XZVzk7{h&|EZ#JjHh{8k&={d;=%BXwD z34w~=+FV3IY#~W*FFZPOyvJg_M;AI+zoUYYtP3zR9zbUUd=R0bMH2EVCQaHLc19W0W$TzQ`{JQ8 zfc!MC)-eNO_m@+7?VHVwS)UPnRpGSz3}XDOt&dqxhJ?v`79M>&*uxwlC8d2B5V;2* zN4LJ}zHN~raB+-j?X4SXmE{v1U~Q#6H%DM{s|x&{1zmX@R&-@>A3QF0de198#HJk) zf1acq!l}U~1{pz6h4oJlD1&@Z@hSaoJ68fmVy{Sk%ggY8LNkJGgM`?>vk)w9}qmx#OFwEP#WSB28R_9)U6}780 zuwEt5JM&kz`6Mk1rL+BvQ3>~q zNu2%XZ(A)Slg?aG-Mpz<(U#8_sV8X+2c`}>I!-0?(Cz zjS^vG{S@*y)e4mc2Mg9u&u(!;!uM8efDPqWT6O7*lF)aiD)-IY}6c^|J|) z^af$;hYW+H;N9KhU7!9&y%WtpKiaCenvRKnA%ci=25WX0zr{+G!O}^1y`UfqJxM{z zi!jj_JQW6&@^p2rQk|erGTL|p_n?ChCyHk>IWja4W%eoFox#s7vW10NXpP zp^-&d;GkN~VZYwqJzQ;l!a`+rX82i$ER?Pu>wm~|8uqu}qSc3gzr3k3C2(QC5+UBU zG=2}v8^Z^Y(#hw85k-CSSw3lvDSvz8YJQY!XQusSWu%JgXu&FG>#+05!+^oH6M2P* ztDGmZLbZsf<@5n>CwH^%vG!u$!Q^laFGJV8nqguJ=8*5ztJ}&Q){3GQmls5o(ur0O2SG2m)*j0->2eX;~yS!-k z%bC+a|EP}22d4a@z?+)7-aQfZBxvVpG-d=0FE&OFYBy-pyorP{88Y%p6++#{8P8r; z?LHVKMqUjfE-_4)$>7uDmEak3aHn-V2QLqf|6CdyBq~b%nZ*8Pl0DWB;U!sc0W6Q9 zM<-OKT3`gsQbc%P8LnWJn4`ZNVLqC?4_U0{a(xYjKZ36p(FaGvN)CA(iGB-X>)jX& zlttU4zx$6Lm^qBmWwy>py8G*i*3YIdB=2socIqgHWUG27f>mLiFns(T_vwr7Ze_(V z>F-WTBULDF85+iH&9pXXi}IZLQ{sj7^qXtU?c(D3=&Q;s)H1$puL&Dt7L}kTp3?94 z0h_#{BlKF~S!pJrjO@(BlIV-sQI>wJ-61#fkx)hgW2=EAPFNX-ly2-ZJ~b7I@7U2ygqn9ZHZMzS$E_O&UR|BLD5Iqy^sq{;hzVtW4zNj+&jq_^9F1(3xP| zXpVwNH`edVsTBnWd>QCi5VjP#n+yo7*h=B=4UM7hjc&IL|OfE%`d4xQVqKL)wWjid2`)lX%MKY-@A;Q2;Z?+rG&xv)!z1L z@*A*m+v#1Tbd)=MY+4)-KA4Ec9FFZRUcHU;@l8A_P0_Ob9ee+0mKAY{SP^0c zul9xD31Qj2r!w=bPcJxDlAlN<(A$6N;avhd8p+puufr#JV1eqH z!};o@^%W&S}i!D_qe?I(teN$dR zj{!kgw-Wq@CfeQ_8Td@qjCuuD2fjah~#2}qOtyUt_H5JfL;Q0sWE&;c-V<| zwSe1o!fTt+L708buO>RvyZt!LT0JNu*(61@bZgAe$Vui5uS$m_Yw1vOw~Y(mgrKO& zBsD=ZQZNRPs>;oo)Fbc_4$uF2$iA1URc8p95lrq?PiQcZq}QmEmT~0gLNvBHYRc}- z$pYt&tTOqf8?F}!Ffo}=*sQ3#aK60^3@j>^Jyg0`abW*Hp zq2KtaXeHjy+zGS6jasq(8)4E%bAVpbRX!WdHqkykHbs76?Xr~g1{qbL;bwAV3M3y4 z1seg>L(?g}bk&HsN&TTps`*~pz6o#DLz5$i)6K{QI^QQ zFU?p&l(G~`_E0jfdEay1_rLd?_dVzL{B_U0=YH%sbOHcy90fuGz`zOs z$5l46p1c>nzqs=ks(`kz=6x7Z-IB!rP*lGyS4cX(EB*^_&t#?!|3g)u`mYE3>IeMY zo%7Cc8cimGMzeVO2?=B}hTL%ka1VgoC_D%4$hQFR58nnQqk*ilse}m9qvbjYqK@l9 z!53xtVP(ZnhK-AL(ck!syI*E_-_xzIP2=P2`b;Tid=Fio{@KHcbI9|XYw(M-%=Osn zyzikl`rYGBr>07L@_egPs+9bikn)N`S`c1tPWi7*}s0HHUy6DDF%9EORiheeQ_RK zdI3OnAb=jLh}x1z<6$@L97+}*-P0RW+6qNUMej+K4I@Nm)>AXPlhe_(KvZ2!&<~s9 zvOxPC2d^LR5hdKk9IU5g6T4GYi(WK)TK8=FL&n=65sTl}=>C}_Ka=j)Cy!tA{{(kX ze$CbHZFMi9u}Z5ww@8}nJmi(%2&a*i;e3<4u0yzFw%XqS&cdG^Qt914gpaeGbTeQUcH$O-Oh1-{vZOh%_v`a?!<)wn+>P zBYa}QvMQ>Dw2LAODYlqGU9WVS9iP*ujVm{_uPCZs`r2B*`Fib(5@ zJFRL`ou}Ca0KM{ly3fNwGPDHQaRA;HE;rM4EXEJwB^jf$5W`*-C6hvc#oWVg~-6OF(KP@UTuyN zduu$+#dmj#ucy94bGqku%de`S50?ZRmIeV?^XQHP)5?7e29Ap&#?XB>F4cZA2rmKj zm-_%|-C*`dc$ZkGs114F08GF!4$gyX$y}OULTv*FrCZ>rt)LZz>$OA@b}#ML<{fm~ z{Z1`xzXk0#8EIL6*75uYS;_nmEw}HL=5Au6pg_8Rnj4&63z`f7?519Rdtb5h>7$u- z|Rk&Va1EMnVr(rd&{ybfdBx_yHI4JHow|V{dNn$%w^tMoZbSKZS8I49W z|Elg3BN5?`5w4^AEZm^VTA-Vsuu)!xYi`cmkVuYiEPunhdnnty_My8aaP#rC*u~`g z=t{p7Jv9#jyF?Kv^W=5GaD1Z5&%8~m>gO(hIPdB-Dw=Xvcw}hiZx)o%_Fq_a)cx5$ zNB5Z_K1cWOpb!)hNj|Uw_2GVzuBPuJZf_%=H|ahJ0x5*f@yAN6Iq>tVhnW0&S?&mD zp^QXTz-EhDerHEVriCuFt;JourT8_kM`J#mcflU+4r-e(!WLtl%jrG@0!}9bBT(WX zw>P^({qxS$J%l>;arm2xmfg|9NX-Ncs5>KIO<*{Ak$tk`M#1#J$QR5b4rJ{XySQnA z&PsFXDleqm-1!8;fn)2pzQbDyfxB0R$D9?UDevk2Sx91b0nmpbFhmnG7sNASF5XM1 zy#76w$*;`oQaN0$BIWwjMA@akKJ@R*%Dr;#dF!w%kSTCeCPJd`@s-O$*7C(tTMl^(a5R=7d1Lw%Dt@(_JHZ=3Mwho~Kelvwsc<& z0?t12lL(*@w<$3>pRiflQa){wcxaM$px(QF>;X2lU$Fn3_=(TmaqGXv4#BB?OmD^d z9#Au3FioxiT<{d@Sm528ud#P8;!|wTrYF0PLRXVYIy(o;6zIMV#3{QL=p7+i#f)G@ z$M^dB>W}prkTT|UY{YdgF`W*+)QLC88|VqEPGq@$ImqdB=OkNNYr@W{dngQIDsd(@ z4$1Cw%{j!XvgX;Ef!9w}VFfDiB*VRP*gd*$0^tkq1Rj|acYDRD!OlQ#o2$^!AWA#y z*_iM7{DYo&#&xlQgUe>E?XkFLNvt}I!fdv75=bp=^!f5#jRE!Dues@9HE^nK$?}l8 zuga6fdzL7BzE*w}DnlRLw*ljl1_AqS0-$QtsH)xIg|%*;{>odG&TIP#LF6EM8dE=O z6<>X^Z+mMVifpw`PWNb8oeezv@XaAZ{4PpY)EMzh%F?_%5Jyld_L`xh0ys}BP>fBL z1#=N}|0X2&uU^1qkSJ~agwJ48J5h)=-gS$24%b~``=!0vi#rU4G8r_l5%m9>{b%>> zlLyWIXP37Ys-f+Zv%>gP-OydmZg+jIOOP&H zF>R8i`v~Z>xKLnVgs5|3Nt0tDp*RZj=wU=sWumTWdAfw8hXyzBX8s3l|4^Ui@B2eZ zlHgpE`E!Q%q!l7cC^J?*BD@q4t{>$HlXW;gG~<3jb_0`9v1=sQl9^SYPxnP2`+i40 z3t_(g(ZdzdnwK^9Y=?M_j^hRSbGMQH`06KazH?<{SUSG-+VHozLZ;Gf`;CICxhB48TX z;{LE8J2YYr{D59d<_GCe5@XE>-3LRf`O}X67gRIaYe7O-DGOnf^VohjNZb>HoRp8O z(rF<@WVwmy%5p?~Y{;56U-o?SaaqQpEUqOnz`0I-Z`I-cZq}XEkm_j((fy{~%%Y%` zxGL&mLewp(MY_)n4meB$O$Gy)qB4OK|LSQyQCWdASWn!8@Psev zTuI70J6!JmZZBbF=C5mDp2SC`B2uHNf?Rf~^`$rM#6ZwYpYmdN7l}*_InZJu22J;& z5V@2Dpj*y3=EVMpg4=f@BCj@SQpytYl8nE1-79+N{e&EQuy!Ykc%0jzdbW*Z)e$!N zZitgDf;Bfotl@HdCDZ!KNLb3a%>^ejCE0*V7U2Wewk<)?RR}I;^B)?VE~aDhMR+c`A#!)siQIvzG!Lc33*%}U`J9xoESB7m+oDfZsxy!O zdOn+rSoskbj9$c{WxDhng>TY*W$@lR3^3Y_6;}+gX3B{U4K24=2qIe0MA0JpEo{Rl zyq`(h5#Jiz0w^rVYr&yQ0S${^$dTH@LVCFGyhE&+p(&mB;G{WLFl|_>OL01xcs7+ z%o1Tt5xrdzXU~Se*dl!;TP!a^qX#TF>Mvcs66o(PFnkNtR45AfpL`P!aT0I*5xIhpYxCVTKEQ`q)G;clvmcChT+!9r-Uu{>M+G_wPqdJn%R9<$sI+ucy)T^KbvZy!QWH`n&yq0BcdkIRF3v diff --git a/app/src/main/res/raw/japanese.mp3 b/app/src/main/res/raw/japanese.mp3 deleted file mode 100644 index 379a6938050723055096af20025fa6d452f4032b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4320 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 BkHP=| diff --git a/app/src/main/res/raw/korean.mp3 b/app/src/main/res/raw/korean.mp3 deleted file mode 100644 index f17488e15429e9f3e4bd9a27b3b9ec0b577cb9e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4416 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 D^BFm+ diff --git a/app/src/main/res/raw/portugues.mp3 b/app/src/main/res/raw/portugues.mp3 deleted file mode 100644 index f7d54262bd996b2956365b7e60914d3d83cb7fda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5280 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 diff --git a/app/src/main/res/raw/simplifiedchinese.mp3 b/app/src/main/res/raw/simplifiedchinese.mp3 deleted file mode 100644 index b9f00f6cbbfa304d949fd2a280ff21de1a1789d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5088 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 z 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 JSKYtb{~P66Pfh>; diff --git a/app/src/main/res/raw/traditionalchinese.mp3 b/app/src/main/res/raw/traditionalchinese.mp3 deleted file mode 100644 index b9f00f6cbbfa304d949fd2a280ff21de1a1789d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5088 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 F{{ilF$iM&q diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml new file mode 100644 index 00000000..8f82d491 --- /dev/null +++ b/app/src/main/res/values-fa/strings.xml @@ -0,0 +1,852 @@ + + + + + وب‌سایت + + + + سیاست حفظ حریم خصوصی + + + شرایط استفاده + + درباره + + توییتر + + بستن + + مرکز پشتیبانی + + + + به نظر می‌رسد شما از یک صفحه کلید شخص ثالث استفاده می‌کنید که می‌تواند آنچه را تایپ می‌کنید ثبت کرده و کلید کاغذی شما را سرقت کند. لطفاً برای محافظت بیشتر به صفحه کلید پیش‌فرض اندروید تغییر دهید. + + خطا + + مشکلی با کلید ذخیره سیستم عامل اندروید شما وجود دارد، لطفاً با support.brainwallet.co تماس بگیرید. + + داده‌های رمزگذاری شده کیف پول ذهنی (Brainwallet) شما اخیراً به دلیل غیرفعال شدن صفحه قفل اندروید شما نامعتبر شده است. + + خطای کلید ذخیره اندروید + + اتصال اینترنت یافت نشد. اتصال خود را بررسی کنید و دوباره تلاش کنید. + + هشدار + + آدرس‌ها کپی شدند + + تمام آدرس‌های کیف پول با موفقیت کپی شدند. + + مجموعه کلید کاغذی + + عالی! + + رمز تنظیم شده + + ارسال ناموفق + + تأیید ارسال + + پول ارسال شد! + + اثر انگشت شناسایی شد + + خطای سریال‌سازی JSON + + کیف پول آماده نیست + + قادر به بازیابی توکن API نیست + + لغو + + نادیده بگیرید + + منو + + نه + + خوب + + دریافت کردن + + ارسال کنید + + تنظیمات + + ارسال کنید + + بله + + مبلغ ارسالی: + + هزینه شبکه: + + شبکه + + زمان پردازش: پیش‌بینی می‌شود این تراکنش در %1$s تکمیل شود. + + ارسال کنید + + تأیید + + به + + هزینه کل: + + برای اطمینان از اینکه همه چیز به درستی نوشته شده است، لطفاً کلمات زیر را از کلید کاغذی خود وارد کنید. + + کلمه #%1$s + + واحد نمایش لایت کوین + + نرخ ارز + + + + کیف پول مغزی به دلیل یک اشکال در نسخه اندروید شما قابل تأیید نیست. [لطفاً برای اطلاعات بیشتر اینجا ضربه بزنید.] + + این دستگاه برای ارسال پیام‌ها پیکربندی نشده است. + + پیام‌رسانی در دسترس نیست + + اثر انگشت شناسایی نشد. لطفاً دوباره تلاش کنید. + + اقتصاد + + ۱۰+ دقیقه + + این گزینه برای تراکنش‌های حساس به زمان توصیه نمی‌شود. + + زمان تحویل تخمینی: %1$s + + عادی + + ۲.۵ - ۵+ دقیقه + + سرعت پردازش + + بررسی موجودی کلید خصوصی... + + ارسال %1$s از این کلید خصوصی به کیف پول شما؟ شبکه لایت کوین هزینه‌ای به میزان %2$s دریافت خواهد کرد. + + این کلید خصوصی در حال حاضر در کیف پول شما موجود است. + + این کلید خصوصی خالی است. + + هزینه‌های تراکنش بیشتر از وجوه موجود در این کلید خصوصی خواهد بود. + + کلید خصوصی معتبر نیست + + خطا در امضای تراکنش + + واردات + + وارد کردن کیف پول + + کیف پول برای وارد کردن + + وارد کردن یک کیف پول، تمام پول از کیف پول دیگر شما را با استفاده از یک تراکنش واحد به کیف پول مغزی شما منتقل می‌کند. + + این کلید خصوصی با رمز عبور محافظت شده است. + + رمز عبور + + + اسکن کلید خصوصی + + موفقیت + + کیف پول با موفقیت وارد شد. + + وارد کردن کیف پول + + باز کردن کلید + + وارد کردن کیف پول شامل تاریخچه تراکنش‌ها یا سایر جزئیات نمی‌شود. + + رمز عبور اشتباه است، لطفاً دوباره تلاش کنید. + + نادیده بگیرید + + امنیت دستگاه به خطر افتاده است +هر برنامه \'جیلبرک\' می‌تواند به داده‌های کیف کلید دسترسی پیدا کند و لایت‌کوین شما را سرقت کند! این کیف پول را فوراً پاک کنید و در یک دستگاه امن بازیابی کنید. + + امنیت دستگاه به خطر افتاده است +هر برنامه \'جیلبرک\' می‌تواند به داده‌های کیچین دسترسی پیدا کند و لایت‌کوین شما را سرقت کند. لطفاً از Brainwallet فقط در دستگاهی که جیلبریک نشده است استفاده کنید. + + هشدار + + خدمات مکان‌یابی غیرفعال است. + + برین‌والت اجازه دسترسی به خدمات موقعیت‌یابی را ندارد. + + شما کیف پول خود را در %1$s ایجاد کردید + + نام کیف پول شما فقط در تاریخچه تراکنش‌های حساب شما نمایش داده می‌شود و توسط هیچ شخص دیگری قابل مشاهده نیست. + + نام کیف پول + + مدیریت کیف پول + + خرید + + قفل کیف پول + + مرکز امنیت + + تنظیمات + + پشتیبانی مشتری + + ایجاد کیف پول جدید + + منو + + بازیابی کیف پول + + به حالت خودکار تغییر دهید + + متصل + + آدرس IP گره و پورت (اختیاری) را وارد کنید + + وارد گره شوید + + به حالت دستی تغییر دهید + + گره اصلی فعلی + + متصل نیست + + وضعیت اتصال گره + + نودهای لایت کوین + + درخواست پرداخت نامعتبر + + سند پشتیبانی نشده یا خراب شده + + گواهی مفقود شده + + درخواست منقضی شده است + + نتوانستم پرداخت را انجام دهم + + پرداخت‌های لایت‌کوین نمی‌توانند کمتر از %1$s باشند. + + خروجی‌های تراکنش لایت‌کوین نمی‌توانند کمتر از %1$s باشند. + + نوع امضای پشتیبانی نشده + + گواهی نامه غیر قابل اعتماد + + برای محافظت از کیف پول شما، رمز عبور دستگاه مورد نیاز است. به تنظیمات بروید و رمز عبور را فعال کنید. + + رمز عبور دستگاه را فعال کنید + + برای محافظت از کیف پول شما، قفل صفحه نمایش دستگاه مورد نیاز است. به «تنظیمات» > «امنیت» > «قفل صفحه نمایش» بروید و برای ادامه فعال کنید. + + قفل صفحه نمایش غیرفعال شد + + کلید کاغذی شما باید ذخیره شود تا در صورت گم شدن یا تغییر تلفن همراه خود، بتوانید از آن استفاده کنید. اینجا را برای ادامه لمس کنید. + + اقدام لازم است + + کیف پول شما ممکن است ناهمگام باشد. این اغلب می‌تواند با اسکن مجدد بلاک‌چین برطرف شود. + + تراکنش رد شد + + کمک کنید تا Brainwallet را با به اشتراک گذاشتن داده‌های ناشناس خود با ما بهبود دهیم + + اشتراک‌گذاری داده‌های ناشناس + + اینجا را لمس کنید تا Touch ID فعال شود + + برای فعال‌سازی احراز هویت اثر انگشت اینجا ضربه بزنید + + فعال‌سازی تاچ آی‌دی + + فعال‌سازی احراز هویت اثر انگشت + + پین + + کیف پول مغزی به استفاده از یک پین ۶ رقمی ارتقا یافته است. اینجا را برای ارتقا لمس کنید. + + ارتقاء پین + + فعال کردن اعلان‌ها برای دریافت پیام‌های ویژه از Brainwallet در آینده. + + اعلان‌های پوش + + خاموش + + روی + + اعلان‌ها + + کپی شده به کلیپ‌بورد. + + ایمیل + + درخواست مبلغ + + اشتراک گذاری + + پیام متنی + + دریافت کردن + + انجام شد + + بازیابی کیف پول + + بازنشانی پین + + وارد کردن کلید کاغذی + + بازیابی کیف پول مغزی خود را با کلید کاغذی خود انجام دهید. + + کلید کاغذی که وارد کردید نامعتبر است. لطفاً هر کلمه را دوباره بررسی کنید و مجدداً تلاش کنید. + + فلش چپ + + بعدی + + برای اطلاعات بیشتر اینجا ضربه بزنید. + + فلش به سمت راست + + کلید کاغذی را برای کیف پولی که می‌خواهید بازیابی کنید، وارد نمایید. + + برای بازنشانی رمز عبور خود، کلمات کلید کاغذی خود را در کادرهای زیر وارد کنید. + + لطفاً ابتدا یک مبلغ را وارد کنید. + + درخواست مبلغ + + همگام‌سازی + + شما در حین همگام‌سازی قادر به ارسال پول نخواهید بود. + + همگام‌سازی با بلاکچین؟ + + ۲۰-۴۵ دقیقه + + اگر یک تراکنش در شبکه لایت‌کوین به عنوان تکمیل‌شده نشان داده می‌شود اما در کیف پول مغزی شما نمایش داده نمی‌شود. + + شما مکرراً خطایی دریافت می‌کنید که می‌گوید تراکنش شما رد شده است. + + شروع همگام‌سازی + + شما در حین همگام‌سازی با بلاک‌چین قادر به ارسال پول نخواهید بود. + + سینک بلاکچین + + زمان تخمینی + + چه زمانی همگام‌سازی کنیم؟ + + فلاش دوربین + + کامل + + در انتظار + + دریافت شد + + ارسال شد + + تمام ویژگی‌های امنیتی را برای حداکثر محافظت فعال کنید. + + تنها راه دسترسی به لایت‌کوین شما در صورت گم کردن یا ارتقاء تلفن همراه‌تان. + + کلید کاغذی + + محافظت از کیف پول مغزی شما در برابر کاربران غیرمجاز. + + رمز 4 رقمی + + مرکز امنیت + + به راحتی کیف پول مغزی خود را باز کنید و تا سقف مشخصی پول ارسال کنید. + + تاچ آی‌دی + + تأیید هویت اثر انگشت + + مبلغ + + موجودی: %1$s + + دسترسی دوربین را در "تنظیمات" > "برنامه‌ها" > "Brainwallet" > "مجوزها" فعال کنید + + دیوار مغزی اجازه دسترسی به دوربین را ندارد + + برای اجازه دسترسی به دوربین به تنظیمات بروید. + + دیوار مغزی اجازه دسترسی به دوربین را ندارد + + مقصد آدرس خود شماست. شما نمی‌توانید به خودتان ارسال کنید. + + نمی‌توان تراکنش را ایجاد کرد. + + یادداشت + + متن منبع برای ترجمه ارائه نشده است. + + هزینه شبکه: %1$s + + هویت گیرنده وجه تأیید نشده است. + + آدرس مقصد یک آدرس لایت‌کوین معتبر نیست. + + تخته یادداشت حاوی آدرس لایت‌کوین معتبر نیست. + + آدرس نامعتبر + + ارسال در طول اسکن مجدد کامل غیرفعال است. + + درحال بارگذاری درخواست + + لطفاً آدرس گیرنده را وارد کنید. + + لطفاً مبلغی را برای ارسال وارد کنید. + + چسباندن + + نمی‌توان تراکنش را منتشر کرد. + + نتوانست درخواست پرداخت را بارگذاری کند + + اسکن + + ارسال کنید + + ارسال کنید + + یک آدرس لایت کوین وارد کنید + + یک دامنه‌ی .crypto، .wallet، .zil، .nft، .blockchain، +.bitcoin، .coin، .888، .dao، یا .x وارد کنید. + + یا + + جستجو + + آدرس شما حل شد! + + آدرس‌های لایت‌کوین فقط برای یک بار استفاده در نظر گرفته شده‌اند. + + استفاده مجدد، حریم خصوصی را هم برای شما و هم برای گیرنده کاهش می‌دهد و می‌تواند منجر به از دست دادن [دارایی] شود اگر گیرنده به طور مستقیم کنترل آدرس را در اختیار نداشته باشد. + + آدرس قبلاً استفاده شده است + + درباره + + تنظیمات پیشرفته + + نمایش ارز + + پیوستن به دسترسی زودهنگام + + آیا از Brainwallet لذت می‌برید؟ + + وارد کردن کیف پول + + مدیریت کردن + + اعلان‌ها + + نظر خود را برای ما بنویسید + + اشتراک‌گذاری داده‌های ناشناس + + سینک بلاکچین + + تنظیمات + + حد مجاز خرج کردن با تاچ آی‌دی + + حد مجاز هزینه برای احراز هویت اثر انگشت + + کیف پول + + شروع/بازیابی کیف پول دیگر + + کمک کنید تا Brainwallet را با به اشتراک گذاری داده‌های ناشناس خود با ما بهبود دهیم. این شامل هیچ اطلاعات مالی نمی‌شود. ما به حریم خصوصی مالی شما احترام می‌گذاریم. + + اشتراک گذاری داده‌ها؟ + + اشتراک‌گذاری داده‌های ناشناس؟ + + کلید کاغذی را دوباره یادداشت کنید + + کلید کاغذی شما تنها راه برای بازیابی کیف پول مغزی شما است اگر تلفن شما گم، دزدیده، خراب یا ارتقا داده شود. + +ما فهرستی از کلمات را به شما نشان خواهیم داد تا روی یک تکه کاغذ بنویسید و در جای امنی نگه دارید. + + کلید کاغذی را یادداشت کنید + + شما آخرین بار کلید کاغذی خود را در %1$s یادداشت کردید + + امن‌ترین و ایمن‌ترین راه برای استفاده از لایت‌کوین. + + اتصال + + همگام‌سازی + + تلاش مجدد + + همگام‌سازی + + %1$s d + + %1$s h + + %1$s م + + %1$s s + + شما می‌توانید محدودیت خرج کردن Touch ID خود را از %1$s سفارشی کنید. + + شما می‌توانید محدودیت مخارج تأیید اثر انگشت خود را از صفحه محدودیت مخارج تأیید اثر انگشت سفارشی کنید + + شما احراز هویت اثر انگشت را در این دستگاه فعال نکرده‌اید. به تنظیمات -> امنیت بروید تا احراز هویت اثر انگشت را راه‌اندازی کنید. + + احراز هویت اثر انگشت فعال نیست + + از اثر انگشت خود برای باز کردن قفل کیف پول مغزی خود استفاده کنید و تا سقف تعیین شده پول ارسال کنید. + + صفحه محدودیت هزینه تاچ آیدی + + محدودیت هزینه: %1$s (%2$s) + + فعال‌سازی تاچ آیدی برای کیف پول مغزی + + فعال‌سازی احراز هویت اثر انگشت + + تاچ آی‌دی + + تأیید هویت اثر انگشت + + شما Touch ID را روی این دستگاه راه‌اندازی نکرده‌اید. به تنظیمات -> شناسه لمسی و رمز عبور بروید تا آن را اکنون راه‌اندازی کنید. + + تاچ آی‌دی تنظیم نشده است + + همیشه رمز عبور را الزامی کنید + + شما برای ارسال هر تراکنش بیش از حد مجاز خرج کردن خود، و هر ۴۸ ساعت از آخرین باری که رمز ۶ رقمی خود را وارد کرده‌اید، باید رمز ۶ رقمی خود را وارد کنید. + + حد مجاز خرج کردن با تاچ آی‌دی + + محدودیت هزینه تأیید اثر انگشت + + موجودی قابل خرج + + کامل + + موجودی پایانی: %1$s + + نرخ ارز هنگام دریافت: + + نرخ ارز هنگام ارسال: + + (%1$s هزینه) + + نامعتبر + + همین الان + + در حال پیشرفت: %1$s + + در حال پیشرفت: %1$s + + موجودی اولیه: %1$s + + منتظر تایید هستم. برخی از فروشندگان برای تکمیل تراکنش نیاز به تأیید دارند. زمان تخمینی: ۱-۲ ساعت. + + حساب + + مبلغ + + تایید شده در بلاک + + یادداشت + + تراکنش‌های شما اینجا نمایش داده خواهند شد. + + در %1$s + + بیشتر... + + انتقال یافت %1$s + + منتقل شد %1$s + + تایید نشده + + دریافت شد %1$s + + دریافت شد %1$s + + ارسال %1$sشد + + ارسال شد %1$s + + وضعیت + + جزئیات تراکنش + + به %1$s + + شناسه تراکنش لایت کوین + + دریافت شده در این آدرس + + ارسال شده به این آدرس + + معلول تا: %1$s + + آدرس من + + بازنشانی پین + + اسکن + + وارد کردن پین + + سنسور لمسی + + باز کردن قفل کیف پول مغزی شما. + + لطفاً دستگاه اندروید خود را برای ادامه باز کنید. + + باز کردن با تاچ آی‌دی + + مشاهده در بلاک‌چین + + احراز هویت لازم است + + کیف پول باز شد + + فراموش کردن عبارت بازیابی یا پین؟ + + این پین را به خاطر بسپارید. اگر آن را فراموش کنید، نمی‌توانید به لایت‌کوین خود دسترسی داشته باشید. + + رمز شما برای باز کردن قفل کیف پول مغزی شما و ارسال پول استفاده خواهد شد. + + تنظیم پین + + وارد کردن مجدد پین + + پین فعلی خود را وارد کنید. + + پین جدید خود را وارد کنید. + + پین جدید خود را دوباره وارد کنید. + + متأسفانه، نمی‌توان پین را به‌روزرسانی کرد. + + خطای به‌روزرسانی پین + + بروزرسانی پین + + آدرس‌های کیف پول به کلیپ‌بورد کپی شوند؟ + + اجازه کپی آدرس کیف پول در کلیپ‌بورد + + کپی آدرس‌های کیف پول + + کپی + + لطفاً برای تأیید این تراکنش، رمز عبور خود را وارد کنید. + + لطفاً برای ادامه، پین خود را وارد کنید. + + رمز مورد نیاز است + + تأیید این تراکنش + + برنامه Brainwallet آیفون را باز کنید تا کیف پول خود را راه‌اندازی کنید. + + رد کردن + + خطایی در بارگذاری محتوا رخ داد. لطفاً دوباره تلاش کنید. + + در حال به‌روزرسانی... + + برین‌والت به‌تازگی به‌روزرسانی شده است! \nاگر به کمک نیاز دارید، دنبال علامت (؟) در گوشه بالا سمت راست اکثر صفحات بگردید. + + به کیف پول مغزی خوش آمدید! + + آیا مطمئن هستید که می‌خواهید این کیف پول را حذف کنید؟ + + پاک کردن کیف پول؟ + + عدم موفقیت در پاک کردن کیف پول. + + شکست خورده + + برای شروع یک کیف پول جدید یا بازیابی یک کیف پول موجود، ابتدا باید کیف پولی که در حال حاضر نصب شده است را پاک کنید. برای ادامه، کلید کاغذی کیف پول فعلی را وارد کنید. + + شروع یا بازیابی کیف پول دیگر به شما امکان می‌دهد تا به یک Brainwallet متفاوت در این دستگاه دسترسی داشته باشید و آن را مدیریت کنید. + + کیف پول فعلی شما از این دستگاه حذف خواهد شد. اگر می‌خواهید در آینده آن را بازیابی کنید، باید کلید کاغذی خود را وارد کنید. + + شروع یا بازیابی کیف پول دیگر + + پاک کردن + + پاک کردن... + + هر کلمه را به ترتیب بنویسید و آن را در مکانی امن نگهداری کنید. + + بعدی + + قبلی + + %1$dاز%2$d + زمان پردازش: این تراکنش‌ها %1$s دقیقه برای پردازش زمان خواهند برد. + آدرس: + لوکس + ۲.۵ - ۵+ دقیقه + این گزینه تقریباً تضمین می‌کند که تراکنش شما پذیرفته می‌شود، اگرچه شما هزینه بیشتری پرداخت می‌کنید. + + مون‌پی + «• خرید LTC با جفت‌های متعدد ارز فیات +• پرداخت با روش‌های متنوع +• ارائه‌دهنده پرداخت جهانی» + بیت‌ریفیل + «• خرید کارت‌های هدیه +• شارژ تلفن‌های پیش‌پرداخت +• استیم، آمازون، Hotels.com +• در ۱۷۰ کشور قابل استفاده است» + دلار استرالیا + پوند استرلینگ + هنگ کنگ دلار + ریال ایران + روبل + اس‌جی‌دی + کد + یورو + ین ژاپن + دلار آمریکا + تاریخ + + تعادل + 1 LTC = %1$s + ارزش فعلی LTC در %1$s + زبان‌ها + آیا مطمئن هستید که می‌خواهید زبان را به انگلیسی تغییر دهید؟ + بستن + + اینستاگرام + ۱: %s ۲: %s ۳: %s ۴: %s \\n۵: %s ۶: %s ۷: %s ۸: %s%s \\n۹: %s ۱۰: %s ۱۱: %s ۱۲: %s %s + نمایش + نمایش عبارت بازیابی من + ترجیح همگام‌سازی: %1$s مثبت‌های کاذب + حریم خصوصی کم (حدود ۴۵ دقیقه) + نیمه خصوصی (~۶۰ دقیقه) + ناشناس (~77 دقیقه) + مهم: برنامه برای اجازه دادن به آدرس‌های 1ltc همگام‌سازی خواهد شد. منتظر بمانید ~1 ساعت برای همگام‌سازی! + + چیزی را از دست ندهید! + بستن + برای دریافت اطلاعات درباره به‌روزرسانی‌ها و مسابقات از تیم Brainwallet ثبت‌نام کنید! پذیرش اعلان‌ها برای دریافت اخبار زنده، قیمت و اطلاعات بازار! + نه، ممنون! + خدمات + هزینه‌ها: + عمومی + اخبار لایت کوین + بروزرسانی کیف پول مغزی + لغو + باشه + لطفاً اجازه اعلان را صادر کنید + اطلاعات مجوز + مجوز اعلان اعطا شد + + + بازگشت + کلمات بذر شما + "فقط برای تو. \n این است" کلید خصوصی "که به شما اجازه می‌دهد ارسال کنید." + بلاک‌چین: لایت‌کوین + من آن را روی کاغذ یا فلز ذخیره کردم + شما ذخیره‌اش کردی، درسته؟ + اثباتش کن! +کلمات را به ترتیب صحیح بکشید. + بازی و همگام‌سازی + آماده‌اید؟ + برای شما انجام می‌دهم. لطفاً انجامش بده + تنها + یک قلم، کاغذ و ۵ دقیقه بردارید + تنظیم رمز عبور برنامه + یک رمز عبور را برای باز کردن قفل کیف پول مغزی خود انتخاب کنید + قفل تلفن نیست! + متفاوتش کن. خنک کنید. + استفاده از بیومتریک + کلیدهای خود را ذخیره کردید. + سطح بعدی را در هم بکوب. + روی یک کلمه ضربه بزنید و آن را به محل مورد نظر بکشید + شارژ کنم؟ + الان ذهن شما خالی است... + دریافت لایت کوین در ۵ دقیقه + لایت کوین بگیرید! + شاید بعداً. + رد کردن + بازیابی قدرت خود + می‌توانی به جایی که از آن شروع کردی برگردی + بازیابی کیف پول مغزی من + صاف + حدس نزن.\n\nبرای این کار به \n۵,۴۴۴,۵۱۷,۹۵۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰,۰۰۰, تلاش نیاز دارید. + تایید + فراموش نکردی، مگه نه؟ وارد کنید دوباره. یا، به عقب برگردید تا از ابتدا شروع کنید. + آماده + بازیابی + رمز عبور نادرست، لطفاً دوباره تلاش کنید! + فلش به سمت پایین و چپ + لوگو + تغییر حالت تاریک + قفل-حالت-تغییر + امنیت + زبان + ارز + بازی‌ها + پشتیبانی + رسانه‌های اجتماعی + قفل + باز کردن + موضوع + نسخه برنامه: + همگام‌سازی فراداده‌ها: + همگام‌سازی + مدت همگام‌سازی: >۲۰ دقیقه + بازی %1$d: + %s + %s + %s + %s + پین + عبارت بازیابی + عبارت کیف پول مغزی + اشتراک‌گذاری داده‌های تحلیلی + بروزرسانی پین + نمایش + خرید LTC + با پشتیبانی مون‌پی + در حال بارگذاری... + کارمزد شبکه (به ازای هر کیلوبایت): مقدار بالاتر به معنای تکمیل سریع‌تر تراکنش است + بالا + متوسط + کم + مبلغ کمتر از حد مجاز (%f) است + مقدار از حد مجاز (%f) بیشتر است + خرید لایت کوین + به آدرس LTC شما واریز شود: + خرید با مون‌پی + آدرس جدید + خرید / دریافت + سفارشی + بازنشانی / شروع مجدد + \ No newline at end of file diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml new file mode 100644 index 00000000..4e8aa15c --- /dev/null +++ b/app/src/main/res/values-pa/strings.xml @@ -0,0 +1,846 @@ + + + + + ویب سائٹ + + + + پرائیویسی پالیسی + + + استعمال کی شرائط + + متعلق + + ٹوئٹر + + بند کرو + + سپورٹ سینٹر + + + + لگدا اے کہ تُسی تیسری پارٹی دا کی بورڈ استعمال کر رہے او، جو تُہاڈا لکھیا ہویا ریکارڈ کر سکدا اے تے تُہاڈی پیپر کی چُرا سکدا اے۔ مہربانی کرکے اضافی تحفظ کے لیے ڈیفالٹ اینڈرائیڈ کی بورڈ پر سوئچ کریں۔ + + غلطی + + تہاڈے اینڈرائیڈ او ایس کی اسٹور وچ کوئی مسئلہ ہے، مہربانی کرکے support.brainwallet.co نال رابطہ کرو۔ + + تہاڈا برین والٹ انکرپٹڈ ڈیٹا حال ہی وچ غیر مؤثر ہو گیا سی کیونجے تہانڈا اینڈرائیڈ لاک سکرین غیر فعال کر دتا گیا سی۔ + + اینڈرائیڈ کی اسٹور خرابی + + کوئی انٹرنیٹ کنکشن نہیں ملا۔ اپنا کنکشن چیک کرو تے دوبارہ کوشش کرو۔ + + انتباہ + + پتے کاپی ہو گئے ہیں۔ + + تمام والٹ ایڈریس کامیابی سے کاپی ہو گئے ہیں۔ + + پیپر کی سیٹ + + کمال! + + پن سیٹ + + بھیجنا ناکام ہوگیا۔ + + تصدیق بھیجو + + پیسے بھیج دیے گئے! + + فنگرپرنٹ تسلیم شدہ ہے۔ + + JSON سیریلائزیشن خرابی + + پرس تیار نہیں ہے۔ + + اے پی آئی ٹوکن حاصل کرنے میں ناکام + + منسوخ کریں۔ + + نظر انداز کریں۔ + + مینؤں + + نہیں + + ٹھیک ہے۔ + + وصول کرنا + + بھیجیں + + ترتیبات + + جمع کرو + + جی ہاں + + بھیجنے والی رقم: + + نیٹ ورک فیس: + + نیٹ ورک + + پروسسنگ وقت: اس لین دین کے مکمل ہونے کی پیش گوئی %1$s میں کی گئی ہے۔ + + بھیجو + + تصدیق + + نو + + کل لاگت: + + یقینی بنانے کے لیے کہ سب کچھ صحیح طریقے سے لکھا گیا ہے، براہ کرم اپنے پیپر کی کی سے مندرجہ ذیل الفاظ درج کریں۔ + + لفظ #%1$s + + لائٹ کوائن ڈسپلے یونٹ + + تبادلہ ریٹ + + + + برین والٹ کو آپ کے اینڈرائیڈ کے ورژن میں ایک بگ کی وجہ سے تصدیق نہیں کی جا سکتی۔ [مزید معلومات کے لیے یہاں ٹیپ کریں۔] + + یہ ڈیوائس پیغامات بھیجنے کے لیے ترتیب نہیں دی گئی۔ + + پیغام رسانی دستیاب نہیں ہے۔ + + فنگر پرنٹ تسلیم نہیں ہوا۔ براہ کرم دوبارہ کوشش کریں۔ + + معیشت + + 10+ منٹ + + یہ آپشن وقت حساس لین دین کے لیے تجویز نہیں کی جاتی۔ + + متوقع ترسیل: %1$s + + باقاعدہ + + ۲.۵ - ۵+ منٹ + + پروسيسنگ سپیڈ + + پرائیویٹ کی بیلنس چیک کر رہے ہیں... + + کیا آپ اس پرائیویٹ کی سے %1$s کو اپنی والٹ میں بھیجنا چاہتے ہیں؟ لائٹ کوائن نیٹ ورک کو %2$s کی فیس موصول ہوگی۔ + + یہ نجی کلید پہلے ہی آپ کے والٹ میں موجود ہے۔ + + یہ نجی کلید خالی ہے۔ + + لین دین دی فیس اس نجی کلید اُتے موجود فنڈز توں زیادہ خرچ ہووے گی۔ + + نجی کلید درست نہیں ہے۔ + + ٹرانزیکشن سائن کرنے میں غلطی + + درآمد + + والٹ درآمد کرنا + + پرس درآمد کرنا ہے۔ + + ایک والٹ کو درآمد کرنے سے آپ کے دوسرے والٹ سے سارا پیسہ ایک ہی لین دین کے ذریعے آپ کے برین والٹ میں منتقل ہو جاتا ہے۔ + + یہ نجی کلید پاس ورڈ سے محفوظ ہے۔ + + پاسورڈ + + + پرائیویٹ کی سکین کریں + + کامیابی + + والٹ کامیابی سے درآمد ہو گیا۔ + + والٹ درآمد کرو + + کلیدی کھولنا + + پرس درآمد کرنے سے لین دین کی تاریخ یا دیگر تفصیلات شامل نہیں ہوتیں۔ + + غلط پاسورڈ، براہ کرم دوبارہ کوشش کریں۔ + + نظر انداز کریں + + ڈیوائس سیکیورٹی متاثر\n کوئی بھی \'جیل بریک\' ایپ کی چین ڈیٹا تک رسائی حاصل کر سکتی ہے اور آپ کے لائٹ کوائن چرا سکتی ہے! اس والٹ کو فوراً صاف کریں اور کسی محفوظ ڈیوائس پر بحال کریں۔ + + ڈیوائس سیکیورٹی متاثر\n کوئی بھی \'جیلبریک\' ایپ کی چین ڈیٹا تک رسائی حاصل کر سکتی ہے اور آپ کے لائٹ کوائن چرا سکتی ہے۔ براہ کرم صرف برین والٹ کو غیر جیل بریک شدہ ڈیوائس پر استعمال کریں۔ + + خبردار + + لوکیشن سروسز غیر فعال ہیں۔ + + برین والٹ کو مقام کی خدمات تک رسائی کی اجازت نہیں ہے۔ + + تُسیں اپنا والٹ %1$s اُتے بنایا۔ + + تہاڈے والٹ دا ناں صرف تہاڈی اکاؤنٹ ٹرانزیکشن ہسٹری وچ ہی نظر آندا اے تے کسے ہور نوں نظر نہیں آ سکدا۔ + + پرس دا ناں + + پرس سنبھالیں + + خریدیں۔ + + لاک والیٹ + + سیکیورٹی سینٹر + + ترتیبات + + گاہک کی حمایت + + نواں والٹ بناؤ + + مینؤ + + والٹ بحال کریں + + خودکار موڈ پر سوئچ کریں۔ + + مربوط + + نوڈ آئی پی ایڈریس اور پورٹ درج کریں (اختیاری) + + نوڈ داخل کریں۔ + + دستی موڈ پر سوئچ کریں۔ + + موجودہ پرائمری نوڈ + + کنیکٹڈ نہیں ہے۔ + + نوڈ کنکشن کی حالت + + لائٹ کوائن نوڈز + + ناقص ادائیگی کی درخواست + + غیر معاون یا خراب شدہ دستاویز + + گمشدہ سرٹیفکیٹ + + درخواست کی میعاد ختم ہو گئی ہے۔ + + ادائیگی نہیں ہو سکی۔ + + لائٹ کوائن ادائیگیاں %1$s سے کم نہیں ہو سکتیں۔ + + لائٹ کوائن ٹرانزیکشن آؤٹ پُٹس %1$s سے کم نہیں ہو سکتے۔ + + غیر معاون دستخط قسم + + غیر معتبر سرٹیفکیٹ + + آپ کے والٹ کی حفاظت کے لیے ایک ڈیوائس پاسکوڈ کی ضرورت ہے۔ سیٹنگز وچ جاؤ تے پاسکوڈ آن کرو۔ + + ڈیوائس پاسکوڈ آن کرو + + آپ کے بٹوے کی حفاظت کے لیے ایک ڈیوائس سکرین لاک کی ضرورت ہے۔ "سیٹنگز" > "سیکیورٹی" > "سکرین لاک" پر جائیں اور جاری رکھنے کے لیے فعال کریں۔ + + سکرین لاک غیر فعال کر دیا گیا ہے۔ + + تہاڈا پیپر کی محفوظ رکھنا لازمی ہے جے کدے تہاڈا فون کھو جائے یا تبدیل ہو جائے۔ یہاں جاری رکھنے کے لیے ٹیپ کریں۔ + + عمل درکار ہے + + تُہاڈا والٹ شاید ہم آہنگی وچ نہیں۔ یہ اکثر بلاک چین کو دوبارہ سکین کر کے ٹھیک کیا جا سکتا ہے۔ + + لین دین مسترد کر دیا گیا ہے۔ + + برین والٹ کو بہتر بنانے میں مدد کریں اور اپنا گمنام ڈیٹا ہمارے ساتھ شیئر کریں۔ + + گمنام ڈیٹا شیئر کرو + + یہاں ٹیپ کریں تاکہ ٹچ آئی ڈی فعال ہو سکے۔ + + یہاں تھپتھپائیں تاکہ فنگر پرنٹ تصدیق فعال ہو سکے۔ + + ٹچ آئی ڈی فعال کریں۔ + + فنگرپرنٹ تصدیق کو فعال کریں۔ + + پن + + برین والٹ نے 6-عددی پن کا استعمال اپ گریڈ کر لیا ہے۔ یہاں اپگریڈ کرنے کے لیے ٹیپ کریں۔ + + پن اپگریڈ کریں + + نوٹیفکیشنز آن کرو تاکہ مستقبل وچ برین والٹ توں خاص پیغامات حاصل کر سکو۔ + + پُش نوٹیفکیشنز + + بند + + تے + + اطلاعات + + کلپ بورڈ وچ نقل کیتا گیا۔ + + ای میل + + رقم دی درخواست کرو + + شئیر + + پیغام + + وصول کرو + + مکمل ہو گیا۔ + + والٹ بحال کریں + + پن کو دوبارہ سیٹ کریں + + پیپر کی کلید درج کریں۔ + + اپنے برین والٹ کو اپنے پیپر کی کے ساتھ بحال کریں۔ + + تُسیں داخل کیتا ہویا پیپر کلید غلط ہے۔ براہ کرم ہر لفظ کو دوبارہ چیک کریں اور دوبارہ کوشش کریں۔ + + بائیں تیر + + اگلا + + یہاں مزید معلومات کے لیے ٹیپ کریں۔ + + دائیں تیر + + براہ کرم اُس والٹ کے لیے پیپر کی درج کریں جسے آپ بحال کرنا چاہتے ہیں۔ + + اپنا پن ری سیٹ کرنے کے لیے، نیچے دیے گئے خانوں میں اپنے پیپر کی کی الفاظ درج کریں۔ + + مہربانی کرکے پہلے ایک رقم درج کریں۔ + + رقم دی درخواست کرو + + ہم آہنگی + + تُسیں پیسے نہیں بھیج سکدے جدو تک ہم آہنگی ہو رہی ہے۔ + + بلاک چین کے ساتھ ہم آہنگی؟ + + ۲۰-۴۵ منٹ + + اگر لائٹ کوائن نیٹ ورک\'تے کوئی لین دین مکمل ہو کے وکھائی دیوے پر تُہاڈے برین والٹ \'چ نہ ہووے۔ + + تُسیں بار بار اِک غلطی دا سامنا کر رہے ہو کہ تُہاڈی ٹرانزیکشن رد کر دِتی گئی اے۔ + + آغاز ہم آہنگی + + تُسیں بلاک چین نال ہم آہنگی کرن دوران پیسے نہیں بھیج سکدے۔ + + سنگ بلاک چین + + تخمینہ شدہ وقت + + کدوں ہم آہنگ کرنا ہے؟ + + کیمرہ فلیش + + مکمل + + زیر التواء + + موصول ہويا + + بھیجیا گیا + + تمام سیکیورٹی خصوصیات کو زیادہ سے زیادہ تحفظ کے لیے فعال کریں۔ + + اگر آپ اپنا فون کھو دیتے ہیں یا اپ گریڈ کرتے ہیں تو اپنے لائٹ کوائن تک رسائی حاصل کرنے کا واحد طریقہ۔ + + پیپر کیی + + آپ کے برین والٹ کو غیر مجاز صارفین سے محفوظ رکھتا ہے۔ + + ۴-عددی پن کوڈ + + سیکیورٹی سینٹر + + آسانی سے اپنا برین والٹ کھولیں اور مقررہ حد تک پیسے بھیجیں۔ + + ٹچ آئی ڈی + + فنگرپرنٹ تصدیق + + رقم + + توازن: %1$s + + "سیٹنگز" > "ایپس" > "برین والٹ" > "پرمیشرز" وچ کیمرہ رسائی دی اجازت دو۔ + + برین والٹ کو کیمرے تک رسائی کی اجازت نہیں ہے۔ + + کیمرہ رسائی کی اجازت دینے کے لیے سیٹنگز پر جائیں۔ + + برین والٹ کو کیمرے تک رسائی کی اجازت نہیں ہے۔ + + منزل مقصود آپنا پتہ ہے۔ تُسیں اپنے آپ نوں نہیں بھیج سکدے۔ + + لین دین پیدا نہیں ہو سکی۔ + + یادداشت + + پیسٹ بورڈ خالی ہے۔ + + نیٹ ورک فیس: %1$s + + ادائیگی کنندہ کی شناخت تصدیق شدہ نہیں ہے۔ + + منزل دا پتہ ایک درست لائٹ کوائن پتہ نہیں ہے۔ + + پیسٹ بورڈ وچ کوئی صحیح لائٹ کوائن پتہ موجود نہیں۔ + + غلط پتہ + + مکمل دوبارہ سکیننگ کے دوران بھیجنا غیر فعال ہے۔ + + درخواست لوڈ ہو رہی ہے۔ + + براہ کرم وصول کنندہ کا پتہ درج کریں۔ + + براہ کرم بھیجنے کے لیے رقم درج کریں۔ + + پیسٹ + + لین دین شائع نہیں ہو سکی۔ + + ادائیگی کی درخواست لوڈ نہیں ہو سکی۔ + + سکین + + بھیجو + + بھیجیں + + لائٹ کوائن پتہ درج کریں۔ + + .کرپٹو، .والٹ، .زیل، .این ایف ٹی، .بلاکچین، .بٹکوائن، .کوائن، .۸۸۸، .ڈاؤ، یا .ایکس ڈومین درج کریں۔ + + یا + + تلاش + + تہاڈا پتہ حل ہو گیا! + + لائٹ کوائن پتہ جات صرف ایک بار استعمال کے لیے بنائے گئے ہیں۔ + + دوبارہ استعمال کرنا آپ اور وصول کنندہ دونوں کے لیے پرائیویسی کو کم کرتا ہے اور اگر وصول کنندہ پتہ کو براہ راست کنٹرول نہیں کرتا تو نقصان کا باعث بن سکتا ہے۔ + + پتہ پہلے ہی استعمال ہو چکا ہے۔ + + متعلق + + ترقی یافتہ ترتیبات + + کرنسی دکھاؤ + + ابتدائی رسائی میں شامل ہوں۔ + + کیا تسی برین والٹ دا لطف لے رہے ہو؟ + + والٹ درآمد کرو + + مینج + + اطلاعات + + ساڈے لئی ریویو چھوڑو + + گمنام ڈیٹا شیئر کرو + + سنگ بلاک چین + + سیٹنگز + + ٹچ آئی ڈی خرچ کرنے دی حد + + فنگر پرنٹ تصدیق خرچ کرنے دی حد + + پرس + + شروع/دوسرا والٹ بحال کریں + + برین والٹ کو بہتر بنانے میں مدد کریں اور اپنا گمنام ڈیٹا ہمارے ساتھ شیئر کریں۔ یہ کسی مالی معلومات کو شامل نہیں کرتا۔ اسیٰ توہاڈی مالی رازداری دی عزت کردے آں۔ + + ڈیٹا شیئر کرو؟ + + گمنام ڈیٹا شیئر کرو؟ + + کاغذ دی چابی دوبارہ لکھو + + تہاڈا پیپر کی واحد طریقہ ہے جڑا تہاڈی برین والٹ نوں بحال کر سکدا اے جے کر تہاڈا فون کھو جائے، چوری ہو جائے، ٹٹ جائے، یا اپگریڈ ہو جائے۔ + +اسی تہانوں کچھ الفاظ دی لسٹ دکھاواں گے جِنہاں نوں تسی کاغذ اُتے لکھ کے محفوظ رکھنا اے۔ + + کاغذ دی چابی لکھو + + تُسیں آخری واری اپنا پیپر کی %1$s اُتے لکھیا۔ + + لائٹ کوائن استعمال کرنے کا سب سے محفوظ اور محفوظ طریقہ۔ + + کنیکٹ کرنا + + ہم آہنگی + + دوبارہ کوشش کریں۔ + + ہم آہنگی + + %1$s د + + %1$s ہ + + %1$s م + + %1$s س + + تُسیں اپنے ٹچ آئی ڈی خرچ دی حد نوں %1$s توں حسب ضرورت تبدیل کر سکدے ہو۔ + + تُسیں فنگرپرنٹ اتھارائزیشن سپینڈنگ لِمٹ سکرین توں اپنی فنگرپرنٹ آتھنٹیکیشن خرچ دی حد نوں اپنی مرضی دے مطابق بنا سکدے ہو۔ + + تُسیں اس ڈیوائس اُتے فنگرپرنٹ تصدیق فعال نہیں کیتی۔ سیٹنگز -> سیکیورٹی پر جائیں تاکہ فنگر پرنٹ تصدیق کو سیٹ اپ کریں۔ + + فنگر پرنٹ تصدیق فعال نہیں ہے۔ + + اپنی برین والٹ کو ان لاک کرنے اور مقررہ حد تک پیسے بھیجنے کے لیے اپنی فنگر پرنٹ کا استعمال کریں۔ + + ٹچ آئی ڈی خرچ کرنے کی حد سکرین + + خرچ دی حد: %1$s (%2$s) + + برین والٹ لئی ٹچ آئی ڈی فعال کرو۔ + + فنگر پرنٹ تصدیق کو فعال کریں۔ + + ٹچ آئی ڈی + + فنگرپرنٹ تصدیق + + تُسیں اس ڈیوائس اُتے ٹچ آئی ڈی سیٹ نئیں کیتا۔ سیٹنگز->ٹچ آئی ڈی & پاسکوڈ پر جا کر اسے ابھی سیٹ اپ کریں۔ + + ٹچ آئی ڈی سیٹ اپ نہیں ہوئی + + ہمیشہ پاسکوڈ کی ضرورت ہے۔ + + تُسیں کسے وی خرچ دی حد توں وادھ لین دین بھیجݨ لئی اپنا 6-عددی پن درج کرݨ لئی پُچھے جاوگے، تے ہر 48 کنٹے بعد جدو تُسیں آخری واری اپنا 6-عددی پن درج کیتا سی۔ + + ٹچ آئی ڈی خرچ کرنے دی حد + + فنگرپرنٹ اجازت خرچ کرنے دی حد + + خرچ کرنے کے لئے دستیاب ہے۔ + + مکمل + + آخری بیلنس: %1$s + + موصول ہونے پر تبادلہ ریٹ: + + بھیجتے وقت تبادلہ ریٹ: + + (%1$sفیس) + + غلط + + ابھی ہال ہی میں + + جاری ہے: %1$s + + جاری ہے: %1$s + + آغازي بیلنس: %1$s + + تصدیق ہونے کا انتظار ہے۔ کچھ تاجران کو لین دین مکمل کرنے کے لیے تصدیق کی ضرورت ہوتی ہے۔ تخمینہ شدہ وقت: 1-2 گھنٹے۔ + + کھاتہ + + رقم + + تصدیق شدہ بلاک میں + + یادداشت + + تہاڈیاں لین دین اتھے نظر آون گیاں۔ + + پر%1$s + + زیادہ... + + منتقل ہو گیا %1$s + + منتقل ہوگیا %1$s + + تصدیق نہیں ہوئی + + موصول ہو گیا %1$s + + موصول ہويا %1$s + + بھیجیا گیا %1$s + + بھیجیا گیا %1$s + + حالت + + ٹرانزیکشن کی تفصیلات + + نو %1$s + + لائٹ کوائن ٹرانزیکشن آئی ڈی + + اس پتے پر موصول ہوا۔ + + اس پتے پر بھیجا گیا + + معذور ہے تآنکہ: %1$s + + میرا پتہ + + پن کو دوبارہ مقرر کریں + + سکین + + پن درج کریں۔ + + ٹچ سینسر + + اپنا برین والٹ کھولیں۔ + + براہ کرم جاری رکھنے کے لیے اپنی اینڈرائیڈ ڈیوائس کو ان لاک کریں۔ + + ٹچ آئی ڈی نال کھولو۔ + + بلاک چین پر دیکھیں + + تصدیق درکار ہے۔ + + پرس کھل گیا + + اپنا سیڈ فریز یا پن بھول گئے؟ + + یاد رکھو اس پن کو۔ اگر تُسیں ایہہ بھُل جاندے او، تے تُسیں اپنی لائٹ کوائن تک رسائی حاصل نہیں کر سکوں گے۔ + + تہاڈا پن کوڈ توہاڈی برین والٹ کھولن لئی تے پیسے بھیجن لئی استعمال ہووے گا۔ + + پن سیٹ کرو + + پن کو دوبارہ درج کریں۔ + + اپنا موجودہ پن درج کریں۔ + + اپنا نواں پن درج کرو۔ + + اپنا نواں پن دوبارہ درج کرو۔ + + معاف کرنا، پن اپڈیٹ نہیں ہو سکی۔ + + پن کو اپڈیٹ کرنے میں غلطی + + پن کو اپڈیٹ کریں + + والٹ پتہ جات کلپ بورڈ پر کاپی کریں؟ + + کلپ بورڈ پر والٹ ایڈریس کاپی کرنے کی اجازت دیں۔ + + والٹ پتہ جات کاپی کرو + + نقل کریں۔ + + براہ کرم اس لین دین کی اجازت دینے کے لیے اپنا پن درج کریں۔ + + براہ کرم جاری رکھنے کے لیے اپنا پن درج کریں۔ + + پن درکار ہے۔ + + اس لین دین کی اجازت دیں۔ + + برین والٹ آئی فون ایپ کھولیں تاکہ آپ اپنی والٹ سیٹ اپ کر سکیں۔ + + برخاست کریں۔ + + مواد لوڈ کرنے میں ایک غلطی ہوئی۔ براہ کرم دوبارہ کوشش کریں۔ + + اپ ڈیٹ ہو رہا ہے... + + برین والٹ نے ابھی تازہ کاری کی ہے! \nاگر آپ کو مدد کی ضرورت ہے، تو زیادہ تر سکرینوں کے اوپر دائیں جانب موجود (?) کو دیکھیں۔ + + برین والٹ میں خوش آمدید! + + کیا تسی یقین نال ایہہ والٹ حذف کرنا چوندے او؟ + + پرس صاف کرو؟ + + پرس صاف کرنے میں ناکام۔ + + ناکام ہو گیا۔ + + نواں والٹ شروع کرنے یا موجودہ والٹ بحال کرنے لئی، تہانوں پہلاں اوس والٹ نوں مٹانا پوے گا جو اس وقت انسٹال ہے۔ جاری رکھنے کے لیے، موجودہ والٹ کی پیپر کی درج کریں۔ + + کسی ہور والٹ نوں شروع کرنا یا بحال کرنا تہاڈے لئی اس ڈیوائس اُتے اک مختلف برین والٹ تک رسائی حاصل کرنا تے اس نوں منیج کرنا ممکن بناندا اے۔ + + آپ کا موجودہ والٹ اس ڈیوائس سے ہٹا دیا جائے گا۔ اگر تسی اسے مستقبل وچ بحال کرنا چاهندے ہو، تاں تہانوں اپنا پیپر کی داخل کرنا پوے گا۔ + + دوسرا والٹ شروع یا بحال کریں + + پونچھو + + صاف کرنا... + + ہر لفظ کو ترتیب سے لکھو اور اسے محفوظ جگہ پر رکھو۔ + + اگلا + + پچھلا + + ت%1$dصویر%2$d 1 دی تصویر 2 نال موازنہ + پروسسنگ وقت: ایہہ لین دین %1$s منٹ لیں گے پروسس کرنے لئی۔ + پتہ: + عیش + ۲.۵ - ۵+ منٹ + یہ آپشن عملی طور پر آپ کے لین دین کی منظوری کی ضمانت دیتا ہے حالانکہ آپ ایک اضافی قیمت ادا کر رہے ہیں۔ + + مون پے + "• ایل ٹی سی کو کئی فیاٹ جوڑوں کے ساتھ خریدیں\n• متعدد طریقوں سے ادائیگی کریں\n• عالمی ادائیگی فراہم کنندہ" + بِٹریفِل + "• تحفے کے کارڈ خریدیں\n• پری پیڈ فونز کو ریفل کریں\n• سٹیم، ایمیزون، ہوٹلز ڈاٹ کام\n• 170 ممالک میں کام کرتا ہے" + اے یو ڈی + پاؤنڈ سٹرلنگ + ایچ کے ڈی + آئی ڈی آر + رُوب + ایس جی ڈی + سی اے ڈی + یورو + جے پی وائی + امریکی ڈالر + تاریخ + + توازن + 1 ایل ٹی سی = %1$s + موجودہ ایل ٹی سی قیمت %1$s میں + زبانیں + کیا آپ واقعی زبان کو انگریزی میں تبدیل کرنا چاہتے ہیں؟ + بند کرو + + انسٹاگرام + 1: %s 2: %s 3: %s 4: %s \\n5: %s 6: %s 7: %s 8: %s%s \\n9: %s 10: %s 11: %s 12: %s %s + شو + میری سیڈ فریس دکھاؤ + ترجیح ہم آہنگی: %1$s غلط مثبتیاں + کم پرائیویسی (تقریباً 45 منٹ) + نیم نجی (تقریباً 60 منٹ) + گمنام (تقریباً 77 منٹ) + اہم: ایپ 1ltc پتوں کو ہم آہنگ کرنے کی اجازت دے گی۔ تقریباً 1 گھنٹہ انتظار کریں تاکہ ہم آہنگی ہو سکے! + + کچھ وی نہ چھڈو! + بند کرو + برین والٹ ٹیم کی طرف سے اپڈیٹس اور مقابلوں کے بارے میں سننے کے لیے سائن اپ کریں! نوٹیفکیشنز قبول کرو تاکہ آپ کو لائیو خبریں، قیمتیں، اور مارکیٹ کی معلومات مل سکیں! + نہیں، شکریہ! + سروس + فیس: + جنرل + لائٹ کوائن خبریں + برین والٹ اپڈیٹ + منسوخ کریں۔ + ٹھیک ہے۔ + براہ کرم اطلاع کی اجازت دیں۔ + اجازت کی معلومات + اطلاع دی اجازت دیتی گئی ہے۔ + + + واپس + تہاڈے بیج دے الفاظ + "صرف آپ کے لئے۔ +یہ ہے" نجی کلید جو تہانوں پیغام بھیجنے دی اجازت دیندا اے۔ + بلاک چین: لائٹ کوائن + میں نے اِسے کاغذ یا دھات پر محفوظ کر لیا۔ + تُسیں اِس نُوں بچا لیا، ٹھیک؟ + ثابت کرو! \nالفاظ نوں صحیح ترتیب وچ کھچو۔ + گیم اینڈ سنک + تیار؟ + اے اپنے لئی کرو۔ براہ کرم یہ کریں۔ + اکیلا + قلم، کاغذ تے 5 منٹ لَے لو۔ + ایپ پاسکوڈ سیٹ کریں + اپنے برین والٹ کو ان لاک کرنے کے لیے ایک پاس کوڈ منتخب کریں۔ + فون لاک کوڈ نہیں! + اسے مختلف بناؤ۔ اسنوں ٹھنڈا بنا دو۔ + بایومیٹرکس کا استعمال کریں۔ + تُسیں اپنی چابیاں بچا لیاں۔ + اگلے درجے کو فتح کرو۔ + الفاظ نوں تھپ تھپاؤ تے اس نوں اپنی جگہ تے کھسکاؤ۔ + ریچارج؟ + اس وقت آپ کا دماغ خالی ہے... + 5 منٹ وچ لائٹ کوائن حاصل کرو + لائٹ کوائن حاصل کرو! + شاید بعد وچ۔ + چھڈو + اپنی طاقت بحال کرو + تُسیں اُتھے واپس جا سکتے ہو جتھے تُسیں شُروع کیتا سی۔ + میرا برین والٹ بحال کرو۔ + صاف + اندازہ نہ لگائیں۔ + +تُہانوں 5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000 کوششاں لگن گیاں۔ + تصدیق کریں۔ + تُسیں بھلّے تاں نئیں؟ اسے دوبارہ داخل کریں۔ یا، واپس جا کر دوبارہ شروع کرو۔ + تیار + بحال کرو + غلط پاسکوڈ، براہ کرم دوبارہ کوشش کریں! + نیچے-کھبے-تیر + لوگو + ٹوگل ڈارک موڈ + ٹوگل-لاک-موڈ + تحفظ + زبان + کرنسی + کھیلاں + مدد + سوشل میڈیا + تالا + ان لاک + موضوع + ایپ ورژن: + میٹا ڈیٹا ہم آہنگ کریں: + مزامنت + ہم آہنگی کا دورانیہ: >20 منٹ + کھیل %1$d: + %s + %s + %s + %s + پن + بیج عبارت + برین والٹ فریس + تجزیاتی ڈیٹا شئیر کریں۔ + پن کو اپ ڈیٹ کریں + شوو + ایل ٹی سی خریدیں۔ + مون پے کے ذریعے چلایا گیا + لوڈ ہو رہا ہے... + نیٹ ورک فیس (فی کلو بائٹ): زیادہ قیمت کا مطلب ہے کہ لین دین جلدی مکمل ہو جاتا ہے۔ + اوپر + درمیانہ + کم + رقم کم از کم حد (%f) سے نیچے ہے۔ + رقم زیادہ سے زیادہ حد (%f) سے تجاوز کر گئی ہے۔ + لائٹ کوائن خریدیں۔ + آپ کے ایل ٹی سی ایڈریس پر جمع کر دیا جائے: + مون پے نال خریداری کرو + نواں پتہ + خرید / وصول + حسب ضرورت + ری سیٹ / دوبارہ شروع کریں + \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml new file mode 100644 index 00000000..d1646132 --- /dev/null +++ b/app/src/main/res/values-pl/strings.xml @@ -0,0 +1,841 @@ + + + + + Strona internetowa + + + + Polityka prywatności + + + Warunki użytkowania + + O + + Twitter + + Zamknij + + Centrum wsparcia + + + + Wygląda na to, że używasz klawiatury innej firmy, która może rejestrować to, co piszesz i kraść Twój klucz Paper Key. Dla dodatkowej ochrony należy przełączyć się na domyślną klawiaturę systemu Android. + + Błąd + + Wystąpił problem z magazynem kluczy systemu operacyjnego Android, skontaktuj się z support.brainwallet.co + + Twoje zaszyfrowane dane Brainwallet zostały niedawno unieważnione, ponieważ ekran blokady Androida został wyłączony. + + Błąd magazynu kluczy systemu Android + + Nie znaleziono połączenia internetowego. Sprawdź połączenie i spróbuj ponownie. + + Ostrzeżenie + + Skopiowane adresy + + Wszystkie adresy portfeli zostały pomyślnie skopiowane. + + Zestaw kluczy papierowych + + Niesamowite! + + Zestaw PIN + + Wysyłanie nie powiodło się + + Wyślij potwierdzenie + + Pieniądze wysłane! + + Rozpoznany odcisk palca + + Błąd serializacji JSON + + Portfel nie jest gotowy + + Nie można pobrać tokenu API + + Anuluj + + Ignorować + + menu + + Nie + + OK + + otrzymywać + + Wyślij + + Ustawienia + + Prześlij + + Tak + + Kwota do wysłania: + + Opłata sieciowa: + + Sieć + + Czas przetwarzania: Przewiduje się, że ta transakcja zakończy się w %1$s. + + Wyślij + + Potwierdzenie + + Do + + Całkowity koszt: + + Aby upewnić się, że wszystko zostało poprawnie zapisane, wpisz następujące słowa z klucza do papieru. + + Słowo #%1$s + + Wyświetlacz Litecoin + + Kurs wymiany + + + + Nie można uwierzytelnić Brainwallet z powodu błędu w wersji systemu Android. [Kliknij tutaj, aby uzyskać więcej informacji]. + + To urządzenie nie jest skonfigurowane do wysyłania wiadomości. + + Wiadomości niedostępne + + Odcisk palca nie został rozpoznany. Spróbuj ponownie. + + Gospodarka + + 10+ minut + + Ta opcja nie jest zalecana w przypadku transakcji wrażliwych na czas. + + Szacowana dostawa: %1$s + + Regularny + + 2,5 - 5+ minut + + Szybkość przetwarzania + + Sprawdzanie salda klucza prywatnego... + + Wysłać %1$sz tego klucza prywatnego do swojego portfela? Sieć Litecoin otrzyma opłatę w wysokości %2$s. + + Ten klucz prywatny znajduje się już w portfelu użytkownika. + + Ten klucz prywatny jest pusty. + + Opłaty transakcyjne kosztowałyby więcej niż środki dostępne na tym kluczu prywatnym. + + Nieprawidłowy klucz prywatny + + Błąd podpisywania transakcji + + Import + + Importowanie portfela + + Importowany portfel + + Importowanie portfela przenosi wszystkie pieniądze z innego portfela do portfela Brainwallet za pomocą jednej transakcji. + + Ten klucz prywatny jest chroniony hasłem. + + hasło + + + Skanowanie klucza prywatnego + + Sukces + + Pomyślnie zaimportowano portfel. + + Importuj portfel + + Klucz odblokowujący + + Import portfela nie obejmuje historii transakcji ani innych szczegółów. + + Błędne hasło, spróbuj ponownie. + + Ignorować + + ZNISZCZONE BEZPIECZEŃSTWO URZĄDZENIA\n Każda aplikacja po jailbreaku może uzyskać dostęp do danych pęku kluczy i wykraść twoje Litecoiny! Natychmiast wyczyść ten portfel i przywróć go na bezpiecznym urządzeniu. + + ZNISZCZONE BEZPIECZEŃSTWO URZĄDZENIA \n Każda aplikacja po jailbreaku może uzyskać dostęp do danych pęku kluczy i wykraść Litecoiny. Brainwallet należy używać wyłącznie na urządzeniach, które nie zostały uszkodzone przez więzienie. + + OSTRZEŻENIE + + Usługi lokalizacji są wyłączone. + + Brainwallet nie ma uprawnień dostępu do usług lokalizacyjnych. + + Utworzyłeś swój portfel na %1$s + + Nazwa portfela pojawia się tylko w historii transakcji na koncie i nie może być widoczna dla nikogo innego. + + Nazwa portfela + + Zarządzanie portfelem + + Kup + + Portfel z zamkiem + + Centrum bezpieczeństwa + + Ustawienia + + Obsługa klienta + + Utwórz nowy portfel + + Menu + + Odzyskaj portfel + + Przełączanie do trybu automatycznego + + Połączony + + Wprowadź adres IP i port węzła (opcjonalnie) + + Wprowadź węzeł + + Przełączanie do trybu ręcznego + + Bieżący węzeł główny + + Brak połączenia + + Status połączenia węzła + + Węzły Litecoin + + Niewłaściwy wniosek o płatność + + Nieobsługiwany lub uszkodzony dokument + + brakujący certyfikat + + żądanie wygasło + + Nie można dokonać płatności + + Płatności w litecoinach nie mogą być niższe niż %1$s. + + Wyniki transakcji Litecoin nie mogą być niższe niż %1$s. + + nieobsługiwany typ podpisu + + niezaufany certyfikat + + Do zabezpieczenia portfela wymagane jest hasło urządzenia. Przejdź do ustawień i włącz kod dostępu. + + Włączanie kodu urządzenia + + Blokada ekranu urządzenia jest niezbędna do ochrony portfela. Przejdź do "Ustawienia" > "Zabezpieczenia" > "Blokada ekranu" i włącz, aby kontynuować. + + Blokada ekranu wyłączona + + Klucz Paper Key należy zapisać na wypadek utraty lub zmiany telefonu. Stuknij tutaj, aby kontynuować. + + Wymagane działanie + + Twój portfel może być niezsynchronizowany. Często można to naprawić poprzez ponowne skanowanie łańcucha bloków. + + Transakcja odrzucona + + Pomóż ulepszyć Brainwallet, udostępniając nam swoje anonimowe dane + + Udostępnianie anonimowych danych + + Stuknij tutaj, aby włączyć Touch ID + + Stuknij tutaj, aby włączyć uwierzytelnianie odciskiem palca + + Włącz Touch ID + + Włącz uwierzytelnianie odciskiem palca + + PIN + + Brainwallet przeszedł na 6-cyfrowy kod PIN. Stuknij tutaj, aby dokonać aktualizacji. + + PIN aktualizacji + + Włącz powiadomienia, aby w przyszłości otrzymywać specjalne wiadomości od Brainwallet. + + Powiadomienia push + + Wył. + + Na + + Powiadomienia + + Skopiowano do schowka. + + E-mail + + Żądanie kwoty + + Udział + + Wiadomość tekstowa + + Odbiór + + Gotowe + + Odzyskaj portfel + + Reset PIN + + Klawisz Enter Paper + + Odzyskaj Brainwallet za pomocą papierowego klucza. + + Wprowadzony klucz papieru jest nieprawidłowy. Sprawdź każde słowo i spróbuj ponownie. + + Strzałka w lewo + + Następny + + Kliknij tutaj, aby uzyskać więcej informacji. + + Strzałka w prawo + + Wprowadź klucz papierowy dla portfela, który chcesz odzyskać. + + Aby zresetować kod PIN, wprowadź słowa z klucza papierowego w polach poniżej. + + Najpierw wprowadź kwotę. + + Żądanie kwoty + + Synchronizacja + + Nie będzie można wysyłać pieniędzy podczas synchronizacji. + + Synchronizacja z Blockchain? + + 20-45 minut + + Jeśli transakcja jest wyświetlana jako zakończona w sieci Litecoin, ale nie w portfelu Brainwallet. + + Wielokrotnie pojawia się błąd informujący, że transakcja została odrzucona. + + Rozpocznij synchronizację + + Nie będzie można wysyłać pieniędzy podczas synchronizacji z blockchainem. + + Synchronizacja łańcucha bloków + + Szacowany czas + + Kiedy synchronizować? + + Lampa błyskowa aparatu + + kompletny + + w toku + + otrzymany + + wysłany + + Włącz wszystkie funkcje bezpieczeństwa dla maksymalnej ochrony. + + Jedyny sposób na uzyskanie dostępu do Litecoin w przypadku utraty lub aktualizacji telefonu. + + Klucz do papieru + + Chroni Brainwallet przed nieautoryzowanymi użytkownikami. + + 4-cyfrowy kod PIN + + Centrum bezpieczeństwa + + Wygodnie odblokuj Brainwallet i wysyłaj pieniądze do ustalonego limitu. + + Touch ID + + Uwierzytelnianie odciskiem palca + + Kwota + + Równowaga: %1$s + + Zezwól na dostęp do kamery w "Ustawienia" > "Aplikacje" > "Brainwallet" > "Uprawnienia". + + Brainwallet nie ma dostępu do kamery + + Przejdź do Ustawień, aby zezwolić na dostęp do kamery. + + Brainwallet nie ma dostępu do kamery + + Miejscem docelowym jest własny adres. Nie można wysyłać do samego siebie. + + Nie można utworzyć transakcji. + + Memo + + Wklejka jest pusta + + Opłata sieciowa: %1$s + + Tożsamość odbiorcy płatności nie została potwierdzona. + + Adres docelowy nie jest prawidłowym adresem Litecoin. + + Pasteboard nie zawiera prawidłowego adresu Litecoin. + + Nieprawidłowy adres + + Wysyłanie jest wyłączone podczas pełnego ponownego skanowania. + + Żądanie załadowania + + Wprowadź adres odbiorcy. + + Wprowadź kwotę do wysłania. + + Pasta + + Nie można opublikować transakcji. + + Nie można załadować żądania płatności + + Skanowanie + + Wyślij + + Wyślij + + Wprowadź adres Litecoin + + Wprowadź domenę .crypto, .wallet, .zil, .nft, .blockchain, \n.bitcoin, .coin, .888, .dao lub .x. + + Lub + + Wyszukiwanie + + Twój adres został rozwiązany! + + Adresy Litecoin są przeznaczone wyłącznie do jednorazowego użytku. + + Ponowne użycie ogranicza prywatność zarówno użytkownika, jak i odbiorcy i może skutkować stratą, jeśli odbiorca nie kontroluje bezpośrednio adresu. + + Adres już używany + + O + + Ustawienia zaawansowane + + Wyświetlanie waluty + + Dołącz do wczesnego dostępu + + Korzystasz z Brainwallet? + + Importuj portfel + + Zarządzanie + + Powiadomienia + + Zostaw nam recenzję + + Udostępnianie anonimowych danych + + Synchronizacja łańcucha bloków + + Ustawienia + + Limit wydatków na Touch ID + + Limit wydatków na uwierzytelnianie odcisków palców + + Portfel + + Uruchamianie/odzyskiwanie innego portfela + + Pomóż ulepszyć Brainwallet, udostępniając nam swoje anonimowe dane. Nie obejmuje to żadnych informacji finansowych. Szanujemy Twoją prywatność finansową. + + Udostępniać dane? + + Udostępniać anonimowe dane? + + Zapisz ponownie klucz do papieru + + Klucz papierowy to jedyny sposób na przywrócenie Brainwallet w przypadku zgubienia, kradzieży, uszkodzenia lub aktualizacji telefonu. Pokażemy Ci listę słów, które należy zapisać na kartce papieru i przechowywać w bezpiecznym miejscu. + + Klucz do zapisywania dokumentów + + Ostatni raz zapisałeś swój papierowy klucz na %1$s + + Najbezpieczniejszy sposób korzystania z Litecoin. + + Łączenie + + Synchronizacja + + Ponów próbę + + Synchronizacja + + %1$s d + + %1$s h + + %1$s m + + %1$s s + + Limit wydatków na Touch ID można dostosować na stronie %1$s. + + Limit wydatków na uwierzytelnianie odcisków palców można dostosować na ekranie Limit wydatków na autoryzację odcisków palców + + Nie włączono uwierzytelniania odcisków palców na tym urządzeniu. Przejdź do Ustawienia -> Bezpieczeństwo, aby skonfigurować uwierzytelnianie odciskiem palca. + + Uwierzytelnianie odciskiem palca nie jest włączone + + Użyj odcisku palca, aby odblokować Brainwallet i wysłać pieniądze do ustalonego limitu. + + Ekran limitu wydatków Touch ID + + Limit wydatków: %1$s (%2$s) + + Włącz Touch ID dla Brainwallet + + Włącz uwierzytelnianie odciskiem palca + + Touch ID + + Uwierzytelnianie odciskiem palca + + Touch ID nie został skonfigurowany na tym urządzeniu. Przejdź do Ustawienia->Touch ID i kod dostępu, aby skonfigurować go teraz. + + Touch ID nie został skonfigurowany + + Zawsze wymagaj kodu dostępu + + Użytkownik zostanie poproszony o wprowadzenie 6-cyfrowego kodu PIN w celu wysłania każdej transakcji przekraczającej limit wydatków, a także co 48 godzin od ostatniego wprowadzenia 6-cyfrowego kodu PIN. + + Limit wydatków na Touch ID + + Limit wydatków na autoryzację odcisków palców + + Dostępne do wydania + + Kompletny + + Saldo końcowe: %1$s + + Kurs wymiany w momencie otrzymania: + + Kurs wymiany w momencie wysłania: + + (%1$s opłata) + + NIEPRAWIDŁOWY + + właśnie teraz + + W toku: %1$s + + W toku: %1$s + + Saldo początkowe: %1$s + + Czekam na potwierdzenie. Niektórzy sprzedawcy wymagają potwierdzenia w celu sfinalizowania transakcji. Szacowany czas: 1-2 godziny. + + konto + + Kwota + + Potwierdzone w bloku + + Memo + + Twoje transakcje pojawią się tutaj. + + na %1$s + + Więcej... + + Przeniesiony %1$s + + Przeniesiony %1$s + + Nie potwierdzono + + Otrzymano %1$s + + Otrzymano %1$s + + Wysłany %1$s + + Wysłany %1$s + + Status + + Szczegóły transakcji + + do %1$s + + Identyfikator transakcji Litecoin + + Odebrane pod tym adresem + + Wysłane na ten adres + + Wyłączone do: %1$s + + Mój adres + + Reset PIN + + Skanowanie + + Wprowadź kod PIN + + Czujnik dotykowy + + Odblokuj swój Brainwallet. + + Aby kontynuować, odblokuj urządzenie z systemem Android. + + Odblokowywanie za pomocą TouchID + + Widok na blockchain + + Wymagane uwierzytelnienie + + Odblokowany portfel + + Nie pamiętasz hasła seed lub kodu PIN? + + Zapamiętaj ten kod PIN. Jeśli go zapomnisz, nie będziesz mieć dostępu do swoich Litecoinów. + + Twój kod PIN zostanie użyty do odblokowania Brainwallet i wysłania pieniędzy. + + Ustaw PIN + + Ponowne wprowadzenie kodu PIN + + Wprowadź aktualny kod PIN. + + Wprowadź nowy kod PIN. + + Wprowadź ponownie nowy kod PIN. + + Przepraszamy, nie mogłem zaktualizować kodu PIN. + + Błąd aktualizacji kodu PIN + + Aktualizacja kodu PIN + + Skopiować adresy portfeli do schowka? + + Autoryzacja kopiowania adresu portfela do schowka + + Kopiowanie adresów portfela + + Kopia + + Wprowadź kod PIN, aby autoryzować tę transakcję. + + Wprowadź kod PIN, aby kontynuować. + + Wymagany kod PIN + + Autoryzuj tę transakcję + + Otwórz aplikację Brainwallet na iPhone\'a, aby skonfigurować portfel. + + Odrzucić + + Wystąpił błąd podczas ładowania zawartości. Spróbuj ponownie. + + Aktualizacja... + + Brainwallet został właśnie zaktualizowany! \Jeśli potrzebujesz pomocy, poszukaj (?) w prawym górnym rogu większości ekranów. + + Witamy w Brainwallet! + + Czy na pewno chcesz usunąć ten portfel? + + Wymazać portfel? + + Nie udało się wyczyścić portfela. + + Nie powiodło się + + Aby uruchomić nowy portfel lub przywrócić istniejący portfel, należy najpierw usunąć aktualnie zainstalowany portfel. Aby kontynuować, wprowadź klucz papieru bieżącego portfela. + + Uruchomienie lub odzyskanie innego portfela umożliwia dostęp do innego portfela Brainwallet i zarządzanie nim na tym urządzeniu. + + Obecny portfel zostanie usunięty z tego urządzenia. Aby przywrócić ją w przyszłości, należy wprowadzić klucz Paper Key. + + Uruchomienie lub odzyskanie innego portfela + + Wycieranie + + Wycieranie... + + Zapisz każde słowo w kolejności i przechowuj je w bezpiecznym miejscu. + + Następny + + Poprzedni + + %1$dz%2$d + Czas przetwarzania: Przetworzenie tych transakcji zajmie %1$s minut. + Adres: + Luksus + 2,5 - 5+ minut + Ta opcja praktycznie gwarantuje akceptację transakcji, mimo że płacisz premię. + + Moonpay + "- Kup LTC za pomocą wielu par walutowych - Płać wieloma metodami - Globalny dostawca płatności" + Bitrefill + "- Kupuj karty podarunkowe \n- Doładuj telefony przedpłacone \n- Steam, Amazon, Hotels.com \n- Działa w 170 krajach" + AUD + GBP + HKD + IDR + RUB + SGD + CAD + EUR + JPY + USD + Historia + + Równowaga + 1 LTC = %1$s + Aktualna wartość LTC w %1$s + Języki + Czy na pewno chcesz zmienić język na angielski? + Zamknij + + Instagram + 1: %s 2: %s 3: %s 4: %s \\n5: %s 6: %s 7: %s 8: %s%s \\n9: %s 10: %s 11: %s 12: %s %s + Pokaż + Pokaż moje nasiona + Preferencje synchronizacji: %1$s fałszywe alarmy + Niski poziom prywatności (~45 minut) + Półprywatnie (~60 minut) + Anonimowy (~77 minut) + WAŻNE: Aplikacja zsynchronizuje się, aby zezwolić na adresy 1ltc. Poczekaj ~1 godzinę na synchronizację! + + Nie przegap niczego! + Zamknij + Zarejestruj się, aby otrzymywać informacje o aktualizacjach i konkursach od zespołu Brainwallet! Zaakceptuj powiadomienia, aby otrzymywać wiadomości na żywo, ceny i informacje rynkowe! + Nie, dzięki! + Usługa + Opłaty: + Ogólne + Wiadomości Litecoin + Aktualizacja Brainwallet + Anuluj + Ok + Prosimy o zezwolenie na powiadomienie + Informacje o zezwoleniu + Powiadomienie Przyznane zezwolenie + + + Powrót + Twoje słowa zalążkowe + "Tylko dla ciebie. \To jest klucz prywatny która umożliwia wysyłanie". + Blockchain: Litecoin + Zapisałem go na papierze lub metalu + Uratowałeś go, prawda? + Udowodnij to! \nPrzeciągnij słowa w odpowiedniej kolejności. + Gra i synchronizacja + Gotowy? + Zrób to dla siebie. Proszę, zrób to + sam + Weź długopis, papier i 5 minut + Konfiguracja kodu aplikacji + Wybierz hasło, aby odblokować Brainwallet + Nie kod blokady telefonu! + Spraw, by było inaczej. Niech będzie fajnie. + Korzystanie z danych biometrycznych + Zachowałeś swoje klucze. + Przejdź na następny poziom. + Stuknij słowo i przeciągnij je na miejsce + Doładować? + W tej chwili twój mózg jest pusty... + Zdobądź Litecoin w 5 minut + Zdobądź trochę Litecoina! + Może później. + Pomiń + Przywróć swoją moc + Możesz wrócić z miejsca, w którym zacząłeś + Przywróć mój Brainwallet + Wyczyść + Nie zgaduj. Zajęłoby ci to 5 444 517 950 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 prób. + Potwierdzenie + Nie zapomniałeś, prawda? Wprowadź go ponownie. Albo wrócić i zacząć od nowa. + Gotowy + Przywracanie + Nieprawidłowe hasło, spróbuj ponownie! + strzałka w dół-lewo + logo + toggle-dark-mode + toggle-lock-mode + Bezpieczeństwo + Język + Waluta + Gry + Wsparcie + Media społecznościowe + Blokada + Odblokowanie + Temat + Wersja aplikacji: + Synchronizacja metadanych: + Synchronizacja + Czas trwania synchronizacji: >20 minut + Gra %1$d: + %s + %s + %s + %s + PIN + Fraza seed + Zwrot Brainwallet + Udostępnianie danych analitycznych + Aktualizacja kodu PIN + Pokaż + Kup LTC + Powered by Moonpay + Ładowanie... + Opłata sieciowa (za kb): Wyższa wartość oznacza szybsze zakończenie transakcji + Top + Średni + Niski + Kwota poniżej minimalnego limitu (%f) + Kwota przekracza maksymalny limit (%f) + Kup Litecoin + Wpłaty należy dokonywać na adres LTC: + Kupuj z Moonpay + Nowy adres + Kup / Odbierz + Niestandardowe + Reset / Rozpocznij od nowa + \ No newline at end of file diff --git a/app/src/test/java/com/brainwallet/tools/util/LocaleHelperTest.kt b/app/src/test/java/com/brainwallet/tools/util/LocaleHelperTest.kt index 62ecd6c5..52cab56b 100644 --- a/app/src/test/java/com/brainwallet/tools/util/LocaleHelperTest.kt +++ b/app/src/test/java/com/brainwallet/tools/util/LocaleHelperTest.kt @@ -56,30 +56,18 @@ class LocaleHelperTest { fun `check all language codes given the subjective business logic which prioritizes localization popularity`() { Language.entries .also { languages -> - assertEquals(16, languages.size) + assertEquals(20, languages.size) } .map { it.code } - .also { langCodes -> + .also { assertEquals( listOf( - "en", - "es", - "in", - "ar", - "uk", - "ru", - "pt", - "hi", - "de", - "ko", - "fr", - "zh-TW", - "tr", - "ja", - "zh-CN", - "it", + "en", "es", "in", "ar", "uk", + "ru", "pt", "hi", "de", "fa", + "pa", "pl", "ko", "fr", "zh-TW", + "tr", "ja", "zh-CN", "it", "sv" ), - langCodes + it ) } diff --git a/fast_follow_asset_pack_01/.DS_Store b/fast_follow_asset_pack_01/.DS_Store deleted file mode 100644 index 4c042faf8a4273d44f0430988725dc059be5ede1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 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 R{x9SE-)8yW|KtC+{~v%HY3%?2 diff --git a/fast_follow_asset_pack_01/src/main/assets/audio/coinflip.mp3 b/fast_follow_asset_pack_01/src/main/assets/audio/coinflip.mp3 deleted file mode 100644 index 976a06f5ba29db578e9497766dc1700baf0a3cc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23680 zcmdpdWmFttll9<(dvKTF3>w_s-Q67m1P|`+Zo!=ZA-KCcgkT}K6C^nOk==dw@ArS} zobImE(`Tl;pIdgTMpl9Y2J|M-C>o*)Vs8r6+omC|tn?pMR)hUNs){7re^fPb`TwZ8 zl4}2>z8(IL2=J6>@&9`i9a|^sw`AFTW@c+^>*C_#>FMe3?;jQx7Z;bBnwpc7Q&dz`RaN!%>(|!S)}Ef8 z;o;$_si~!TI;9`uhNv8BIdJ`#*Mbu9)T6fmvQnqF--deO5nR9di6BpNwpo6j&Jr}yjE z-@OhR4h}fikS-KNBBnF=*$F7o;0S&o%AH>8@u!_49u}IWP(Kel`;PQ=W8CLGTKos1 zZwq^uub3qYL3j%WA4$Dj#bE^?lV--!`01*=7*q{tTd_vZyk_fZDNW^+6ujnn%RKVr z-WhHMz~J3iteBRKCF8jxr8StNM~*F=&54$c zMhH(}QeFR3^o8xKr4mla2r;J}Ron3J1YpfHy{AX#Y%m zR$3bm!CIrzb%ZluSXt7lfKAN6ioV%?g2Es0$|6Fb5CRvH(xvH&c7uDjgMQHnB$SXN z)r-cfl~fnRjqY6RA=jBf57XfjV* z8C_$cRJ|aw8*_LrM_MXD8$y{Do(Ar=M@aXM)OlPf|GpLodcq?! z?n16Y#KqvO%^+tJ&HgR_wKV^`JJ|YP^-XExeSX_NJG}e?ftp8mr~`n1CR7uM6cRb_ z?`(mg-Y|yUivw~zx}e&q3j`+z(x3-|VE_9YZkbtn)E>vuk2Kupd(_@Pl$Wj90!ehPYU32zdVXT_k!m#V)KqhIjDMyI z{}m>LZA{?{w}H(nzNrZv=y*RA!o^ODPf?Kxg`r6cB5YP8@W4Bg7X={(_If2E>81VJ zh6((QfsX@|3R7jm3BzSwOCj1@p@9WPP8?%SH}C@^#6ih(6WiAvR}AX~JAR>OU0kZ+ z?wti^!a!Wez(@+vNRuqw3fbx+VMl==#2`?G2v&F%Y3V3mlf2Kss%;=>6~cglF2E%D z$pQzYjw|!dn>iL9q*K+x?A|5)u06BPm(?~s?}oP8gc=260q;OQt1^grIHXy)dVfC& zU85rj9RwrN03tNe0rNqHgKFSbaiCNsTEs=LS#4XDn#u_nat}|=`%KdtV+&2Jm`uQ6 z)BE*zh;SjM~;HzW^q=M8I)5+?+=BGF17QZU{;l3$ zYVFs8=P;X-qo*FAxU#Dw0BC;k#>_9BBP~-4w~=Hw!wiIB$cBp}uz{vU!nei>k|7w8 z0yn`Bx<)%MKw-wxqJ;jy<<)GfX!1G{(w#k3<2#c#$dn{9Oyi$slC9@s_Ruw2;uOS- zoL3iT(+QO#9i~YWLS5!Z>$HNT!>0+PLkIe1yf3dENSR|g<)4h|X;#$JXNgl+U9emB z^*7DAI9Y?{UvNvjfu1bAQ3HA{Falm0i5E>4KtymgM)#uOtFL3JanDcVVwPe83t(~SmwWB*w znfTk8Wyt6W>T}+y7zi2D8OSl-wE@On?CXJ(trb=PFy5NWaAQo9S?Lht{{lw`I+ zi1LWIj+x@jDPQJJf#4Hj8joV7jlFuiC$ zOHdxTMD>>MVCXzjUh>PbPa|w#X<&$Kd$)C5-Cxtia} z0@<6%Cx)|XcJ0-(9-qjI@5C1L*^#!%p^DgETOpsd(Og3DG{(EWkwNw2EfvPzb^!5%9QT~^atJId2Sb`XTXZR+QYLcoS{2CEVB z2ErW*Y0gcJL2#(+eR8NRQiv1#q0WTqVEFd%0Gi~gg}|=(-F@@oi%eg&AXCxZc1v}bZ-~XnJ6d*&UMM}qH%EKZ1PEtb z%GYWv&*ICpyT^wI&Ml* zg4H|{6AT!hzCpN2o?nc;JPSA)(^QxdoP&v}Ibx%IG7G%#;bA(FDW>e{7iWHotywU9 z00$SR&Z0i3C!d_%`x~~*Gc$&{!W1lqBTaLKdT8sTp75lqmNb`Cu|cW-sAWslK;UUS za`smD-fjsdEt}9Qf3#Du)r_6SG~ZS#lsX*pm%C>zXk4}vxp^4jZ0$)u zi9Ig?SHOnz)MmjzL0iDy4Dgq)Ep=M0ol-!Y4<&-Vkoxv+&Q|Hfcr((M`&3qeVuSij zxs@E`2G8Ifp6;nBGzbkTNuV>IcV9T=8ANsGKqGdqERZwOGP3|@{RIX6!h(Yu4226S zyVC1CZTnhR&K5XiaegE8XSz#950Ew1$DSil$h(=QiD`WC3$Cl6cr?m}xwjp}kRrzl zhmlq49W51cXs|#zLZeQXd$+7=PRXM1ZR}GP36IMXw0q<13v8JoOMxCOyz~?jwFn%@ z#2n)XJ{Xz>HlErWX9JfutB3|iKFn=6S}zu-xkNYui$#<;r`Q=#Qv|XT!{B>Pni$n) z6+ITi>>LXQURb~D$v^oFsA0*JGHaS~Y&B*pYhl?ND#e#5h!OCDKp3fel(zys>3)rq zK=A}`z(D~}@O<4e8lUH}JZaiO0HTj}89)D~efo5IxAWor@A_u{s~2Nn@hProt5`z^ zL*x#p9>t~=i7K%PXcC$G1FXXOrK(tkI#T9HMl?aQ6$Yk`IJ8bb0viQ13LHV z8Z2!kQs0dnBV&nLQtEN{#Y{xV)JWKE*wm83k&T*_aZa6$X0-IepDvnd@r8)Rk~je+q(*#aE|R z$8QMrQi(zE(eHZzwVu^;;joVcijviJrPPPau*ZsWq7FuilE3}y>t6yim(-5h({q@s zj>=}#4do<>n4L;#bEodq0xAjr~d;cpj2n?5}EO!Sr=S-Cj;oD~4Ghib?ZYO3XrRIfAX<(6h{aRd5uUQ$v{zWhMXqbqwG{YZ zWTp%wm961q=KL*jiYAkrD~)OEo2oZz^KZwhyf>|L_o7>v_Amni z13_dGkNG`Ij?`+eVR6GMT4gmYU2=x9wRy0pn8#d__5$uZ#^3X9)vHE3?A+7GXb%@; zHLxq&Z|IMx!(?h@C@at6vtd9`ddz?~@M4{E@haV9{2H-xRXv^oTnPiruP1VCW8&&@ z^n$&y_)1H9(Zt&t)TLuKai)LRXSh?~>Y=-Je;u)(&?`gED{??kGQsq@Hg++g91sVB zpb$EXp*RfaGKM(h7)%TZR1hV`>a-^HW<*+4@(`iBV&15U4)0#>w9M32xxdPk6-|b* zm!L{t;=1g9s-VkGhEqg)%XqznX5KuXX*hz%sp-G)Jp~$xiIMTuk8>46rN;(Q9Z~pv zAUkvLK4Kmyo&+V7io!_S%w7+Y`w%8~Z7c}q@7~JkuD_-mrf~@iX|7ESrA%w~*xjBG ztk~DunELI7hd>+K&yA!w|xApR=4Ik+q&j4R%Y)} z!cDQ9W(eR%z`fS<7YdU)OZ*R*s9brl*{mEkosSDUbR`?r`ZGA&q=|XsASX+V}l+a+SK3(Vp7) zy*P1K#fhT>6dVZ=!JrmAjUQ2LqNw^UB~j6CFo8i~a8hV+2rwE|#N~2nru*6!QcFLH ziDeyh`k*s3Dz!?~)H!g@d_QLTmn^MuEF>X6Y~K+Mc>6=chbd8ca)?Cs|57z6k}aK( zSA>mBpx4u?haSzaeNETdKpmUl8Fd_C?=bQocPp{5ORsI$6TC)tjMZSU?MJEhbQws$ z&aHPPNO``gb5$v5nvY*jn3gToSx^-b?Zc>+D_iL<^XO<7=dsJPxAH7gNK$o>d(5g< zie6C9B%D{&P{4`amkemO)Bj}uNpNX-$tTUfWVVq}zjpShs%0@P0Yjhsz85Ns{w-z$ zd&hF;)wRNBh5;MJ9l-5Zm0y9|qAsHhB=~gj2*N*yD}Tc**F=j#e%QI^{i*~dHBAcm zh3I5hctv_xHGnV`Ad#~;GPx+!kwah<6qI54$sd^$feM`Xu#x8ph{f6Fg|UgKgqg)< z(b^keM-R@wuTW;_C+@Z}XA+sk9v$csWK|!Q*8M4>1H}(8B@s@t^41LD>(Vfe!C^F~#&zbIk4vAu9o(%Gig~$=H-`En8 zB0;jVE)po1krEV8!iHtYJLsy+p_oG%5d6EA6a{Bq z_Z98b-@Uzz>%Z5=ZwJJoV`pHeJgS}PwQSW$GV1)`#s6EuIqykj$wSFrURx7)>N(?U zZL(b@Y2^X0wt$_eL#wE+y!^3no9{IM^t`;WSg%f&&cjLU!q%=+b8t~XtnfJ4&nvGl zua9`S?RiQ+0-n8JQ~b=>Cz!G|DQcn%|9tZB%+83gHh~j_Hx@v|q;wDFhFb1raC5mT z6x9};Kp&1V*`8Pqt0Zkp?=W_#;TkhjN?wWK&{0@O5sRx**J{quNWTA6YH0E;VXqo9 zx-+7}O#R`c_2}04dk#6p%^#xP3q&^7<=Y70)fX5by)#yP89>T@hFDJVZO}}lRo|gJ zeSb%-3++_KT~<0@h4@LgW5IRpIYX8j_rUSM-n}C`mGirQhN5rY1V7I;i}}=vU)Fd* z>)qYMM-HS6hePqoG~$}m)A*fb)q!>9M!}<7xvM6DgLd{qNzIK7x~otA30dpmdh~-* zry!x|RUj3Z65jOh31AflfC=E`#jS-?zci9qhz6|)D~*aG_7fIq`P=CLs=aIF?Yq%E zI%7ADwxgaej`}__7it(xO%j?@lkGo(mGqzl5aS)f2=4YB{v_i-W4VkGaKpP}Y@3#v z1XK3~_gVD8#6o0x|48)U;7DMx2Ol?jr^{Dl?t%yLc5cynop*>~=G}D%L1w=yU1xH*G3{*rP^8PX6AC%wQ<^JbP=RqS%aihNc%vX|sR^P(+q2Vwl z)tNvS;)l2J4V_SPL|=A~J4u(Io7c+H7uLKPL<0~b1>ftP@sl%ede?II)sv4q5b*dp zKp8k;EUwCe1J`{Fr`GXh$cyK>jQ)ZdkQG27oW3`3w*9ViwA?aQZ=_;V=@ZM~403H$ zIY+9TZDmJ>xx^0~$&a-~y|SfO zk1I9s%@SHL+V+f8iPOWB5r#>JmTowG)Th~0xC=*C%=H#-1xeS%l}$}s{FyrSpJCBb zF-<$fK$wXI&nG=SdI2QI*F zonid(`O(ODZvj_KGpYJ1L#U3Cs>@(R)?|>@i`?p-EsY*w^%B)7NqheamTs;KRppiUaw{a+4 z$<--L>+ZF$YB-<|md;^TQCW~PtLX=0B_5AZf(z~bIn%qqQM@=AUuRZ1iK%~?>5&QV z7mBma4SEKdx6Cx5q&nqgSj7yLN{x7P{D3pDj0%kL6tiB;mw@2FRtt|5N2{pl2 zDk-XrC%N)7Tx@Y%i6Z}5AY62y#us<;;& zs4TdL@19A|wc2}X1rMM0-sp;xH%}~ZmyB=HH+fl93tD?hV|}SJMt;xZ znDXj9E+frhkp6wB+gg+Ti7{p4Yk5?4cBZv`CKA6~3#NlZ36Xc~>S&`FG$p$@7ZuuQ zk7S_yqLynaw4?)5!<-Jn$7xH*PT8(xEy`rgZCz|+AU$wq%|_vc*Kv*R=xL!T6Af_f`$ZN_(> z^!D+X$D0Y88Oq8MuKbgo(xaW}A}#$1YN_??xVSTX`FmmWGy@#G z>Yq7$eeu`52q?HCS?$T!YB+#AX$te12B-hnsGe<6{&{~lpP755_KldBQg3J+1Rwc7 zZ0JiZn>tWk=M#|rk`e&C0O!W9`5PzBKkgb!e@xd}Rq2q2#E0~}KGD3cIi*+1S(dpr zIZOy5R#u^(%*^j5b~JT}a}+l>G9n>F7-YI>cfo6zaB3)K>X=X;?73%z2o5J3GRZGnZ?!jvGe2*gGJ4Ra9mC&*Of63hUD3=c9P zpulLzhY5q2fEnO3z$nn*Uf4KlkeU0}$%cR2>|!8-thMZCYY~tvCIM9;7|K~s6z`!s z5NdstY6heNGAZp$R_FPMV*B_fIF!6b$$bsEGVOm22^C)WJ4_jrS1`d zYz-|kpzK-5MOmX|qN$ofZr?t>WeNsKAkO_*R{eC^rnBSIxb%TP;#;b>owMAYzd_E* zZK~w?_%a05c*$qJ?NL{8f@JHYW68+5nYLNE(^FgLm3P!h@dU|%o=JNk-AQ%4Rw{sy z(Sx4mjzMKDS?=_2XFVg&f?i&&JzXhR=R@A9jia*eg=wZ6ntA=%X}Qz3sNOfT&N@5) ze6rNO^!yTt{PMfPovF@<n1wVN)j?D=;TH0_>qTVlu>Q5hjfgpocyVG0`m+Fzt0avYl<## zQ-w6tk|vLZ+}$dNF-4X7M=8mP@nkYQbv{{2(Y*Elkl3YG=_Y#z!02Lpv{sCyrNpKj ziEfY@6|>(2!J_u-BO&BFqM^|H_#pgVJF~)|q;OG}%81@yCL#vpCML6orlK&xR$xQ| zY9VN7IJpUp8YBuRe2n+t0>faDhS|2DplGKs5s+!LL`fflldcvKIUIz?UlUA%D8NNe z9@+v&qTrh;bg7#)vgJk)s(4T>beU!^PZ`dNMA#8-zpaChSlMpR-1qECsOyJahSBjN zpGhCwHe`oPp%IBBPP)$7Qjz$wv`W zsyxi_K`M8q*RuQQ`pu_h3?Dlt!j!NTSu2?>LnR->HTI0cplY3_lr$>2Iz2c3mK`zb z=H_Lm*k6A+KRNMaG2F1{^<4X%sbns}tnQQcAlUHV^r-gQvM~ zP!3dqTLIP|D(bUjH{#tj+F~uqBsiC*SKKgDcc#tNSBXcYND&67uHuIqqoWaHFz2oh zOX17p1GT-k)X~+{L zVP|vV#YGs?p4X8qA0pZft=q}w6vOQFMZv&wx>t*Wd2Jw2X>t@8`TZlhq8PA1py}e4 z{Oyk1w#W?QUMw6zVx1NEP@K8r^pWQ~eaW9nruG{vQ7u{2wcWqO=R0h8fA#K*qY8Tw zc)n^c!wu-X1T;HoR-tcsyKeZE^1MXVKx%fFGWJb3ckQ}<+InE&->x3|2=nK2q^2yk zj(p56%FfFf4=*65H9^@Gu8?TdSkB4kZkTu~06gQ*objzz?f|6E0k3$?lfts;woFOF)cL%KyC-%GPVIJzKYT zdd5vYuN&%5r5gq3HzzlerSl0C8!B3=C5dkgFETkVOy43DzTv{(6QeTMi`wkA1<9sp zUE}qn2%4^)4&CEJ+={H|_V65haQ5I^eV&?11F{v7>sugXglf>Cq?K?5$I{UIpuiW_ zJzBA*_r23OZRfdQe{hGKwKg@-3xEem5tgAMN9_1HZrFct^HR@vxGb9Wc)GbhSanL{ zE83hZ7V_6s_Ov!S&AiM0LA)D1+T2q9+|ZECnqg_Tuaoi{OC7g+ajL~;(krPtL)n02 z`Q56f)6NHWG3_xpd4gxjp`6h%pUv0isOrd{n^clvgmQY+amh4gb{Sk;9^ys0g-JT* zIBcT%@)u13%)UN0PwdW(zCT;cx*oLlTpkwq3PH7u!mmBR^viB6`o1)9cy+ZNx=Ii} zL1T<#-y@})hljyqoqUc1!ezf0!=Fr6A{bzTbm)z##p>IxQq=$WB zU5^CCBpyt-#b+>qY?u*P1D8&YbD}_IM})W^CPjd$h63pT1?Qo{p>5Q7LUAd)_z$9e z8@7l<`{eJwCu-XU8^RC%jG&XYe<^)i;Qn*0%o8h~oJ8Ck2TXfJ3eQ1tCh!@NaQI&l zS*orof>%9l-@bP&o#NU@?3T`Q}SrnRQrY+`Rk^I#@tVWMxn45jD zx7|iZ2zQP>+0=sfedc6Q6JQ8NwUD9{Gr|G(> zfx~Cmt?PS1li3HSL4&}>+k8O4#S3sBJQ;gv-G<|}XmHI?3ZB0_2(x2J-iLuWS%@jE zEVL(whG@-1XUSlQV3Q_J$d(U-4diI+&Z~@=1Iwx*X68ijT)!KBL9o2=mmmrnB)Eo! zB8VYjEE(WF@gy%3FcT=hqPGGYb;m40{k0e0b=RaO9VWe4yakoBjf-doRX@ORG&LV? zIs_jpyYpG8=Tnzq@QLh%7|Smtd$=nuO{Rw3I%CNQs!@m;M0rQ`B}+@+<2ojhOSx%v z3~Mx;t=-GvTc^hWGV1ZISvb?bl>Q*_AT~>>_{qMjiW> z(sv~3^#0f%Z;KxYZ+V|&R;52zH7sM}?Mpn8v9c*hU;XqmX_2j7I+31wr7Nww!zR|9 zAybMr7|j|B3(?Q$lySPHR6Lyx3_V6FK2>ojqQQp`^R4Ew2LS4UR^YU|r{Ex)c3%CW z#)5LPOtVplyEG-rJ+Wd`Zyrpd#OgGLM^j;^qZOqKaLKw`^2=I~qG+%c?vV zU=q_+WVS(n%3v7!8+?AiGC_YI`n`*~oO$PdK&1nMNEu>YvKdZ%65c$p(Q?5TKE))s zV}x5v^kMyG^U5jNW1UW&$y$jBP0Qlv(&9c+Df?DQ!34?-L5ob1FV){NO~*x*{5p~` zH1Icefyt#AU=yw-+EALBXuhTHJ4a=|z=q&#t-d>%&m;pB3M|=1J+Z(?B!V;@h6pw@ z$%w@?U0yU^*j^Y3i_1@zFDoqa6P0Kk!1d1U6HX-WsOJi`H+MpSHtE1-aPND%ax4^= zJ`f5Wn^E@K&7RK@$8C|S;rX}J(MneIWyX=++3Vz_vFe;Q>$nO$<9G*-n#gG;m1+KH>Sblr}mhYQFnFS86-YdpU#h_*Bpu?(Z zR+2T_BVExXK04dDSqnRx$G$n!uNIr25iDC-Uu7~Gx!FqWw}zU*D>ltPegx{9MJy<% zgnoyv?xDkRj*6#+Wy$#+{ug_9RW^DfCUMHRkshJUyGMYaIrAd+#OP~k{18@FrP%D@ zv}!at9Yn>TlsBZvl)@WW*}QQ)n(bJq>MEP7KY#Dwz&$~~?g7FqeGdo&FMAhPM`sxe z`O;^)vq2=U?Hol;g{P?yY6GjtoMYb9=t?eX(Obm|b_(jVmIx8 zK_EZEOLqnoqQ0_qFC;|_i|?+M;W4rZSO~aK2qGUtkaF!dzfQ&zSvHonusGI=CQ_e3 zcmI}jT}n(l>(DebbmzOp z?EO*_^C5pzjrO4FK)VQmoF!Hcv90@?=8D)lOEUGk<#4WprmZL?jY`=*;SC7hRQmdd z^7F$-0J!_TFKvOQ=;fs{m3w`?@tgnR!R;64HLbc?6;cZwLu3f-`ta?G40T4XcMj$| z)+lKjc#$IvWoSE_?5Zj+M>YCq^wMo1;<8KK`KT;)d0bO5tF!X?16Z5!wC(USEzJNO4s6)>fIQ z!7=?9Z32UDrcQ_v2~9^wTq1SYPk<4KVr9{bM}lZS%Yzlp^=UcR#eGM>RnOo?$`vua zS8*t>`NuM5O<@+^$BYh-B5w&s={+``C6*`P>bd53&M+@~8i`7c|Lm`Cr|$1bzB0$p z`?ytS&}vTQJ!quInMVKqkw3Qj4{?i7!*>ZXPfTQAW#axDaU^euW9#fg;H3VCxY1La zX!xHzen$o}TjQOLg3QAni%wDF7)n~Ed#oBT3nPPp6&81mvdu{L29qVhniNVob>qcW z%^GQv_B>h13MH!tlXEPo)|}Q8cJD%U!NkQjoJqm(h0403?)az(Lm=oz`_}*f@CE9H zA7_AW?IIR-UW1+j;95O2OjQ>#4>pO%+zLF2J7a%4XEs|6hk(vv5ltJHN=~QnP#!uz zg6&g1Sry?}=p-yw5oc43pSfR%LBVD*$q@)8GCNG%>w&=y`Q@Zz5`mMcN7PQU?Sap6 zzQ;y%LP!uujF*oTyfnxH6Tj9v?N6G7I|CMt0_;ald3xrM%C-G zc|uA=)m)Kye(P=|4Xw?$(IwbGQxBN*EPvF|NxRkqn(yUOL?q#Y_f4|tM&#_Zzne075&kywG(RO_{%7tgVtBYcLdLH%xm6N5N4Mo&*K8Ue*A zMMkM0i67*xlP0&Y6F9dx6orLW_fm2dtJ5~U^~*oO_SqF{?Br%_$B`dt9 zNSOqeMCVkMrfHNqWCBS>iT0UYTwkgV<;!`ciqo26WozX1FZP+g9qB{sXe6MX2?zT{ z#(%pN8_c!NOh@^xfzWKAJQ&201j-YpF)C`P(=gN7M{2mK*m*@X z!ZTSKzu>Wu9`BbKK7V;vjg*IP6BVD630Y-OO+ciM#PA!J7!wH%1IIw46Ezw!h{GXE z9C|fJ++aErE74u8=-5T7Q{;2ZyjG5hJpIS9lvZOXJQz2K zln{ha#OJSfmNC;20O*VH`Zd*4i-(6AluqpH9`&nQ%XM0`0lOugo%RBMCV${P5IRcXMtMqP>~X~YJqOW{6Z%6)k4+vU0}swqlS!@W>}Zdy zEyQf^kBDo-hM3kT>EX(lt;3{7i9sSqi!svQ_-sUcl(E#wHph85#pWd>*B>X36d+?O z{H?d#4c}-+KyCA4n9Y^E1-^5!Xp2QJbxKu#AQt+;n)RaNF7TaQDy; zJ1hmxCRXudagieZyqBUKP#hC+2HWxjBRVI7}N5HN~0Z)@D>&<qlk&bEemU!=2W$PqNw-VpH^3Z!O$>DYCbOvHJ+bvHPzm7O{_v!IzZj zbFOmk{yFb6o2|1}FNoryl~`-XSiD0F&FBXn^e}-c(tMzL3V3Yk?nb}seD&P`o**)& zMu*=aK$Gy=S%MjkT*V&_^^h>o%^l?sP6H6U8bp_=2LBNl<8(G;mKv!;u|bFUNw7E>>6Z3t9;IS@@R^ zlNSeyEIU#G#w3=4qV|9XgQe%yU4MMK#aHmzIr~h|UuE=Lb0VMq_1I<2l7sMFfN8<9 zxkJl2xU>ew%Sl9)$Mo8_B}ccv%uv|g$hO!rGwog4;Hx)D4l7>z!g-4g-;>u{)=g)`@xbH%p0KAm-0$u`w?-F*|-#Nii=K+P->}mf3 zAgt-0`xK`5rTpCUwf zBv5`~TcKDo&{xLB4yVB*VUnR>S&q)bL{wmDLyH(EL0~n^9p||pnhxMLKIVJ&>14Y5 zBYY%EEuH^5x+N1`(Deabsi*6?0QvsK&vD>tLS2s3swmHjB8*VqAph|y>$F7Gpl(YS zOX|qCIo9cmT@K=`x{@+>PW;{ew46(o!KxN}D&w?5Z+6MxZ>WLkWQjDYT?x4*pSzVF z7mi7t{>%!uYVq2Ch`Rxe_$R!TC}cWP%mn`!MiOWmiZh6RrHIs9iIR~A3p-mkx2?WL zrMp78pVC)h(gz#XD_#YQWMn+KU;b)baP*CF@geyPXJ)2mYyWfqL2iF5{C5y;X~Em@ z#MS4kF+=-jUCX_Q`N){0Q7t~|nsA?*3ad}cgMP!MQ?6MUA2rfMgOpBbDM`4_>z`ik znpmVw_I-;bKnW31`(lZ#PnqH#EXwf#HOK^3&^ZLF`< zzzEQC_uc=&I&}Q~&p+&w&|&o74SjpQC3|W#3sy#HrG-vs`bd|6I2mRFMqdLC-nu7U zp6UMn79z~U$J4r%*@D~NKrQ8a6_HeP$27VxVgwjm*3RB$8Xt@k8ZoALz$WZ-$4l6s zJ}FJlHxTL8HDJ1N*U;lY>kMNfC@`{^C}+9TRG_(AKu0G+L{g$^S@s>q=W$gV%d@ss zR^5!eHb%7^Eft9bk^9F?Bl4n#i!bu1lL=F|c7@m8(cE%uafxbWQ%_4cTSIbdYv(G( z@#xDgCXD|oqL1wL{FJ{V%gEN2e&_$Y<4dHr6)hMFK}B`1w$GJ7!ipr=n#yZi=~V*a zXS0LJxPX&Hpr{=94{^Jo;a8hC8s>wHF!LLyO?5=}$VPGI&~hX=_^(7MHPKNRN?0zl zNO{}1>1sEd?w6XKo~zI2=a>6Y91l;Pt+RaI%)rR2> z`~i*wQG(56%s{Nm`w%OZk-0jH=UwW7- z=g*&1wn;UIj^a+*Khe2r)~c1F6?&;1j;YrkT+|WK(tR%c9W(fp%Q$vmdL$WZ5#IyE zb0q-vISDuQj~Nf`$3;1D#k?E?_37l7pqeV+;KA}QFcWa?fng8FVhypR+bE2ZFND|-C4@GxU(AT8pWr>6or;L^ZJ?fEUgl`44=Z#s)cA(FzV$n`88M2@IVdPzLQ= z6JeZrL6j(aIBCH{YkIm_Oh(CnIXPW<{i}bb2VA^z1sM3mp~L7=DRnNj~@?dvyhaczS^QANb8&#+THkU5b>qlWERN?N;d=V z>6X}XBa?{B$la@gEg{q@()HE0l8>somPM<#>`6y*I`NZ=xT-3?YkxV7_?3mXDi45_ z+a4Vm_|-XCV(oczHok%Key@iEqtDO48%6GMaW^TUz5#SqR{hzVifX4diQp}CVpvT% z@pDtLEyLFxP~ob={z)rAW-mEfWn0-^nf=+sNnywgvWUnjd#MZ`D4|?aY|@KShA|w4 zI)yj+Mb#t_Inri+d(TKOLv`KOHEwJRPl>VW0(tUTk%wnn*|BM0sr1|5FWH2AAAV+J z9~>|9s(*NA;8&vMTV16qbaFtKHYs&IVT{T=Qw*`6+rRAS>_4m!Piap&qKeC<-s%@8 zWY&nr*{?OWEAcJfQzNRj_`~u$q9_JA{Y8jA)SrI;f}!%FOEieh+Kx;ZxOjPaefdd} zwPpBICAaJ=bv)1&-)(#0rXVL<&WBuRPOrJAqy-}6s-Kzw9%*{uOCG9%-Cj<-1Kx2E z*c_Kpq%MDMZ&TG(I+dM=gi`1td29agLL!4F9On##$mj!4yn-K&567e~n$yRtd&bY5 zLQti?Ut?=xvn=-#>fyU*z&@c&O)3m>u&F?pVZPg?3fX2?n2qhC!oij%`l_v(&U3N; zK&e%<-o_)#xIM{9>5J#Dy0LgZrrwqyS#=k?k;|7_FQ>Vj`4HdZ=B>HGmIk7y(G}#^ zC-F1}GCaOjs^?Eel=5Q8rF~;TEe_I7p6V%^tiGlkqG9sOL$uhXduZsrU-j3+(9)~P7JHIn2(+n`MGkDm69NQxqDTqXZ7&hL$A{NOr}bwts^Sa*JPS!6gwP+T~Z-S-N6wfDo}@w8MRgQ7nB>#4=|IV z>>^K{hnO*a=#4d0-^Rhww@?UQOrs#7J>y?`qHv2PidFs!V4Un#E9lfo(@9X-Q+Qu> zf>)g#%h9^Fb=52c?Ncj#$rKkFeGF5?iLBc3cX^1t*Rhm@lcUGqkMR*A)K1d$UO9r^ zDq&SCDnGERKTRMtyX+Cv_UU~e(B$0>;I1@ii3Re`6zoYgwdC0uAZFRe(!~s1DjTkq z$kM935k-i|SsDf|FY;`l(ovHYe#yk`C8QRwSc8YaFT<1{-zIx%8Gyz5yX)uDW4Abz z2eq(W{oG^HB+STuc@bzDPKtElSEKIF4?YVWpCYaEQuoz=!i4nF06@U;tLNu^Vfi)o z#)+WMQ#Tf`DR2KRud^^v(lqGe{~Q=CV-u0Jx6dP(QdlH=RIu$pW6Q{MNSum86G z@6as@yjOBZ-``^8+I|l7yI=A7^*G2VoXfv>Mnh&;s?1Z2~eJ0j8(q4 z*X^#fT>rTx{tI;DD|>o%KXlza4rAx@bTn#glaBKJ(23VseIxnmU)6uxR^8Z_o1AGek9 z0=wH&Chx`9eUeErOjA13t=G((T8h3{i3$V5KDQ_n*)I{v&=H@OJhR&?t>Pfjd~rP3 zp{*=lVk+BJ$VuXbiM`;!!{8B=w!e+AU^ytX1Q$BWx7mK0hU%59*7plWHfq+(@P&G_ zdb0F!)af3Cl~&YSTCUa!ir|xFU74OETAfXtJcN3?E|;*B1`0 zHL2eM*5Z9}G{z@)^g^*9L922%ScYVC-x~-g4?HwJhPw_e^(&uU)D6?1H7}eWhP!(< zwMF{y>mCZ?eLOY!Abymc2&(P8&A6yLop^|xO#GOmaFzYx2gsNfHfhva4qcUk9WmEb zQJ+EXfKB4lz6Bo@iH?LBju5qYBw}lS6qfq3~Mj>M&Q{+80 zqI`=V%^)839m?wsTj|~N0tK-5>5}v%x0GlCFI=lAFTyk`d&-*z&-|U*iPQ^`smH#% zKieXHKfP8@8p?p}D<>sl^DJ&_mgz z#oot~=l|EvRlY^RecK_F5D*ZM1_>Q{01=RuE@>E$h8bXZX(>q+l#=cg>698$KpJL- z?v@<71{Du5(>TS_ux2bu<5c2y zNaDoCxvApz8K3-Xs`j^$FwSNi0s;#B2SUL}z$1TGYLWWH z>BbDC5f^sHVbG;aw=7mMRCZdJD9??ls^Q2ai&Q{Iz>@ce2b9!lm>7t>$bwsqbb;3S zPJU>%;1{o6&dM-yEH@RO|^X4W%6ygV!OA2|@5a|r1tJyzefjng)Y0Y44VV#EEvyqgWi zhOV~MfJbL$ zua4!d`<|EJR0PfQt`^K?J0|@=>@qy$`>Ib`_VstBz~dc(WBqh`O1C-yeM(M;KuOx~ zyN4KyB^Ynm=cfZiJ&gRLL^!{P!sN5g`Q>hh_tMX4qGDB~C{}9Cj@4Zvw$#*3jyNj1 zfdM^a@jwZejm#ct!YHB4Q>`m6m}Bi-f1x>Prr3!YhA;h)2*)SvcU)YN0Qb!X z`r4yZ*5C5{Osin7Nblboo_r7wE*#?i9(lZNdhIKE)0cB|j=UfB8$6Hk2^)Ye)1AQD z$OoZMmjpn}6xcb^>kH!tj{SGEMAG9P1$PO#G4-E*3?SL+jRE%@(C7_rOrST$YtuPt2co-qPDS@&aAMYgg^RK(;u59Bjhpk zRib=11!rOHkD8{XHLV3-Oi1DTAEJ(Hw5?xO7}RwBdfZHKpSV3X#)+0{MGau-Fz7c# z*uk9?bFS{+^qrAuM&F(p?;HyK zBrqyt?m#~Ul~%9RpEdfZ_1XY}Hc zv;g{sOcX{|2sN5T!KkzDIhK@0=fH(O+@P=_QS-{PFfzlX=}k=BwbwNZ+7ENn3bT8& zmw&HtGJebmWA6POjgA`lMs@zAuh%D%C+~77uCt5l#Ye=!Ev~OWws6WBH5r(}TIsgX>n) zW?}|92C&@RXHqXR4YSHAwly6|157tNLm+~MCwGYN%)qTE{y3Ns?cLne#l;Fi77!^) zN9OQAku^1Kxc2nfO;Fa;YZ*u9miYoz^Lq*0kuB@!svu0umWv^F;Ib8J(NMFe)|wnqI<21rTKt3xai|KEZU%>%_Ef1;(D`+o~YG=sDp``!=p zl_z!iSgbkm()Kbgk{SHvfMWa`0}b8{>h>Tle`-B#jb_6EQLi9!rvISc;4svEE}6S2 zy?J^1&yZbTwoE?hpUdIF3<#Mx}GP4ZaDTR(a0D@QRHZ;{`G1deic}2r5v22oQIH zg1lN7-hG$%gn4t#gl=oiHDFLjUB5L*5sz)TwAQCE%ToT>yNZ(KqoPGNDzrizfjLA3yO z%c9TNqt@NO&g!)Z>Z8VGw30Y0_|9H5I&Y_EOlOc8y|ts@Fqs9MC6&|tLMT0-ZwWBW z%DKbL-~PTV&5o>~3X3rUdkZ@!Htj^)<}T@*=J;v1R$rs%rkkguM|xfq4X>*eHEKW} zV5XAlPA0;@1<@W;p19vOOb8mekNcE3q5KD{Oisc1JJe)kzaW_nWsC;0E2DHH!b-7_ z52+(Sq35ag-Nd1)1^cznU0A$Kn{ua#F5<^e9^=$(;|-H`#V)wbctKgGiI<(`-#xiv z2uOfnu7e>Hbp<*ECP&3};E%uF_-|Za_kQGC@5uj|i)WZQxZ!Ek_VhkkX1qrCW4(lI z+fDJBu`|ODIR*+Ql^mZx6K6CEsjyILwxtQDl+yZ@3BGo4j{iz)Q{aBrA~dEaPAW1} z-sd*-R6ZoNY+ALYIhxy@mS3d5TYF;SY6C(sKrU7AQso7a4>Mvi<^whs51#&#USOxIe|EOA;zZe`t(9vf zj7bol-;_)Tbu;#uG$9-`*g_uS3YY~Q8cidOycBDXy@or^Ls;1{?U<|0RJEX&x6v>0 zEB-hxix$e=)jcv?WB@#%AHOvkzY5IGX_m=&>r#)ot9RpHQ`zu?^H-iU&ktjTOnmG< z2l)FRSaH7yEA%a4-KDtV5gu>sJb*<~e=Cb!g>c(PIex5uY-}X(z?QUVHkHgdgzhA` z=hKV#T-tzR`3_H91%mf^#bUCSMN$@mPkwO|AHFelc6@3wM(?!0?PHVWWLp!~olV?1 z4i1%BZc-S$I;M4eyp(`duJAKkWx;t&7fY=3C~+>Muv1xGQB$g9XFvWv{2_mc>u8sG z*RS8#|Iic?5lOtoEE6Ia7bi*S~P2Gs~Heb0_kl z1j|xODlIS=-#jY9aC|N*zSCb2}h2 zQsI7j<>7Ug zs1oMO^Utbve;n1NOFk!y`dP>nta2zflZnp|7VB14Lgf}$@JGP}^3+Z=-o)zkP+WSC z#_qOH+E3ciw}Q>2&=)C3-R|AqV&{_9+N4(5c3a@#tN!Zknomhzkd^{u?^+rPH+y6^ zZd3WYBaNm%?xt5p`vgF$F?@9;FtGJZ4ug4yhWYeVePg227>Tc4c$rxtOd(TH;wNe( z9=#sks>sxLpE&XL@>#8EjQz?-%`tyAod_WnbAvrj3Qtcx^69EK>2#B_vIOMzK%69U zvKpvjxC|aK$cdyl4!Q+W;S`^8mGyGnRGWFA5hEQnz+-PqF<-rv>DB!WKNY4$t=E^G3J)sb^5?+A&VcM^e=f*pGg9l&Xwa;op<$?zmVNndP ze(wqsWm>Cp#Od}ROR31|w4aoY6|L+p^LquoEsoO|-HxrEjv*&e@AMN8x;=Lnr#4?q zW36)eq6i8Bv#d*TA3{oD4bp1%|M9p!!jS%JjmHSZeXPfEZqub<`O~1l+^5euu<1L~ ze;xm*;~9x80GyJuaI*VwZX1bYkC#541mRn2c;`ZZ7dVBG&k+@EYe4G*JkL!tIr{ z1Brv|r~ANQkdIpecDJ6K&=+XyN=RZ>#})tm)1^7Q{v@d`x+QVq%jmGP>qEw=E2|WL zXka?q9l|xcSJ=5NX!)jO{X&RV!ZRW5&l*=z%>LFKMB9L zqMpm`)IonUgP|U^hQ2TvXjloc3lpCB{-e!ybRwaAg^d-*>RnJJ265_+5gBfSA?;C7 zL#SV@c_PxbJyQo>y_Xcp^KA{A0oO5y$TdS7rn0;O{ERBTA5E0){V{Vt_{FVV|5Q&f zNit`+%DD$yDva6)uGefHz`oI&;&=$ZVqEIS!J{Y!l@Wi{XqMy!txF zlVXZb>R3#_={&d=L#bC>sjK2e94V!ZO52LGd-%qksmQ6KVex>etgT~w9@Ev5C_nQS z@?_eJ_ohM}scb#9?f2zi;T9P~l(W4l!Cdl`Q|+Ov9T>$Rukz6tJG zLp)QTvR=(onSGWmSd;>46x08UH3K&DuuU-*VbuFi!AL)t@o$R)toz#(Cr$wU^#tyA z@OXZl2A%j6BrXb_023aW=^-S~@AGEHp1`HhzhOq?qG(L}MSEwB%M%*)L|ThQr4IA4 z-q&WjU12(|ExC%o@Yp%+5lBR7Msc_UIBp&ngzrr3I_A3Vx(?XjRkRAWwEYxDSQzYX zPdx?{Bl0ORc%N%wyVAvwx2QR1?@%?H+%-Txey4j60z1BD}v#Lj!#2l7G-SQuWzrtFj)uiOPiKAeT{c$@$XaD%eR3| znASjQiQ)Z4kE6ny>Z10Az#QU9Pm5Nv9JTlkeA7T&T_fNmE8_D6Q5?jX@fm=WaUAon zSyW^N$Y5r7>Y+^}1qx8UFp`LFHVGq#p*oZzsBn^``6a%wNeRRx)BEqfr!zYa z&|Z9EV7l!Gw78@v=Vs|k=N>utJU!7DcU>2Yb>rp-&zcy3UE9gX2t55kI!f= z2bCqUT*Xt2EN{6_#waPPz-IYXNlXkEh(~iTbZ(uoe~r6>WA1$;!uBi7@DT0;p-@$h zQ3-vg3UQL`(vrXD@cmbqQiYK9N_cTy=T|w9y}3kvhU^QtujAR0=36g4Bbp2 zwoUDpJFVIY5ZAi)69t0PgnM2A@0aD+cLk;(lWD$&|IqKQ$(FDpgOd5xT93qJ%4BKTdBe}Nc+!v_ME(V z3}MKV26^||3>*cc9T^0DytQho(n}?_M{OB@6fuIc=o|)0}c3FTE zr~3f(KQ8g#=biWRyy>o|hxG9Gx3$h0CGBR)eq2SqVl%da)@aDU=%l0&zqE+TH z2fo`^2Gc-A*5hnj%CFI!qa;8A{kX6w}c7YRP_ z#C}uX%oHa#vr1~9?>=(j>xUReaz&dV?a7|*q9Wo6A4ys=f)69W$C05cr%w7p3Z*eO z6JOCUHNt^l?2Yd~w%BB)Bh+xiG8*augaAV8yNHmflPebt zMh9fid9cZE=nEJbLbPaN1xdaqqizD{&_3!(2pj`H#-oG!G?uUdZWS z6<=gmNL8rQAZ{T<9%At48VjZNquqO`kD;Y5+9HhO7w3Ly*j3ojSVwe5o&@rgd* zrX(32=3tU9F~8XEldEjK+E4aH`?C+Hch=Cn>`r|Yh{$n}6y}PB)q7Q%6xDiQFa4$u zd;)*N3lDCOEi_s5#I$6h#vE3F!;qI0S;b;^CjpvF=2IbHQzh6~zxWtQ5x3h2V51 zmmg4&1iz_a2UPb; zHP{kU&#O|ouE*nfdh9f-HC|n#CP@cTRKPQ3NWApkXtiIn$hl8WiAp5MXXh@Dse?_N z0|p5K0cFKym;DH=Q$e|nw++2c z*zmre(FwA@STG-TZ6fKz>bRj!74<@@4LM%6n6bn|{t@J>sVZQUC4;jDX98mov=`#g z#CvzBwut&CL z&1TJ9n*N0S7SibSPD9k!4~_S~Lp~c~BBlzUF_DHkfR*k?pJK(1cFt7$TLl!e<=$99 zo@r~Z>ZqTxe;*nOey;^*|DdKK@?b3As`;pYrLM4uraSs)5B!UMvHibe_7~t@n{FZ-y?B_;Mh#`M`7NZ*Y#f$A)f;- zN2mi{_mHY*M|6;P=5!OfRwWOosFa?2rZ9VrN=*u(BtBbezh=1Qdgf#Is$Ho{?2V#2 zau|3eTVPL%J|Z=?1%Ehip(Kb^6(Uo#AKk$$v~-niQofA9Fyx~Vn8G?BH^8)-?8Llm z%+Hx@DDVN?@4Cg|T}&J1Q!FYyel#N=jXcVUPo`!)`94uZH}`!Dr#J1Asp%sPEO!kQ zPXzTPU4Fm+kyPxaY{l;MAyGSQ-kLnI1^J=~e(^?tdIX;quZm!r&@OB?d@a`$7fVP9nv+`R}Fjoua~x54^e-ADfwv- zO`W7_wf6qSmWtM{E9A?f5?pRHt%L6#9C*%L;tY&2y;OAXSKF=ZN#}Pjv%0vt*DZw6 zY^sod7T&S_6i7qhXYzka)E_*cSN|EL<$vZ~Y{NzsT?=sFgXPJJzXV2;eu%ZVfqZ{NYFIJQX-Za|wrRI;_sJ#C%iTqwSlO*Sa8cMjp%*?w+74QK{)Vog zfHd>q_$B=;-xa?j?@;hZmDg~21xTff@#S;h3;p~qC{xbPgv8qkJlxmMtTLJq zxH#x=kGFuvdlt_5T(5w3n8bmRgd2AZGqUj%et*njH=tJ4bl5lz@?*GAwyFRPB}%gq zo8o^~8vIw>;TkglWW3VrATBSGVeJt*Y^{h+JbffaCU#Kac|Tt7ju|P|G|jU3;qjFP zy$tmx1YXwt+hgn~E4QtzLcQ z7RiJbQIqghGltQu!UqF!MAOiEQG(Hdi@u!mLrieH*OqFgO*L-LS$(bWmetEIr<84(>nt zHaxbpB9vL|=_-rjI=tNbbwNj95v_oxXE(&C&~BWWo0HjZ-MTss?q)t8YMt6KBj2}s z<$DU&)eHF)K@sT`SfUT$A0&v_iV&4?zBq)B!^Uo{U-%2bD=8)=AGmJ`7KLpFn)RC8 z)F`(R>7mKIxy_pEx@&Zt{N?4&TYZI$hB3dO@go26_FN$ib{?}%`+OZO`;P;VA0n8D z&VhAagz<_xQ+soFyt%qb04V#ScxsW^`@1JbuE>FyK|y5o1b5W zw@*~JnEx^vskoNZy!Xtu^j@tms`~@Edon_1G6qTiaro)Zf7Lfk^Sx!!D|C{CWP-kt zbzD?EJf=f3Tve_|-+3MKMG;}!&jA425*LaTx1`MvaXw1vGh9$#Zv7q6_Qdl_*`nMf zNB%Fug_GTFrMXM-|dD!r|?teUM~V96Bk=;TYJ=zFcv&CTy^m@S4snjj9m zJ2e&AY)&E8eQ*K!P7w~R@P&j#M+3;(^o)DUikjR30^ zDS~qZ5h}{eC?%U;!I7v|C=I0w{#NU(?)_7lzW*$*_M}BS?{=C?t9?caj=u576x%}i>mU-c=suA&=hlJ8QQtMu-=1C1 z6kWv<$z9zW;Qrz?$s^D9Mpm_nMUq^(zPwm&DC~H3zw;(PC!b~NLc+12wXr7U;JxPt ztH(xL1P>8fe8KI5Pbz_TRo_59mWw~D4gjo3OXrIsr@&kF6W&CY3%}mlx_DS!?}a0d z3d1)g2aB9?tcgWtXPxB>uB%==Q&TZ``Tm|}!gdpTLQY?fxmoQ2{iA#ds#wh+Sar-W zz`@DPOA7Lx;g_?@0Dws1-z2|$$?;6weAtA?Vh?3nr6!)qg% zkwz)W4-u=NrRYO9zFO}z-Y%B|$&JWd8*=+~_ce_>?K=#z&K|+Fk-gVYMx)Y@e;E;7 zSPauP0>ae#Jj-&IknM3fWXC!CwGW-}l2Zqo_`h@l(|J1=Jk#$`)UHar5fb-p2LG`0 z7|X5M|ME(Cr!!cr{G`WilMBd}rwHJ!tY4v_~V%z(0TuC$Ez>T>=?Kceh z!#Xk6GJG(`^WsuRT(5WEa=L&U0l~BZ0m#=p`bwDz){O!Na2!lCr}!(;vwD)TT?lx4 zZo935BwHDgLplK+d{5h|H+EX4ZZMV!$*iY)(kZqirl91}k^SYg`8QjG@gY9^G9ij3 z79E{>90D6SoMQhMroaEMEV=SW*8!9P-b~3x4NR4;piIvcD84hOxF?f=uBf17y6jW( z_EpT_6=m|-kw3C7mx7I5VmO?&IlW+T*bIrYGSxQISCEy%U@HFI{?!HL?*?Cia{;J0 z*ngb=_l5s3@bd94B?m(O6#!r~0_ZI+y-+d)@lEbN^HNZFH~xL&yx03jkvl>1Nn|~& zCO3k+{_I1Ew;5Lxx*~5Tj6QL)VtOqzC&i(Cc5=cPYp$Yf#eoUqIXr#<8p2 z4b6~G-#h>1PtyCBBB7!$mq=kW!V+=a9qR$8yYAW(UEX#v2pK?C=v}`%V;m2rF6w=< z&{+`)RyO-w?%kpRsVqjfd$3sHg6=t*_zH*ZTSw-ks8s-|TDrW%>>%UI%W>S^4!1Y@|YEF#lQq3SnV8oJxs{VsN#5qJmzcJq~tO}}wtN%Y!_77$P%72;r dGA|Qwk&6EZ_y4zBAb*{wfO8TEjr(8t{|Aj;XFc-BX|iCnh-&HFM@zH zks`eX4k}eaks=^Pf$TT&%)IZH`_A0^;eNQ!%=)s|TEF@4XU|%*!ChoG01wI;g&1)I zpPcz2;We7E^pF}`4S%RUTlTRq)crXfENTIO`uZH}Lb>Q5%$>bljGsUfYs>;c2L!)A zB%8w`fG}5c7##~`8mbNY?kINIEWA5e|O-#YjVk1Ig8f z#w?gR$Mh77)^lFNV$#f^<5Zu89fB%={ACCrcd%W{vIA8i6{X|Dp=FNIs~_8UK=M9V zY@KuIQbE`~Ar_A=l%&xbJ$IE~hTG{um~ohoG8b#PC7d}TBv?^!t?~F>XRh7X`VWq5 zVu>$qw8v0=IA>>b0We{OFXSeCRFOke6=)fHlH&X(+l|P!UqxzO?ZS54xPZ=nQfA7E zS+lmGxWc{XW5+{Pk8W*bwypmB75rlRkkPhK;Nn;2inJ@Y5kM{v}%Wdk2l@X6znkG|4Q zh)tm%2gk81ePxI3s;;Gj94%8ccASxMtamNP@_c{jAMb%FgzUUuQ$}iFHP4P^%H9hxQei| zxqV173V9?d&*pVYxb;_}X@eUlF2so*po^h z9@Q(E;d*_MoqqUO{kMey*MX@!61oosxXm?1|G}bI>m_j}P@FCB1=SaUXUK*@?B#(5 zM@-Jfs?g>ASC0)IXkr42L=v>r&mJ(I#mMQb27Abak6NGj$3iiZn1F(qJl*srf)w*B zOhb8J#lVVKH>}*%1kcp@j#KzHp>~KqEJE{R zyiSWg=G1EYYfxjh7~2JhH;xN)G+7*>QK45d`Mf1XylOJ^afDw@Ov*nzzG!=L0umC< zB~7{$t#$sHRG%L~luZQYn6aZ1-ewIAs@|f$OC$Mw2`zhgCIFR?81-^Ko-n+(vd8gM6?_iG@K82bZXsn1{XjaxesNqrajFB;)6Ei_leK|y&ejYGvhaEh8#>$93 zg`TkfwTHuD%v5!!tj|v|nt@>d6h0tLq%S-jsb^qVpTVf;EL9mng57F~EjSt%QF%Y? zgQ8P@I%>->wgZ8w!~qhLcMUvXuP1Sn(!Sz zH1H+8XeH5=D+TZ}83@^5z(8F5`K{cV`Njg*-R^(o!@co74<3A@oQ#C2y7xjpxfh}@ zQ+*2rlN7~g!O}jG!)M5E!sLSFR}JaYAuN!;no^c9t`mp1@I)q8wlI#@RR0ECSdjn>SYl6$ z+wwX55j2n6ZS~o0L%E54f727Lglto~s8g{q-H^cs;0du1L9w1eb+KJvkB9bsqzjOu$Lo~R@O6N6a(-T)&uVP1drnJwF4 zEDZhp6Kl?r4?GsK7rDTKG7|<3z*K#i4&z)(3&5YeA@ePbb3-BfambVj*}WqTMS*jN z^@z#L>bH68+R}zjG2->_sJ<_(FPR)BtRKemPLm7UY)%Y!adX)(6glkxvC=Y6HrC z&Tq9){cw2yS~UPOCFJa?&z%iCv0VK0-DRJb0+O9pv?|3`H0JUqOsm(}r}P_cY1#}f zL=j;qB|S9@dL>@<1D8#+#30dCW|+J%N6CFZndt6I~h)bZcvHxb@UQw=~( zGvt1!{PHvGR;G0_*X+!p^TMNKGxvNI0*`wvGQC%Gct9@Oq{2XnFjnWdlIzOq4Cs}J zr(aTb74{aDH4Dt}8nKB__W1i{v!{=8K@2rN0WLgS4glr^sj1q$!vQbDr%7fxJ$Jc$ z^^~rPu@^cBc1Bhxo)quDfS&7#jktVSs7AEN3PZXvO`I(avC+CORm%7~*e|k8Pw*W# z8D%kcB35PcRR3)EG}SMJcWzSi6Cza1*GRnDR}BX+N~fL$yxRywY4F@${v#rq{SlnG z=2@vDUOF^F@A@W}ZP(4K@(vjK-){c%`L(jU0$W2q*RJLzb841+RXWZbD4~nbV(+H< zwQ%7!ijT(o-p+EeZETyjZm@Y#0Kde4I^2@wi2$)hGQ?H}LoeN()|h@a|rATs8P0T`NqfJQ$R z4i?@GUmPmq9$?wxaJ3h~p_egG)n7OYd9uCzJ?WvZ-@K_u=EPgP7TiuukZs#tqO}y7 zXUfNDB`fqQqF6kTWzLJclXWa!GKn7foa*->TqyrPFf_hnVnD*NE~;V=H#hILVaymk za)W=^DxAj5N-(K;`Dlr>U(ecltebj#nBs8d;o?hIkfWThT{G+Qq8zVugG=_^*}p)^ zJ>E)hB}*+yZ+U)vAxlJvev#fzhb0%{?Iib=W2P^Yu#}=^o$YFQkICUoH1uB z>mlmeRk0K^ReYBI;*KvoG4}bH2ogpHJrjR%U+3;wxk&X(h3=KoQG9@VWbn2^?q!HV z;yz(8Sz5?hB(~afq*%SPDA=)j3gZel#|H_qF)-5iGWElw7zRasX*%U&3H>RiD{dno zxN^o1)qI9`C5g|bBp-!}&s1?^p!yHsUc%*&H!wh2(QQQ0ZP2Da70`3NZ3dxFQ zu(REnZv63NznxL-&ZfbmnY*Fpe0Q1Rhl(X`R-zuKC_v8{80#|&=~YLu>%JX^Sm%QxYz*Py_q^LY>{jVKBJH*rIDC`zz9tL88^^cM>;s*e{; z;FtuuP)!2NIfyiR`#d*gIPFz)r4SJ>=RU9J`SbbXe*ZZCoO9mi^ZI=MI6rWM)D55*x9~vMuvtKclzvW< zHQ^2ZvzdjU|L-QuEb?F?eO%6~LFtw#Iu-sP0G$w%lh;6`BE(eS9Eq+#V{2pFQc$1v z{sr|x5Y#o`QjfKeF^(_ud==K|S0=6i9{4bn8)qocksN4e8#zOJ>$@!i*Od_8)I`v( zyfzP>lDI|hSe@g*J0Z9>2;>(qoNZby8Y__=EN_+@ZdHW;xEpJq+& zJ`IQ6Oi0Sp@om3U3S{e2^+i;Dg={iiizZ(j_QG|n_ncJg*wk%XSyB?3o|+GzU&MWI zE`WRlMs|x12=o+WxqAEaU|$6*$rXJgp|I2z;3#WVZGJ6ke0-;qX}bEFJw#EU)cTPGwly}om=(%TkVf-hG9e$1VpbOcupYV( zF8fjariw`F=RARj)F&ziR1RL+_YC^>so2SJ-K;YLd>&Ie%lh7hcwBgng(;zFOq$u) z@5+}e%tn-9-br+SOC8^O{~_{8cd}^(!rVW+Lk{x!FjZ4UfM9a|c5tY)Zn5i#vwM-X zN6()snJ@Vl(!?t}cnk=ZU5>M27DoOz4PDOBVD zcsk0*1H*_RyeS{9i3pBoBR#+WRKsfJeZas5{{913gGQ>?ctp&UD_$eq&U1mQD!r=D z#dq9*r`#qI@_En`xAFmZ65TiK1y-e_fipEbvx*0^HScn9fB$;Scd)WhO8(kZi@<3Z zn+PJyEgkNI$Qrs!Lcy~XmcY#xUK>rVQyt!qYRQ)|++O)vLfAXfGY_ef0(?iF|D7MT zkWd0dI~af5lh0(&GF!M-7loD+;W_3|!+dCW?$6)UGCN|}^~wClQxYvCY|k)!3=b)B zN-e~JOD1aA4L*lSuT^KSH6)iz)1XRIk#l8EzCxpqUv$&9aVq2sVvuDez2Eo zlicC+vMaR@M5~&sttaMLF84w}N4YzDZTsNo4s1SP@_TdB7i@QVjexSXYKp##R)b5@K3jz( z3OU)=R0Tvxf?)qNxY5E=B<=HIckY6ShW4}s%$+I2i^glR{es% zeUQww@d?~>Ra&~FIgmR3^LRkJTK1vLy?f|mF1|-fQ}1|qSWUD~68JNuaan?a>Yu** z-Jnw;ACL64VE`{lbj8Na0 z8P*cG1QdCl6ShGUJH&F#pZANC(LcO4Yib|gl#uVfng{wh!&Oanu?``SuZrl+s{r1- zH5>F(xD#i|8eACMkJ<{W9{YMu{%Cu6JL6OC$$|cRv(2%@FK8}}_^fC88lE^po+pd2wi&Pl7_7^aOE%a0l_+Q4hsm$46PpDf zvA5n#nWm(1@j{{MR-D$w-LIqIPso=LxGPZvsM|E}wr%*WHU73guyjLE{t{_(%@cR{ zQ8r`lLH}*#jBu%-#I3*p{#s$T3H$@<$P1@#J;f5^v)IxAX|#3{yA*Bc6ZgUe@cUPA z_xks^ot;9KR{0L(qmZ*gB>=*zWw&?-Tn4wd>xvny^A=y2iMM^-yq~5OctiV9bKgWc8 zQB=8DJ^-^i=w~bDi#l~poLLy-cs*G+*}RY2*VS~RJ2*99qF5AK4~ zFZ_-jR35dxJeT^zPP=gK%dC_0%k;Z0;OgDBozmSncq$gl&(ltxs65}U6E?E!b6h(t^U^K4Ph}Fh7=%m~V?(ffEtQ*US^^r4X9=UwyUlq@`#H+ZN|%qT6_w(?I> zI3?W;)liT!V2{E7=l}IDWVukyLH-tXM(I&1$5rgd*E2%3Ut#ua+2nG28a5f7@UcXn z7m1H&6QfdhLOz{9BI*;`+b1mRosH%FrqTnT2NhTl z&wDs{@ka^f*uOp=Q&MgrY;DY+ zZo?J(Ip#8!&7d4{ZKwq!2>EU(aiw}F|BslukFhIG%52kjr*57a9I8zTt$Wwmwd`g8 zhko+TC$@m4jpU=X#m^tSD9J58$jU18`?|vTv+kAZmBOcLdXMZmlc<{4e=L}`E?*bl zC*R+HvjO?%QQ2xWK;qlLj^ahlAB$lyO8sL^ZY#-~fmR;?zCYI|GZw zd-KbRvrw*4JjTiV0UEgHjNh{!h!;yFq)K+|(0*JNm8dLED-$wPGN}nRrbR8{_EGB% zrwR=pdZt_Q=i&ZXUkf<%?FN{j|9AfpCra z7Z%qde+jeiVTbFar9Ea)*C)=U@PhN61=eRfWfmo)N43ax4As1G1ssbiS?d72_H_k+z;gms*2M!tj!RQ1sc4aCB)CFnoM|N!{K$dLP^~cJ%aC z#->N)2rsSM_9%tV*c;reUYY5d8z?I%5{Y*I9Tj6kO5P0QJ0TbaC4k3KvrjV)@l}Wl zGvvX^TgN}1>5e3RY-r@Jf6wD~#RpB{#NlQ?Us>R%95=cu>`H-~DnFWLt%R<#p>J_K`3*G1YK@#j12rc|9JplGX@TZOM;*?aos0Pkmxr}*6abgPj|Y> z1e_+FX5NO0Pl_Lh5krp33F8`q^HPt74xhXtb42`u0-t($S}a2P4E&5-$d_pZT1Lcq z@kh$o5$WKDcfaDH{5AjeZ*CT|o(7d24*Ttp#89Y#Su8Vjq8vA;YfLx7U$Y?9#@1yx zpAT;HE4DEkpQ)t?cWKxXyXwXJXnXh~BHFb)NCw~EKV}rDY|0wl7p-EpRr^CeDCj5U z3Xn_V0zGB}^=pRE!b$sZG1hUc6b zPHr5Ls~o2BQVe)a=@e%Z1=6J5l}2vK@9y4&E)K8!a(^kvUqR=;1Axe$z&soCvYW%# zOw%ii%y}tiyBTG@|Jz&jKO4yZ#xG9U1Kg5x{~7Ur--7%(UZzwtAYd5uf1mtkH~$SW C1S38G diff --git a/fast_follow_asset_pack_01/src/main/assets/audio/hindi.mp3 b/fast_follow_asset_pack_01/src/main/assets/audio/hindi.mp3 deleted file mode 100644 index 7ba1ad66b8a76602c541525030faaaa6cf72a0ac..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6912 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 diff --git a/fast_follow_asset_pack_01/src/main/assets/audio/japanese.mp3 b/fast_follow_asset_pack_01/src/main/assets/audio/japanese.mp3 deleted file mode 100644 index 379a6938050723055096af20025fa6d452f4032b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4320 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 BkHP=| diff --git a/fast_follow_asset_pack_01/src/main/assets/audio/korean.mp3 b/fast_follow_asset_pack_01/src/main/assets/audio/korean.mp3 deleted file mode 100644 index f17488e15429e9f3e4bd9a27b3b9ec0b577cb9e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4416 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 D^BFm+ diff --git a/fast_follow_asset_pack_01/src/main/assets/audio/portugues.mp3 b/fast_follow_asset_pack_01/src/main/assets/audio/portugues.mp3 deleted file mode 100644 index f7d54262bd996b2956365b7e60914d3d83cb7fda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5280 zcmbu?Wmpv7+XwJjN5x!Rq!AF1 z6oH***O$-rfA>4D=9+8fGv9Mx_nesn9;x&Klu3Sz5KTG=0EvDbYM1VA%12EKMJR;e z5fD!nzS)!+Q33z}5``VX|NkHndje2n0ndUkGw(MnW$p8vC7+WrY~lkm1msZA6U6$| zH!4_EAX(CoMgMKv&b)-1D0s}D+8*W@kz6K({#|m0jEk!QoxqOyLnqz~YFR_@Jbr_C za@zXH0=(?^_{(6Dh$uta=Ypp}Ij4s@-r~pd@>4=R<@ARrmJOUwOobRThh#zlD!0p1 z`hM{2s?E106;^etS=7xx)yB~IdJkUT_0APTQ9jQp(I1`VOj}bmVoZl|Q;*#bHImq8 zm97z^%hDX>)Y7e5%7vIZNi20Wxn)crO?tk^`4rT!sc=ZT0&r!oborTGY42vv_B0cl zH0d1XZNjc=6(@L(Rx=Zm;sP5Si+q_q=xs;^Q{ zyAe{5_uAmVfk=3onj9{^MH<*wAEPIi(j}@$mH&BN=hU$U+%l1v0;gXfZc%x5-(X^# zCq9X!UB~&9G>Y9xz`_{nwp!@G_0ez@X*FY`J9bos#3Bg}<-xi7rs{KYvp*j>nV*8I z`&W1L3yxFN)$cAXg2Fu?BJsMpD>NH;BDU=#13=>LE0!Ez8kh*XKb#ORE{)ugx_G{E#{DPfr1`vc8UqT<|H#yftkYaj48&K~ z%AA!ks^SoXh15JoASvz}bM$&HXA(5y{2Q>JQ$@J^evu{%G@a75;&{tm90e`nGgCsB ztKjLM@es)0vX_bL=V3lij;L)_YeK>~j&GgE>}(M!#}JbA2}|Lo-FUNL z^JQ*f%E&OLuADH3GA-oHKhvM(<>q;V83(duXU`aqtpAk{-l|kVkfm#u--p+~)NsBi z>VFqY}5R>+%Wm|VuI5I^^US9RhS=XvhEHkR7J|5_;GROIHut1_bV2sui^#DhL z;7n7h@!>lorAbN}zBoDL6B5N!z3L*}?2nm~io=6>0hKRn$%W8=FV@Q zSxh@=zt5i%bjHjq&hKN5-F_rx$md@;Ukj!w`34v<^+ekcME?{{;4D`(IR4qtmff)U zH4q%18zf}#)+5ahQ!i@yW?;;KH*7WiH!6{#V*HN#S(GgwIPB?a@nDi)LPWqz^32lQ z!mjSU^<||KzU%3iP@HcDZ7zrdo{{MgADvoSh}Fmj9e^Il3oL$!^ zprROzEy$V7o^_0M@#ddJ{)F(@)Kh-nUKnWPeLrwCdx5SZSkJ6=*!>Z)+}^k2HL0>O zSX++sohknmn*%*WIs;=oM+E(!=ie{RZyHp5A(^<(llooN$>-#cnXhBRj6Az*kFt!B zy23$((22HJfT^wb5}#$T%__4Vl#Sj{oelYv7q3jZEmfja6&B56o?(1$g7crkG%O7u zmUKY==4xLAb0TLZ1#03v*Yw?cQpXh1`?cTINnbtat6ucgp%p*W&A6>8`h=yCzC>ZLz$A?Ry)Alb18Wp zkx!C6f!M`CVe-L|)7A|ZS&5|OG65kF=bNxSL!uyw<^cHnyFQopyo+Z}yS_ku3RL;W zzF`!UITzaw8~YZSWEIs;myxX36lK&4KE~5ZyLl|GOUh=7Zi-OD4yk>W{uNpDZUo6$l*Bu0PbMag~sCAzqTp(+0}mIXEvuD>{$mns}e2ua^4D{EqzVfp25xV!H^k zKNQX#ax5)2<%O~dx<(RCNDywm(b240!p<{3%FQ`h;3YHEgs`Tti7y1_lhZ7Brvsm7 zQIF;F5ktQUm~{7K2!uI=SIH+-Rr2iE6~%K3T%~?0o`GCVn54!0@%$}j+NC|oG_Yss zuQqEniZN;#*c_EHp)mW(PKkZU6-3KC<)T9yKTa9v6I124qysY)C~?O(U#pzxGaovs zDBjTeol72mfynUGLOg`T7pig&l1(;Qj@=o(wQeZ<03=x;=zlcKW1h2!THhO@S$XIz+pEDNiNc^ z(*v3KF?@Q2^QmDF3U^=w>KOqQ&_x%ls5B3x35E z?>x)m574_orAP^0{S-6y1|?>9KT>uz#|V(Kyql~eQV*-NTmSN#r3BVe|7~X@v(QZzwB3w?AIO!Auzv`Js6B$R&Tg z6;qqoXrlQ|Kb~eAQ|pee7;!l;Xm$T$$%^HBw)q<_1fXc9`LF-QV1Y_Wz_gC%Rmm{w z*pCQ~5M+88Zykg!CXZd9;XS?X`QEp*%mxa%*&YCJ^<4LSX|AHt2gBZ+mMN!HU`Nb! zi=(x5JzLWF%R?!t57A533m=w(tYvc^Ye(YpE5Jh6(3ymCOB=WC;x219o}`#EEZLiV+28#XUFUt{R+>zy z5@k-BmW4uahT_4zf%vB|F0?(KBs8fw?6G(Jn#WN4T>1G9M^&4{p8l&We3KV47dFqk z=Um{}}eJy&f3ML`TacvxE-t z*8SL(Ux{!&al zn@|s_T*l~7h_FGm@-OMV9YWSxi^HRZasE@-d1EcmHGw(^4D9Xw7Y3k zKE!M$+&8hFYm#ERk{~s^j-OA$f6PSVBCqccB}IGBOx5IivlSUKv=n4#5rucwUwa=_ zcuiQap2u98KgnINdIS<<4ys}g{SqgI`JW2ESki-KDyZ2Mek!>AE!1jtl ztr*Uag|QW2^BbTmKyb^zT-9OfnOHId!5uFNl+*-^mMBMk@0^v(&YyjThK~Vm8jx@| z4j7$}N%jj0G|ytQD`(IN#q~-h*Iewvmfa5ZTECztU(e0HmP-;wwTSaG;30xVz=)A& zlfv!1JVs@!Lp2A6lh)OyWI7ii20a$`)PuVwAJ43nUkoVrRLg-UuTsfC31tV-Sp(Xd&0wpv zHTtFq`#W^SXR8fXRE#ygSqr0uS_R{?1owSnhxgaE2s1Waw~kayFPbDf^1gKjlKe_L z$`0Sk6#_ASm)ox3l0##3=?>1XhnCU40Y1%o&MdXj`+e9%(lZG>z2o*JgD5gX`gZ|? zv?>?D`gLl#UawW-QazpY2{#_9R}}EBfCO1lOEiTP=mE}xIsQV~*jOFdNE%ukQ~Qss zYSeEU8R7h1s%NxCK%mNp!Hte@6-guN%GSkf8btU2!YGmFGtD)7#uy6EgBax>A%MO8 zeYb05SZ5QwbXYn`>$rU1vG8-@LZsYvcCxABi~FxSiPSww35%(Y<8LLL0WmoL6U{0^ zDWIX(MuoE8mFE^Tu3RpQL>aB{8Y#`kN#?=0Bseq4JFpcO0@HLcL3ie=>%e`m=JXM2 z{A6F|9?dxap2{%$ceja)f~rY!_6<5o`#`VKZ}H4X`>22Up$iPP0930j-y$wx!l;ym zAKo2t?Ngbj2d2EEm45CbiE|W?A6pwLZbQ>wy<7~kWgTZN`fc6w`|9`a8tCiiqHog^ zK0v{PBWqh94KeI)2pYlGsYkAZr`&_{r(vrsm4LKfYrRpg!ts+8-WMdv{2Joo8hYFf zB*olU53hWY7>h!;=dqZ0pDkk(VQhVZSV8c_q;KZ1%*$}8Kxshi9`)*l#eOEZXTuty z<`bp)nWslppFbMse}{ei=eKcc;CFeJKJ_75^HhT}u|&PK9wOljDgiG}K-<5_Adk6k zby)ftjiHw1#%yBHxALLgNaMDB3YgQ%dwpue2o$r}o!0Iy)CLG&zlR=}O~;f=Y{G5clu9TjTr<>MVvlz`&rb$ie-U zzBWcxBfp#9_GY9)2=PHG`x;Z6E?8roU>p$*AyxL3xKovNKR>g@j4B{k^!A&|%%>9zL>IT70eY<3V;ag8}#{{5TV+rE(WXaGuwB*_RBdZ;`r;*VBvZFuZK`c}4vE>Msp zI2HL0^f}<;BFr*T3og1Y-pJ0+KiAzL{3bA=(lWIxT!+;@Oi`RwuS&S<42Xrf`jEn| zQ!1Z13Ul?;$~nLzKbL(FJ+@bKH{Kn7C`-UB@&3-LVIdMNAxnF;{`sV4+ip8>eEB>~VC$2q|cRakLc zr+v9|y`+Cothr0`*j*5bE>RZE5GVv3r3@q0=_8dBk*djM;)Ye7tI+w%te zwpf*H5S<^bl0PDT=e|;8q(LT1_NvYI-~MP4F8%r#7*f;OBp`|En{p|rvn+?ZaJrTa zIME(jCii+z1PjOE@oXu0^@~>4p>I;h*~h1|L9LtgsJ2Ry{a&^3D|*wF1CK|Q-Y5H8 zlm%9U_dJ?DE(tJHlh5PwFTevdFR}IE+_6|NQ+{&O)jPAJ;l2-*GKoZ{A%vr(H^GdP zG)3n;atq`wrvM63z2uI10+kl{>ps0emD^>8a zSn$8^*BTtE1^``=oJw}lzQN`nfS96i^(Y2ONPuM z-z!`(uaqPo!3#y}DC(+;35o~{oBYS|@BO8!wKxE})j0p7^}lY%`P)=3G9$nT+;n@Z~v0F0l1MU|}(6cVk;ZMWi}(bKiCY1ow#-#-Obw zLI4+5jxbn0LSaTo8|NX@42>iiJ_2!KxD4{f7r+iy#6;})ZLlMyz1^XcLzQjY$JsSi z*is0d?z&iX&N&AGH^b=WfR^SXv(Z)5a`)3HGYp%(((nC9&i14k5Ck_&9+?Mdm@Tc} z_^P~dr)ZPnB|6BO2*q9RmZNp~){ zR~E$@?qB*?d|$dlHvDm(kE0K&tk+~HpC5AmYN}&5y@L0MAhlH|ESX8MOWo*BEyL#$ zgj*4TmxFkz#P!l4v~L>`dtnx@S!W(on{#ySm>Xhb2`U?;xxW571Ja@L^(~j1rw6sS zJB%YP$-YpYWqT2^l^^zM!jj{nj#(4+q_rW)KDMgMc3J?>b3B$ZQh;j?k4n{ zyP&p+VL5;~C;-k2RX5~6L;9i35n>FVLx58Q56t00#tr!ID&vPu%|%r?NWpy6`!6*D zVm;qpW9N%sfE@vCxS6gd&)|-bn-0mlDnGxbj*c8$soJf9VrtaF`y9s(^i5qQPKU-W zmj?lIheI=Te)a#091fT=3xW6*Hhr>SLXFG4__HDPQRO&>;7HX;m|)9DSqXL)7}N@5 zV?xhxYsdDj`#%&(s?dwXCiJArNG3j$be}xX#lOnLRelCSGo9xIHW#AUx)1upZ)=4I zX8Q3NkmlAc+n`x^S~h>UjGZ#zA9p!Py-3_ff!9*aAL|-;$?3sl?Z*oRH!?HV8woqg zXJoC^SHwIKr}-HArqwdZ%pp;l;44YRbHH^|yd{DdKCj^W`?r8u7QCD*578NrF?gO) zr~)JczDe0$7=%e?bx)zGMF%0JvS4++*pyaRP8l$Bn{0A&o4qV(lAx9*sr#yZDHa6R zK5)PUnbW33HE)u9l!Pm=anhm(`2}2ZaKPJsd~XIU8OCD)Qn`_5h8q3lnR@u2->liZ z?ET{wwVG>Dd$2XeNB?ku8%Vnnu0}0al-3)4fFYtqAhMg=#{teKPbtlELOSL9Z~3D8vNHTUB=N0%XY*UKn@dH9-Cn%~Sw;Yt)`%*n~bE2r5mMd$->Dki?%>Ye9G zONn&nC6I(7T(M-4yR)?Yjp4(EjFD{s4AV8g*L^$|1Zhs);C$>-?EWREZ~ND`i+4XX zs;v1hirjkf>bG2zx9{2KcHQ4t9^-$GXh;@6TKaHd(owphTJnWDMM%@i3_A=v`E2gu z&o5C++k}JthwBg*@-e`H?$W0${p<$cfY#vG>Fc#-kw2jB1sFl+GVe~Puo+VRlBdoe z1yvc1Y69fZunbayhbqFo#}GF@9T!*1I^=Mi-hMD1I@k>^)veIe`4mut%# z2Xt^FjuU&qAb9QaK9~pYt<6_Q-`Y(#>=S-t^LOvdRp@*M$4;-~pTT_72~`>cBxvB_JhVpy{a|l1NfTjy^Z) zLhnEv2BY$_Mine=P&INXqxX{qQCDDk(g;l?Y$j^J#n_%kF?EeDZ>_HAEFEn(q*jF5 z)k1VD$a)Ol^pHi10Wgt#HX^!~%YkE0bWZ+`SDxMT;UMelfuPIOknYLi@GQl3PD+J` z0Gut0W1ZwB%5%=SRr#+&WphnxxV-f<#jR#}=igkU`s>e&U)4A{6k-_Bo;Uq1jNx0s zA_=MxX9NK6Cf(^Sh)V41**aT?+z;*O5_Nj?b!4Yau#t`_A^HNk37>WP zkyI5`i`i@v@ZgzbH3ifa3fAMUkyW+paMX0OE^Clk2+Wf z>Vq?%vxmSl92!sj*el6r!=MUnkp_Aa4F8yDsSqC0X8_^4_tJ2Gam#cdMM{i{s|&#j zvCs$_UIrvr*j;$_yNn>9Rc{v;0kzR8SpG)q{;2HF zEd84ef*>zfHQlWCV;w6*sn-nyhE>m_|7IIY3(B?Rt~allhFzEiR- zq zLeq>S>&tHEtU|}b6%o@Q_`@vMV<&5N{Q<{Pru-8VF=y;4aO4{O1bvN0JtJ@JJJs8& zpOW-eseW->5DGikf0X#JkBC5z8QwrHQTbu@Y*HvYxWAl!f6*^Ww#eoQ)Y#Ba^?knD zN%)DOVkw{J2bg2P-K!>voMB={Twyp@)_yETx=$F5WGgV7j2k9u@>&&uV2|7kj*;I0 zt`&^~N=)$MA@*!4+UZI45|0vOVJ}l|mIe7dU7^n!1f4cxY(`LsByl56gD@g8^A^SK zO*Sg+`n$u)?m5Dk{;Xh-#?JKIBkrdGvs;CJ&lhC9S83E3lHpsy;veAwA{vjYyZD%a z?LC{IR!7?5K9&BN{-Ig|n(Z=vTS;K6X|tG0?f#Uvq?`OqTx)_>^W0d zdL#oUUSd%!L(28c;q!Z@j#^%mWCwYQEOV)^Uj=pyERCiA6n+J%L#WbDN-jL?HoLg8 zCJUcU=`tbZ0-50l!(F0@K%5C4C5cH$XU<@^9vK&~Sex95Zj6UuiFo$X}GI|8mzZ z$3d~+18;!rj`zkWxFFJZ{zn&ki~Enlvo&%Ot}o7iWlc@QPs_vH~+OZa%v6JN+<{S^t>DjTFql*w^0Rda*n0V+P5L!SHxe_Z7 zsXmtQ&~cLx3s+?IiV`}>HP!xFQDBGrqmpkuQkda8!Jh6(LMSjmSV@_RC2h1!<%u?E zY!fbEbe|II%Pg|}O-S(f{Qa7r1*#pUSAw=K20L)Ek82FJmnoKY2)hJsdz8et3nPj0 z9)^?+aNSN(AsvBGeU`(;YRd4v`TQIKKy?srYHG?nrYI=H7rT1c`;g#o4uwJciZc}@ zEyotts~yf7o-;+MoKRJD_*?7O7X2ZA``*7(;NN~K05Dqs^z{$<)&KMV c!$AJs|9_@Gze+Nmpa1v&LyG_Q&_C_}3n!bdwEzGB diff --git a/fast_follow_asset_pack_01/src/main/assets/audio/simplifiedchinese.mp3 b/fast_follow_asset_pack_01/src/main/assets/audio/simplifiedchinese.mp3 deleted file mode 100644 index b9f00f6cbbfa304d949fd2a280ff21de1a1789d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5088 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 z 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 JSKYtb{~P66Pfh>; diff --git a/fast_follow_asset_pack_01/src/main/assets/audio/traditionalchinese.mp3 b/fast_follow_asset_pack_01/src/main/assets/audio/traditionalchinese.mp3 deleted file mode 100644 index b9f00f6cbbfa304d949fd2a280ff21de1a1789d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5088 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 F{{ilF$iM&q diff --git a/settings.gradle.kts b/settings.gradle.kts index 504b5ee8..b3356345 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -22,5 +22,4 @@ dependencyResolutionManagement { rootProject.name = "Brainwallet Android" include(":app") include(":install_time_asset_pack") -include(":fast_follow_asset_pack_01") From 4ff50b82fcd882439a3b24f859233320668dfa81 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Sun, 29 Jun 2025 13:50:10 +0700 Subject: [PATCH 049/116] fix: fix YourSeedProveItState.isWordUsedCorrectly (#111) --- .../screens/yourseedproveit/YourSeedProveItScreen.kt | 10 ++-------- .../ui/screens/yourseedproveit/YourSeedProveItState.kt | 10 ++++++++-- .../yourseedproveit/YourSeedProveItViewModel.kt | 10 ++++++---- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt index 04fcf6f2..71d1c56e 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt @@ -187,14 +187,8 @@ fun YourSeedProveItScreen( Spacer(modifier = Modifier.weight(0.1f)) SeedWordsLayout { - itemsIndexed(items = state.shuffledSeedWords) { index, word -> - - val isWordUsedCorrectly = - state.correctSeedWords.values.any { (expectedWord, actualWord) -> - expectedWord == word && actualWord == word - } - - if (isWordUsedCorrectly) { + itemsIndexed(items = state.shuffledSeedWords) { index, (correctIndex, word) -> + if (state.isWordUsedCorrectly(correctIndex, word)) { Box(modifier = Modifier.fillMaxWidth()) } else { SeedWordItem( diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt index 1da5cc92..b69ac06b 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt @@ -2,11 +2,17 @@ package com.brainwallet.ui.screens.yourseedproveit data class YourSeedProveItState( val correctSeedWords: Map = emptyMap(), - val shuffledSeedWords: List = emptyList(), + val shuffledSeedWords: List> = emptyList(), val orderCorrected: Boolean = false, ) data class SeedWordItem( val expected: String, val actual: String = "" -) \ No newline at end of file +) + +fun YourSeedProveItState.isWordUsedCorrectly(currentIndex: Int, currentWord: String): Boolean { + return correctSeedWords[currentIndex]?.let { seedWordItem -> + seedWordItem.expected == currentWord && seedWordItem.actual == currentWord + } ?: false +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt index 998ddb00..c6406a2d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt @@ -17,11 +17,13 @@ class YourSeedProveItViewModel : BrainwalletViewModel() { override fun onEvent(event: YourSeedProveItEvent) { when (event) { is YourSeedProveItEvent.OnLoad -> _state.update { + val correctSeedWords = event.seedWords.mapIndexed { index, word -> + index to SeedWordItem(expected = word) + }.toMap() + it.copy( - correctSeedWords = event.seedWords.mapIndexed { index, word -> - index to SeedWordItem(expected = word) - }.toMap(), - shuffledSeedWords = event.seedWords.shuffled() + correctSeedWords = correctSeedWords, + shuffledSeedWords = correctSeedWords.map { it.key to it.value.expected }.shuffled(), ) } From 2fd094f0819ff77412bbc356d36d4bbb397b05f2 Mon Sep 17 00:00:00 2001 From: Andhika Yuana Date: Tue, 5 Aug 2025 21:23:32 +0700 Subject: [PATCH 050/116] Upgrade targetSdk 36 (#113) * chore: change drawable with density for brainwallet_logotype_white * chore: adjustment WelcomeScreen.kt * chore: adjustment for targetSdk 36 also support 16KB page size --- app/CMakeLists.txt | 5 +- app/build.gradle.kts | 4 +- app/src/main/AndroidManifest.xml | 5 +- .../java/com/brainwallet/BrainwalletApp.kt | 5 -- .../main/java/com/brainwallet/di/Module.kt | 5 +- .../ui/screens/welcome/WelcomeScreen.kt | 67 ++++++++++-------- .../brainwallet_logotype_white.png | Bin 0 -> 62457 bytes .../brainwallet_logotype_white.png | Bin 0 -> 39557 bytes .../brainwallet_logotype_white.png | Bin 0 -> 85102 bytes .../brainwallet_logotype_white.png | Bin 0 -> 144825 bytes .../brainwallet_logotype_white.png | Bin 0 -> 141693 bytes .../drawable/brainwallet_logotype_black.png | Bin 122516 -> 0 bytes .../drawable/brainwallet_logotype_color.png | Bin 130982 -> 0 bytes .../drawable/brainwallet_logotype_white.png | Bin 126886 -> 0 bytes gradle/libs.versions.toml | 6 +- 15 files changed, 51 insertions(+), 46 deletions(-) create mode 100644 app/src/main/res/drawable-hdpi/brainwallet_logotype_white.png create mode 100644 app/src/main/res/drawable-mdpi/brainwallet_logotype_white.png create mode 100644 app/src/main/res/drawable-xhdpi/brainwallet_logotype_white.png create mode 100644 app/src/main/res/drawable-xxhdpi/brainwallet_logotype_white.png create mode 100644 app/src/main/res/drawable-xxxhdpi/brainwallet_logotype_white.png delete mode 100644 app/src/main/res/drawable/brainwallet_logotype_black.png delete mode 100644 app/src/main/res/drawable/brainwallet_logotype_color.png delete mode 100644 app/src/main/res/drawable/brainwallet_logotype_white.png diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 628e7234..d17111b0 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -84,8 +84,11 @@ include_directories(src/main/secp/secp256k1/src/) include_directories(src/main/secp/secp256k1/) include_directories(src/main/secp/) +# support compiling 16 KB-aligned: https://developer.android.com/guide/practices/page-sizes#cmake +target_link_options(core-lib PRIVATE "-Wl,-z,max-page-size=16384") + # add lib dependencies target_link_libraries( core-lib android - log) + log) \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 802fe2e6..66c1b24e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,12 +14,12 @@ val localProperties = gradleLocalProperties(rootDir, providers) android { namespace = "com.brainwallet" - compileSdk = 34 + compileSdk = 36 defaultConfig { applicationId = "ltd.grunt.brainwallet" minSdk = 29 - targetSdk = 34 + targetSdk = 36 versionCode = 202506271 versionName = "v4.6.2" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index dd68f40a..303a4051 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -51,15 +51,16 @@ tools:ignore="GoogleAppIndexingWarning,UnusedAttribute" tools:replace="android:fullBackupContent,android:allowBackup"> + + - + - diff --git a/app/src/main/java/com/brainwallet/BrainwalletApp.kt b/app/src/main/java/com/brainwallet/BrainwalletApp.kt index 03fd029e..8a55523b 100644 --- a/app/src/main/java/com/brainwallet/BrainwalletApp.kt +++ b/app/src/main/java/com/brainwallet/BrainwalletApp.kt @@ -16,11 +16,6 @@ import com.brainwallet.tools.listeners.SyncReceiver import com.brainwallet.tools.manager.AnalyticsManager import com.brainwallet.tools.util.BRConstants import com.brainwallet.tools.util.Utils -import com.google.firebase.analytics.FirebaseAnalytics -import com.google.firebase.analytics.ktx.analytics -import com.google.firebase.analytics.setConsent -import com.google.firebase.crashlytics.FirebaseCrashlytics -import com.google.firebase.ktx.Firebase import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger import org.koin.core.context.GlobalContext.startKoin diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt index b95bbeec..d8f47bd3 100644 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ b/app/src/main/java/com/brainwallet/di/Module.kt @@ -23,8 +23,8 @@ import com.brainwallet.ui.screens.yourseedwords.YourSeedWordsViewModel import com.brainwallet.util.cryptography.KeyStoreKeyGenerator import com.brainwallet.util.cryptography.KeyStoreManager import com.brainwallet.worker.CurrencyUpdateWorker -import com.google.firebase.ktx.Firebase -import com.google.firebase.remoteconfig.ktx.remoteConfig +import com.google.firebase.Firebase +import com.google.firebase.remoteconfig.remoteConfig import kotlinx.serialization.json.Json import okhttp3.MediaType.Companion.toMediaType import okhttp3.OkHttpClient @@ -35,7 +35,6 @@ import org.koin.core.component.inject import org.koin.core.module.dsl.viewModel import org.koin.core.module.dsl.viewModelOf import org.koin.dsl.module -import retrofit2.HttpException import retrofit2.Retrofit import retrofit2.converter.kotlinx.serialization.asConverterFactory diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index 845a9073..cec6d05a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -7,12 +7,14 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape @@ -93,39 +95,44 @@ fun WelcomeScreen( modifier = Modifier .fillMaxSize() .background(BrainwalletTheme.colors.surface) - .verticalScroll(rememberScrollState()), + .verticalScroll(rememberScrollState()) + .padding(WindowInsets.systemBars.asPaddingValues()), ) { - Image( - painterResource(R.drawable.brainwallet_logotype_white), - contentDescription = "brainwallet_logotype_white", - contentScale = ContentScale.Fit, - colorFilter = ColorFilter.tint( - BrainwalletTheme.colors.content, - ), + Column( modifier = Modifier .align(Alignment.TopCenter) - .fillMaxWidth() - .padding(horizontal = 55.dp) - .padding(vertical = 30.dp) - ) + .padding(vertical = 20.dp) + ) { + Image( + painterResource(R.drawable.brainwallet_logotype_white), + contentDescription = "brainwallet_logotype_white", + contentScale = ContentScale.Fit, + colorFilter = ColorFilter.tint( + BrainwalletTheme.colors.content, + ), + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 55.dp) + ) + + // Animation Placeholder + LottieAnimation( + modifier = Modifier + .fillMaxWidth() + .padding(leadTrailPadding.dp) + .background( + BrainwalletTheme.colors.surface, + BrainwalletTheme.shapes.large + ) + .height(thirdOfScreenHeight.dp) + .clip(BrainwalletTheme.shapes.large), + composition = composition, + contentScale = ContentScale.FillWidth, + alignment = Alignment.Center, + progress = { progress } + ) + } - // Animation Placeholder - LottieAnimation( - modifier = Modifier - .offset(y = 120.dp) - .fillMaxWidth() - .padding(leadTrailPadding.dp) - .background( - BrainwalletTheme.colors.surface, - BrainwalletTheme.shapes.large - ) - .height(thirdOfScreenHeight.dp) - .clip(BrainwalletTheme.shapes.large), - composition = composition, - contentScale = ContentScale.FillWidth, - alignment = Alignment.Center, - progress = { progress } - ) Column( modifier = Modifier.align(Alignment.BottomCenter), diff --git a/app/src/main/res/drawable-hdpi/brainwallet_logotype_white.png b/app/src/main/res/drawable-hdpi/brainwallet_logotype_white.png new file mode 100644 index 0000000000000000000000000000000000000000..673e585927cf814ef31cb37eca64e03d08cf7d6e GIT binary patch literal 62457 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-mdpi/brainwallet_logotype_white.png b/app/src/main/res/drawable-mdpi/brainwallet_logotype_white.png new file mode 100644 index 0000000000000000000000000000000000000000..1f1ddde1c1455a82c9aa83c961eab2b1dbc78560 GIT binary patch literal 39557 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 B;b#B< literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/brainwallet_logotype_white.png b/app/src/main/res/drawable-xhdpi/brainwallet_logotype_white.png new file mode 100644 index 0000000000000000000000000000000000000000..fbeb2b26e5a19bddfcb69f11101090f6f1e00ab3 GIT binary patch literal 85102 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 YGwQ~>#~|+Mi30y9%Bsm!NtyZo9|tQ8lK=n! literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/brainwallet_logotype_white.png b/app/src/main/res/drawable-xxhdpi/brainwallet_logotype_white.png new file mode 100644 index 0000000000000000000000000000000000000000..dc83ec4363fd943c8cbc7490effb0c93d357fcee GIT binary patch literal 144825 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 lcEpqaJplA{Fe*mfq!vz2U literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxxhdpi/brainwallet_logotype_white.png b/app/src/main/res/drawable-xxxhdpi/brainwallet_logotype_white.png new file mode 100644 index 0000000000000000000000000000000000000000..83c8c67ac1b3aa6092e0ce14bd5cb741d61184dd GIT binary patch literal 141693 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

TQeIS) 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 z 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 tJWj@@a_?v}|IJhSj~|uHLiT+f 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

tC!G&WD-N?p#b2V16Em7>CjOLVDDVE-8AC0bHv& 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 Yh;7R~q-{L-4(g{Qr!HG5^D_MZ0M0o1(f|Me diff --git a/app/src/main/res/drawable/brainwallet_logotype_white.png b/app/src/main/res/drawable/brainwallet_logotype_white.png deleted file mode 100644 index cc0f84e77b043182278ace91d0664e5c2ac2c0a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126886 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 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 90f8dedd..cd3b7691 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] kotlin = "2.0.0" -agp = "8.5.0" +agp = "8.5.1" androidx-core-ktx = "1.12.0" androidx-appcompat = "1.6.1" androidx-legacy-support = "1.0.0" @@ -25,7 +25,7 @@ google-play-feature-delivery = "2.1.0" google-play-review = "2.0.1" squareup-okhttp-bom = "4.12.0" squareup-retrofit = "2.11.0" -firebase-bom = "32.7.1" +firebase-bom = "34.0.0" jakewarthon-timber = "4.7.1" eclipse-jetty = "9.2.19.v20160908" junit = "4.13.2" @@ -87,7 +87,7 @@ firebase-analytics = { module = "com.google.firebase:firebase-analytics" } firebase-crashlytics = { module = "com.google.firebase:firebase-crashlytics" } firebase-crashlytics-ndk = { module = "com.google.firebase:firebase-crashlytics-ndk" } #firebase-iid = { module = "com.google.firebase:firebase-iid" } -firebase-config = { module = "com.google.firebase:firebase-config-ktx" } +firebase-config = { module = "com.google.firebase:firebase-config" } firebase-messaging = { module = "com.google.firebase:firebase-messaging" } firebase-inappmessaging = { module = "com.google.firebase:firebase-inappmessaging-display" } jakewarthon-timber = { module = "com.jakewharton.timber:timber", version.ref = "jakewarthon-timber" } From 4efd95fcdbc454e0b05d9f34eaa18afb907e249c Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Tue, 19 Aug 2025 03:19:43 +0700 Subject: [PATCH 051/116] feat(#195): adopt koin annotation for dependency injection (#120) --- app/build.gradle.kts | 4 + .../java/com/brainwallet/BrainwalletApp.kt | 18 ++- .../FirebaseRemoteConfigRepository.kt | 63 +++++++++ .../data/repository/LtcRepository.kt | 83 ----------- .../data/repository/LtcRepositoryImpl.kt | 93 ++++++++++++ .../repository/SelectedPeersRepository.kt | 84 ----------- .../repository/SelectedPeersRepositoryImpl.kt | 89 ++++++++++++ .../data/repository/SettingRepository.kt | 80 ----------- .../data/repository/SettingRepositoryImpl.kt | 91 ++++++++++++ .../data/source/LocalCacheSource.kt | 2 +- .../data/source/RemoteConfigSource.kt | 59 -------- .../main/java/com/brainwallet/di/AppModule.kt | 95 +++++++++++++ .../main/java/com/brainwallet/di/Module.kt | 132 ------------------ .../navigation/LegacyNavigation.kt | 3 +- .../BrainwalletMessagingService.kt | 8 +- .../notification/NotificationHandler.kt | 125 ++++++++++------- .../brainwallet/ui/BrainwalletViewModel.kt | 2 +- .../buylitecoin/BuyLitecoinViewModel.kt | 3 +- .../ui/screens/home/SettingsViewModel.kt | 3 +- .../home/receive/ReceiveDialogViewModel.kt | 2 + .../screens/inputwords/InputWordsViewModel.kt | 2 + .../ui/screens/ready/ReadyViewModel.kt | 4 +- .../setpasscode/SetPasscodeViewModel.kt | 2 + .../ui/screens/unlock/UnLockViewModel.kt | 3 +- .../ui/screens/welcome/WelcomeViewModel.kt | 2 + .../YourSeedProveItViewModel.kt | 2 + .../yourseedwords/YourSeedWordsViewModel.kt | 2 + .../util/cryptography/KeyStoreKeyGenerator.kt | 61 -------- .../util/cryptography/KeyStoreManager.kt | 4 +- .../impl/KeyStoreKeyGeneratorImpl.kt | 65 +++++++++ .../worker/CurrencyUpdateWorker.kt | 2 + .../brainwallet/BrainwalletScreengrabApp.kt | 4 +- .../FirebaseRemoteConfigRepositoryTest.kt} | 9 +- .../notification/NotificationHandlerTest.kt | 49 +++++-- build.gradle.kts | 1 + gradle/libs.versions.toml | 9 +- 36 files changed, 670 insertions(+), 590 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt create mode 100644 app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt create mode 100644 app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepositoryImpl.kt create mode 100644 app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt create mode 100644 app/src/main/java/com/brainwallet/di/AppModule.kt delete mode 100644 app/src/main/java/com/brainwallet/di/Module.kt create mode 100644 app/src/main/java/com/brainwallet/util/cryptography/impl/KeyStoreKeyGeneratorImpl.kt rename app/src/test/java/com/brainwallet/data/{source/RemoteConfigSourceFirebaseImplTest.kt => repository/FirebaseRemoteConfigRepositoryTest.kt} (91%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 66c1b24e..b42bd6bd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -8,6 +8,7 @@ plugins { alias(libs.plugins.jetbrains.kotlin.serialization) alias(libs.plugins.google.services) alias(libs.plugins.firebase.crashlytics) + alias(libs.plugins.ksp) } val localProperties = gradleLocalProperties(rootDir, providers) @@ -215,6 +216,9 @@ dependencies { implementation (libs.airbnb.lottie.compose) implementation(platform(libs.koin.bom)) implementation(libs.bundles.koin) + implementation(platform(libs.koin.annotation.bom)) + implementation(libs.koin.annotation) + ksp(libs.koin.annotation.compiler) implementation(platform(libs.squareup.okhttp.bom)) implementation(libs.bundles.squareup.okhttp) diff --git a/app/src/main/java/com/brainwallet/BrainwalletApp.kt b/app/src/main/java/com/brainwallet/BrainwalletApp.kt index 8a55523b..9143a90f 100644 --- a/app/src/main/java/com/brainwallet/BrainwalletApp.kt +++ b/app/src/main/java/com/brainwallet/BrainwalletApp.kt @@ -6,28 +6,33 @@ import android.app.Application import android.content.Context import android.content.res.Resources import com.appsflyer.AppsFlyerLib -import com.brainwallet.di.appModule -import com.brainwallet.di.dataModule -import com.brainwallet.di.viewModelModule -import com.brainwallet.notification.setupNotificationChannels +import com.brainwallet.data.source.RemoteConfigSource +import com.brainwallet.di.AppModule +import com.brainwallet.notification.NotificationHandler import com.brainwallet.presenter.activities.util.BRActivity import com.brainwallet.presenter.entities.ServiceItems import com.brainwallet.tools.listeners.SyncReceiver import com.brainwallet.tools.manager.AnalyticsManager import com.brainwallet.tools.util.BRConstants import com.brainwallet.tools.util.Utils +import org.koin.android.ext.android.inject import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger import org.koin.core.context.GlobalContext.startKoin import org.koin.core.logger.Level +import org.koin.ksp.generated.module import timber.log.Timber import timber.log.Timber.DebugTree import java.util.Timer import java.util.TimerTask import java.util.concurrent.atomic.AtomicInteger +import kotlin.concurrent.thread open class BrainwalletApp : Application() { + private val remoteConfigSource: RemoteConfigSource by inject() + private val notificationHandler: NotificationHandler by inject() + override fun onCreate() { super.onCreate() @@ -35,7 +40,7 @@ open class BrainwalletApp : Application() { /** DEV: Top placement requirement. **/ val enableCrashlytics = !Utils.isEmulatorOrDebug(this) - setupNotificationChannels(this) + notificationHandler.setupNotificationChannels(this) AnalyticsManager.init(this) AnalyticsManager.logCustomEvent(BRConstants._20191105_AL) @@ -72,8 +77,9 @@ open class BrainwalletApp : Application() { startKoin { androidLogger(if (BuildConfig.DEBUG) Level.DEBUG else Level.ERROR) androidContext(this@BrainwalletApp) - modules(dataModule, viewModelModule, appModule) + modules(AppModule.dataModule, AppModule.module) } + thread { remoteConfigSource.initialize() } } // override fun attachBaseContext(base: Context) { diff --git a/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt b/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt new file mode 100644 index 00000000..15d7323f --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt @@ -0,0 +1,63 @@ +package com.brainwallet.data.repository + +import com.brainwallet.BuildConfig +import com.brainwallet.R +import com.brainwallet.data.source.RemoteConfigSource +import com.google.firebase.remoteconfig.ConfigUpdate +import com.google.firebase.remoteconfig.ConfigUpdateListener +import com.google.firebase.remoteconfig.FirebaseRemoteConfig +import com.google.firebase.remoteconfig.FirebaseRemoteConfigException +import com.google.firebase.remoteconfig.remoteConfigSettings +import org.koin.core.annotation.Single +import timber.log.Timber + +@Single(binds = [RemoteConfigSource::class]) +class FirebaseRemoteConfigRepository( + private val remoteConfig: FirebaseRemoteConfig +) : RemoteConfigSource { + + init { + val configSettings = remoteConfigSettings { + minimumFetchIntervalInSeconds = if (BuildConfig.DEBUG) { + 0 // fetch every time in debug mode + } else { + 60 * 180 // fetch every 3 hours in production mode + } + } + remoteConfig.setConfigSettingsAsync(configSettings) + remoteConfig.setDefaultsAsync(R.xml.remote_config_defaults) + } + + override fun initialize() { + remoteConfig.fetchAndActivate() + .addOnSuccessListener { Timber.d("timber: RemoteConfig Success fetchAndActivate") } + .addOnFailureListener { + Timber.d( + it, + "timber: RemoteConfig Failure fetchAndActivate" + ) + } + remoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener { + override fun onUpdate(configUpdate: ConfigUpdate) { + Timber.d("timber: [RemoteConfig] onUpdate ${configUpdate.updatedKeys}") + } + + override fun onError(error: FirebaseRemoteConfigException) { + Timber.d("timber: [RemoteConfig] onError ${error.code} | ${error.message}") + } + + }) + } + + override fun getString(key: String): String { + return remoteConfig.getString(key) + } + + override fun getNumber(key: String): Double { + return remoteConfig.getDouble(key) + } + + override fun getBoolean(key: String): Boolean { + return remoteConfig.getBoolean(key) + } +} diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index 39542354..b6914b6f 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -1,19 +1,9 @@ package com.brainwallet.data.repository -import android.content.Context -import android.content.SharedPreferences -import androidx.core.net.toUri -import com.brainwallet.BuildConfig import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Fee import com.brainwallet.data.model.MoonpayCurrencyLimit -import com.brainwallet.data.source.RemoteApiSource -import com.brainwallet.data.source.fetchWithCache import com.brainwallet.data.source.response.GetMoonpayBuyQuoteResponse -import com.brainwallet.tools.manager.BRSharedPrefs -import com.brainwallet.tools.manager.FeeManager -import com.brainwallet.tools.sqlite.CurrencyDataSource -import com.brainwallet.tools.util.Utils interface LtcRepository { suspend fun fetchRates(): List @@ -26,79 +16,6 @@ interface LtcRepository { suspend fun fetchMoonpaySignedUrl(params: Map): String - class Impl( - private val context: Context, - private val remoteApiSource: RemoteApiSource, - private val currencyDataSource: CurrencyDataSource, - private val sharedPreferences: SharedPreferences, - ) : LtcRepository { - - //todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies - override suspend fun fetchRates(): List { - return runCatching { - val rates = remoteApiSource.getRates() - - //legacy logic - FeeManager.updateFeePerKb(context) - val selectedISO = BRSharedPrefs.getIsoSymbol(context) - rates.forEachIndexed { index, currencyEntity -> - if (currencyEntity.code.equals(selectedISO, ignoreCase = true)) { - BRSharedPrefs.putIso(context, currencyEntity.code) - BRSharedPrefs.putCurrencyListPosition(context, index - 1) - } - } - - //save to local - currencyDataSource.putCurrencies(rates) - return rates - }.getOrElse { currencyDataSource.getAllCurrencies(true) } - - } - - /** - * for now we just using [Fee.Default] - * will move to [RemoteApiSource.getFeePerKb] after fix the calculation when we do send - * - * maybe need updaete core if we need to use dynamic fee? - */ - override suspend fun fetchFeePerKb(): Fee = Fee.Default //using static fee - - override suspend fun fetchLimits(baseCurrencyCode: String): MoonpayCurrencyLimit { - return sharedPreferences.fetchWithCache( - key = "${PREF_KEY_BUY_LIMITS_PREFIX}${baseCurrencyCode.lowercase()}", - cachedAtKey = "${PREF_KEY_BUY_LIMITS_PREFIX_CACHED_AT}${baseCurrencyCode.lowercase()}", - cacheTimeMs = 5 * 60 * 1000, //5 minutes - fetchData = { - remoteApiSource.getMoonpayCurrencyLimit(baseCurrencyCode) - } - ) - } - - override suspend fun fetchBuyQuote(params: Map): GetMoonpayBuyQuoteResponse = - remoteApiSource.getBuyQuote(params) - - override suspend fun fetchMoonpaySignedUrl(params: Map): String { - val externalTransactionID = Utils.getEncryptedAgentString(context) - val finalParams = params + mapOf( - "defaultCurrencyCode" to "ltc", - "externalTransactionId" to externalTransactionID, - "currencyCode" to "ltc", - "themeId" to "main-v1.0.0", - ) - return remoteApiSource.getMoonpaySignedUrl(finalParams) - .signedUrl.toUri() - .buildUpon() - .apply { - if (BuildConfig.DEBUG) { - authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com - } - } - .build() - .toString() - } - - } - companion object { const val PREF_KEY_NETWORK_FEE_PER_KB = "network_fee_per_kb" const val PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT = "${PREF_KEY_NETWORK_FEE_PER_KB}_cached_at" diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt new file mode 100644 index 00000000..72730ccc --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt @@ -0,0 +1,93 @@ +package com.brainwallet.data.repository + +import android.content.Context +import android.content.SharedPreferences +import androidx.core.net.toUri +import com.brainwallet.BuildConfig +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.Fee +import com.brainwallet.data.model.MoonpayCurrencyLimit +import com.brainwallet.data.repository.LtcRepository.Companion.PREF_KEY_BUY_LIMITS_PREFIX +import com.brainwallet.data.repository.LtcRepository.Companion.PREF_KEY_BUY_LIMITS_PREFIX_CACHED_AT +import com.brainwallet.data.source.RemoteApiSource +import com.brainwallet.data.source.fetchWithCache +import com.brainwallet.data.source.response.GetMoonpayBuyQuoteResponse +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.manager.FeeManager +import com.brainwallet.tools.sqlite.CurrencyDataSource +import com.brainwallet.tools.util.Utils +import org.koin.core.annotation.Single + +@Single(binds = [LtcRepository::class]) +class LtcRepositoryImpl( + private val context: Context, + private val remoteApiSource: RemoteApiSource, + private val currencyDataSource: CurrencyDataSource, + private val sharedPreferences: SharedPreferences, +) : LtcRepository { + + //todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies + override suspend fun fetchRates(): List { + return runCatching { + val rates = remoteApiSource.getRates() + + //legacy logic + FeeManager.updateFeePerKb(context) + val selectedISO = BRSharedPrefs.getIsoSymbol(context) + rates.forEachIndexed { index, currencyEntity -> + if (currencyEntity.code.equals(selectedISO, ignoreCase = true)) { + BRSharedPrefs.putIso(context, currencyEntity.code) + BRSharedPrefs.putCurrencyListPosition(context, index - 1) + } + } + + //save to local + currencyDataSource.putCurrencies(rates) + return rates + }.getOrElse { currencyDataSource.getAllCurrencies(true) } + + } + + /** + * for now we just using [Fee.Default] + * will move to [RemoteApiSource.getFeePerKb] after fix the calculation when we do send + * + * maybe need updaete core if we need to use dynamic fee? + */ + override suspend fun fetchFeePerKb(): Fee = Fee.Default //using static fee + + override suspend fun fetchLimits(baseCurrencyCode: String): MoonpayCurrencyLimit { + return sharedPreferences.fetchWithCache( + key = "${PREF_KEY_BUY_LIMITS_PREFIX}${baseCurrencyCode.lowercase()}", + cachedAtKey = "${PREF_KEY_BUY_LIMITS_PREFIX_CACHED_AT}${baseCurrencyCode.lowercase()}", + cacheTimeMs = 5 * 60 * 1000, //5 minutes + fetchData = { + remoteApiSource.getMoonpayCurrencyLimit(baseCurrencyCode) + } + ) + } + + override suspend fun fetchBuyQuote(params: Map): GetMoonpayBuyQuoteResponse = + remoteApiSource.getBuyQuote(params) + + override suspend fun fetchMoonpaySignedUrl(params: Map): String { + val externalTransactionID = Utils.getEncryptedAgentString(context) + val finalParams = params + mapOf( + "defaultCurrencyCode" to "ltc", + "externalTransactionId" to externalTransactionID, + "currencyCode" to "ltc", + "themeId" to "main-v1.0.0", + ) + return remoteApiSource.getMoonpaySignedUrl(finalParams) + .signedUrl.toUri() + .buildUpon() + .apply { + if (BuildConfig.DEBUG) { + authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com + } + } + .build() + .toString() + } + +} diff --git a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt index 0275d542..2d8513ff 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt @@ -1,93 +1,9 @@ package com.brainwallet.data.repository -import android.content.SharedPreferences -import androidx.core.content.edit -import com.brainwallet.di.json -import kotlinx.serialization.json.jsonObject -import okhttp3.Call -import okhttp3.Callback -import okhttp3.OkHttpClient -import okhttp3.Response -import okio.IOException -import timber.log.Timber -import kotlin.coroutines.resume -import kotlin.coroutines.suspendCoroutine - interface SelectedPeersRepository { suspend fun fetchSelectedPeers(): Set - class Impl( - private val okHttpClient: OkHttpClient, - private val sharedPreferences: SharedPreferences, - ) : SelectedPeersRepository { - - private companion object { - const val PREF_KEY_SELECTED_PEERS = "selected_peers" - const val PREF_KEY_SELECTED_PEERS_CACHED_AT = "${PREF_KEY_SELECTED_PEERS}_cached_at" - } - - override suspend fun fetchSelectedPeers(): Set { - val lastUpdateTime = sharedPreferences.getLong(PREF_KEY_SELECTED_PEERS_CACHED_AT, 0) - val currentTime = System.currentTimeMillis() - val cachedPeers = sharedPreferences.getStringSet(PREF_KEY_SELECTED_PEERS, null) - - // Check if cache exists and is less than 6 hours old - if (!cachedPeers.isNullOrEmpty() && (currentTime - lastUpdateTime) < 6 * 60 * 60 * 1000) { - return cachedPeers - } - - val request = okhttp3.Request.Builder() - .url(LITECOIN_NODES_URL) - .build() - - return suspendCoroutine { continuation -> - okHttpClient.newCall(request).enqueue(object : Callback { - override fun onFailure(call: Call, e: IOException) { - continuation.resume(emptySet()) //just return empty if failed or need hardcoded? - } - - override fun onResponse(call: Call, response: Response) { - val jsonString = response.body?.string() - - if (response.isSuccessful.not()) { - continuation.resume(cachedPeers ?: emptySet()) - return - } - - val parsedResult = jsonString?.let { - val jsonElement = json.parseToJsonElement(it) - val dataObject = jsonElement.jsonObject["data"]?.jsonObject - val nodesObject = dataObject?.get("nodes")?.jsonObject - - //filter criteria - val requiredServices = 0x01 or 0x04 // NODE_NETWORK | NODE_BLOOM - - nodesObject?.entries - ?.filter { entry -> - val flags = - entry.value.jsonObject["flags"]?.toString()?.toIntOrNull() - flags != null && (flags and requiredServices) == requiredServices - } - ?.map { it.key.replace(":9333", "") } - ?.toSet().also { Timber.d("Total Selected Peers ${it?.size}") } - ?: emptySet() - - } ?: emptySet() - - sharedPreferences.edit { - putStringSet(PREF_KEY_SELECTED_PEERS, parsedResult) - putLong(PREF_KEY_SELECTED_PEERS_CACHED_AT, currentTime) - } - - continuation.resume(parsedResult) - } - }) - } - } - - } - companion object { const val LITECOIN_NODES_URL = "https://api.blockchair.com/litecoin/nodes" } diff --git a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepositoryImpl.kt new file mode 100644 index 00000000..454be2d2 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepositoryImpl.kt @@ -0,0 +1,89 @@ +package com.brainwallet.data.repository + +import android.content.SharedPreferences +import androidx.core.content.edit +import com.brainwallet.data.repository.SelectedPeersRepository.Companion.LITECOIN_NODES_URL +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.jsonObject +import okhttp3.Call +import okhttp3.Callback +import okhttp3.OkHttpClient +import okhttp3.Response +import okio.IOException +import org.koin.core.annotation.Single +import timber.log.Timber +import kotlin.coroutines.resume +import kotlin.coroutines.suspendCoroutine + +@Single(binds = [SelectedPeersRepository::class]) +class SelectedPeersRepositoryImpl( + private val okHttpClient: OkHttpClient, + private val sharedPreferences: SharedPreferences, + private val json: Json +) : SelectedPeersRepository { + + private companion object { + const val PREF_KEY_SELECTED_PEERS = "selected_peers" + const val PREF_KEY_SELECTED_PEERS_CACHED_AT = "${PREF_KEY_SELECTED_PEERS}_cached_at" + } + + override suspend fun fetchSelectedPeers(): Set { + val lastUpdateTime = sharedPreferences.getLong(PREF_KEY_SELECTED_PEERS_CACHED_AT, 0) + val currentTime = System.currentTimeMillis() + val cachedPeers = sharedPreferences.getStringSet(PREF_KEY_SELECTED_PEERS, null) + + // Check if cache exists and is less than 6 hours old + if (!cachedPeers.isNullOrEmpty() && (currentTime - lastUpdateTime) < 6 * 60 * 60 * 1000) { + return cachedPeers + } + + val request = okhttp3.Request.Builder() + .url(LITECOIN_NODES_URL) + .build() + + return suspendCoroutine { continuation -> + okHttpClient.newCall(request).enqueue(object : Callback { + override fun onFailure(call: Call, e: IOException) { + continuation.resume(emptySet()) //just return empty if failed or need hardcoded? + } + + override fun onResponse(call: Call, response: Response) { + val jsonString = response.body?.string() + + if (response.isSuccessful.not()) { + continuation.resume(cachedPeers ?: emptySet()) + return + } + + val parsedResult = jsonString?.let { + val jsonElement = json.parseToJsonElement(it) + val dataObject = jsonElement.jsonObject["data"]?.jsonObject + val nodesObject = dataObject?.get("nodes")?.jsonObject + + //filter criteria + val requiredServices = 0x01 or 0x04 // NODE_NETWORK | NODE_BLOOM + + nodesObject?.entries + ?.filter { entry -> + val flags = + entry.value.jsonObject["flags"]?.toString()?.toIntOrNull() + flags != null && (flags and requiredServices) == requiredServices + } + ?.map { it.key.replace(":9333", "") } + ?.toSet().also { Timber.d("Total Selected Peers ${it?.size}") } + ?: emptySet() + + } ?: emptySet() + + sharedPreferences.edit { + putStringSet(PREF_KEY_SELECTED_PEERS, parsedResult) + putLong(PREF_KEY_SELECTED_PEERS_CACHED_AT, currentTime) + } + + continuation.resume(parsedResult) + } + }) + } + } + +} diff --git a/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt index 3f217918..484b5249 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt @@ -1,17 +1,8 @@ package com.brainwallet.data.repository -import android.content.SharedPreferences -import androidx.core.content.edit import com.brainwallet.data.model.AppSetting -import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Language -import com.brainwallet.tools.manager.FeeManager -import com.brainwallet.tools.sqlite.CurrencyDataSource import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update interface SettingRepository { @@ -41,77 +32,6 @@ interface SettingRepository { fun getSelectedFeeType(): String - class Impl( - private val sharedPreferences: SharedPreferences, - private val currencyDataSource: CurrencyDataSource - ) : SettingRepository { - - private val _state = MutableStateFlow(load()) - val state: StateFlow = _state.asStateFlow() - - override val settings: Flow - get() = state - - override suspend fun save(setting: AppSetting) { - sharedPreferences.edit { - putBoolean(KEY_IS_DARK_MODE, setting.isDarkMode) - putString(KEY_LANGUAGE_CODE, setting.languageCode) - putString(KEY_FIAT_CURRENCY_CODE, setting.currency.code) - } - _state.update { setting } - } - - override fun getCurrentLanguage(): Language { - return sharedPreferences.getString(KEY_LANGUAGE_CODE, Language.ENGLISH.code) - .let { languageCode -> Language.find(languageCode) } - } - - override fun updateCurrentLanguage(languageCode: String) { - sharedPreferences.edit { putString(KEY_LANGUAGE_CODE, languageCode) } - _state.update { it.copy(languageCode = languageCode) } - } - - override fun isDarkMode(): Boolean { - return sharedPreferences.getBoolean(KEY_IS_DARK_MODE, true) - } - - override fun toggleDarkMode(isDarkMode: Boolean) { - sharedPreferences.edit { - putBoolean(KEY_IS_DARK_MODE, isDarkMode) - } - _state.update { it.copy(isDarkMode = isDarkMode) } - } - - override fun putSelectedFeeType(feeType: String) { - sharedPreferences.edit { - putString(KEY_SELECTED_FEE_TYPE, feeType) - } - } - - override fun getSelectedFeeType(): String = - sharedPreferences.getString(KEY_SELECTED_FEE_TYPE, FeeManager.REGULAR) - ?: FeeManager.REGULAR - - - private fun load(): AppSetting { - return AppSetting( - isDarkMode = sharedPreferences.getBoolean(KEY_IS_DARK_MODE, true), - languageCode = sharedPreferences.getString(KEY_LANGUAGE_CODE, Language.ENGLISH.code) - ?: Language.ENGLISH.code, - currency = sharedPreferences.getString(KEY_FIAT_CURRENCY_CODE, "USD").let { - currencyDataSource.getCurrencyByIso(it) - ?: return@let CurrencyEntity( - "USD", - "US Dollar", - -1f, - "$" - ) - } - - ) - } - } - companion object { const val KEY_IS_DARK_MODE = "is_dark_mode" const val KEY_LANGUAGE_CODE = "language_code" diff --git a/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt new file mode 100644 index 00000000..fc862d72 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt @@ -0,0 +1,91 @@ +package com.brainwallet.data.repository + +import android.content.SharedPreferences +import androidx.core.content.edit +import com.brainwallet.data.model.AppSetting +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.Language +import com.brainwallet.data.repository.SettingRepository.Companion.KEY_FIAT_CURRENCY_CODE +import com.brainwallet.data.repository.SettingRepository.Companion.KEY_IS_DARK_MODE +import com.brainwallet.data.repository.SettingRepository.Companion.KEY_LANGUAGE_CODE +import com.brainwallet.data.repository.SettingRepository.Companion.KEY_SELECTED_FEE_TYPE +import com.brainwallet.tools.manager.FeeManager +import com.brainwallet.tools.sqlite.CurrencyDataSource +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import org.koin.core.annotation.Single + +@Single(binds = [SettingRepository::class]) +class SettingRepositoryImpl( + private val sharedPreferences: SharedPreferences, + private val currencyDataSource: CurrencyDataSource +) : SettingRepository { + + private val _state = MutableStateFlow(load()) + val state: StateFlow = _state.asStateFlow() + + override val settings: Flow + get() = state + + override suspend fun save(setting: AppSetting) { + sharedPreferences.edit { + putBoolean(KEY_IS_DARK_MODE, setting.isDarkMode) + putString(KEY_LANGUAGE_CODE, setting.languageCode) + putString(KEY_FIAT_CURRENCY_CODE, setting.currency.code) + } + _state.update { setting } + } + + override fun getCurrentLanguage(): Language { + return sharedPreferences.getString(KEY_LANGUAGE_CODE, Language.ENGLISH.code) + .let { languageCode -> Language.find(languageCode) } + } + + override fun updateCurrentLanguage(languageCode: String) { + sharedPreferences.edit { putString(KEY_LANGUAGE_CODE, languageCode) } + _state.update { it.copy(languageCode = languageCode) } + } + + override fun isDarkMode(): Boolean { + return sharedPreferences.getBoolean(KEY_IS_DARK_MODE, true) + } + + override fun toggleDarkMode(isDarkMode: Boolean) { + sharedPreferences.edit { + putBoolean(KEY_IS_DARK_MODE, isDarkMode) + } + _state.update { it.copy(isDarkMode = isDarkMode) } + } + + override fun putSelectedFeeType(feeType: String) { + sharedPreferences.edit { + putString(KEY_SELECTED_FEE_TYPE, feeType) + } + } + + override fun getSelectedFeeType(): String = + sharedPreferences.getString(KEY_SELECTED_FEE_TYPE, FeeManager.REGULAR) + ?: FeeManager.REGULAR + + + private fun load(): AppSetting { + return AppSetting( + isDarkMode = sharedPreferences.getBoolean(KEY_IS_DARK_MODE, true), + languageCode = sharedPreferences.getString(KEY_LANGUAGE_CODE, Language.ENGLISH.code) + ?: Language.ENGLISH.code, + currency = sharedPreferences.getString(KEY_FIAT_CURRENCY_CODE, "USD").let { + currencyDataSource.getCurrencyByIso(it) + ?: return@let CurrencyEntity( + "USD", + "US Dollar", + -1f, + "$" + ) + } + + ) + } +} diff --git a/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt b/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt index d86d312d..e00a051e 100644 --- a/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt @@ -2,7 +2,7 @@ package com.brainwallet.data.source import android.content.SharedPreferences import androidx.core.content.edit -import com.brainwallet.di.json +import com.brainwallet.di.AppModule.json import kotlinx.serialization.encodeToString /** diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt index dc5c7ff4..d39b04fb 100644 --- a/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt @@ -1,14 +1,5 @@ package com.brainwallet.data.source -import com.brainwallet.BuildConfig -import com.brainwallet.R -import com.google.firebase.remoteconfig.ConfigUpdate -import com.google.firebase.remoteconfig.ConfigUpdateListener -import com.google.firebase.remoteconfig.FirebaseRemoteConfig -import com.google.firebase.remoteconfig.FirebaseRemoteConfigException -import com.google.firebase.remoteconfig.remoteConfigSettings -import timber.log.Timber - interface RemoteConfigSource { companion object { @@ -20,54 +11,4 @@ interface RemoteConfigSource { fun getString(key: String): String fun getNumber(key: String): Double fun getBoolean(key: String): Boolean - - class FirebaseImpl( - private val remoteConfig: FirebaseRemoteConfig - ) : RemoteConfigSource { - - init { - val configSettings = remoteConfigSettings { - minimumFetchIntervalInSeconds = if (BuildConfig.DEBUG) { - 0 // fetch every time in debug mode - } else { - 60 * 180 // fetch every 3 hours in production mode - } - } - remoteConfig.setConfigSettingsAsync(configSettings) - remoteConfig.setDefaultsAsync(R.xml.remote_config_defaults) - } - - override fun initialize() { - remoteConfig.fetchAndActivate() - .addOnSuccessListener { Timber.d("timber: RemoteConfig Success fetchAndActivate") } - .addOnFailureListener { - Timber.d( - it, - "timber: RemoteConfig Failure fetchAndActivate" - ) - } - remoteConfig.addOnConfigUpdateListener(object : ConfigUpdateListener { - override fun onUpdate(configUpdate: ConfigUpdate) { - Timber.d("timber: [RemoteConfig] onUpdate ${configUpdate.updatedKeys}") - } - - override fun onError(error: FirebaseRemoteConfigException) { - Timber.d("timber: [RemoteConfig] onError ${error.code} | ${error.message}") - } - - }) - } - - override fun getString(key: String): String { - return remoteConfig.getString(key) - } - - override fun getNumber(key: String): Double { - return remoteConfig.getDouble(key) - } - - override fun getBoolean(key: String): Boolean { - return remoteConfig.getBoolean(key) - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/di/AppModule.kt b/app/src/main/java/com/brainwallet/di/AppModule.kt new file mode 100644 index 00000000..3c9fd77c --- /dev/null +++ b/app/src/main/java/com/brainwallet/di/AppModule.kt @@ -0,0 +1,95 @@ +package com.brainwallet.di + +import android.content.Context +import android.content.SharedPreferences +import com.brainwallet.BuildConfig +import com.brainwallet.data.source.RemoteApiSource +import com.brainwallet.tools.sqlite.CurrencyDataSource +import com.brainwallet.tools.util.BRConstants +import com.google.firebase.Firebase +import com.google.firebase.remoteconfig.remoteConfig +import kotlinx.serialization.json.Json +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.OkHttpClient +import okhttp3.logging.HttpLoggingInterceptor +import org.koin.android.ext.koin.androidApplication +import org.koin.core.annotation.ComponentScan +import org.koin.core.annotation.Module +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +import org.koin.dsl.module +import retrofit2.Retrofit +import retrofit2.converter.kotlinx.serialization.asConverterFactory +import kotlin.getValue + +@Module +@ComponentScan("com.brainwallet") +object AppModule { + + val json = Json { + ignoreUnknownKeys = true + explicitNulls = false + prettyPrint = true + } + + val dataModule = module { + single { Firebase.remoteConfig } + single { json } + factory { provideOkHttpClient() } + single { provideRetrofit(get(), get(), BRConstants.BW_API_PROD_HOST) } + single { provideApi(get()) } + single { CurrencyDataSource.getInstance(get()) } + single { provideSharedPreferences(context = androidApplication()) } + } + + + private fun provideSharedPreferences( + context: Context, + name: String = "${BuildConfig.APPLICATION_ID}.prefs" + ): SharedPreferences { + return context.getSharedPreferences(name, Context.MODE_PRIVATE) + } + + private fun provideOkHttpClient(): OkHttpClient = OkHttpClient.Builder() + .addInterceptor { chain -> + val requestBuilder = chain.request() + .newBuilder() + .addHeader("Accept", "application/json") + .addHeader("Content-Type", "application/json") + .addHeader("X-Litecoin-Testnet", "false") + .addHeader("Accept-Language", "en") + chain.proceed(requestBuilder.build()) + } + .addInterceptor(HttpLoggingInterceptor().apply { + setLevel( + when { + BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.BODY + else -> HttpLoggingInterceptor.Level.NONE + } + ) + }) + .build() + + internal fun provideRetrofit( + json: Json, + okHttpClient: OkHttpClient, + baseUrl: String = BRConstants.BW_API_PROD_HOST, + ): Retrofit = Retrofit.Builder() + .baseUrl(baseUrl) + .client(okHttpClient) + .addConverterFactory( + json.asConverterFactory( + "application/json; charset=UTF8".toMediaType() + ) + ) + .build() + + internal inline fun provideApi(retrofit: Retrofit): T = + retrofit.create(T::class.java) + + inline fun getKoinInstance(): T { + return object : KoinComponent { + val value: T by inject() + }.value + } +} diff --git a/app/src/main/java/com/brainwallet/di/Module.kt b/app/src/main/java/com/brainwallet/di/Module.kt deleted file mode 100644 index d8f47bd3..00000000 --- a/app/src/main/java/com/brainwallet/di/Module.kt +++ /dev/null @@ -1,132 +0,0 @@ -package com.brainwallet.di - -import android.content.Context -import android.content.SharedPreferences -import com.brainwallet.BuildConfig -import com.brainwallet.data.repository.LtcRepository -import com.brainwallet.data.repository.SelectedPeersRepository -import com.brainwallet.data.repository.SettingRepository -import com.brainwallet.data.source.RemoteApiSource -import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.tools.sqlite.CurrencyDataSource -import com.brainwallet.tools.util.BRConstants -import com.brainwallet.ui.screens.buylitecoin.BuyLitecoinViewModel -import com.brainwallet.ui.screens.home.SettingsViewModel -import com.brainwallet.ui.screens.home.receive.ReceiveDialogViewModel -import com.brainwallet.ui.screens.inputwords.InputWordsViewModel -import com.brainwallet.ui.screens.ready.ReadyViewModel -import com.brainwallet.ui.screens.setpasscode.SetPasscodeViewModel -import com.brainwallet.ui.screens.unlock.UnLockViewModel -import com.brainwallet.ui.screens.welcome.WelcomeViewModel -import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel -import com.brainwallet.ui.screens.yourseedwords.YourSeedWordsViewModel -import com.brainwallet.util.cryptography.KeyStoreKeyGenerator -import com.brainwallet.util.cryptography.KeyStoreManager -import com.brainwallet.worker.CurrencyUpdateWorker -import com.google.firebase.Firebase -import com.google.firebase.remoteconfig.remoteConfig -import kotlinx.serialization.json.Json -import okhttp3.MediaType.Companion.toMediaType -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor -import org.koin.android.ext.koin.androidApplication -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject -import org.koin.core.module.dsl.viewModel -import org.koin.core.module.dsl.viewModelOf -import org.koin.dsl.module -import retrofit2.Retrofit -import retrofit2.converter.kotlinx.serialization.asConverterFactory - -//todo module using koin as di framework here - -val json = Json { - ignoreUnknownKeys = true - explicitNulls = false - prettyPrint = true -} - -val dataModule = module { - factory { provideOkHttpClient() } - single { provideRetrofit(get(), BRConstants.BW_API_PROD_HOST) } - - single { provideApi(get()) } - - single { - RemoteConfigSource.FirebaseImpl(Firebase.remoteConfig).also { - it.initialize() - } - } - single { SelectedPeersRepository.Impl(get(), get()) } - single { CurrencyDataSource.getInstance(get()) } - single { provideSharedPreferences(context = androidApplication()) } - single { SettingRepository.Impl(get(), get()) } - single { LtcRepository.Impl(get(), get(), get(), get()) } -} - -val viewModelModule = module { - viewModelOf(::WelcomeViewModel) - viewModelOf(::SettingsViewModel) - viewModel { ReadyViewModel() } - viewModel { InputWordsViewModel() } - viewModel { SetPasscodeViewModel() } - viewModel { UnLockViewModel() } - viewModel { YourSeedProveItViewModel() } - viewModel { YourSeedWordsViewModel() } - viewModel { ReceiveDialogViewModel(get(), get()) } - viewModel { BuyLitecoinViewModel(get(), get()) } -} - -val appModule = module { - single { KeyStoreManager(get(), KeyStoreKeyGenerator.Impl()) } - single { CurrencyUpdateWorker(get()) } -} - -private fun provideSharedPreferences( - context: Context, - name: String = "${BuildConfig.APPLICATION_ID}.prefs" -): SharedPreferences { - return context.getSharedPreferences(name, Context.MODE_PRIVATE) -} - -private fun provideOkHttpClient(): OkHttpClient = OkHttpClient.Builder() - .addInterceptor { chain -> - val requestBuilder = chain.request() - .newBuilder() - .addHeader("Accept", "application/json") - .addHeader("Content-Type", "application/json") - .addHeader("X-Litecoin-Testnet", "false") - .addHeader("Accept-Language", "en") - chain.proceed(requestBuilder.build()) - } - .addInterceptor(HttpLoggingInterceptor().apply { - setLevel( - when { - BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.BODY - else -> HttpLoggingInterceptor.Level.NONE - } - ) - }) - .build() - -internal fun provideRetrofit( - okHttpClient: OkHttpClient, - baseUrl: String = BRConstants.BW_API_PROD_HOST -): Retrofit = Retrofit.Builder() - .baseUrl(baseUrl) - .client(okHttpClient) - .addConverterFactory( - json.asConverterFactory( - "application/json; charset=UTF8".toMediaType() - ) - ) - .build() - -internal inline fun provideApi(retrofit: Retrofit): T = - retrofit.create(T::class.java) - -inline fun getKoinInstance(): T { - return object : KoinComponent { - val value: T by inject() - }.value -} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt index 26e1b5dc..10503556 100644 --- a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt +++ b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt @@ -10,8 +10,7 @@ import androidx.core.net.toUri import com.brainwallet.BuildConfig import com.brainwallet.R import com.brainwallet.data.repository.LtcRepository -import com.brainwallet.data.source.RemoteApiSource -import com.brainwallet.di.getKoinInstance +import com.brainwallet.di.AppModule.getKoinInstance import com.brainwallet.presenter.activities.BreadActivity import com.brainwallet.ui.BrainwalletActivity import kotlinx.coroutines.CoroutineScope diff --git a/app/src/main/java/com/brainwallet/notification/BrainwalletMessagingService.kt b/app/src/main/java/com/brainwallet/notification/BrainwalletMessagingService.kt index d44ba2af..06cd68c7 100644 --- a/app/src/main/java/com/brainwallet/notification/BrainwalletMessagingService.kt +++ b/app/src/main/java/com/brainwallet/notification/BrainwalletMessagingService.kt @@ -1,11 +1,13 @@ package com.brainwallet.notification +import com.brainwallet.di.AppModule import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import timber.log.Timber - -class BrainwalletMessagingService : FirebaseMessagingService() { +class BrainwalletMessagingService( + private val notificationHandler: NotificationHandler = AppModule.getKoinInstance() +) : FirebaseMessagingService() { override fun onCreate() { super.onCreate() @@ -19,7 +21,7 @@ class BrainwalletMessagingService : FirebaseMessagingService() { Timber.d("timber: onMessageReceived data=${message.data}") Timber.d("timber: onMessageReceived notification=${message.notification?.title}, ${message.notification?.body}") - if (NotificationHandler.handleMessageReceived(this, message)) { + if (notificationHandler.handleMessageReceived(this, message)) { return } } diff --git a/app/src/main/java/com/brainwallet/notification/NotificationHandler.kt b/app/src/main/java/com/brainwallet/notification/NotificationHandler.kt index e0284842..893d37a6 100644 --- a/app/src/main/java/com/brainwallet/notification/NotificationHandler.kt +++ b/app/src/main/java/com/brainwallet/notification/NotificationHandler.kt @@ -11,15 +11,34 @@ import android.os.Build import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import com.brainwallet.R +import com.brainwallet.notification.NotificationHandler.Companion.NOTIFICATION_CHANNEL_ID_BRAINWALLET_UPDATE +import com.brainwallet.notification.NotificationHandler.Companion.NOTIFICATION_CHANNEL_ID_GENERAL +import com.brainwallet.notification.NotificationHandler.Companion.NOTIFICATION_CHANNEL_ID_LITECOIN_NEWS import com.brainwallet.presenter.activities.BreadActivity import com.google.firebase.messaging.RemoteMessage -import com.brainwallet.notification.NotificationHandler.NOTIFICATION_CHANNEL_ID_GENERAL -import com.brainwallet.notification.NotificationHandler.NOTIFICATION_CHANNEL_ID_LITECOIN_NEWS -import com.brainwallet.notification.NotificationHandler.NOTIFICATION_CHANNEL_ID_BRAINWALLET_UPDATE +import org.koin.core.annotation.Single -object NotificationHandler { +fun interface NotificationHandlerBuilderProvider { + fun createNotificationBuilder(context: Context, channelId: String): NotificationCompat.Builder +} + +fun interface NotificationNotifier { + fun notify(context: Context, notificationBuilder: NotificationCompat.Builder) +} + +@Single +@SuppressLint("MissingPermission") +class NotificationHandler( + private val notificationBuilderProvider: NotificationHandlerBuilderProvider = + NotificationHandlerBuilderProvider { context, channelId -> + NotificationCompat.Builder(context, channelId) + }, + private val notificationNotifier: NotificationNotifier = NotificationNotifier { context, notificationBuilder -> + NotificationManagerCompat.from(context) + .notify(System.currentTimeMillis().toInt(), notificationBuilder.build()) + } +) { - @SuppressLint("MissingPermission") fun handleMessageReceived(context: Context, remoteMessage: RemoteMessage): Boolean { if (remoteMessage.data.containsKey(KEY_DATA_BRAINWALLET).not()) { return false @@ -36,66 +55,68 @@ object NotificationHandler { val intent = Intent(context, BreadActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } - val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) + val pendingIntent = + PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) - val notification = NotificationCompat.Builder(context, channelId) + val notification = notificationBuilderProvider.createNotificationBuilder(context, channelId) .setContentTitle(title) .setContentText(body) .setSmallIcon(R.drawable.brainwallet_logotype_white) .setContentIntent(pendingIntent) .setAutoCancel(true) - NotificationManagerCompat.from(context) - .notify(System.currentTimeMillis().toInt(), notification.build()) + notificationNotifier.notify(context, notification) return true } - const val KEY_DATA_BRAINWALLET = "brainwallet" + fun setupNotificationChannels(context: Context) { + createNotificationChannel( + context, + NOTIFICATION_CHANNEL_ID_GENERAL, + context.getString(R.string.notification_channel_name_general) + ) + createNotificationChannel( + context, + NOTIFICATION_CHANNEL_ID_LITECOIN_NEWS, + context.getString(R.string.notification_channel_name_litecoin_news) + ) + createNotificationChannel( + context, + NOTIFICATION_CHANNEL_ID_BRAINWALLET_UPDATE, + context.getString(R.string.notification_channel_name_brainwallet_update) + ) + } - const val NOTIFICATION_CHANNEL_ID_GENERAL = "general" - const val NOTIFICATION_CHANNEL_ID_LITECOIN_NEWS = "litecoin-news" - const val NOTIFICATION_CHANNEL_ID_BRAINWALLET_UPDATE = "brainwallet-update" + private fun createNotificationChannel( + context: Context, + channelId: String, + name: String, + ) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel( + channelId, + name, + NotificationManager.IMPORTANCE_DEFAULT + ).also { notificationChannel -> + val notificationManager = + context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager + notificationManager.createNotificationChannel(notificationChannel) + } + } + } - val defaultNotificationChannels = setOf( - NOTIFICATION_CHANNEL_ID_GENERAL, - NOTIFICATION_CHANNEL_ID_LITECOIN_NEWS, - NOTIFICATION_CHANNEL_ID_BRAINWALLET_UPDATE - ) -} + companion object { + const val KEY_DATA_BRAINWALLET = "brainwallet" -fun setupNotificationChannels(context: Context) { - createNotificationChannel( - context, - NOTIFICATION_CHANNEL_ID_GENERAL, - context.getString(R.string.notification_channel_name_general) - ) - createNotificationChannel( - context, - NOTIFICATION_CHANNEL_ID_LITECOIN_NEWS, - context.getString(R.string.notification_channel_name_litecoin_news) - ) - createNotificationChannel( - context, - NOTIFICATION_CHANNEL_ID_BRAINWALLET_UPDATE, - context.getString(R.string.notification_channel_name_brainwallet_update) - ) -} + const val NOTIFICATION_CHANNEL_ID_GENERAL = "general" + const val NOTIFICATION_CHANNEL_ID_LITECOIN_NEWS = "litecoin-news" + const val NOTIFICATION_CHANNEL_ID_BRAINWALLET_UPDATE = "brainwallet-update" -private fun createNotificationChannel( - context: Context, - channelId: String, - name: String, -) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel( - channelId, - name, - NotificationManager.IMPORTANCE_DEFAULT - ).also { notificationChannel -> - val notificationManager = - context.getSystemService(NOTIFICATION_SERVICE) as NotificationManager - notificationManager.createNotificationChannel(notificationChannel) - } + val defaultNotificationChannels = setOf( + NOTIFICATION_CHANNEL_ID_GENERAL, + NOTIFICATION_CHANNEL_ID_LITECOIN_NEWS, + NOTIFICATION_CHANNEL_ID_BRAINWALLET_UPDATE + ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt b/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt index 381d9c77..9d526ec7 100644 --- a/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt @@ -2,7 +2,7 @@ package com.brainwallet.ui import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.brainwallet.di.json +import com.brainwallet.di.AppModule.json import com.brainwallet.navigation.UiEffect import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt index 5e6e6316..30975ab3 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt @@ -1,6 +1,5 @@ package com.brainwallet.ui.screens.buylitecoin -import android.util.Log import androidx.lifecycle.viewModelScope import com.brainwallet.R import com.brainwallet.data.model.AppSetting @@ -21,7 +20,9 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +@KoinViewModel class BuyLitecoinViewModel( private val settingRepository: SettingRepository, private val ltcRepository: LtcRepository diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt index 738af4be..46f5c426 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt @@ -22,8 +22,9 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel - +@KoinViewModel class SettingsViewModel( private val settingRepository: SettingRepository, private val ltcRepository: LtcRepository diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt index f6b2ba8a..e381351c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt @@ -21,8 +21,10 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel //todo: wip +@KoinViewModel class ReceiveDialogViewModel( private val settingRepository: SettingRepository, private val ltcRepository: LtcRepository, diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt index 7da2b003..bfdd4aad 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt @@ -16,7 +16,9 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +@KoinViewModel class InputWordsViewModel : BrainwalletViewModel() { private val _state = MutableStateFlow(InputWordsState()) diff --git a/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyViewModel.kt index b66a6889..25fac5c8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyViewModel.kt @@ -1,7 +1,9 @@ package com.brainwallet.ui.screens.ready import com.brainwallet.ui.BrainwalletViewModel +import org.koin.android.annotation.KoinViewModel +@KoinViewModel class ReadyViewModel : BrainwalletViewModel() { override fun onEvent(event: ReadyEvent) { @@ -9,4 +11,4 @@ class ReadyViewModel : BrainwalletViewModel() { is ReadyEvent.OnLoad -> Unit } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeViewModel.kt index cd867bc7..982dd71d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeViewModel.kt @@ -11,7 +11,9 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +@KoinViewModel class SetPasscodeViewModel : BrainwalletViewModel() { private val _state = MutableStateFlow(SetPasscodeState()) diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt index 686b562c..30e3274a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt @@ -15,10 +15,11 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel import timber.log.Timber import java.math.BigDecimal - +@KoinViewModel class UnLockViewModel : BrainwalletViewModel() { private val _state = MutableStateFlow(UnLockState()) diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeViewModel.kt index 5045014e..47a282e0 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeViewModel.kt @@ -20,8 +20,10 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel //TODO: revisit this later +@KoinViewModel class WelcomeViewModel( private val settingRepository: SettingRepository ) : BrainwalletViewModel() { diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt index c6406a2d..e54f745f 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt @@ -8,7 +8,9 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +@KoinViewModel class YourSeedProveItViewModel : BrainwalletViewModel() { private val _state = MutableStateFlow(YourSeedProveItState()) diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt index 562b8b97..b85e71c7 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt @@ -5,7 +5,9 @@ import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.BrainwalletViewModel import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +@KoinViewModel class YourSeedWordsViewModel : BrainwalletViewModel() { override fun onEvent(event: YourSeedWordsEvent) { diff --git a/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreKeyGenerator.kt b/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreKeyGenerator.kt index ff4c51ac..c8aa3d92 100644 --- a/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreKeyGenerator.kt +++ b/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreKeyGenerator.kt @@ -1,68 +1,7 @@ package com.brainwallet.util.cryptography - -import android.os.Build -import android.security.keystore.KeyGenParameterSpec -import android.security.keystore.KeyProperties.AUTH_BIOMETRIC_STRONG -import android.security.keystore.KeyProperties.KEY_ALGORITHM_AES -import android.security.keystore.KeyProperties.PURPOSE_DECRYPT -import android.security.keystore.KeyProperties.PURPOSE_ENCRYPT -import com.brainwallet.tools.security.BRKeyStore -import com.brainwallet.tools.security.BRKeyStore.NEW_BLOCK_MODE -import com.brainwallet.tools.security.BRKeyStore.NEW_PADDING -import javax.crypto.KeyGenerator import javax.crypto.SecretKey interface KeyStoreKeyGenerator { fun generateKey(alias: String, isAuthRequired: Boolean, authTimeout: Int?): SecretKey - - class Impl : KeyStoreKeyGenerator { - - private val keyGenerator by lazy { - KeyGenerator.getInstance(KEY_ALGORITHM_AES, BRKeyStore.ANDROID_KEY_STORE) - } - - override fun generateKey( - alias: String, - isAuthRequired: Boolean, - authTimeout: Int? - ): SecretKey { - val keySpecBuilder = getKeyGenSpecBuilder(alias) - if (isAuthRequired) { - setUserAuth(keySpecBuilder, authTimeout) - } - keyGenerator.init(keySpecBuilder.build()) - return keyGenerator.generateKey() - } - - private fun getKeyGenSpecBuilder(alias: String): KeyGenParameterSpec.Builder { - val purposes = PURPOSE_DECRYPT or PURPOSE_ENCRYPT - - return KeyGenParameterSpec.Builder(alias, purposes) - .setBlockModes(NEW_BLOCK_MODE) - .setRandomizedEncryptionRequired(false) - .setEncryptionPaddings(NEW_PADDING) - } - - private fun setUserAuth( - builder: KeyGenParameterSpec.Builder, authTimeout: Int? - ) { - builder.setUserAuthenticationRequired(true) - if (authTimeout != null) { - setAuthTimeout(builder, authTimeout) - } - } - - private fun setAuthTimeout(builder: KeyGenParameterSpec.Builder, authTimeout: Int) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - if (authTimeout != 0) { - builder.setUserAuthenticationParameters(authTimeout, AUTH_BIOMETRIC_STRONG) - } - } else { - val timeout = if (authTimeout == 0) -1 else authTimeout - builder.setUserAuthenticationValidityDurationSeconds(timeout) - } - } - - } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreManager.kt b/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreManager.kt index 6f72268b..1223f2fb 100644 --- a/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreManager.kt +++ b/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreManager.kt @@ -4,14 +4,14 @@ import android.content.Context import android.security.keystore.UserNotAuthenticatedException import com.brainwallet.tools.security.BRKeyStore import com.brainwallet.tools.security.BRKeyStore.AliasObject -import com.brainwallet.tools.security.BRKeyStore.CANARY_ALIAS -import com.brainwallet.tools.security.BRKeyStore.PHRASE_ALIAS import kotlinx.coroutines.runBlocking import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import org.koin.core.annotation.Single import timber.log.Timber import java.security.KeyStore +@Single class KeyStoreManager( private val context: Context, private val keyGenerator: KeyStoreKeyGenerator, diff --git a/app/src/main/java/com/brainwallet/util/cryptography/impl/KeyStoreKeyGeneratorImpl.kt b/app/src/main/java/com/brainwallet/util/cryptography/impl/KeyStoreKeyGeneratorImpl.kt new file mode 100644 index 00000000..8a14c8db --- /dev/null +++ b/app/src/main/java/com/brainwallet/util/cryptography/impl/KeyStoreKeyGeneratorImpl.kt @@ -0,0 +1,65 @@ +package com.brainwallet.util.cryptography.impl + +import android.os.Build +import android.security.keystore.KeyGenParameterSpec +import android.security.keystore.KeyProperties.AUTH_BIOMETRIC_STRONG +import android.security.keystore.KeyProperties.KEY_ALGORITHM_AES +import android.security.keystore.KeyProperties.PURPOSE_DECRYPT +import android.security.keystore.KeyProperties.PURPOSE_ENCRYPT +import com.brainwallet.tools.security.BRKeyStore +import com.brainwallet.tools.security.BRKeyStore.NEW_BLOCK_MODE +import com.brainwallet.tools.security.BRKeyStore.NEW_PADDING +import com.brainwallet.util.cryptography.KeyStoreKeyGenerator +import org.koin.core.annotation.Single +import javax.crypto.KeyGenerator +import javax.crypto.SecretKey + +@Single(binds = [KeyStoreKeyGenerator::class]) +class KeyStoreKeyGeneratorImpl : KeyStoreKeyGenerator { + + private val keyGenerator by lazy { + KeyGenerator.getInstance(KEY_ALGORITHM_AES, BRKeyStore.ANDROID_KEY_STORE) + } + + override fun generateKey( + alias: String, + isAuthRequired: Boolean, + authTimeout: Int? + ): SecretKey { + val keySpecBuilder = getKeyGenSpecBuilder(alias) + if (isAuthRequired) { + setUserAuth(keySpecBuilder, authTimeout) + } + keyGenerator.init(keySpecBuilder.build()) + return keyGenerator.generateKey() + } + + private fun getKeyGenSpecBuilder(alias: String): KeyGenParameterSpec.Builder { + val purposes = PURPOSE_DECRYPT or PURPOSE_ENCRYPT + + return KeyGenParameterSpec.Builder(alias, purposes) + .setBlockModes(NEW_BLOCK_MODE) + .setRandomizedEncryptionRequired(false) + .setEncryptionPaddings(NEW_PADDING) + } + + private fun setUserAuth( + builder: KeyGenParameterSpec.Builder, authTimeout: Int? + ) { + builder.setUserAuthenticationRequired(true) + if (authTimeout != null) { + setAuthTimeout(builder, authTimeout) + } + } + + private fun setAuthTimeout(builder: KeyGenParameterSpec.Builder, authTimeout: Int) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (authTimeout != 0) { + builder.setUserAuthenticationParameters(authTimeout, AUTH_BIOMETRIC_STRONG) + } + } else { + val timeout = if (authTimeout == 0) -1 else authTimeout + builder.setUserAuthenticationValidityDurationSeconds(timeout) + } + } +} diff --git a/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt b/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt index 739da912..d49b325b 100644 --- a/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt +++ b/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt @@ -8,7 +8,9 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import org.koin.core.annotation.Single +@Single class CurrencyUpdateWorker( private val ltcRepository: LtcRepository ) { diff --git a/app/src/screengrab/kotlin/com/brainwallet/BrainwalletScreengrabApp.kt b/app/src/screengrab/kotlin/com/brainwallet/BrainwalletScreengrabApp.kt index 4dbbde76..6e14bcf3 100644 --- a/app/src/screengrab/kotlin/com/brainwallet/BrainwalletScreengrabApp.kt +++ b/app/src/screengrab/kotlin/com/brainwallet/BrainwalletScreengrabApp.kt @@ -8,6 +8,8 @@ import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger import org.koin.core.context.GlobalContext.startKoin import org.koin.core.logger.Level +import com.brainwallet.di.AppModule +import org.koin.ksp.generated.module import timber.log.Timber class BrainwalletScreengrabApp : BrainwalletApp() { @@ -23,7 +25,7 @@ class BrainwalletScreengrabApp : BrainwalletApp() { startKoin { androidLogger(if (BuildConfig.DEBUG) Level.DEBUG else Level.ERROR) androidContext(this@BrainwalletScreengrabApp) - modules(dataModule, viewModelModule, appModule) + modules(AppModule.dataModule, AppModule.module) } } } diff --git a/app/src/test/java/com/brainwallet/data/source/RemoteConfigSourceFirebaseImplTest.kt b/app/src/test/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepositoryTest.kt similarity index 91% rename from app/src/test/java/com/brainwallet/data/source/RemoteConfigSourceFirebaseImplTest.kt rename to app/src/test/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepositoryTest.kt index 7af41f07..6c98db43 100644 --- a/app/src/test/java/com/brainwallet/data/source/RemoteConfigSourceFirebaseImplTest.kt +++ b/app/src/test/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepositoryTest.kt @@ -1,5 +1,6 @@ -package com.brainwallet.data.source +package com.brainwallet.data.repository +import com.brainwallet.data.source.RemoteConfigSource import com.google.android.gms.tasks.Tasks import com.google.firebase.remoteconfig.FirebaseRemoteConfig import io.mockk.every @@ -10,14 +11,14 @@ import org.junit.Assert.assertEquals import org.junit.Before import org.junit.Test -class RemoteConfigSourceFirebaseImplTest { +class FirebaseRemoteConfigRepositoryTest { private val firebaseRemoteConfig: FirebaseRemoteConfig = mockk(relaxed = true) private lateinit var remoteConfigSource: RemoteConfigSource @Before fun setUp() { - remoteConfigSource = RemoteConfigSource.FirebaseImpl(firebaseRemoteConfig) + remoteConfigSource = FirebaseRemoteConfigRepository(firebaseRemoteConfig) } @Test @@ -76,4 +77,4 @@ class RemoteConfigSourceFirebaseImplTest { assertEquals(100.0, actual, .1) } -} \ No newline at end of file +} diff --git a/app/src/test/java/com/brainwallet/notification/NotificationHandlerTest.kt b/app/src/test/java/com/brainwallet/notification/NotificationHandlerTest.kt index 5a860d26..c8a5813e 100644 --- a/app/src/test/java/com/brainwallet/notification/NotificationHandlerTest.kt +++ b/app/src/test/java/com/brainwallet/notification/NotificationHandlerTest.kt @@ -3,15 +3,17 @@ package com.brainwallet.notification import android.content.Context import android.os.Bundle import androidx.collection.arrayMapOf -import androidx.core.app.NotificationManagerCompat +import androidx.core.app.NotificationCompat import com.google.firebase.messaging.Constants.MessageNotificationKeys import com.google.firebase.messaging.Constants.MessagePayloadKeys import com.google.firebase.messaging.RemoteMessage -import io.mockk.Runs +import io.mockk.MockKAnnotations import io.mockk.every -import io.mockk.just -import io.mockk.mockk +import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.RelaxedMockK import io.mockk.mockkStatic +import io.mockk.unmockkAll +import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Before @@ -20,11 +22,36 @@ import org.junit.Test class NotificationHandlerTest { - private val context: Context = mockk(relaxed = true) + @MockK + private lateinit var context: Context + + @MockK + private lateinit var notificationHandlerBuilderProvider: NotificationHandlerBuilderProvider + + @RelaxedMockK + private lateinit var notificationNotifier: NotificationNotifier + + @RelaxedMockK + private lateinit var notificationBuilder: NotificationCompat.Builder + + private lateinit var sut: NotificationHandler @Before fun setUp() { mockkStatic(MessagePayloadKeys::class) + MockKAnnotations.init(this, relaxUnitFun = true) + every { + notificationHandlerBuilderProvider.createNotificationBuilder( + any(), + any() + ) + } returns notificationBuilder + sut = NotificationHandler(notificationHandlerBuilderProvider, notificationNotifier) + } + + @After + fun tearDown() { + unmockkAll() } @Test @@ -34,7 +61,7 @@ class NotificationHandlerTest { every { MessagePayloadKeys.extractDeveloperDefinedPayload(any()) } returns arrayMapOf() - val actual = NotificationHandler.handleMessageReceived(context, remoteMessage) + val actual = sut.handleMessageReceived(context, remoteMessage) assertEquals(false, actual) } @@ -76,13 +103,9 @@ class NotificationHandlerTest { if (testOSVersion == 6 || testOSVersion == 15) { assertTrue(successMessage, true) - } - else { - mockkStatic(NotificationManagerCompat::class) - every { NotificationManagerCompat.from(context).notify(any()) } just Runs - - val actual = NotificationHandler.handleMessageReceived(context, remoteMessage) - assertEquals(failMessage,true, actual) + } else { + val actual = sut.handleMessageReceived(context, remoteMessage) + assertEquals(failMessage, true, actual) } } diff --git a/build.gradle.kts b/build.gradle.kts index 26e5212f..8cbe07fb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -8,6 +8,7 @@ plugins { alias(libs.plugins.jetbrains.kotlin.serialization) apply false alias(libs.plugins.google.services) apply false alias(libs.plugins.firebase.crashlytics) apply false + alias(libs.plugins.ksp) apply false } tasks.register("clean", Delete::class) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index cd3b7691..fc956caf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -31,6 +31,8 @@ eclipse-jetty = "9.2.19.v20160908" junit = "4.13.2" mockk = "1.13.13" koin-bom = "4.0.2" +koin-annotation-bom = "2.1.0" +ksp = "2.0.0-1.0.24" [libraries] androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" } @@ -112,7 +114,9 @@ koin-android = { module = "io.insert-koin:koin-android" } koin-android-compat = { module = "io.insert-koin:koin-android-compat" } koin-compose = { module = "io.insert-koin:koin-compose" } koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel" } - +koin-annotation-bom = { module = "io.insert-koin:koin-annotations-bom", version.ref = "koin-annotation-bom" } +koin-annotation = { module = "io.insert-koin:koin-annotations" } +koin-annotation-compiler = { module = "io.insert-koin:koin-ksp-compiler", version.ref = "koin-annotation-bom" } [bundles] androidx-lifecycle = ["androidx-lifecycle-runtime", "androidx-lifecycle-viewmodel", "androidx-lifecycle-viewmodel-compose"] @@ -136,4 +140,5 @@ jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serializati jetbrains-kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version = "2.1.0" } jetbrains-kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } google-services = { id = "com.google.gms.google-services", version = "4.4.2" } -firebase-crashlytics = { id = "com.google.firebase.crashlytics", version = "3.0.2" } \ No newline at end of file +firebase-crashlytics = { id = "com.google.firebase.crashlytics", version = "3.0.2" } +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } \ No newline at end of file From 5900ed4082aef15f11158064e2b5e133fc60364c Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 19 Aug 2025 15:08:59 +0100 Subject: [PATCH 052/116] Create PULL_REQUEST_TEMPLATE.md Create PULL_REQUEST_TEMPLATE.md --- .github/PULL_REQUEST_TEMPLATE.md | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..9cbe9c85 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,59 @@ +# Pull Request Template - Android Development + +## 📱 Description + + + + +## Platform +- [ ] Android +- [ ] iOS +- [ ] Games-Unity +- [ ] DevOps (AWS) +- [ ] Website +- [ ] C/Golang + +## 🎯 Type of Change + +- [ ] 🐛 Bug fix (non-breaking change which fixes an issue) +- [ ] ✨ New feature (non-breaking change which adds functionality) +- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] 🔧 Refactoring (code change that neither fixes a bug nor adds a feature) +- [ ] 📚 Documentation update +- [ ] 🎨 UI/UX improvement +- [ ] ⚡ Performance improvement +- [ ] 🧪 Test addition or improvement + +## 📋 Changes Made + +- +- +- + +## 🔗 Related Issues + +- Fixes # +- Related to # + +## 🧪 Tests Status +- [ ] Tests ran successfully locally? +- [ ] Added more tests? How many? +- [ ] Code coverage percentage of the codebase: __% + + +## 📸 Screenshots/Videos + + + +### Before + + +### After + + +## 🎯 Reviewers + +@kcw-grunt, @josikie + + + From 3b1f628e0918d9108cafc578e433cca479c5667f Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 19 Aug 2025 21:08:33 +0100 Subject: [PATCH 053/116] bump for test (#121) * bump for test * Updated the template * polishes --- .github/PULL_REQUEST_TEMPLATE.md | 26 +++++++------------------- app/build.gradle.kts | 2 +- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 9cbe9c85..df64dbb1 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,10 +1,6 @@ -# Pull Request Template - Android Development - ## 📱 Description - - ## Platform - [ ] Android - [ ] iOS @@ -15,22 +11,20 @@ ## 🎯 Type of Change -- [ ] 🐛 Bug fix (non-breaking change which fixes an issue) -- [ ] ✨ New feature (non-breaking change which adds functionality) -- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] 🐛 Bug fix +- [ ] ✨ New feature - [ ] 🔧 Refactoring (code change that neither fixes a bug nor adds a feature) - [ ] 📚 Documentation update - [ ] 🎨 UI/UX improvement - [ ] ⚡ Performance improvement - [ ] 🧪 Test addition or improvement -## 📋 Changes Made +## 📋 Changes - - -- -## 🔗 Related Issues +### 🔗 Related Issues - Fixes # - Related to # @@ -40,20 +34,14 @@ - [ ] Added more tests? How many? - [ ] Code coverage percentage of the codebase: __% - ## 📸 Screenshots/Videos -### Before - - -### After - +| Before | After | +|--------|-------| +||| ## 🎯 Reviewers @kcw-grunt, @josikie - - - diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b42bd6bd..2032355a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -21,7 +21,7 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 36 - versionCode = 202506271 + versionCode = 202506272 versionName = "v4.6.2" multiDexEnabled = true From f11d5a81ebc315b026714a0b76021d6e98cd16c3 Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Wed, 20 Aug 2025 17:36:42 +0700 Subject: [PATCH 054/116] feat(#174): initiate games module (#119) --- .gitmodules | 4 ++++ app/build.gradle.kts | 7 +++++++ build.gradle.kts | 1 + gradle/libs.versions.toml | 3 ++- modules/games | 1 + settings.gradle.kts | 18 ++++++++++++++++++ 6 files changed, 33 insertions(+), 1 deletion(-) create mode 160000 modules/games diff --git a/.gitmodules b/.gitmodules index 17190631..bd038a83 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,7 @@ [submodule "app/src/main/jni/core"] path = app/src/main/jni/core url = https://github.com/brainwallet-co/core.git +[submodule "modules/games"] + path = modules/games + url = https://github.com/gruntsoftware/android-games.git + update = none diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2032355a..a15a6cae 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -188,6 +188,13 @@ dependencies { } } + val gamesModule = findProject(":modules:games:content") + if (gamesModule != null) { + implementation(gamesModule) + } else { + logger.lifecycle("⚠️ Submodule ':modules:games:content' not found — skipping dependency") + } + implementation("androidx.webkit:webkit:1.9.0") implementation(libs.androidx.core) implementation(libs.androidx.appcompat) diff --git a/build.gradle.kts b/build.gradle.kts index 8cbe07fb..a34bb719 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,6 +2,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.library) apply false alias(libs.plugins.jetbrains.kotlin.android) apply false alias(libs.plugins.jetbrains.kotlin.compose) apply false alias(libs.plugins.jetbrains.kotlin.kapt) apply false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fc956caf..c234152d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -135,10 +135,11 @@ squareup-okhttp = ["squareup-okhttp", "squareup-okhttp-logging-interceptor"] [plugins] android-application = { id = "com.android.application", version.ref = "agp" } +android-library = { id = "com.android.library", version.ref = "agp" } jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } jetbrains-kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version = "2.1.0" } jetbrains-kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } google-services = { id = "com.google.gms.google-services", version = "4.4.2" } firebase-crashlytics = { id = "com.google.firebase.crashlytics", version = "3.0.2" } -ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } \ No newline at end of file +ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } diff --git a/modules/games b/modules/games new file mode 160000 index 00000000..a5f408cc --- /dev/null +++ b/modules/games @@ -0,0 +1 @@ +Subproject commit a5f408cc093f729b32f351e29d010a31242eef8e diff --git a/settings.gradle.kts b/settings.gradle.kts index b3356345..2ee160e5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -11,15 +11,33 @@ pluginManagement { gradlePluginPortal() } } + dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } + + versionCatalogs { + val gamesToml = file("modules/games/gradle/libs.versions.toml") + if (gamesToml.exists()) { + create("games") { + from(files(gamesToml)) + } + } else { + logger.lifecycle("⚠️ Submodule catalog 'games' not loaded — file not found: $gamesToml") + } + } } rootProject.name = "Brainwallet Android" include(":app") include(":install_time_asset_pack") +val gamesDir = file("modules/games/content") +if (gamesDir.exists()) { + include(":modules:games:content") +} else { + logger.lifecycle("⚠️ Submodule ':modules:games:content' not included — folder not found: $gamesDir") +} \ No newline at end of file From 77ed7dfd7b63b285e1b45b7f2762b7dc8505a360 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Wed, 20 Aug 2025 15:55:37 +0100 Subject: [PATCH 055/116] Force pushed the version and code bump and catch up with Prod. --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a15a6cae..a68ebc9c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -21,8 +21,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 36 - versionCode = 202506272 - versionName = "v4.6.2" + versionCode = 202506273 + versionName = "v4.7.1" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") From ef353e37358557a53ca8099f4f2802566b8c5cba Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 25 Aug 2025 09:12:16 +0100 Subject: [PATCH 056/116] =?UTF-8?q?=F0=9F=9A=80[Release=20v4.7.2]=20Merge?= =?UTF-8?q?=20into=20Develop=20(#127)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🚀[Release v4.4.7] Merge into Main (#70) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.0] Merge into Main (#78) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.4] Merge into Main (#87) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * Updated README * code bump * chore: open bread activity first then open moonpay widget (#88) * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.5] Merge into Main (#101) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Update build.gradle.kts --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.0] Merge into Main (#104) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * version bump * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.1] Merge into Main (#107) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * build bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.2] Merge into Main (#110) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * Removed unused audio files * polished tests * removed unused asset pack * code bump * code bump * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * broke out completion of the seed phrase and navigation - Feedback was a user could complete seed phrase and not tap "Game and Sync" - Forced users to start all over - Saved a correct seed phrase confirmation into memory * code bump * fix for https://console.firebase.google.com/project/brainwallet-mobile/crashlytics/app/android:ltd.grunt.brainwallet/issues/1386f366ab35e9112a6b742d629bb0be?time=last-seven-days&types=crash&sessionEventKey=685DA96C00BF00015A7AFEA30E0DB49C_2098799426616143441 * measure where users tap * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly * Cleaned commented out BuyLitecoinscreen * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.7.0] Merge into Main (#115) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly (#111) * Upgrade targetSdk 36 (#113) * chore: change drawable with density for brainwallet_logotype_white * chore: adjustment WelcomeScreen.kt * chore: adjustment for targetSdk 36 also support 16KB page size * bump clean extra semicolon * Update pro-guard-rules * Updated the version --------- Co-authored-by: andhikayuana * Updated games module to v1.1.0 * Updated the games submodule * Renamed and tested with user skips --------- Co-authored-by: andhikayuana --- README.md | 5 ++++ app/build.gradle.kts | 4 +-- app/proguard-rules.pro | 2 +- .../java/com/brainwallet/data/model/Fee.kt | 2 +- .../navigation/LegacyNavigation.kt | 2 ++ .../com/brainwallet/ui/BrainwalletActivity.kt | 4 +++ .../screens/buylitecoin/BuyLitecoinScreen.kt | 1 - .../ui/screens/home/SettingsEvent.kt | 1 - .../settingsrows/LitecoinBlockchainDetail.kt | 4 +++ .../ui/screens/home/receive/ReceiveDialog.kt | 1 - .../ui/screens/topup/TopUpScreen.kt | 1 + .../ui/screens/welcome/WelcomeScreen.kt | 1 + .../yourseedproveit/YourSeedProveItEvent.kt | 2 ++ .../yourseedproveit/YourSeedProveItScreen.kt | 4 +++ .../YourSeedProveItViewModel.kt | 5 ++++ .../brainwallet/tools/util/BRConstantsTest.kt | 28 +++++++++---------- gradle/libs.versions.toml | 2 +- modules/games | 2 +- 18 files changed, 48 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 4cd2e194..0c961d8d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,8 @@ ## Easy and secure Brainwallet is a easy and fun way to use your crypto (Litecoin) and memorize your seed words + +### Release notes + +- v4.5.4 + - Added new MP Buy UI diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a68ebc9c..253c6aca 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -21,8 +21,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 36 - versionCode = 202506273 - versionName = "v4.7.1" + versionCode = 202506295 + versionName = "v4.7.2" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 7ab25998..44883644 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -40,7 +40,7 @@ -dontwarn org.slf4j.impl.StaticLoggerBinder -dontwarn org.slf4j.impl.StaticMDCBinder -dontwarn org.slf4j.impl.StaticMarkerBinder - +-dontwarn java.lang.reflect.AnnotatedType -keepclasseswithmembernames class * { native ; diff --git a/app/src/main/java/com/brainwallet/data/model/Fee.kt b/app/src/main/java/com/brainwallet/data/model/Fee.kt index b1d086ae..28413fd9 100644 --- a/app/src/main/java/com/brainwallet/data/model/Fee.kt +++ b/app/src/main/java/com/brainwallet/data/model/Fee.kt @@ -91,4 +91,4 @@ fun FeeOption.getFiatFormatted(currencyEntity: CurrencyEntity): String { fun List.getSelectedIndex(selectedFeeType: String): Int { return indexOfFirst { it.type == selectedFeeType }.takeIf { it >= 0 } ?: 2 //2 -> index of top, since we have [low,medium,top] -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt index 10503556..a46e3261 100644 --- a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt +++ b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import timber.log.Timber +import com.google.firebase.analytics.FirebaseAnalytics //provide old navigation using intent activity @@ -35,6 +36,7 @@ object LegacyNavigation { auth: Boolean ) { Timber.i("timber: startBreadActivity: %s", from.javaClass.name) + val intent = if (auth) BrainwalletActivity.createIntent(from, Route.UnLock()) else Intent(from, BreadActivity::class.java) intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) diff --git a/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt b/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt index 8ef9dfda..ed8b27d9 100644 --- a/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt +++ b/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt @@ -32,6 +32,7 @@ import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGAC import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGACY_DIALOG_WIPE_ALERT import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGACY_EFFECT_RESET_PIN import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel.Companion.LEGACY_EFFECT_ON_PAPERKEY_PROVED +import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel.Companion.LEGACY_NAVIGATE_TO_HOME import com.brainwallet.ui.theme.BrainwalletAppTheme import com.brainwallet.util.EventBus import com.brainwallet.wallet.BRWalletManager @@ -115,6 +116,9 @@ class BrainwalletActivity : BRActivity() { LEGACY_EFFECT_ON_PAPERKEY_PROVED -> { BRSharedPrefs.putPhraseWroteDown(this@BrainwalletActivity, true) + } + + LEGACY_NAVIGATE_TO_HOME -> { LegacyNavigation.startBreadActivity( this@BrainwalletActivity, false diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt index 89fd9473..ad6b3cf5 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt @@ -47,7 +47,6 @@ fun BuyLitecoinScreen( val loadingState by viewModel.loadingState.collectAsState() val appSetting by viewModel.appSetting.collectAsState() val context = LocalContext.current - LaunchedEffect(Unit) { viewModel.onEvent(BuyLitecoinEvent.OnLoad(context)) viewModel.uiEffect.collect { effect -> diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt index 61a8ced4..cf6b1d31 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt @@ -8,7 +8,6 @@ sealed class SettingsEvent { val shareAnalyticsDataEnabled: Boolean = false, val lastSyncMetadata: String? = null, ) : SettingsEvent() - object OnSecurityUpdatePinClick : SettingsEvent() object OnSecuritySeedPhraseClick : SettingsEvent() object OnSecurityShareAnalyticsDataClick : SettingsEvent() diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt index f964e418..1c3e6ef8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt @@ -14,6 +14,10 @@ import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt index 8292904c..e96a1f2a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt @@ -90,7 +90,6 @@ fun ReceiveDialog( val appSetting by viewModel.appSetting.collectAsState() val context = LocalContext.current val wheelPickerFiatCurrencyState = rememberWheelPickerState(0) - LaunchedEffect(Unit) { viewModel.onEvent(ReceiveDialogEvent.OnLoad(context)) viewModel.uiEffect.collect { effect -> diff --git a/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt index 22f5722d..7ef16b33 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.brainwallet.R +import com.brainwallet.navigation.LegacyNavigation import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index cec6d05a..d5a1fd2b 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.width diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt index 68816d6a..b315d980 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt @@ -13,5 +13,7 @@ sealed class YourSeedProveItEvent { object OnGameAndSync : YourSeedProveItEvent() + object OnCompletedPaperKey : YourSeedProveItEvent() + object OnClear : YourSeedProveItEvent() } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt index 71d1c56e..e505438c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt @@ -53,6 +53,8 @@ import com.brainwallet.R import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect +import com.brainwallet.tools.manager.AnalyticsManager +import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.LargeButton @@ -86,6 +88,8 @@ fun YourSeedProveItScreen( LaunchedEffect(state.orderCorrected) { if (state.orderCorrected) { coinAudioPlayer.start() + viewModel.onEvent(YourSeedProveItEvent.OnCompletedPaperKey) + AnalyticsManager.logCustomEvent(BRConstants._20250303_DSTU) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt index e54f745f..75f68797 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt @@ -51,6 +51,10 @@ class YourSeedProveItViewModel : BrainwalletViewModel() { } YourSeedProveItEvent.OnGameAndSync -> viewModelScope.launch { + EventBus.emit(EventBus.Event.Message(LEGACY_NAVIGATE_TO_HOME)) + } + + YourSeedProveItEvent.OnCompletedPaperKey -> viewModelScope.launch { EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_PAPERKEY_PROVED)) } } @@ -58,5 +62,6 @@ class YourSeedProveItViewModel : BrainwalletViewModel() { companion object { const val LEGACY_EFFECT_ON_PAPERKEY_PROVED = "onPaperKeyProved" + const val LEGACY_NAVIGATE_TO_HOME = "navigateToHome" } } \ No newline at end of file diff --git a/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt b/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt index 5779b8df..1f6fee1b 100644 --- a/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt +++ b/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt @@ -16,12 +16,12 @@ class BRConstantsTest { @Test fun `validate App external URL constant`(){ - assertSame(BRConstants.TWITTER_LINK,"https://twitter.com/Brainwallet_App"); - assertSame(BRConstants.INSTAGRAM_LINK,"https://www.instagram.com/brainwalletapp"); - assertSame(BRConstants.WEB_LINK,"https://brainwallet.co"); - assertSame(BRConstants.TOS_LINK,"https://brainwallet.co/privacy-policy.html"); - assertSame(BRConstants.MOBILE_MP_LINK,"https://brainwallet.co/mobile-top-up.html"); - assertSame(BRConstants.BITREFILL_AFFILIATE_LINK,"https://www.bitrefill.com/"); + assertSame(BRConstants.TWITTER_LINK,"https://twitter.com/Brainwallet_App") + assertSame(BRConstants.INSTAGRAM_LINK,"https://www.instagram.com/brainwalletapp") + assertSame(BRConstants.WEB_LINK,"https://brainwallet.co") + assertSame(BRConstants.TOS_LINK,"https://brainwallet.co/privacy-policy.html") + assertSame(BRConstants.MOBILE_MP_LINK,"https://brainwallet.co/mobile-top-up.html") + assertSame(BRConstants.BITREFILL_AFFILIATE_LINK,"https://www.bitrefill.com/") } @Test @@ -89,7 +89,7 @@ class BRConstantsTest { // public ActivityScenarioRule mActivityRule = new ActivityScenarioRule<>(IntroActivity.class); // @Before // public void setUp() { -// Log.e(TAG, "setUp: "); +// Log.e(TAG, "setUp: ") // } // // @After @@ -97,16 +97,16 @@ class BRConstantsTest { // } // @Test // public void testLitecoinSymbolConstants() { -// Assert.assertSame(BRConstants.litecoinLowercase,"ł"); -// Assert.assertSame(BRConstants.litecoinUppercase,"Ł"); +// Assert.assertSame(BRConstants.litecoinLowercase,"ł") +// Assert.assertSame(BRConstants.litecoinUppercase,"Ł") // } // @Test // public void testAppExternalURLConstants() { -// Assert.assertSame(BRConstants.TWITTER_LINK,"https://twitter.com/Brainwallet_App"); -// Assert.assertSame(BRConstants.WEB_LINK,"https://brainwallet.co"); -// Assert.assertSame(BRConstants.TOS_LINK,"https://brainwallet.co/privacy"); -// Assert.assertSame(BRConstants.CUSTOMER_SUPPORT_LINK,"https://support.brainwallet.co/hc/en-us/requests/new"); -// Assert.assertSame(BRConstants.BITREFILL_AFFILIATE_LINK,"https://www.bitrefill.com/"); +// Assert.assertSame(BRConstants.TWITTER_LINK,"https://twitter.com/Brainwallet_App") +// Assert.assertSame(BRConstants.WEB_LINK,"https://brainwallet.co") +// Assert.assertSame(BRConstants.TOS_LINK,"https://brainwallet.co/privacy") +// Assert.assertSame(BRConstants.CUSTOMER_SUPPORT_LINK,"https://support.brainwallet.co/hc/en-us/requests/new") +// Assert.assertSame(BRConstants.BITREFILL_AFFILIATE_LINK,"https://www.bitrefill.com/") // } // @Test // public void testFirebaseAnalyticsConstants() { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c234152d..f1ff0cc4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] kotlin = "2.0.0" -agp = "8.5.1" +agp = "8.7.3" androidx-core-ktx = "1.12.0" androidx-appcompat = "1.6.1" androidx-legacy-support = "1.0.0" diff --git a/modules/games b/modules/games index a5f408cc..b2cc09df 160000 --- a/modules/games +++ b/modules/games @@ -1 +1 @@ -Subproject commit a5f408cc093f729b32f351e29d010a31242eef8e +Subproject commit b2cc09df06d90baa9836b8789c38de569e2e8f8f From e25e9e11a8aad4a3c2492ce4a3300f0a589ca2c0 Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Mon, 25 Aug 2025 17:57:58 +0700 Subject: [PATCH 057/116] Fix(#227): Crash when launching MoonPay Widget (#126) Refactored the MoonPay widget integration to a dedicated Composable (`MoonPayWidgetLauncher`) to ensure proper state handling and loading behavior. - Added `MoonPayWidgetLauncher.kt` with Composable and ViewModel for managing signed URL fetch and Custom Tab launch. - Ensures loading state covers the whole screen, preventing UI crashes. - Removed legacy static method `LegacyNavigation.showMoonPayWidget`. - Updated `ReceiveDialog.kt` and `BuyLitecoinScreen.kt` to use the new Composable. - Minor cleanup in `LegacyNavigation.kt`. --- .../navigation/LegacyNavigation.kt | 62 +---------- .../navigation/MoonPayWidgeLauncher.kt | 103 ++++++++++++++++++ .../screens/buylitecoin/BuyLitecoinScreen.kt | 20 ++-- .../ui/screens/home/receive/ReceiveDialog.kt | 19 ++-- 4 files changed, 123 insertions(+), 81 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/navigation/MoonPayWidgeLauncher.kt diff --git a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt index a46e3261..21c82cda 100644 --- a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt +++ b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt @@ -1,26 +1,14 @@ package com.brainwallet.navigation import android.app.Activity -import android.app.ProgressDialog import android.content.Context import android.content.Intent -import android.widget.Toast -import androidx.browser.customtabs.CustomTabsIntent -import androidx.core.net.toUri -import com.brainwallet.BuildConfig import com.brainwallet.R -import com.brainwallet.data.repository.LtcRepository -import com.brainwallet.di.AppModule.getKoinInstance import com.brainwallet.presenter.activities.BreadActivity import com.brainwallet.ui.BrainwalletActivity -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import timber.log.Timber import com.google.firebase.analytics.FirebaseAnalytics - //provide old navigation using intent activity object LegacyNavigation { @@ -67,52 +55,4 @@ object LegacyNavigation { ) = BrainwalletActivity.createIntent(context, destination).also { context.startActivity(it) } - - @JvmOverloads - @JvmStatic - fun showMoonPayWidget( - context: Context, - params: Map = mapOf(), - isDarkMode: Boolean = true, - ) { - val ltcRepository: LtcRepository = getKoinInstance() - val progressDialog = ProgressDialog(context).apply { - setMessage(context.getString(R.string.loading)) - setCancelable(false) - show() - } - - CoroutineScope(Dispatchers.Main).launch { - try { - val result = withContext(Dispatchers.IO) { - ltcRepository.fetchMoonpaySignedUrl( - params = params.toMutableMap().apply { - put("theme", if (isDarkMode) "dark" else "light") - } - ) - } - - val widgetUri = result.toUri().buildUpon() - .apply { - if (BuildConfig.DEBUG) { - authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com - } - } - .build() - val intent = CustomTabsIntent.Builder() - .setColorScheme(if (isDarkMode) CustomTabsIntent.COLOR_SCHEME_DARK else CustomTabsIntent.COLOR_SCHEME_LIGHT) - .build() - intent.launchUrl(context, widgetUri) - } catch (e: Exception) { - Toast.makeText( - context, - "Failed to load: ${e.message}, please try again later", - Toast.LENGTH_LONG - ).show() - } finally { - progressDialog.dismiss() - } - } - } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/navigation/MoonPayWidgeLauncher.kt b/app/src/main/java/com/brainwallet/navigation/MoonPayWidgeLauncher.kt new file mode 100644 index 00000000..7677a4de --- /dev/null +++ b/app/src/main/java/com/brainwallet/navigation/MoonPayWidgeLauncher.kt @@ -0,0 +1,103 @@ +package com.brainwallet.navigation + +import android.net.Uri +import android.widget.Toast +import androidx.browser.customtabs.CustomTabsIntent +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.core.net.toUri +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.brainwallet.BuildConfig +import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.ui.composable.LoadingDialog +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +import org.koin.compose.viewmodel.koinViewModel + +@KoinViewModel +class MoonPayWidgetLauncherViewModel( + private val settingRepository: SettingRepository, + private val ltcRepository: LtcRepository, + private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO +) : ViewModel() { + + private val _isLoading = MutableStateFlow(false) + val isLoading = _isLoading.asStateFlow() + + private val _result = Channel>>() + val result = _result.receiveAsFlow() + + fun launch(params: Map) { + _isLoading.update { true } + viewModelScope.launch(ioDispatcher) { + val isDarkMode = settingRepository.isDarkMode() + _result.send(ltcRepository.runCatching { + val result = ltcRepository.fetchMoonpaySignedUrl( + params = params.toMutableMap().apply { + put("theme", if (isDarkMode) "dark" else "light") + } + ) + isDarkMode to result.toUri().buildUpon() + .apply { + if (BuildConfig.DEBUG) { + authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com + } + } + .build() + }) + _isLoading.update { false } + } + } +} + +@Composable +fun MoonPayWidgetLauncher( + modifier: Modifier = Modifier, + viewModel: MoonPayWidgetLauncherViewModel = koinViewModel(), + onResult: () -> Unit = {} +) { + val context = LocalContext.current + val isLoading by viewModel.isLoading.collectAsState() + + AnimatedVisibility(isLoading, modifier = modifier) { + LoadingDialog() + } + + LaunchedEffect(Unit) { + viewModel.result.collect { result -> + result.fold( + onSuccess = { (isDarkMode, uri) -> + val intent = CustomTabsIntent.Builder() + .setColorScheme( + if (isDarkMode) CustomTabsIntent.COLOR_SCHEME_DARK + else CustomTabsIntent.COLOR_SCHEME_LIGHT + ) + .build() + intent.launchUrl(context, uri) + }, + onFailure = { e -> + Toast.makeText( + context, + "Failed to load: ${e.message}, please try again later", + Toast.LENGTH_LONG + ).show() + } + ) + onResult.invoke() + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt index ad6b3cf5..e1aa80a0 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt @@ -9,7 +9,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack -import androidx.compose.material.icons.filled.Done import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme @@ -26,22 +25,22 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import com.brainwallet.R -import com.brainwallet.navigation.LegacyNavigation +import com.brainwallet.navigation.MoonPayWidgetLauncher +import com.brainwallet.navigation.MoonPayWidgetLauncherViewModel import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.LargeButton -import com.brainwallet.ui.composable.LoadingDialog -import com.brainwallet.ui.screens.home.receive.ReceiveDialogEvent import com.brainwallet.ui.theme.BrainwalletTheme -import org.koin.compose.koinInject +import org.koin.compose.viewmodel.koinViewModel //TODO: wip @Composable fun BuyLitecoinScreen( onNavigate: OnNavigate, - viewModel: BuyLitecoinViewModel = koinInject() + viewModel: BuyLitecoinViewModel = koinViewModel(), + moonPayWidgetLauncherViewModel: MoonPayWidgetLauncherViewModel = koinViewModel() ) { val state by viewModel.state.collectAsState() val loadingState by viewModel.loadingState.collectAsState() @@ -148,21 +147,20 @@ fun BuyLitecoinScreen( modifier = Modifier.align(Alignment.BottomCenter), enabled = loadingState.visible.not(), onClick = { - //open bread activity first then open moonpay widget - LegacyNavigation.restartBreadActivity(context) - LegacyNavigation.showMoonPayWidget( - context = context, + moonPayWidgetLauncherViewModel.launch( params = mapOf( "baseCurrencyCode" to appSetting.currency.code, "baseCurrencyAmount" to state.fiatAmount.toString(), "language" to appSetting.languageCode, "walletAddress" to state.address - ) + ), + ) } ) { Text(stringResource(R.string.buy_litecoin_button_moonpay)) } } + MoonPayWidgetLauncher(viewModel = moonPayWidgetLauncherViewModel) } } \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt index e96a1f2a..86389cea 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt @@ -63,7 +63,8 @@ import androidx.fragment.app.FragmentManager import com.brainwallet.R import com.brainwallet.data.model.getFormattedText import com.brainwallet.data.model.isCustom -import com.brainwallet.navigation.LegacyNavigation +import com.brainwallet.navigation.MoonPayWidgetLauncher +import com.brainwallet.navigation.MoonPayWidgetLauncherViewModel import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.composable.MoonpayBuyButton import com.brainwallet.ui.composable.VerticalWheelPicker @@ -77,13 +78,14 @@ import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import org.koin.android.ext.android.inject -import org.koin.compose.koinInject +import org.koin.compose.viewmodel.koinViewModel import timber.log.Timber @Composable fun ReceiveDialog( onDismissRequest: () -> Unit, - viewModel: ReceiveDialogViewModel = koinInject() + viewModel: ReceiveDialogViewModel = koinViewModel(), + moonPayWidgetLauncherViewModel: MoonPayWidgetLauncherViewModel = koinViewModel() ) { val state by viewModel.state.collectAsState() val loadingState by viewModel.loadingState.collectAsState() @@ -369,24 +371,23 @@ fun ReceiveDialog( //todo: revisit this later //viewModel.onEvent(ReceiveDialogEvent.OnMoonpayButtonClick) - LegacyNavigation.showMoonPayWidget( - context = context, + moonPayWidgetLauncherViewModel.launch( params = mapOf( "baseCurrencyCode" to state.selectedFiatCurrency.code, "baseCurrencyAmount" to state.fiatAmount.toString(), "language" to appSetting.languageCode, "walletAddress" to state.address, ), - isDarkMode = appSetting.isDarkMode ) - onDismissRequest.invoke() }, ) // } } - - + MoonPayWidgetLauncher( + viewModel = moonPayWidgetLauncherViewModel, + onResult = onDismissRequest + ) } } From e0aebb533ad39733b19ba992dad8e678175e7754 Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Mon, 25 Aug 2025 18:51:58 +0700 Subject: [PATCH 058/116] feat(#138): Improve Unlock Screen UI and add dark mode toggle (#122) --- app/build.gradle.kts | 3 + .../com/brainwallet/navigation/UiEffect.kt | 1 + .../com/brainwallet/tools/qrcode/QRUtils.java | 48 +- .../ui/composable/BrainWalletLogo.kt | 39 ++ .../ui/composable/DarkModeToggleButton.kt | 29 +- .../brainwallet/ui/composable/Foundation.kt | 2 + .../ui/composable/PasscodeIndicator.kt | 7 +- .../ui/screens/home/receive/ReceiveDialog.kt | 548 +++++++++--------- .../home/receive/ReceiveDialogFragment.kt | 66 +++ .../ui/screens/unlock/UnLockEvent.kt | 5 +- .../ui/screens/unlock/UnLockScreen.kt | 187 ++---- .../ui/screens/unlock/UnLockState.kt | 1 + .../ui/screens/unlock/UnLockViewModel.kt | 35 +- .../unlock/components/UnLockScreenBody.kt | 111 ++++ .../unlock/components/UnLockScreenFooter.kt | 89 +++ .../unlock/components/UnLockScreenHeader.kt | 51 ++ .../java/com/brainwallet/ui/theme/Theme.kt | 7 +- .../brainwallet/util/CurrencyDataGetter.kt | 41 ++ .../brainwallet/util/VersionCodeProvider.kt | 22 + .../brainwallet_logotype_color.webp | Bin 0 -> 13554 bytes .../brainwallet_logotype_color.webp | Bin 0 -> 5224 bytes .../brainwallet_logotype_color.webp | Bin 0 -> 7898 bytes .../brainwallet_logotype_color.webp | Bin 0 -> 20550 bytes .../brainwallet_logotype_color.webp | Bin 0 -> 35226 bytes .../brainwallet_logotype_color.webp | Bin 0 -> 56492 bytes app/src/main/res/drawable/ic_clickable_qr.xml | 9 + app/src/main/res/values/strings.xml | 2 +- .../ui/screens/unlock/UnLockViewModelTest.kt | 359 ++++++++++++ .../util/CurrencyDataGetterTest.kt | 125 ++++ .../brainwallet/util/MainDispatcherRule.kt | 23 + .../util/VersionCodeProviderTest.kt | 44 ++ gradle/libs.versions.toml | 5 + 32 files changed, 1429 insertions(+), 430 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt create mode 100644 app/src/main/java/com/brainwallet/util/CurrencyDataGetter.kt create mode 100644 app/src/main/java/com/brainwallet/util/VersionCodeProvider.kt create mode 100644 app/src/main/res/drawable-hdpi/brainwallet_logotype_color.webp create mode 100644 app/src/main/res/drawable-ldpi/brainwallet_logotype_color.webp create mode 100644 app/src/main/res/drawable-mdpi/brainwallet_logotype_color.webp create mode 100644 app/src/main/res/drawable-xhdpi/brainwallet_logotype_color.webp create mode 100644 app/src/main/res/drawable-xxhdpi/brainwallet_logotype_color.webp create mode 100644 app/src/main/res/drawable-xxxhdpi/brainwallet_logotype_color.webp create mode 100644 app/src/main/res/drawable/ic_clickable_qr.xml create mode 100644 app/src/test/java/com/brainwallet/ui/screens/unlock/UnLockViewModelTest.kt create mode 100644 app/src/test/java/com/brainwallet/util/CurrencyDataGetterTest.kt create mode 100644 app/src/test/java/com/brainwallet/util/MainDispatcherRule.kt create mode 100644 app/src/test/java/com/brainwallet/util/VersionCodeProviderTest.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 253c6aca..aac3d3e6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -220,6 +220,7 @@ dependencies { implementation(libs.bundles.google.play.feature.delivery) implementation(libs.bundles.google.play.review) implementation(libs.kotlinx.serialization.json) + implementation(libs.kotlinx.coroutines.android) implementation (libs.airbnb.lottie.compose) implementation(platform(libs.koin.bom)) implementation(libs.bundles.koin) @@ -243,6 +244,8 @@ dependencies { testImplementation(libs.junit) testImplementation(libs.mockk) + testImplementation(libs.turbine) + testImplementation(libs.kotlinx.coroutines.tests) androidTestImplementation(platform(libs.androidx.compose.bom)) androidTestImplementation(libs.bundles.androidx.compose.ui.test) diff --git a/app/src/main/java/com/brainwallet/navigation/UiEffect.kt b/app/src/main/java/com/brainwallet/navigation/UiEffect.kt index 4ac64282..6e28b2e5 100644 --- a/app/src/main/java/com/brainwallet/navigation/UiEffect.kt +++ b/app/src/main/java/com/brainwallet/navigation/UiEffect.kt @@ -19,6 +19,7 @@ sealed class UiEffect { } data class ShowDialog(val name: String): UiEffect() + data object ShowMoonPayDialog: UiEffect() data class ShowMessage( val message: String, diff --git a/app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java b/app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java index a0e9fd5f..d426ea80 100644 --- a/app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java +++ b/app/src/main/java/com/brainwallet/tools/qrcode/QRUtils.java @@ -7,6 +7,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.Color; import android.graphics.Point; import android.view.Display; import android.view.WindowManager; @@ -66,6 +67,51 @@ public static Bitmap encodeAsBitmap(String content, int dimension) { return bitmap; } + public static Bitmap encodeAsTransparentBitmap(String content, int dimension) { + if (content == null) { + return null; + } + + Map hints = new EnumMap<>(EncodeHintType.class); + String encoding = guessAppropriateEncoding(content); + if (encoding != null) { + hints.put(EncodeHintType.CHARACTER_SET, encoding); + } + hints.put(EncodeHintType.MARGIN, 1); + + BitMatrix result; + try { + result = new MultiFormatWriter().encode( + content, + BarcodeFormat.QR_CODE, + dimension, + dimension, + hints + ); + } catch (IllegalArgumentException | WriterException e) { + Timber.e(e); + return null; + } + + if (result == null) return null; + + int width = result.getWidth(); + int height = result.getHeight(); + int[] pixels = new int[width * height]; + + for (int y = 0; y < height; y++) { + int offset = y * width; + for (int x = 0; x < width; x++) { + // Black pixels stay black, white becomes transparent + pixels[offset + x] = result.get(x, y) ? Color.BLACK : Color.TRANSPARENT; + } + } + + Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + bitmap.setPixels(pixels, 0, width, 0, 0, width, height); + return bitmap; + } + public static boolean generateQR(Context ctx, String bitcoinURL, ImageView qrcode) { if (qrcode == null || bitcoinURL == null || bitcoinURL.isEmpty()) return false; WindowManager manager = (WindowManager) ctx.getSystemService(Activity.WINDOW_SERVICE); @@ -94,7 +140,7 @@ public static Bitmap generateQR(Context ctx, String litecoinUrl) { int smallerDimension = Math.min(width, height); smallerDimension = (int) (smallerDimension * 0.45f); Bitmap bitmap = null; - bitmap = QRUtils.encodeAsBitmap(litecoinUrl, smallerDimension); + bitmap = QRUtils.encodeAsTransparentBitmap(litecoinUrl, smallerDimension); return bitmap; } diff --git a/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt b/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt new file mode 100644 index 00000000..b22a053c --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt @@ -0,0 +1,39 @@ +package com.brainwallet.ui.composable + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import com.brainwallet.R +import com.brainwallet.data.model.AppSetting +import com.brainwallet.ui.theme.BrainwalletAppTheme +import com.brainwallet.ui.theme.BrainwalletTheme +import com.brainwallet.ui.theme.LocalDarkModeFlag + +@Composable +fun BrainWalletLogo(modifier: Modifier = Modifier) { + val iconLogo = if (LocalDarkModeFlag.current) { + R.drawable.brainwallet_logotype_white + } else { + R.drawable.brainwallet_logotype_color + } + Image( + painterResource(iconLogo), + contentDescription = "brainwallet_logo", + modifier = modifier + ) +} + +@PreviewLightDark +@Composable +private fun BrainWalletLogoPreview() { + BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) { + Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) { + BrainWalletLogo() + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt index 05b89e53..2a9688d5 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt @@ -1,10 +1,12 @@ package com.brainwallet.ui.composable + import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Icon import androidx.compose.material3.IconToggleButton @@ -14,8 +16,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import com.brainwallet.R +import com.brainwallet.data.model.AppSetting +import com.brainwallet.ui.theme.BrainwalletAppTheme import com.brainwallet.ui.theme.BrainwalletTheme @Composable @@ -23,18 +28,17 @@ fun DarkModeToggleButton( checked: Boolean, onCheckedChange: (Boolean) -> Unit, modifier: Modifier = Modifier, + iconButtonSizeInDp: Int = 32 ) { - val iconButtonSize = 32 - IconToggleButton( checked = checked, onCheckedChange = onCheckedChange, - modifier = modifier, + modifier = modifier.size(iconButtonSizeInDp.dp), ) { Box( modifier = Modifier .fillMaxSize() - .width(iconButtonSize.dp) + .size(iconButtonSizeInDp.dp) .aspectRatio(1f) .clip(CircleShape) .border( @@ -47,12 +51,21 @@ fun DarkModeToggleButton( Icon( modifier = Modifier .align(Alignment.Center) - .width(iconButtonSize.dp) - .aspectRatio(1f), + .size((iconButtonSizeInDp * 0.6).dp), tint = if (checked) BrainwalletTheme.colors.warn else BrainwalletTheme.colors.surface, painter = painterResource(if (checked) R.drawable.ic_light_mode else R.drawable.ic_dark_mode), contentDescription = stringResource(R.string.toggle_dark_mode), ) } } -} \ No newline at end of file +} + +@PreviewLightDark +@Composable +private fun DarkModeToggleButtonPreview() { + BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) { + Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) { + DarkModeToggleButton(checked = isSystemInDarkTheme(), onCheckedChange = {}, ) + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt index f72137f5..16f92a0e 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt @@ -27,6 +27,7 @@ import com.brainwallet.ui.theme.BrainwalletTheme fun BrainwalletScaffold( modifier: Modifier = Modifier, topBar: @Composable () -> Unit = {}, + bottomBar: @Composable () -> Unit = {}, floatingActionButton: @Composable () -> Unit = {}, content: @Composable (PaddingValues) -> Unit ) { @@ -35,6 +36,7 @@ fun BrainwalletScaffold( containerColor = BrainwalletTheme.colors.surface, contentColor = BrainwalletTheme.colors.content, topBar = topBar, + bottomBar = bottomBar, floatingActionButton = floatingActionButton, content = content ) diff --git a/app/src/main/java/com/brainwallet/ui/composable/PasscodeIndicator.kt b/app/src/main/java/com/brainwallet/ui/composable/PasscodeIndicator.kt index 32aead18..9837d962 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PasscodeIndicator.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/PasscodeIndicator.kt @@ -3,17 +3,20 @@ package com.brainwallet.ui.composable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @Composable fun PasscodeIndicator( - passcode: List + passcode: List, + modifier: Modifier = Modifier, ) { Row( + modifier = modifier, horizontalArrangement = Arrangement.spacedBy(12.dp) ) { passcode.forEach { digit -> PinDotItem(checked = digit > -1) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt index 86389cea..64f7446e 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt @@ -2,15 +2,12 @@ package com.brainwallet.ui.screens.home.receive -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup import android.widget.Toast import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -49,26 +46,28 @@ import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.asImageBitmap -import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp -import androidx.fragment.app.DialogFragment -import androidx.fragment.app.FragmentManager import com.brainwallet.R +import com.brainwallet.data.model.AppSetting import com.brainwallet.data.model.getFormattedText import com.brainwallet.data.model.isCustom import com.brainwallet.navigation.MoonPayWidgetLauncher import com.brainwallet.navigation.MoonPayWidgetLauncherViewModel import com.brainwallet.navigation.UiEffect +import com.brainwallet.ui.LoadingState import com.brainwallet.ui.composable.MoonpayBuyButton import com.brainwallet.ui.composable.VerticalWheelPicker import com.brainwallet.ui.composable.WheelPickerFocusVertical +import com.brainwallet.ui.composable.WheelPickerState import com.brainwallet.ui.composable.rememberWheelPickerState import com.brainwallet.ui.theme.BrainwalletAppTheme import com.brainwallet.ui.theme.BrainwalletTheme @@ -77,13 +76,13 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter -import org.koin.android.ext.android.inject import org.koin.compose.viewmodel.koinViewModel import timber.log.Timber @Composable fun ReceiveDialog( onDismissRequest: () -> Unit, + modifier: Modifier = Modifier, viewModel: ReceiveDialogViewModel = koinViewModel(), moonPayWidgetLauncherViewModel: MoonPayWidgetLauncherViewModel = koinViewModel() ) { @@ -123,52 +122,94 @@ fun ReceiveDialog( viewModel.onEvent(ReceiveDialogEvent.OnFiatCurrencyChange(state.fiatCurrencies[it])) } } + ReceiveDialog( + state = state, + loadingState = loadingState, + modifier = modifier, + appSetting = appSetting, + wheelPickerFiatCurrencyState = wheelPickerFiatCurrencyState, + onDismissRequest = onDismissRequest, + onMoonPayLaunch = moonPayWidgetLauncherViewModel::launch, + onEvent = viewModel::onEvent + ) + MoonPayWidgetLauncher( + viewModel = moonPayWidgetLauncherViewModel, + onResult = onDismissRequest + ) +} - Column( - modifier = Modifier - .verticalScroll(rememberScrollState()) - .fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally - ) { - CenterAlignedTopAppBar( - colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = BrainwalletTheme.colors.content //invert surface +@Composable +private fun ReceiveDialog( + state: ReceiveDialogState, + modifier: Modifier = Modifier, + appSetting: AppSetting = AppSetting(), + loadingState: LoadingState = LoadingState(), + wheelPickerFiatCurrencyState: WheelPickerState = rememberWheelPickerState(0), + onDismissRequest: () -> Unit = {}, + onMoonPayLaunch: (Map) -> Unit = {}, + onEvent: (ReceiveDialogEvent) -> Unit = {} +) { + val context = LocalContext.current + Box( + modifier = modifier + .background( + BrainwalletTheme.colors.content, + shape = BrainwalletTheme.shapes.large + ) + .border( + width = 1.dp, + color = BrainwalletTheme.colors.surface, + shape = BrainwalletTheme.shapes.large ), - expandedHeight = 56.dp, - title = { - Text( - text = stringResource(R.string.bottom_nav_item_buy_receive_title).uppercase(), - style = BrainwalletTheme.typography.titleSmall - ) - }, - navigationIcon = { - if (state.moonpayWidgetVisible()) { - IconButton(onClick = { - viewModel.onEvent(ReceiveDialogEvent.OnSignedUrlClear) - }) { + ) { + Column( + modifier = Modifier + .padding(12.dp) + .verticalScroll(rememberScrollState()) + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + CenterAlignedTopAppBar( + colors = TopAppBarDefaults.centerAlignedTopAppBarColors( + containerColor = BrainwalletTheme.colors.content //invert surface + ), + expandedHeight = 56.dp, + title = { + Text( + text = stringResource(R.string.bottom_nav_item_buy_receive_title).uppercase(), + style = BrainwalletTheme.typography.titleSmall.copy( + color = BrainwalletTheme.colors.surface + ) + ) + }, + navigationIcon = { + if (state.moonpayWidgetVisible()) { + IconButton(onClick = { + onEvent(ReceiveDialogEvent.OnSignedUrlClear) + }) { + Icon( + Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = stringResource(R.string.back) + ) + } + } + }, + actions = { + IconButton( + modifier = Modifier.testTag("buttonClose"), + onClick = onDismissRequest + ) { Icon( - Icons.AutoMirrored.Filled.ArrowBack, - contentDescription = stringResource(R.string.back) + Icons.Default.Close, + contentDescription = stringResource(R.string.AccessibilityLabels_close), + tint = BrainwalletTheme.colors.surface ) } } - }, - actions = { - IconButton( - modifier = Modifier.testTag("buttonClose"), - onClick = onDismissRequest - ) { - Icon( - Icons.Default.Close, - contentDescription = stringResource(R.string.AccessibilityLabels_close), - tint = BrainwalletTheme.colors.surface - ) - } - } - ) + ) - //moonpay widget - //todo: revisit this later + //moonpay widget + //todo: revisit this later // AnimatedVisibility(visible = state.moonpayWidgetVisible()) { // state.moonpayBuySignedUrl?.let { signedUrl -> // MoonpayBuyWidget( @@ -179,278 +220,227 @@ fun ReceiveDialog( // } - //buy / receive + //buy / receive // AnimatedVisibility(visible = state.moonpayWidgetVisible().not()) { - Column { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically - ) { - state.qrBitmap?.asImageBitmap()?.let { imageBitmap -> - Image( + Column { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + state.qrBitmap?.asImageBitmap()?.let { imageBitmap -> + Image( + modifier = Modifier + .weight(1f), + bitmap = imageBitmap, + contentDescription = "address", + colorFilter = ColorFilter.tint(BrainwalletTheme.colors.surface) + ) + } ?: Box( modifier = Modifier - .weight(1f), - bitmap = imageBitmap, - contentDescription = "address" + .weight(1f) + .height(180.dp) + .background(Color.Gray) ) - } ?: Box( - modifier = Modifier - .weight(1f) - .height(180.dp) - .background(Color.Gray) - ) - Column( - modifier = Modifier - .weight(1f), - verticalArrangement = Arrangement.spacedBy(8.dp) - ) { - Text( - text = state.address, - style = BrainwalletTheme.typography.bodyLarge.copy( - fontWeight = FontWeight.Bold, - color = BrainwalletTheme.colors.surface - ), - maxLines = 4, - overflow = TextOverflow.Ellipsis - ) - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(4.dp) + Column( + modifier = Modifier + .weight(1f), + verticalArrangement = Arrangement.spacedBy(8.dp) ) { Text( - text = stringResource(R.string.new_address).uppercase(), - style = BrainwalletTheme.typography.bodySmall.copy( - color = BrainwalletTheme.colors.surface, + text = state.address, + style = BrainwalletTheme.typography.bodyLarge.copy( + fontWeight = FontWeight.Bold, + color = BrainwalletTheme.colors.surface ), - modifier = Modifier.weight(1f) + maxLines = 4, + overflow = TextOverflow.Ellipsis ) - OutlinedIconButton( - modifier = Modifier.size(32.dp), - onClick = { - viewModel.onEvent(ReceiveDialogEvent.OnCopyClick(context)) - Toast.makeText( - context, - R.string.Receive_copied, - Toast.LENGTH_SHORT - ) - .show() - }, - colors = IconButtonDefaults.outlinedIconButtonColors( - containerColor = BrainwalletTheme.colors.content.copy(alpha = 0.5f) - ), + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(4.dp) ) { - Icon( - painter = androidx.compose.ui.res.painterResource(id = R.drawable.ic_copy), - contentDescription = stringResource(R.string.URLHandling_copy), - tint = BrainwalletTheme.colors.surface + Text( + text = stringResource(R.string.new_address).uppercase(), + style = BrainwalletTheme.typography.bodySmall.copy( + color = BrainwalletTheme.colors.surface, + ), + modifier = Modifier.weight(1f) ) + OutlinedIconButton( + modifier = Modifier.size(32.dp), + onClick = { + onEvent(ReceiveDialogEvent.OnCopyClick(context)) + Toast.makeText( + context, + R.string.Receive_copied, + Toast.LENGTH_SHORT + ) + .show() + }, + colors = IconButtonDefaults.outlinedIconButtonColors( + containerColor = BrainwalletTheme.colors.content.copy(alpha = 0.5f) + ), + ) { + Icon( + painter = androidx.compose.ui.res.painterResource(id = R.drawable.ic_copy), + contentDescription = stringResource(R.string.URLHandling_copy), + tint = BrainwalletTheme.colors.surface + ) + } } } } - } - HorizontalDivider() + HorizontalDivider() - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center - ) { - VerticalWheelPicker( - modifier = Modifier.weight(1f), - focus = { - WheelPickerFocusVertical( - dividerColor = BrainwalletTheme.colors.surface.copy( - alpha = 0.5f - ) - ) - }, - unfocusedCount = 1, - count = state.fiatCurrencies.size, - state = wheelPickerFiatCurrencyState, - ) { index -> - Text( - text = state.fiatCurrencies[index].code, - fontWeight = FontWeight.Bold, - color = BrainwalletTheme.colors.surface - ) - } - - Column( - modifier = Modifier.weight(1f), - horizontalAlignment = Alignment.CenterHorizontally + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center ) { - Text( - text = state.getLtcAmountFormatted(loadingState.visible), - style = BrainwalletTheme.typography.titleLarge.copy( + VerticalWheelPicker( + modifier = Modifier.weight(1f), + focus = { + WheelPickerFocusVertical( + dividerColor = BrainwalletTheme.colors.surface.copy( + alpha = 0.5f + ) + ) + }, + unfocusedCount = 1, + count = state.fiatCurrencies.size, + state = wheelPickerFiatCurrencyState, + ) { index -> + Text( + text = state.fiatCurrencies[index].code, fontWeight = FontWeight.Bold, color = BrainwalletTheme.colors.surface ) - ) - Text( - text = state.getRatesUpdatedAtFormatted(), - style = BrainwalletTheme.typography.bodySmall.copy( - color = BrainwalletTheme.colors.surface + } + + Column( + modifier = Modifier.weight(1f), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + text = state.getLtcAmountFormatted(loadingState.visible), + style = BrainwalletTheme.typography.titleLarge.copy( + fontWeight = FontWeight.Bold, + color = BrainwalletTheme.colors.surface + ) ) - ) + Text( + text = state.getRatesUpdatedAtFormatted(), + style = BrainwalletTheme.typography.bodySmall.copy( + color = BrainwalletTheme.colors.surface + ) + ) + } } - } - LazyRow( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(8.dp) - ) { - itemsIndexed(items = state.getQuickFiatAmountOptions()) { index, quickFiatAmountOption -> - AssistChip( - enabled = loadingState.visible.not(), - onClick = { - viewModel.onEvent( - ReceiveDialogEvent.OnFiatAmountOptionIndexChange( - index, - quickFiatAmountOption + LazyRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(8.dp) + ) { + itemsIndexed(items = state.getQuickFiatAmountOptions()) { index, quickFiatAmountOption -> + AssistChip( + enabled = loadingState.visible.not(), + onClick = { + onEvent( + ReceiveDialogEvent.OnFiatAmountOptionIndexChange( + index, + quickFiatAmountOption + ) ) - ) - }, - label = { + }, + label = { + Text( + text = if (quickFiatAmountOption.isCustom()) + stringResource(R.string.custom) + else quickFiatAmountOption.getFormattedText(), + style = BrainwalletTheme.typography.bodyMedium.copy( + color = BrainwalletTheme.colors.surface + ) + ) + }, + leadingIcon = { + if (index == state.selectedQuickFiatAmountOptionIndex) { + Icon(Icons.Default.Check, contentDescription = null) + } + } + ) + } + } + + + AnimatedVisibility(visible = state.isQuickFiatAmountOptionCustom()) { + OutlinedTextField( + modifier = Modifier.fillMaxWidth(), + prefix = { Text( - text = if (quickFiatAmountOption.isCustom()) - stringResource(R.string.custom) - else quickFiatAmountOption.getFormattedText() + text = state.selectedFiatCurrency.symbol, + style = BrainwalletTheme.typography.bodyMedium.copy(color = BrainwalletTheme.colors.surface) ) }, - leadingIcon = { - if (index == state.selectedQuickFiatAmountOptionIndex) { - Icon(Icons.Default.Check, contentDescription = null) + trailingIcon = { + IconButton(onClick = { + onEvent(ReceiveDialogEvent.OnFiatAmountChange(state.fiatAmount)) + }) { + Icon(Icons.Default.Done, contentDescription = null) + } + }, + textStyle = BrainwalletTheme.typography.bodyMedium.copy(color = BrainwalletTheme.colors.surface), + value = "${if (state.fiatAmount < 1) "" else state.fiatAmount}", + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), + onValueChange = { input -> + val amount = input.toFloatOrNull() ?: 0f + onEvent(ReceiveDialogEvent.OnFiatAmountChange(amount, false)) + }, + shape = BrainwalletTheme.shapes.large, + isError = state.errorFiatAmountStringId != null, + supportingText = { + state.errorFiatAmountStringId?.let { + Text(stringResource(it, state.fiatAmount)) } } ) } - } - - AnimatedVisibility(visible = state.isQuickFiatAmountOptionCustom()) { - OutlinedTextField( + MoonpayBuyButton( modifier = Modifier.fillMaxWidth(), - prefix = { - Text( - text = state.selectedFiatCurrency.symbol, - style = BrainwalletTheme.typography.bodyMedium.copy(color = BrainwalletTheme.colors.surface) + enabled = loadingState.visible.not(), + onClick = { + + //todo: revisit this later + //viewModel.onEvent(ReceiveDialogEvent.OnMoonpayButtonClick) + onMoonPayLaunch( + mapOf( + "baseCurrencyCode" to state.selectedFiatCurrency.code, + "baseCurrencyAmount" to state.fiatAmount.toString(), + "language" to appSetting.languageCode, + "walletAddress" to state.address, + ) ) }, - trailingIcon = { - IconButton(onClick = { - viewModel.onEvent(ReceiveDialogEvent.OnFiatAmountChange(state.fiatAmount)) - }) { - Icon(Icons.Default.Done, contentDescription = null) - } - }, - textStyle = BrainwalletTheme.typography.bodyMedium.copy(color = BrainwalletTheme.colors.surface), - value = "${if (state.fiatAmount < 1) "" else state.fiatAmount}", - singleLine = true, - keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), - onValueChange = { input -> - val amount = input.toFloatOrNull() ?: 0f - viewModel.onEvent(ReceiveDialogEvent.OnFiatAmountChange(amount, false)) - }, - shape = BrainwalletTheme.shapes.large, - isError = state.errorFiatAmountStringId != null, - supportingText = { - state.errorFiatAmountStringId?.let { - Text(stringResource(it, state.fiatAmount)) - } - } ) - } - - MoonpayBuyButton( - modifier = Modifier.fillMaxWidth(), - enabled = loadingState.visible.not(), - onClick = { - - //todo: revisit this later - //viewModel.onEvent(ReceiveDialogEvent.OnMoonpayButtonClick) - - moonPayWidgetLauncherViewModel.launch( - params = mapOf( - "baseCurrencyCode" to state.selectedFiatCurrency.code, - "baseCurrencyAmount" to state.fiatAmount.toString(), - "language" to appSetting.languageCode, - "walletAddress" to state.address, - ), - ) - }, - ) // } - } - MoonPayWidgetLauncher( - viewModel = moonPayWidgetLauncherViewModel, - onResult = onDismissRequest - ) - } -} - -/** - * describe [ReceiveDialogFragment] for backward compat, - * since we are still using [com.brainwallet.presenter.activities.BreadActivity] - */ -class ReceiveDialogFragment : DialogFragment() { - - private val viewModel: ReceiveDialogViewModel by inject() - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return ComposeView(requireContext()).apply { - setContent { - val appSetting by viewModel.appSetting.collectAsState() - /** - * we need this theme inside this fragment, - * because we are still using fragment to display ReceiveDialog composable - * pls check BreadActivity.handleNavigationItemSelected - */ - BrainwalletAppTheme(appSetting = appSetting) { - Box( - modifier = Modifier - .padding(12.dp) - .background( - BrainwalletTheme.colors.content, - shape = BrainwalletTheme.shapes.large - ) - .border( - width = 1.dp, - color = BrainwalletTheme.colors.surface, - shape = BrainwalletTheme.shapes.large - ) - .padding(12.dp), - ) { - ReceiveDialog( - viewModel = viewModel, - onDismissRequest = { dismiss() } - ) - } - } } } } +} - override fun onStart() { - super.onStart() - dialog?.window?.setLayout( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT +@PreviewLightDark +@Composable +private fun ReceiveDialogPreview() { + val appSetting = AppSetting(isDarkMode = isSystemInDarkTheme()) + BrainwalletAppTheme(appSetting) { + ReceiveDialog( + modifier = Modifier.padding(12.dp), + state = ReceiveDialogState(), + appSetting = appSetting ) - dialog?.window?.setBackgroundDrawableResource(android.R.color.transparent) - isCancelable = false } - - companion object { - @JvmStatic - fun show(manager: FragmentManager) { - ReceiveDialogFragment().show(manager, "ReceiveDialogFragment") - } - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt new file mode 100644 index 00000000..6cfb2a19 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt @@ -0,0 +1,66 @@ +package com.brainwallet.ui.screens.home.receive + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ComposeView +import androidx.compose.ui.unit.dp +import androidx.fragment.app.DialogFragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.viewModels +import com.brainwallet.ui.theme.BrainwalletAppTheme +import org.koin.compose.viewmodel.koinViewModel + +/** + * describe [ReceiveDialogFragment] for backward compat, + * since we are still using [com.brainwallet.presenter.activities.BreadActivity] + */ +class ReceiveDialogFragment : DialogFragment() { + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return ComposeView(requireContext()).apply { + setContent { + val viewModel = koinViewModel() + val appSetting by viewModel.appSetting.collectAsState() + /** + * we need this theme inside this fragment, + * because we are still using fragment to display ReceiveDialog composable + * pls check BreadActivity.handleNavigationItemSelected + */ + BrainwalletAppTheme(appSetting = appSetting) { + ReceiveDialog( + modifier = Modifier.padding(12.dp), + viewModel = viewModel, + onDismissRequest = { dismiss() } + ) + } + } + } + } + + override fun onStart() { + super.onStart() + dialog?.window?.setLayout( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) + dialog?.window?.setBackgroundDrawableResource(android.R.color.transparent) + isCancelable = false + } + + companion object { + @JvmStatic + fun show(manager: FragmentManager) { + ReceiveDialogFragment().show(manager, "ReceiveDialogFragment") + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt index c83406f9..bd090257 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt @@ -1,16 +1,15 @@ package com.brainwallet.ui.screens.unlock -import android.content.Context - sealed class UnLockEvent { data class OnLoad( - val context: Context, val isUpdatePin: Boolean = false, ) : UnLockEvent() data class OnPinDigitChange( val digit: Int, val isValidPin: (String) -> Boolean ) : UnLockEvent() + object OnToggleDarkMode : UnLockEvent() + object OnQrClicked : UnLockEvent() object OnDeletePinDigit : UnLockEvent() } diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt index 0ea4da7e..204716e8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt @@ -2,168 +2,105 @@ package com.brainwallet.ui.screens.unlock - -import android.widget.Toast -import androidx.compose.foundation.Image +import androidx.activity.ComponentActivity +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp +import androidx.fragment.app.FragmentActivity import com.brainwallet.R +import com.brainwallet.data.model.AppSetting import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.UiEffect -import com.brainwallet.tools.manager.AnalyticsManager -import com.brainwallet.tools.security.AuthManager -import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.composable.BrainwalletScaffold -import com.brainwallet.ui.composable.BrainwalletTopAppBar -import com.brainwallet.ui.composable.PasscodeIndicator -import com.brainwallet.ui.composable.PasscodeKeypad -import com.brainwallet.ui.composable.PasscodeKeypadEvent -import com.brainwallet.ui.theme.BrainwalletTheme -import org.koin.compose.koinInject +import com.brainwallet.ui.screens.home.receive.ReceiveDialogFragment +import com.brainwallet.ui.screens.unlock.components.UnLockScreenBody +import com.brainwallet.ui.screens.unlock.components.UnLockScreenFooter +import com.brainwallet.ui.screens.unlock.components.UnLockScreenHeader +import com.brainwallet.ui.theme.BrainwalletAppTheme +import org.koin.compose.viewmodel.koinViewModel @Composable fun UnLockScreen( onNavigate: OnNavigate, + modifier: Modifier = Modifier, isUpdatePin: Boolean = false, - viewModel: UnLockViewModel = koinInject() + viewModel: UnLockViewModel = koinViewModel() ) { - val state by viewModel.state.collectAsState() - val context = LocalContext.current - + val fragmentManager = (LocalContext.current as? FragmentActivity)?.supportFragmentManager + val uiState by viewModel.state.collectAsState() LaunchedEffect(Unit) { - viewModel.onEvent(UnLockEvent.OnLoad(context, isUpdatePin)) + viewModel.onEvent(UnLockEvent.OnLoad(isUpdatePin)) viewModel.uiEffect.collect { effect -> when (effect) { is UiEffect.Navigate -> onNavigate.invoke(effect) + is UiEffect.ShowMoonPayDialog -> fragmentManager?.let { + ReceiveDialogFragment.show(it) + } else -> Unit } } } + UnLockScreen(uiState = uiState, modifier = modifier, onEvent = viewModel::onEvent) +} - LaunchedEffect(state.passcode.all { it > -1 }) { +@Composable +private fun UnLockScreen( + uiState: UnLockState, + modifier: Modifier = Modifier, + onEvent: (UnLockEvent) -> Unit = {}, +) { + LaunchedEffect(uiState.passcode.all { it > -1 }) { // } - - /// Layout values - val columnPadding = 18 val horizontalVerticalSpacing = 8 - BrainwalletScaffold( + modifier = modifier, topBar = { - BrainwalletTopAppBar( - navigationIcon = { - /// No-op Retained spacing for remote banner - }) - } - ) { paddingValues -> - Column( - modifier = Modifier - .padding(paddingValues) - .padding(columnPadding.dp) - .fillMaxSize() - .verticalScroll(rememberScrollState()), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), - ) { - - Image( - modifier = Modifier - .fillMaxWidth(0.80f) - .padding(horizontalVerticalSpacing.dp), - painter = painterResource(R.drawable.brainwallet_logotype_white), - contentDescription = stringResource(R.string.logo), - colorFilter = ColorFilter.tint( - BrainwalletTheme.colors.content, + UnLockScreenHeader( + modifier = Modifier.padding(16.dp), + formattedLtcPrice = stringResource( + R.string.Login_ltcPrice, + uiState.formattedCurrency ), ) - Spacer(modifier = Modifier.weight(1f)) - - if (state.isUpdatePin) { - Text(stringResource(R.string.UpdatePin_enterCurrent)) - } else { - Text(stringResource(R.string.Login_ltcPrice, state.formattedCurrency)) - Text(stringResource(R.string.Login_currentLtcPrice, state.iso)) - } - - // TODO - // https://developer.android.com/develop/ui/compose/animation/customize - // Box( - // modifier = Modifier - // .fillMaxWidth() - // .height(100.dp) - // .background(Color.White) - // ) { - // //todo - // Text("todo") - // } - - Spacer(modifier = Modifier.weight(1f)) - - PasscodeIndicator(passcode = state.passcode) - - Spacer(Modifier.height(16.dp)) - - PasscodeKeypad { passcodeKeypadEvent -> - when (passcodeKeypadEvent) { - PasscodeKeypadEvent.OnDelete -> viewModel.onEvent(UnLockEvent.OnDeletePinDigit) - is PasscodeKeypadEvent.OnPressed -> viewModel.onEvent( - UnLockEvent.OnPinDigitChange( - digit = passcodeKeypadEvent.digit, - isValidPin = { pin -> - - //provide old logic here, its like on the BrainwalletActivity.onUnlock - return@OnPinDigitChange AuthManager.getInstance() - .checkAuth(pin, context).also { isValid -> - if (isValid) { - AuthManager.getInstance().authSuccess(context) - AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) - AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) - - } else { - AuthManager.getInstance().authFail(context) - //for now just toast - Toast.makeText( - context, - R.string.incorrect_passcode, - Toast.LENGTH_SHORT - ).show() - } - } - } - ) - ) - } - } - - Spacer(modifier = Modifier.weight(1f)) - - //app version - Text( - text = BRConstants.APP_VERSION_NAME_CODE, - style = MaterialTheme.typography.bodyMedium.copy(textAlign = TextAlign.Center) + }, + bottomBar = { + UnLockScreenFooter( + uiState.formattedVersion, + modifier = Modifier.padding(bottom = 26.dp), + onEvent = onEvent ) } + ) { paddingValues -> + UnLockScreenBody( + passcode = uiState.passcode, + isUpdatePin = uiState.isUpdatePin, + verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), + modifier = Modifier.padding(paddingValues) + .padding(top = 16.dp), + onEvent = onEvent + ) + } +} + +@PreviewLightDark +@Composable +private fun UnLockScreenPreview() { + BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) { + UnLockScreen(uiState = UnLockState( + isUpdatePin = true, + formattedCurrency = "$90.00", + formattedVersion = "v4.0.0 (202501201)" + )) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockState.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockState.kt index ff12dab1..7483e3ab 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockState.kt @@ -6,6 +6,7 @@ data class UnLockState( val iso: String = "USD", val formattedCurrency: String = "", val isUpdatePin: Boolean = false, + val formattedVersion: String = "" ) fun UnLockState.isPasscodeFilled(): Boolean = passcode.all { it > -1 } diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt index 30e3274a..0405c4ba 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt @@ -1,17 +1,18 @@ package com.brainwallet.ui.screens.unlock import androidx.lifecycle.viewModelScope +import com.brainwallet.data.repository.SettingRepository import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect -import com.brainwallet.tools.manager.BRSharedPrefs -import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.tools.util.BRConstants -import com.brainwallet.tools.util.BRCurrency import com.brainwallet.ui.BrainwalletViewModel +import com.brainwallet.util.CurrencyDataGetter import com.brainwallet.util.EventBus +import com.brainwallet.util.VersionCodeProvider import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch @@ -20,9 +21,14 @@ import timber.log.Timber import java.math.BigDecimal @KoinViewModel -class UnLockViewModel : BrainwalletViewModel() { +class UnLockViewModel( + versionCodeProvider: VersionCodeProvider, + private val settingRepository: SettingRepository, + private val currencyDataGetter: CurrencyDataGetter +) : BrainwalletViewModel() { - private val _state = MutableStateFlow(UnLockState()) + private val _state = + MutableStateFlow(UnLockState(formattedVersion = versionCodeProvider.getFormatted())) val state: StateFlow = _state.asStateFlow() override fun onEvent(event: UnLockEvent) { @@ -73,17 +79,16 @@ class UnLockViewModel : BrainwalletViewModel() { } is UnLockEvent.OnLoad -> { - val iso = BRSharedPrefs.getIsoSymbol(event.context) + val iso = currencyDataGetter.getIsoSymbol() var formattedCurrency: String? = null - val currency = CurrencyDataSource.getInstance(event.context).getCurrencyByIso(iso) + val currency = currencyDataGetter.getCurrencyByIso(iso) if (currency != null) { val roundedPriceAmount: BigDecimal = BigDecimal(currency.rate.toDouble()).multiply(BigDecimal(100)) .divide(BigDecimal(100), 2, BRConstants.ROUNDING_MODE) formattedCurrency = - BRCurrency.getFormattedCurrencyString( - event.context, + currencyDataGetter.getFormattedCurrencyString( iso, roundedPriceAmount ) @@ -102,6 +107,16 @@ class UnLockViewModel : BrainwalletViewModel() { } } } + + UnLockEvent.OnToggleDarkMode -> viewModelScope.launch { + settingRepository.settings.firstOrNull()?.let { + settingRepository.save( + it.copy(isDarkMode = it.isDarkMode.not()) + ) + } + } + + UnLockEvent.OnQrClicked -> sendUiEffect(UiEffect.ShowMoonPayDialog) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt new file mode 100644 index 00000000..cdf2f09c --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt @@ -0,0 +1,111 @@ +package com.brainwallet.ui.screens.unlock.components + +import android.widget.Toast +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import com.brainwallet.R +import com.brainwallet.data.model.AppSetting +import com.brainwallet.tools.manager.AnalyticsManager +import com.brainwallet.tools.security.AuthManager +import com.brainwallet.tools.util.BRConstants +import com.brainwallet.ui.composable.PasscodeIndicator +import com.brainwallet.ui.composable.PasscodeKeypad +import com.brainwallet.ui.composable.PasscodeKeypadEvent +import com.brainwallet.ui.screens.unlock.UnLockEvent +import com.brainwallet.ui.theme.BrainwalletAppTheme +import com.brainwallet.ui.theme.BrainwalletTheme +import com.google.common.collect.ImmutableList + +@Composable +fun UnLockScreenBody( + passcode: List, + isUpdatePin: Boolean, + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Center, + onEvent: (UnLockEvent) -> Unit = {} +) { + val context = LocalContext.current + Column( + modifier = modifier + .padding(18.dp) + .fillMaxSize() + .verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = verticalArrangement, + ) { + AnimatedVisibility(isUpdatePin) { + Text( + stringResource(R.string.UpdatePin_enterCurrent), + modifier = Modifier + ) + } + Spacer(modifier = Modifier.weight(1f)) + PasscodeIndicator(passcode = passcode, modifier = Modifier) + Spacer(modifier = Modifier.weight(1f)) + PasscodeKeypad { passcodeKeypadEvent -> + when (passcodeKeypadEvent) { + PasscodeKeypadEvent.OnDelete -> onEvent(UnLockEvent.OnDeletePinDigit) + is PasscodeKeypadEvent.OnPressed -> onEvent( + UnLockEvent.OnPinDigitChange( + digit = passcodeKeypadEvent.digit, + isValidPin = { pin -> + + //provide old logic here, its like on the BrainwalletActivity.onUnlock + return@OnPinDigitChange AuthManager.getInstance() + .checkAuth(pin, context).also { isValid -> + if (isValid) { + AuthManager.getInstance().authSuccess(context) + AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) + AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) + + } else { + AuthManager.getInstance().authFail(context) + //for now just toast + Toast.makeText( + context, + R.string.incorrect_passcode, + Toast.LENGTH_SHORT + ).show() + } + } + } + ) + ) + } + } + Spacer(modifier = Modifier.weight(1f)) + } +} + +@PreviewLightDark +@Composable +private fun UnLockScreenBodyPreview() { + BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) { + Box( + modifier = Modifier + .background(BrainwalletTheme.colors.background) + .fillMaxWidth() + ) { + UnLockScreenBody(isUpdatePin = true, passcode = ImmutableList.of(1, 2)) + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt new file mode 100644 index 00000000..733f2068 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt @@ -0,0 +1,89 @@ +package com.brainwallet.ui.screens.unlock.components + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import com.brainwallet.R +import com.brainwallet.data.model.AppSetting +import com.brainwallet.ui.composable.DarkModeToggleButton +import com.brainwallet.ui.screens.unlock.UnLockEvent +import com.brainwallet.ui.theme.BrainwalletAppTheme +import com.brainwallet.ui.theme.BrainwalletTheme +import com.brainwallet.ui.theme.LocalDarkModeFlag + +@Composable +fun UnLockScreenFooter( + version: String, + modifier: Modifier = Modifier, + onEvent: (UnLockEvent) -> Unit = {} +) { + Column( + modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Row(modifier = Modifier + .padding(bottom = 24.dp) + .padding(horizontal = 85.dp)) { + DarkModeToggleButton( + checked = LocalDarkModeFlag.current, + onCheckedChange = { + onEvent(UnLockEvent.OnToggleDarkMode) + }, + iconButtonSizeInDp = 43 + ) + Spacer(modifier = Modifier.weight(1f)) + Image( + painterResource(R.drawable.ic_clickable_qr), + contentDescription = "clickable_qr", + modifier = Modifier.size(39.dp).clickable { + onEvent(UnLockEvent.OnQrClicked) + }, + colorFilter = ColorFilter.tint( + BrainwalletTheme.colors.border + ) + ) + } + Text( + version, + modifier = Modifier.fillMaxWidth(), + style = MaterialTheme.typography + .bodyMedium + .copy( + textAlign = TextAlign.Center, + color = BrainwalletTheme.colors.border + ) + ) + } +} + +@PreviewLightDark +@Composable +private fun UnLockScreenFooterPreview() { + BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) { + Box( + modifier = Modifier + .background(BrainwalletTheme.colors.background) + .fillMaxWidth() + ) { + UnLockScreenFooter(version = "v4.0.0 (202501201)") + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt new file mode 100644 index 00000000..81aa128e --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt @@ -0,0 +1,51 @@ +package com.brainwallet.ui.screens.unlock.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import com.brainwallet.data.model.AppSetting +import com.brainwallet.ui.composable.BrainWalletLogo +import com.brainwallet.ui.theme.BrainwalletAppTheme +import com.brainwallet.ui.theme.BrainwalletTheme + +@Composable +fun UnLockScreenHeader( + formattedLtcPrice: String, + modifier: Modifier = Modifier, +) { + Column( + modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + modifier = Modifier + .padding(bottom = 52.dp) + .fillMaxWidth(), + text = formattedLtcPrice, + textAlign = TextAlign.End, + color = BrainwalletTheme.colors.border + ) + BrainWalletLogo(modifier = Modifier.width(268.dp)) + } +} + +@PreviewLightDark +@Composable +private fun UnLockScreenHeaderPreview() { + BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) { + Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) { + UnLockScreenHeader(formattedLtcPrice = "100") + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt index 36afabbe..9b421ce5 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt @@ -59,6 +59,10 @@ val LocalLanguageCode = staticCompositionLocalOf { Language.ENGLISH.code //default } +val LocalDarkModeFlag = staticCompositionLocalOf { + false +} + @Composable fun BrainwalletAppTheme( appSetting: AppSetting = AppSetting(), @@ -68,7 +72,8 @@ fun BrainwalletAppTheme( CompositionLocalProvider( LocalBrainwalletColors provides colors, - LocalLanguageCode provides appSetting.languageCode + LocalLanguageCode provides appSetting.languageCode, + LocalDarkModeFlag provides appSetting.isDarkMode, ) { MaterialTheme( typography = AppTypography, diff --git a/app/src/main/java/com/brainwallet/util/CurrencyDataGetter.kt b/app/src/main/java/com/brainwallet/util/CurrencyDataGetter.kt new file mode 100644 index 00000000..4c6ebf21 --- /dev/null +++ b/app/src/main/java/com/brainwallet/util/CurrencyDataGetter.kt @@ -0,0 +1,41 @@ +package com.brainwallet.util + +import android.content.Context +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.sqlite.CurrencyDataSource +import com.brainwallet.tools.util.BRCurrency +import org.koin.core.annotation.Single +import java.math.BigDecimal + +@Single +class CurrencyDataGetter( + private val context: Context, + private val currencyDataSource: CurrencyDataSource = CurrencyDataSource.getInstance(context), + private val isoSymbolGetter: (Context) -> String = { BRSharedPrefs.getIsoSymbol(context) }, + private val formattedCurrencyStringGetter: (Context, String, BigDecimal) -> String? = + { context, isoCurrencyCode, amount -> + BRCurrency.getFormattedCurrencyString( + context, + isoCurrencyCode, + amount + ) + } +) { + fun getIsoSymbol(): String { + return isoSymbolGetter.invoke(context) + } + + fun getCurrencyByIso( + iso: String + ): CurrencyEntity? { + return currencyDataSource.getCurrencyByIso(iso) + } + + fun getFormattedCurrencyString( + isoCurrencyCode: String, + amount: BigDecimal + ): String? { + return formattedCurrencyStringGetter.invoke(context, isoCurrencyCode, amount) + } +} diff --git a/app/src/main/java/com/brainwallet/util/VersionCodeProvider.kt b/app/src/main/java/com/brainwallet/util/VersionCodeProvider.kt new file mode 100644 index 00000000..264ccccf --- /dev/null +++ b/app/src/main/java/com/brainwallet/util/VersionCodeProvider.kt @@ -0,0 +1,22 @@ +package com.brainwallet.util + +import com.brainwallet.BuildConfig +import org.koin.core.annotation.Factory + +@Factory +class VersionCodeProvider( + private val versionCodeGetter: () -> Int = { BuildConfig.VERSION_CODE }, + private val versionNameGetter: () -> String = { BuildConfig.VERSION_NAME } +) { + fun getVersionCode(): Int { + return versionCodeGetter() + } + + fun getVersionName(): String { + return versionNameGetter() + } + + fun getFormatted(): String { + return "${getVersionName()} (${getVersionCode()})" + } +} diff --git a/app/src/main/res/drawable-hdpi/brainwallet_logotype_color.webp b/app/src/main/res/drawable-hdpi/brainwallet_logotype_color.webp new file mode 100644 index 0000000000000000000000000000000000000000..dfc5fa0c709b7da9189d124d4cedf18856119927 GIT binary patch literal 13554 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 s&Z7rKus@Ap!JZKS09Veh*`5D^m~k1Z23 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�zD;yOR#mu6nn2tCES=Q} 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 E0Nd0`YXATM literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/brainwallet_logotype_color.webp b/app/src/main/res/drawable-xhdpi/brainwallet_logotype_color.webp new file mode 100644 index 0000000000000000000000000000000000000000..acc02566264fa4722eec1444c899c54a7bbddc74 GIT binary patch literal 20550 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�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�wLzFQv`q`f7}Cl>lr|a z5do0-p@%YHkTY_fA|NXH@E!*Q+sFw6riMfSmGfM;Sv;ZsYo{=?YL=&MJ`EdyKO!R6;?0^$C?U*O zcQl2S^`jQ1x2Y=Ob}7HfUv_T_2v%_hR2Ww(nqdYtRYc}Q1cYrsTmrDDB&U^d9^hvn ztOJ~j0P>GmUnKHTUY`=KD^VQ4S%4=&SQrucQ);PLa~R*(0Hm%(h5-Ci!W{so(QyKx zML^tNvj~Vf5Qc|oK1KCGiF}IX7DHL~;NQv)A|Uw!Q?u9i)B zH3jTJ(3ld1KynlW>j0GjE@Tvd$>NwPd$%Nrlun~>knI$BT#A$se1{2Ax`9Y2v{{-8?*HCW0(g)@ z+*MGp8D<4KKJbu8IrLJ8N|6$zJ^;sS&8F6_q-1aJC?X@*{85HP1Y{SK+D>OXN$IAR z%2e77$b-A@PbENZfq;rgX|0EVsHK*gQV6hyQIPW{MWh@7ggGQ408%AqwwoNJU;zIw z1t7zp4QCc!G!dXqcM$>91-e4^c9PQV%Voj}TLn3}Ql#AS^L~^eky0%u)jgL{aTFB| zrHJKcXlib3*FpDbWH5EToH6TO(Qk4I)u&fs>^lH81X6U#5|He=yVM|*8zk%GXdqiC%sE!16_ow8?p}C2)k!y4!j8FwmVZwwzTYwYWHD&!S}S+k4(ak z%$y(jDX&i`w#pm>-}9ln=Ev6DGS3SkX5Z%|Ke7|csC=?>Uaa>!d|y@k$W1O=_WQe5 zT5_nlW$`03O^)VAF3}yE9^TcML4M@NmidvL^XKXS+j$hccWv3j@Mqe=Za$@vyGG3S z{{6Y-VP@|32LNzg1&bkSAA}bGTt8EgI#ifb5X|n61~3tbDJmMhO0){1QxIlv8AN9a zT2`TXeX0^SsaY5$*XpkMo*&{gzGwUH+A=?KGkz2mrb1_m3bP+@Hb9sH;0nO(BUcNT zm2{7CLt-M|v&cvDK;QyMo`Ns~;1vkdAeB^JkEmcOTY;5bcWs#;xmj;+%C<_(fFH%l zWy^d|$GY1na;cfIEnDVCA<-3&G`8|7*p+AJmM!x=H`_htW%emfFC$Z)2{=4$Sl|CL zKQi;a7hFsQAvE7>Lm+$i13sH)3QHcVU~&HjR%oNZ1@dnhD@rj7!i&}r6J}E~$lGi{ zSPlZ6yhlCgk3m@pskRB6UghH|fMpQOE!3r}z%8qCp8($qsGBOPj0xb>DqMyxWx=;H z+Lez159lh4gBLpL_66XA(-Ja*6$>KFYFNYelc{F{lC=ru4DcX4eX9X3nGq{3s*GpH z-4wtkY})}$5J157&B+;=ZXT3p?lLwiRv>Jer51eBTG#&$07llSp?7;bNdP4cGO2-2 z6qrkv?7Un^2^<3hN3Pa8qS8akBgD*XCq5Ct6Fl zW$%m8_O*#3>}de^SQ?q7<`Kk{AtUEbk1d7wWKcDlE)8Cyr0FnV+bp$$-vscU67scT ZH4=+Y60!1617J@ENE@*k6^j-g)W$1t_z3_2 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/brainwallet_logotype_color.webp b/app/src/main/res/drawable-xxhdpi/brainwallet_logotype_color.webp new file mode 100644 index 0000000000000000000000000000000000000000..868fac8e4cc207b1df65fdb27375b1457aca143c GIT binary patch literal 35226 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 + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8323d2ac..443eee4f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -740,7 +740,7 @@ Balance - 1 LTC = %1$s + %1$s = 1Ł Current LTC value in %1$s Languages Are you sure you want to change the language to English? diff --git a/app/src/test/java/com/brainwallet/ui/screens/unlock/UnLockViewModelTest.kt b/app/src/test/java/com/brainwallet/ui/screens/unlock/UnLockViewModelTest.kt new file mode 100644 index 00000000..fe266cc9 --- /dev/null +++ b/app/src/test/java/com/brainwallet/ui/screens/unlock/UnLockViewModelTest.kt @@ -0,0 +1,359 @@ +package com.brainwallet.ui.screens.unlock + +import app.cash.turbine.test +import com.brainwallet.data.model.AppSetting +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.navigation.Route +import com.brainwallet.navigation.UiEffect +import com.brainwallet.util.CurrencyDataGetter +import com.brainwallet.util.EventBus +import com.brainwallet.util.MainDispatcherRule +import com.brainwallet.util.VersionCodeProvider +import io.mockk.MockKAnnotations +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.RelaxedMockK +import io.mockk.mockkObject +import io.mockk.unmockkAll +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.After +import org.junit.Before +import org.junit.Rule +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +class UnLockViewModelTest { + + @get:Rule + val mainDispatcherRule = MainDispatcherRule() + + @MockK + private lateinit var mockVersionCodeProvider: VersionCodeProvider + + @MockK + private lateinit var mockSettingRepository: SettingRepository + + @RelaxedMockK + private lateinit var mockCurrencyDataGetter: CurrencyDataGetter + + private lateinit var viewModel: UnLockViewModel + + @Before + fun setUp() { + MockKAnnotations.init(this, relaxUnitFun = true) + every { mockVersionCodeProvider.getFormatted() } returns "v4.7.1" + + viewModel = UnLockViewModel( + versionCodeProvider = mockVersionCodeProvider, + settingRepository = mockSettingRepository, + currencyDataGetter = mockCurrencyDataGetter + ) + } + + @After + fun tearDown() { + unmockkAll() + } + + @Test + fun `given viewModel initialization when created then state contains formatted version`() = + runTest { + viewModel.state.test { + val initialState = awaitItem() + + assert(initialState.formattedVersion == "v4.7.1") { + "Expected formatted version to be 'v4.7.1' but was '${initialState.formattedVersion}'" + } + assert(initialState.passcode == List(4) { -1 }) { + "Expected passcode to be empty list of -1 values but was '${initialState.passcode}'" + } + assert(initialState.iso == "USD") { + "Expected default ISO to be 'USD' but was '${initialState.iso}'" + } + assert(!initialState.isUpdatePin) { + "Expected isUpdatePin to be false but was '${initialState.isUpdatePin}'" + } + } + } + + @Test + fun `given valid pin digit when OnPinDigitChange event then passcode updates correctly`() = + runTest { + viewModel.state.test { + awaitItem() // Skip initial state + + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = 5, isValidPin = { false })) + + val updatedState = awaitItem() + assert(updatedState.passcode[0] == 5) { + "Expected first digit to be 5 but was '${updatedState.passcode[0]}'" + } + assert(updatedState.passcode.drop(1).all { it == -1 }) { + "Expected remaining digits to be -1 but were '${updatedState.passcode.drop(1)}'" + } + } + } + + @Test + fun `given multiple pin digits when OnPinDigitChange events then passcode fills sequentially`() = + runTest { + viewModel.state.test { + awaitItem() + + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = 1, isValidPin = { false })) + awaitItem() + + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = 2, isValidPin = { false })) + awaitItem() + + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = 3, isValidPin = { false })) + val thirdDigitState = awaitItem() + + assert(thirdDigitState.passcode == listOf(1, 2, 3, -1)) { + "Expected passcode to be [1, 2, 3, -1] but was '${thirdDigitState.passcode}'" + } + } + } + + @Test + fun `given invalid digit when OnPinDigitChange with digit less than -1 then passcode remains unchanged`() = + runTest { + viewModel.state.test { + val initialState = awaitItem() + + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = -5, isValidPin = { false })) + + expectNoEvents() + assert(initialState.passcode == List(4) { -1 }) { + "Expected passcode to remain unchanged but was modified" + } + } + } + + @Test + fun `given full passcode when OnPinDigitChange then no additional digits accepted`() = runTest { + viewModel.state.test { + awaitItem() + + repeat(4) { index -> + viewModel.onEvent( + UnLockEvent.OnPinDigitChange( + digit = index + 1, + isValidPin = { false }) + ) + awaitItem() + } + + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = 9, isValidPin = { false })) + + expectNoEvents() + } + } + + @Test + fun `given filled passcode in update mode with valid pin when OnPinDigitChange then navigates to SetPasscode`() = + runTest { + mockkObject(EventBus) + + viewModel.state.test { + awaitItem() + + viewModel.onEvent(UnLockEvent.OnLoad(isUpdatePin = true)) + awaitItem() + + repeat(3) { index -> + viewModel.onEvent( + UnLockEvent.OnPinDigitChange( + digit = index + 1, + isValidPin = { true }) + ) + awaitItem() + } + + viewModel.onEvent( + UnLockEvent.OnPinDigitChange( + digit = 4, + isValidPin = { true }) + ) + awaitItem() + } + + viewModel.uiEffect.test { + val effect = awaitItem() + assert(effect is UiEffect.Navigate) { + "Expected Navigate effect but was '${effect::class.simpleName}'" + } + val navigateEffect = effect as UiEffect.Navigate + assert(navigateEffect.destinationRoute is Route.SetPasscode) { + "Expected navigation to SetPasscode but was '${ + navigateEffect.destinationRoute!!::class.simpleName + }'" + } + } + } + + @Test + fun `given filled passcode in normal mode when OnPinDigitChange then emits LegacyUnLock event`() = + runTest { + mockkObject(EventBus) + coEvery { EventBus.emit(any()) } returns Unit + + viewModel.state.test { + awaitItem() + + repeat(3) { index -> + viewModel.onEvent( + UnLockEvent.OnPinDigitChange( + digit = index + 1, + isValidPin = { false }) + ) + awaitItem() + } + + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = 4, isValidPin = { false })) + awaitItem() + } + + testScheduler.advanceUntilIdle() + + coVerify { + EventBus.emit(match { event -> + event.passcode == listOf(1, 2, 3, 4) + }) + } + } + + @Test + fun `given passcode with digits when OnDeletePinDigit then removes last entered digit`() = + runTest { + viewModel.state.test { + awaitItem() + + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = 7, isValidPin = { false })) + awaitItem() + viewModel.onEvent(UnLockEvent.OnPinDigitChange(digit = 8, isValidPin = { false })) + awaitItem() + + viewModel.onEvent(UnLockEvent.OnDeletePinDigit) + val stateAfterDelete = awaitItem() + + assert(stateAfterDelete.passcode == listOf(7, -1, -1, -1)) { + "Expected passcode to be [7, -1, -1, -1] after deletion but was '${stateAfterDelete.passcode}'" + } + } + } + + @Test + fun `given empty passcode when OnDeletePinDigit then passcode remains unchanged`() = runTest { + viewModel.state.test { + val initialState = awaitItem() + + viewModel.onEvent(UnLockEvent.OnDeletePinDigit) + + expectNoEvents() + assert(initialState.passcode == List(4) { -1 }) { + "Expected empty passcode to remain unchanged after delete" + } + } + } + + @Test + fun `given OnLoad event with context when processed then updates state with currency information`() = + runTest { + val mockCurrency = CurrencyEntity(rate = 1.2f) + + every { mockCurrencyDataGetter.getIsoSymbol() } returns "EUR" + every { mockCurrencyDataGetter.getCurrencyByIso("EUR") } returns mockCurrency + every { + mockCurrencyDataGetter.getFormattedCurrencyString( + "EUR", + any() + ) + } returns "€1.20" + + viewModel.state.test { + awaitItem() + + viewModel.onEvent(UnLockEvent.OnLoad(isUpdatePin = false)) + + val updatedState = awaitItem() + assert(updatedState.iso == "EUR") { + "Expected ISO to be 'EUR' but was '${updatedState.iso}'" + } + assert(updatedState.formattedCurrency == "€1.20") { + "Expected formatted currency to be '€1.20' but was '${updatedState.formattedCurrency}'" + } + assert(updatedState.isUpdatePin == false) { + "Expected isUpdatePin to be false but was '${updatedState.isUpdatePin}'" + } + } + } + + + @Test + fun `given OnLoad event with null currency when processed then state remains unchanged`() = + runTest { + every { mockCurrencyDataGetter.getIsoSymbol() } returns "INVALID" + every { mockCurrencyDataGetter.getCurrencyByIso("INVALID") } returns null + + viewModel.state.test { + val initialState = awaitItem() + + viewModel.onEvent(UnLockEvent.OnLoad(isUpdatePin = false)) + + expectNoEvents() + assert(initialState.iso == "USD") { + "Expected ISO to remain 'USD' when currency is null" + } + } + } + + @Test + fun `given OnToggleDarkMode event when settings exist then toggles dark mode setting`() = + runTest { + val mockSettings = AppSetting(isDarkMode = false) + + coEvery { mockSettingRepository.settings } returns flowOf(mockSettings) + coEvery { mockSettingRepository.save(any()) } returns Unit + + viewModel.onEvent(UnLockEvent.OnToggleDarkMode) + testScheduler.advanceUntilIdle() + + coVerify { + mockSettingRepository.save(match { it.isDarkMode }) + } + } + + @Test + fun `given OnQrClicked event when processed then sends ShowMoonPayDialog effect`() = runTest { + viewModel.onEvent(UnLockEvent.OnQrClicked) + + viewModel.uiEffect.test { + val effect = awaitItem() + assert(effect is UiEffect.ShowMoonPayDialog) { + "Expected ShowMoonPayDialog effect but was '${effect::class.simpleName}'" + } + } + } + + @Test + fun `given isPasscodeFilled extension when all digits are filled then returns true`() { + val filledState = UnLockState(passcode = listOf(1, 2, 3, 4)) + assert(filledState.isPasscodeFilled()) { + "Expected isPasscodeFilled to return true for filled passcode" + } + } + + @Test + fun `given isPasscodeFilled extension when passcode has empty digits then returns false`() { + val partialState = UnLockState(passcode = listOf(1, 2, -1, -1)) + assert(!partialState.isPasscodeFilled()) { + "Expected isPasscodeFilled to return false for partially filled passcode" + } + } +} diff --git a/app/src/test/java/com/brainwallet/util/CurrencyDataGetterTest.kt b/app/src/test/java/com/brainwallet/util/CurrencyDataGetterTest.kt new file mode 100644 index 00000000..0bdf4cd0 --- /dev/null +++ b/app/src/test/java/com/brainwallet/util/CurrencyDataGetterTest.kt @@ -0,0 +1,125 @@ +package com.brainwallet.util + +import android.content.Context +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.tools.sqlite.CurrencyDataSource +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.unmockkAll +import io.mockk.verify +import org.junit.After +import org.junit.Before +import org.junit.Test +import java.math.BigDecimal + +class CurrencyDataGetterTest { + + @MockK + private lateinit var mockContext: Context + + @MockK + private lateinit var mockCurrencyDataSource: CurrencyDataSource + + @MockK + private lateinit var mockIsoSymbolGetter: (Context) -> String + + @MockK + private lateinit var mockFormattedCurrencyStringGetter: (Context, String, BigDecimal) -> String? + + private lateinit var currencyDataGetter: CurrencyDataGetter + + @Before + fun setUp() { + MockKAnnotations.init(this, relaxUnitFun = true) + currencyDataGetter = CurrencyDataGetter( + context = mockContext, + currencyDataSource = mockCurrencyDataSource, + isoSymbolGetter = mockIsoSymbolGetter, + formattedCurrencyStringGetter = mockFormattedCurrencyStringGetter + ) + } + + @After + fun tearDown() { + unmockkAll() + } + + @Test + fun `given valid context when getting iso symbol then returns expected symbol`() { + val expectedIsoSymbol = "USD" + every { mockIsoSymbolGetter.invoke(mockContext) } returns expectedIsoSymbol + + val actualIsoSymbol = currencyDataGetter.getIsoSymbol() + assert(actualIsoSymbol == expectedIsoSymbol) { + "Expected ISO symbol to be '$expectedIsoSymbol' but was '$actualIsoSymbol'" + } + verify(exactly = 1) { mockIsoSymbolGetter.invoke(mockContext) } + } + + @Test + fun `given valid iso code when getting currency by iso then returns currency entity`() { + val isoCode = "EUR" + val expectedCurrency = CurrencyEntity().apply { + code = isoCode + name = "Euro" + } + every { mockCurrencyDataSource.getCurrencyByIso(isoCode) } returns expectedCurrency + + val actualCurrency = currencyDataGetter.getCurrencyByIso(isoCode) + + assert(actualCurrency == expectedCurrency) { + "Expected currency entity with code '$isoCode' but was '$actualCurrency'" + } + verify(exactly = 1) { mockCurrencyDataSource.getCurrencyByIso(isoCode) } + } + + @Test + fun `given invalid iso code when getting currency by iso then returns null`() { + val invalidIsoCode = "INVALID" + every { mockCurrencyDataSource.getCurrencyByIso(invalidIsoCode) } returns null + + val actualCurrency = currencyDataGetter.getCurrencyByIso(invalidIsoCode) + + assert(actualCurrency == null) { + "Expected null for invalid ISO code '$invalidIsoCode' but was '$actualCurrency'" + } + verify(exactly = 1) { mockCurrencyDataSource.getCurrencyByIso(invalidIsoCode) } + } + + @Test + fun `given valid currency code and amount when getting formatted string then returns formatted currency`() { + val currencyCode = "GBP" + val amount = BigDecimal("123.45") + val expectedFormattedString = "£123.45" + every { + mockFormattedCurrencyStringGetter.invoke(mockContext, currencyCode, amount) + } returns expectedFormattedString + + val actualFormattedString = currencyDataGetter.getFormattedCurrencyString(currencyCode, amount) + + assert(actualFormattedString == expectedFormattedString) { + "Expected formatted currency '$expectedFormattedString' but was '$actualFormattedString'" + } + verify(exactly = 1) { + mockFormattedCurrencyStringGetter.invoke(mockContext, currencyCode, amount) + } + } + + @Test + fun `given invalid currency code when getting formatted string then returns null`() { + val invalidCurrencyCode = "INVALID" + val amount = BigDecimal("100.00") + every { + mockFormattedCurrencyStringGetter.invoke(mockContext, invalidCurrencyCode, amount) + } returns null + val actualFormattedString = currencyDataGetter.getFormattedCurrencyString(invalidCurrencyCode, amount) + + assert(actualFormattedString == null) { + "Expected null for invalid currency code '$invalidCurrencyCode' but was '$actualFormattedString'" + } + verify(exactly = 1) { + mockFormattedCurrencyStringGetter.invoke(mockContext, invalidCurrencyCode, amount) + } + } +} diff --git a/app/src/test/java/com/brainwallet/util/MainDispatcherRule.kt b/app/src/test/java/com/brainwallet/util/MainDispatcherRule.kt new file mode 100644 index 00000000..a06c45c8 --- /dev/null +++ b/app/src/test/java/com/brainwallet/util/MainDispatcherRule.kt @@ -0,0 +1,23 @@ +package com.brainwallet.util + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestDispatcher +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.resetMain +import kotlinx.coroutines.test.setMain +import org.junit.rules.TestWatcher +import org.junit.runner.Description + +@OptIn(ExperimentalCoroutinesApi::class) +class MainDispatcherRule( + val testDispatcher: TestDispatcher = UnconfinedTestDispatcher(), +) : TestWatcher() { + override fun starting(description: Description) { + Dispatchers.setMain(testDispatcher) + } + + override fun finished(description: Description) { + Dispatchers.resetMain() + } +} diff --git a/app/src/test/java/com/brainwallet/util/VersionCodeProviderTest.kt b/app/src/test/java/com/brainwallet/util/VersionCodeProviderTest.kt new file mode 100644 index 00000000..31503883 --- /dev/null +++ b/app/src/test/java/com/brainwallet/util/VersionCodeProviderTest.kt @@ -0,0 +1,44 @@ +package com.brainwallet.util + +import io.mockk.every +import io.mockk.mockk +import junit.framework.TestCase.assertEquals +import org.junit.Test + +class VersionCodeProviderTest { + + @Test + fun `Given a version code, When getVersionCode called, Then return that version code`() { + val versionCodeGetter: () -> Int = mockk() + every { versionCodeGetter.invoke() } returns 123 + val provider = VersionCodeProvider(versionCodeGetter = versionCodeGetter) + + val result = provider.getVersionCode() + assertEquals(123, result) + } + + @Test + fun `Given a version name, When getVersionName called, Then return that version name`() { + val versionNameGetter: () -> String = mockk() + every { versionNameGetter.invoke() } returns "1.2.3" + val provider = VersionCodeProvider(versionNameGetter = versionNameGetter) + + val result = provider.getVersionName() + assertEquals("1.2.3", result) + } + + @Test + fun `Given version code and name, When getFormatted called, Then return formatted string`() { + val versionCodeGetter: () -> Int = mockk() + val versionNameGetter: () -> String = mockk() + every { versionCodeGetter.invoke() } returns 456 + every { versionNameGetter.invoke() } returns "2.0.0" + val provider = VersionCodeProvider( + versionCodeGetter = versionCodeGetter, + versionNameGetter = versionNameGetter + ) + + val result = provider.getFormatted() + assertEquals("2.0.0 (456)", result) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f1ff0cc4..f18f2b70 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -33,6 +33,8 @@ mockk = "1.13.13" koin-bom = "4.0.2" koin-annotation-bom = "2.1.0" ksp = "2.0.0-1.0.24" +turbine = "1.2.1" +coroutines = "1.10.2" [libraries] androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" } @@ -117,6 +119,9 @@ koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel" } koin-annotation-bom = { module = "io.insert-koin:koin-annotations-bom", version.ref = "koin-annotation-bom" } koin-annotation = { module = "io.insert-koin:koin-annotations" } koin-annotation-compiler = { module = "io.insert-koin:koin-ksp-compiler", version.ref = "koin-annotation-bom" } +turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" } +kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } +kotlinx-coroutines-tests = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } [bundles] androidx-lifecycle = ["androidx-lifecycle-runtime", "androidx-lifecycle-viewmodel", "androidx-lifecycle-viewmodel-compose"] From 7d8dd142aaf381106c27c02732a09f147f8b5f3e Mon Sep 17 00:00:00 2001 From: Josi Kie <54074780+josikie@users.noreply.github.com> Date: Mon, 25 Aug 2025 22:29:46 +0700 Subject: [PATCH 059/116] Redesign welcome screen (#123) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Redesign welcome screen * Redesign ready screen * 🚀[Release v4.7.2] Merge into Develop (#127) * 🚀[Release v4.4.7] Merge into Main (#70) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.0] Merge into Main (#78) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.4] Merge into Main (#87) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * Updated README * code bump * chore: open bread activity first then open moonpay widget (#88) * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.5] Merge into Main (#101) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Update build.gradle.kts --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.0] Merge into Main (#104) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * version bump * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.1] Merge into Main (#107) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * build bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.2] Merge into Main (#110) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * Removed unused audio files * polished tests * removed unused asset pack * code bump * code bump * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * broke out completion of the seed phrase and navigation - Feedback was a user could complete seed phrase and not tap "Game and Sync" - Forced users to start all over - Saved a correct seed phrase confirmation into memory * code bump * fix for https://console.firebase.google.com/project/brainwallet-mobile/crashlytics/app/android:ltd.grunt.brainwallet/issues/1386f366ab35e9112a6b742d629bb0be?time=last-seven-days&types=crash&sessionEventKey=685DA96C00BF00015A7AFEA30E0DB49C_2098799426616143441 * measure where users tap * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly * Cleaned commented out BuyLitecoinscreen * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.7.0] Merge into Main (#115) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly (#111) * Upgrade targetSdk 36 (#113) * chore: change drawable with density for brainwallet_logotype_white * chore: adjustment WelcomeScreen.kt * chore: adjustment for targetSdk 36 also support 16KB page size * bump clean extra semicolon * Update pro-guard-rules * Updated the version --------- Co-authored-by: andhikayuana * Updated games module to v1.1.0 * Updated the games submodule * Renamed and tested with user skips --------- Co-authored-by: andhikayuana * Fix(#227): Crash when launching MoonPay Widget (#126) Refactored the MoonPay widget integration to a dedicated Composable (`MoonPayWidgetLauncher`) to ensure proper state handling and loading behavior. - Added `MoonPayWidgetLauncher.kt` with Composable and ViewModel for managing signed URL fetch and Custom Tab launch. - Ensures loading state covers the whole screen, preventing UI crashes. - Removed legacy static method `LegacyNavigation.showMoonPayWidget`. - Updated `ReceiveDialog.kt` and `BuyLitecoinScreen.kt` to use the new Composable. - Minor cleanup in `LegacyNavigation.kt`. * feat(#138): Improve Unlock Screen UI and add dark mode toggle (#122) --------- Co-authored-by: Kerry Washington Co-authored-by: andhikayuana Co-authored-by: Joseph Sanjaya --- .../ui/screens/ready/ReadyScreen.kt | 27 +++++++++---------- .../ui/screens/welcome/WelcomeScreen.kt | 2 +- app/src/main/res/values-ar/strings.xml | 10 +++---- app/src/main/res/values-de/strings.xml | 10 +++---- app/src/main/res/values-es/strings.xml | 10 +++---- app/src/main/res/values-fa/strings.xml | 10 +++---- app/src/main/res/values-fr/strings.xml | 10 +++---- app/src/main/res/values-hi/strings.xml | 10 +++---- app/src/main/res/values-in/strings.xml | 8 +++--- app/src/main/res/values-it/strings.xml | 10 +++---- app/src/main/res/values-ja/strings.xml | 10 +++---- app/src/main/res/values-ko/strings.xml | 8 +++--- app/src/main/res/values-pa/strings.xml | 10 +++---- app/src/main/res/values-pl/strings.xml | 10 +++---- app/src/main/res/values-pt/strings.xml | 10 +++---- app/src/main/res/values-ru/strings.xml | 10 +++---- app/src/main/res/values-sv/strings.xml | 10 +++---- app/src/main/res/values-tr/strings.xml | 10 +++---- app/src/main/res/values-uk/strings.xml | 10 +++---- app/src/main/res/values-zh-rCN/strings.xml | 10 +++---- app/src/main/res/values-zh-rTW/strings.xml | 10 +++---- app/src/main/res/values/strings.xml | 10 +++---- 22 files changed, 112 insertions(+), 113 deletions(-) diff --git a/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyScreen.kt index 1201b0a7..4be9e0dc 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyScreen.kt @@ -55,10 +55,10 @@ fun ReadyScreen( } /// Layout values - val leadingCopyPadding = 16 + val leadingCopyPadding = 18 val horizontalVerticalSpacing = 8 - val spacerHeight = 90 + val spacerHeight = 40 val activeRowHeight = 70 @@ -89,7 +89,7 @@ fun ReadyScreen( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), ) { - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(0.5f)) Row { Icon( Icons.AutoMirrored.Filled.ArrowForward, @@ -101,28 +101,27 @@ fun ReadyScreen( scaleY = 2f ) ) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(0.3f)) } + Spacer(modifier = Modifier.height(16.dp)) + Text( text = stringResource(R.string.ready_setup), style = MaterialTheme.typography.displaySmall.copy(textAlign = TextAlign.Left), - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), + fontWeight = FontWeight.Bold ) Text( text = buildAnnotatedString { append(stringResource(R.string.ready_setup_details_1)) - append(" ") - withStyle( - style = SpanStyle( - fontWeight = FontWeight.Bold, - ) - ) { - append(stringResource(R.string.ready_setup_details_2)) + append("\n\n") + append(stringResource(R.string.ready_setup_details_2)) + append("\n\n") + withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { + append(stringResource(R.string.ready_setup_details_3)) } - append(". ") - append(stringResource(R.string.ready_setup_details_3)) }, style = MaterialTheme.typography.bodyLarge, modifier = Modifier.fillMaxWidth() diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index d5a1fd2b..3c9773fb 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -205,7 +205,7 @@ fun WelcomeScreen( ) { Text( - text = stringResource(R.string.ready), + text = stringResource(R.string.MenuViewController_createButton), fontSize = buttonFontSize.sp, fontWeight = FontWeight.SemiBold, ) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 4c1e559c..82a13420 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -386,10 +386,10 @@ لقد أنقذته، أليس كذلك؟ أثبت ذلك!\nاسحب الكلمات بالترتيب الصحيح. اللعبة والمزامنة - مستعد؟ - افعل هذا من أجلك. من فضلك افعلها - وحيد - أحضر قلمًا وورقة و5 دقائق + ؟هل أنت مستعد للبدء؟ + هذا لك وحدك. + قم بإعداد رمز مرور التطبيق، ثم افتح مدير كلمات المرور الخاص بك أو استخدم قلمًا لتسجيله وعبارة البذرة الجديدة. + نحن لا نعرفه وليس لدينا نسخة منه! رمز مرور تطبيق الإعداد اختر رمز مرور لفتح Brainwallet الخاص بك ليس رمز قفل الهاتف! @@ -406,7 +406,7 @@ يتأكد أنت لم تنسى أليس كذلك؟ أدخله مرة أخرى. أو، العودة للبدء من جديد. مستعد - يعيد + استعادة باستخدام عبارة البذور رمز المرور غير صحيح، يرجى المحاولة مرة أخرى! سهم لأسفل لليسار شعار diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 31708d56..cd1386df 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -748,10 +748,10 @@ Du hast es gespeichert, oder? Beweisen Sie es!\nZiehen Sie die Wörter in die richtige Reihenfolge. Spiel & Synchronisierung - Bereit? - Tun Sie dies für Sie. Bitte tun Sie es - allein - Schnappen Sie sich einen Stift, Papier und 5 Minuten + Bereit zum Start? + Das ist nur für dich. + Richten Sie den App-Passcode ein, öffnen Sie Ihren Passwort-Manager oder nehmen Sie einen Stift, um ihn und Ihre neue Seed-Phrase aufzuzeichnen. + Wir kennen es nicht und haben auch keine Kopie! App-Passcode einrichten Wählen Sie einen Passcode, um Ihr Brainwallet zu entsperren Kein Telefonsperrcode! @@ -768,7 +768,7 @@ Bestätigen Du hast es nicht vergessen, oder? Geben Sie es erneut ein. Oder gehen Sie zurück, um von vorne zu beginnen. Bereit - Wiederherstellen + Mit Seed-Phrase wiederherstellen Falscher Passcode, bitte versuchen Sie es erneut! Pfeil nach unten links Logo diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3eaded9b..e4363ff4 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -747,10 +747,10 @@ Lo guardaste, ¿verdad? ¡Pruébalo!\nArrastra las palabras en el orden correcto. Juego y sincronización - ¿Listo? - Haz esto por ti. por favor hazlo - solo - Coge bolígrafo, papel y 5 minutos. + ¿Listo para empezar? + Esto es solo para ti. + Configura el código de acceso de la aplicación, abre tu administrador de contraseñas o toma un bolígrafo para registrarlo junto con tu nueva frase inicial. + ¡No lo sabemos ni tenemos copia! Configurar el código de acceso de la aplicación Elija una contraseña para desbloquear su Brainwallet ¡No es un código de bloqueo del teléfono! @@ -767,7 +767,7 @@ Confirmar No lo olvidaste ¿verdad? Ingrese nuevamente. O regrese para empezar de nuevo. Listo - Restaurar + Restaurar con frase semilla Código de acceso incorrecto, ¡inténtelo de nuevo! flecha abajo-izquierda logo diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 8f82d491..b70bfedc 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -777,10 +777,10 @@ اثباتش کن! کلمات را به ترتیب صحیح بکشید. بازی و همگام‌سازی - آماده‌اید؟ - برای شما انجام می‌دهم. لطفاً انجامش بده - تنها - یک قلم، کاغذ و ۵ دقیقه بردارید + آماده برای شروع؟ + این فقط برای توئه. + کد عبور برنامه را تنظیم کنید، مدیر رمز عبور خود را باز کنید یا یک خودکار بردارید و آن و عبارت بازیابی جدید خود را یادداشت کنید. + ما نه آن را می‌شناسیم و نه نمونه‌ای از آن داریم! تنظیم رمز عبور برنامه یک رمز عبور را برای باز کردن قفل کیف پول مغزی خود انتخاب کنید قفل تلفن نیست! @@ -803,7 +803,7 @@ تایید فراموش نکردی، مگه نه؟ وارد کنید دوباره. یا، به عقب برگردید تا از ابتدا شروع کنید. آماده - بازیابی + بازیابی با عبارت Seed رمز عبور نادرست، لطفاً دوباره تلاش کنید! فلش به سمت پایین و چپ لوگو diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 2d0343e3..92b63a25 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -748,10 +748,10 @@ Vous l\'avez sauvegardé, n\'est-ce pas ? Prouvez-le !\nFaites glisser les mots dans le bon ordre. Jeu et synchronisation - Prêt? - Faites cela pour vous. S\'il te plaît, fais-le - seul - Prenez un stylo, du papier et 5 minutes + Prêt à commencer? + Ceci est pour toi seul. + Configurez le mot de passe de l\'application, ouvrez votre gestionnaire de mots de passe ou prenez un stylo pour l\'enregistrer ainsi que votre nouvelle phrase de départ. + Nous ne le savons pas et n’en avons pas de copie ! Configurer le mot de passe de l\'application Choisissez un mot de passe pour déverrouiller votre Brainwallet Pas un code de verrouillage du téléphone ! @@ -768,7 +768,7 @@ Confirmer Vous n\'avez pas oublié, n\'est-ce pas ? Entrez-le à nouveau. Ou revenez en arrière pour recommencer. Prêt - Restaurer + Restaurer avec une phrase de départ Code d\'accès incorrect, veuillez réessayer ! flèche bas-gauche logo diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index cb889a37..73407e9f 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -386,10 +386,10 @@ आपने इसे सहेज लिया, है ना? इसे साबित करें!\nशब्दों को सही क्रम में खींचें। गेम और सिंक - तैयार? - यह आपके लिए करें. कृपया इसे करते हैं - अकेला - एक कलम, कागज़ और 5 मिनट पकड़ें + शुरू करने के लिए तैयार हैं? + यह केवल आपके लिए है. + ऐप पासकोड सेट करें, अपना पासवर्ड मैनेजर खोलें या इसे और अपने नए बीज वाक्यांश को रिकॉर्ड करने के लिए एक पेन लें। + हमें इसकी जानकारी नहीं है और न ही हमारे पास इसकी कोई प्रति है! ऐप पासकोड सेटअप करें अपने ब्रेनवॉलेट को अनलॉक करने के लिए एक पासकोड चुनें फ़ोन लॉक कोड नहीं! @@ -406,7 +406,7 @@ पुष्टि करना तुम भूले तो नहीं? इसे दोबारा दर्ज करें. या, दोबारा शुरू करने के लिए वापस जाएं। तैयार - पुनर्स्थापित करना + बीज वाक्यांश के साथ पुनर्स्थापित करें ग़लत पासकोड, कृपया पुनः प्रयास करें! नीचे-बाएँ-तीर प्रतीक चिन्ह diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 73f60f4d..e89fb5f4 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -750,10 +750,10 @@ Anda menyimpannya, kan? Buktikan!\nSeret kata-kata dalam urutan yang benar. Permainan & Sinkronisasi - Siap? + Siap untuk memulai? Lakukan ini untukmu. Tolong lakukan itu - sendiri - Ambil pena, kertas, dan 5 menit + Atur kode sandi aplikasi, buka pengelola kata sandi Anda atau ambil pena untuk mencatatnya & frasa benih baru Anda. + Kami tidak mengetahuinya dan kami tidak memiliki salinannya! Siapkan kode sandi aplikasi Pilih kode sandi untuk membuka kunci Brainwallet Anda Bukan kode kunci telepon! @@ -770,7 +770,7 @@ Mengonfirmasi Kamu tidak lupa kan? Masukkan lagi. Atau, kembali untuk memulai kembali. Siap - Memulihkan + Pulihkan dengan Seed Phrase Kode Sandi salah, silakan coba lagi! panah kiri bawah logo diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 69116bf1..3a15ed68 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -748,10 +748,10 @@ L\'hai salvato, vero? Dimostralo!\nTrascina le parole nell\'ordine corretto. Gioco e sincronizzazione - Pronto? - Fallo per te. Per favore, fallo - solo - Prendi carta, penna e 5 minuti + Pronto per iniziare? + Questo è solo per te. + Imposta il codice di accesso dell\'app, apri il tuo gestore di password o prendi una penna per registrarlo insieme alla tua nuova frase seed. + Non lo sappiamo e non ne abbiamo una copia! Imposta il codice di accesso dell\'app Scegli un passcode per sbloccare il tuo Brainwallet Non è un codice di blocco del telefono! @@ -768,7 +768,7 @@ Confermare Non te ne sei dimenticato, vero? Inseriscilo di nuovo. Oppure torna indietro per ricominciare da capo. Pronto - Ripristinare + Ripristina con la frase Seed Codice di accesso errato, riprova! freccia giù a sinistra logo diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 5550e8f1..097163d0 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -748,10 +748,10 @@ 保存したんですよね? 証明してください!\n正しい順序で単語をドラッグしてください。 ゲームと同期 - 準備ができて? - あなたのためにこれをしてください。やってください - 一人で - ペンと紙を用意して 5 分 + 시작할 준비가 되셨나요? + これはあなただけのためのものです。 + アプリのパスコードを設定し、パスワード マネージャーを開くか、ペンを用意してパスコードと新しいシード フレーズを記録します。 + 私たちはそれを知りませんし、コピーも持っていません! アプリのパスコードを設定する パスコードを選択してブレインウォレットのロックを解除します 携帯電話のロックコードではありません。 @@ -768,7 +768,7 @@ 確認する 忘れてませんでしたよね?もう一度入力してください。または、戻って最初からやり直します。 準備ができて - 復元する + シードフレーズで復元 パスコードが間違っています。もう一度お試しください。 左下矢印 ロゴ diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 693a92ae..aafc1c57 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -749,9 +749,9 @@ 증명해보세요!\n올바른 순서로 단어를 드래그하세요. 게임 및 동기화 준비가 된? - 당신을 위해 이것을하십시오. 꼭 해주세요 - 홀로 - 펜과 종이를 들고 5분 + 이건 당신만을 위한 거예요. + 앱 비밀번호를 설정하고 비밀번호 관리자를 열거나 펜을 가져와서 비밀번호와 새로운 시드 문구를 기록하세요. + 우리는 그것을 모르고 사본도 없습니다! 앱 비밀번호 설정 Brainwallet을 잠금 해제하려면 비밀번호를 선택하세요 전화 잠금 코드가 아닙니다! @@ -768,7 +768,7 @@ 확인하다 잊지 않았지? 다시 입력하세요. 아니면 돌아가서 다시 시작하세요. 준비가 된 - 복원하다 + 시드 프레이즈로 복원 잘못된 비밀번호입니다. 다시 시도해 주세요! 아래쪽 왼쪽 화살표 심벌 마크 diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 4e8aa15c..98248e3e 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -769,10 +769,10 @@ تُسیں اِس نُوں بچا لیا، ٹھیک؟ ثابت کرو! \nالفاظ نوں صحیح ترتیب وچ کھچو۔ گیم اینڈ سنک - تیار؟ - اے اپنے لئی کرو۔ براہ کرم یہ کریں۔ - اکیلا - قلم، کاغذ تے 5 منٹ لَے لو۔ + شروع کرنے کے لیے تیار ہیں؟ + یہ صرف آپ کے لیے ہے۔ + ایپ پاس کوڈ سیٹ اپ کریں، اپنا پاس ورڈ مینیجر کھولیں یا اسے اور اپنے نئے سیڈ فقرے کو ریکارڈ کرنے کے لیے قلم پکڑیں۔ + ہم اسے نہیں جانتے اور نہ ہی ہمارے پاس کوئی کاپی ہے! ایپ پاسکوڈ سیٹ کریں اپنے برین والٹ کو ان لاک کرنے کے لیے ایک پاس کوڈ منتخب کریں۔ فون لاک کوڈ نہیں! @@ -796,7 +796,7 @@ تُہانوں 5,444,517,950,000,000,000,000,000,000,000,000,000,000,000,000,000 کوششاں لگن گیاں۔ تصدیق کریں۔ تُسیں بھلّے تاں نئیں؟ اسے دوبارہ داخل کریں۔ یا، واپس جا کر دوبارہ شروع کرو۔ - تیار + بیج کے جملے کے ساتھ بحال کریں۔ بحال کرو غلط پاسکوڈ، براہ کرم دوبارہ کوشش کریں! نیچے-کھبے-تیر diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index d1646132..fe6e4805 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -766,10 +766,10 @@ Uratowałeś go, prawda? Udowodnij to! \nPrzeciągnij słowa w odpowiedniej kolejności. Gra i synchronizacja - Gotowy? - Zrób to dla siebie. Proszę, zrób to - sam - Weź długopis, papier i 5 minut + Gotowy zacząć? + Detta är bara för dig. + Ställ in appens lösenord, öppna lösenordshanteraren eller ta en penna för att anteckna det och din nya fröfras. + Vi vet det inte och har inte heller någon kopia! Konfiguracja kodu aplikacji Wybierz hasło, aby odblokować Brainwallet Nie kod blokady telefonu! @@ -792,7 +792,7 @@ Potwierdzenie Nie zapomniałeś, prawda? Wprowadź go ponownie. Albo wrócić i zacząć od nowa. Gotowy - Przywracanie + Przywróć za pomocą frazy początkowej Nieprawidłowe hasło, spróbuj ponownie! strzałka w dół-lewo logo diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 1e68ec84..dcbb7c14 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -747,10 +747,10 @@ Você salvou, certo? Prove!\nArraste as palavras na ordem correta. Jogo e sincronização - Preparar? - Faça isso por você. Por favor faça isso - sozinho - Pegue uma caneta, papel e 5 minutos + Pronto para começar? + Isto é somente para você. + Configure a senha do aplicativo, abra seu gerenciador de senhas ou pegue uma caneta para registrá-la junto com sua nova frase-semente. + Não sabemos e nem temos uma cópia! Configurar senha do aplicativo Escolha uma senha para desbloquear seu Brainwallet Não é um código de bloqueio do telefone! @@ -767,7 +767,7 @@ Confirmar Você não esqueceu, não é? Digite novamente. Ou volte para começar de novo. Preparar - Restaurar + Restaurar com frase semente Senha incorreta, tente novamente! seta para baixo à esquerda logotipo diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 183a5c30..ad65ef57 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -748,10 +748,10 @@ Ты сохранил это, да? Докажите это!\nПеретащите слова в правильном порядке. Игра и синхронизация - Готовый? - Сделайте это для себя. Пожалуйста, сделай это - один - Возьмите ручку, бумагу и 5 минут. + Готовы начать? + Это только для тебя. + Установите код доступа к приложению, откройте менеджер паролей или возьмите ручку, чтобы записать его и новую начальную фразу. + Мы этого не знаем и у нас нет копии! Установить пароль приложения Выберите пароль, чтобы разблокировать свой Brainwallet Это не код блокировки телефона! @@ -768,7 +768,7 @@ Подтверждать Ты ведь не забыл? Введите его еще раз. Или вернитесь, чтобы начать все сначала. Готовый - Восстановить + Восстановить с помощью Seed-фразы Неправильный пароль, попробуйте еще раз! стрелка вниз-влево логотип diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 1e7f0342..6e155cf2 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -386,10 +386,10 @@ Du sparade det, eller hur? Bevisa det!\nDra orden i rätt ordning. Spel och synkronisering - Redo? - Gör det här åt dig. Snälla gör det - ensam - Ta en penna, papper och 5 minuter + Redo att börja? + Detta är bara för dig. + Ställ in appens lösenord, öppna lösenordshanteraren eller ta en penna för att anteckna det och din nya fröfras. + Vi vet det inte och vi har ingen kopia! Konfigurera appens lösenord Välj ett lösenord för att låsa upp din Brainwallet Inte en telefonlåskod! @@ -406,7 +406,7 @@ Bekräfta Du glömde väl inte? Skriv in det igen. Eller gå tillbaka för att börja om. Redo - Återställa + Återställ med Seed Phrase Felaktigt lösenord, försök igen! ned-vänster-pil logotyp diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index cd3a9eaf..71f767b1 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -770,10 +770,10 @@ Onu kurtardın, değil mi? Kanıtlayın!\nKelimeleri doğru sıraya göre sürükleyin. Oyun ve Senkronizasyon - Hazır? - Bunu kendin için yap. Lütfen yap - yalnız - Bir kalem, kağıt alın ve 5 dakika + Başlamaya hazır mısınız? + Bu sadece sana özel. + Uygulama şifrenizi ayarlayın, şifre yöneticinizi açın veya bir kalem alıp şifrenizi ve yeni başlangıç ​​cümlenizi kaydedin. + Biz bunu bilmiyoruz, kopyası da bizde yok! Uygulama şifresini ayarla Beyin Cüzdanınızın kilidini açmak için bir şifre seçin Telefon kilit kodu değil! @@ -790,7 +790,7 @@ Onaylamak Unutmadın değil mi? Tekrar girin. Veya baştan başlamak için geri dönün. Hazır - Eski haline getirmek + Tohum İfadesi ile Geri Yükle Yanlış Şifre, lütfen tekrar deneyin! sol aşağı ok logo diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index cd63237d..311e84e9 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -754,10 +754,10 @@ Ви зберегли його, правда? Доведіть це!\nПеретягніть слова в правильному порядку. Гра та синхронізація - готовий - Зробіть це для вас. Будь ласка, зробіть це - поодинці - Візьміть ручку, папір і 5 хвилин + Готові почати? + Це тільки для тебе. + Налаштуйте пароль програми, відкрийте менеджер паролів або візьміть ручку, щоб записати його та нову початкову фразу. + Ми цього не знаємо і не маємо копії! Налаштуйте пароль програми Виберіть пароль, щоб розблокувати свій Brainwallet Не код блокування телефону! @@ -774,7 +774,7 @@ Підтвердити Ви не забули? Введіть його знову. Або поверніться, щоб почати спочатку. Готовий - Відновити + Відновлення за початкової фрази Неправильний пароль, спробуйте ще раз! стрілка вниз-ліворуч логотип diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 4f28b512..e43d6b0f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -748,10 +748,10 @@ 你救了它,对吗? 证明一下!\n按正确的顺序拖动单词。 游戏与同步 - 准备好? - 为你做这件事。请这样做 - 独自的 - 拿起笔、纸和 5 分钟 + 准备好开始了吗? + 这是只属于你一个人的。 + 设置应用程序密码,打开密码管理器或拿一支笔记录它和你的新种子短语。 + 我们不知道,也没有副本! 设置应用程序密码 选择密码来解锁您的 Brainwallet 不是手机锁码! @@ -768,7 +768,7 @@ 确认 你没有忘记吧?再次输入。或者,返回重新开始。 准备好 - 恢复 + 使用种子短语恢复 密码错误,请重试! 左下箭头 标识 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 378bc1aa..8e29fb69 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -747,10 +747,10 @@ 你救了它,對嗎? 證明一下! 遊戲與同步 - 準備好? - 為你做這件事。請這樣做 - 獨自的 - 拿起筆、紙和 5 分鐘 + 準備好開始了嗎? + 我們不知道,也沒有副本! + 設定應用程式密碼,打開密碼管理器或拿一支筆記錄它和你的新種子短語。 + 我們不知道,也沒有副本! 設定應用程式密碼 選擇密碼來解鎖您的 Brainwallet 不是手機鎖碼! @@ -767,7 +767,7 @@ 確認 你沒有忘記吧?再次輸入。或者,返回重新開始。 準備好 - 恢復 + 使用種子短語恢復 密碼錯誤,請重試! 左下箭頭 標識 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 443eee4f..cb798919 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -785,10 +785,10 @@ You saved it, right? Prove it!\nDrag the words in the correct order. Game & Sync - Ready? - Do this for you. Please do it - alone - Grab a pen, paper and 5 minutes + Ready to start? + This is for you alone. + Setup the app passcode, open your password manager or grab a pen to record it & your new seed phrase. + We do not know it nor do we have a copy! Setup app passcode Pick a passcode to unlock your Brainwallet Not a phone lock code! @@ -811,7 +811,7 @@ Confirm You didn’t forget did you? Enter it again. Or, go back to start over. Ready - Restore + Restore With Seed Phrase Incorrect Passcode, please try again! down-left-arrow logo From 18df29329942d52f7cbaa0a4c22524c788a1a415 Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Tue, 26 Aug 2025 15:05:43 +0700 Subject: [PATCH 060/116] fix(#226): android test failure on RecoverWalletScreenGrabsTest (#130) Move SCREENGRAB_PAPERKEY build config to debug build type The `SCREENGRAB_PAPERKEY` build configuration field, used for screengrab tests, was previously defined in both the `debug` and `screengrab` build types. This commit moves the definition solely to the `debug` build type, as the `screengrab` build type inherits from `debug` and thus already has access to this field. Additionally, unused imports were removed from `BrainwalletScreengrabApp.kt`. --- app/build.gradle.kts | 14 +++++++------- .../com/brainwallet/BrainwalletScreengrabApp.kt | 3 --- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index aac3d3e6..8c8ae5bb 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -71,6 +71,13 @@ android { firebaseCrashlytics { nativeSymbolUploadEnabled = true } + buildConfigField("String[]", "SCREENGRAB_PAPERKEY", + "new String[] {${ + localProperties.getProperty("SCREENGRAB_PAPERKEY", "") + .split(" ") + .joinToString { "\"$it\"" } + }}" + ) } val release by getting { @@ -125,13 +132,6 @@ android { applicationId = "ltd.grunt.brainwallet.screengrab" versionNameSuffix = "-screengrab" resValue("string", "app_name", "Brainwallet (screengrab)") - buildConfigField("String[]", "SCREENGRAB_PAPERKEY", - "new String[] {${ - localProperties.getProperty("SCREENGRAB_PAPERKEY", "") - .split(" ") - .joinToString { "\"$it\"" } - }}" - ) externalNativeBuild { cmake { diff --git a/app/src/screengrab/kotlin/com/brainwallet/BrainwalletScreengrabApp.kt b/app/src/screengrab/kotlin/com/brainwallet/BrainwalletScreengrabApp.kt index 6e14bcf3..c181d83e 100644 --- a/app/src/screengrab/kotlin/com/brainwallet/BrainwalletScreengrabApp.kt +++ b/app/src/screengrab/kotlin/com/brainwallet/BrainwalletScreengrabApp.kt @@ -1,9 +1,6 @@ package com.brainwallet import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.di.appModule -import com.brainwallet.di.dataModule -import com.brainwallet.di.viewModelModule import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidLogger import org.koin.core.context.GlobalContext.startKoin From 9b191b777b5e40a92b0629a74ade4e385a48c93b Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Tue, 26 Aug 2025 15:50:12 +0700 Subject: [PATCH 061/116] fix(#223): fix issue on test environment SLF4J + agent warnings in test env (#129) - Added `slf4j-android` as a test dependency to provide a proper SLF4J binding and avoid "StaticLoggerBinder" warnings. - Configured JVM args for Gradle test tasks to enable dynamic agent loading, suppressing Byte Buddy agent warnings during test runs. --- app/build.gradle.kts | 8 +++++++- gradle/libs.versions.toml | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8c8ae5bb..abf18b73 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -245,12 +245,14 @@ dependencies { testImplementation(libs.junit) testImplementation(libs.mockk) testImplementation(libs.turbine) + testImplementation(libs.slf4j.android) testImplementation(libs.kotlinx.coroutines.tests) androidTestImplementation(platform(libs.androidx.compose.bom)) androidTestImplementation(libs.bundles.androidx.compose.ui.test) androidTestImplementation(libs.bundles.android.test) androidTestImplementation(libs.fastlane.screengrab) + androidTestImplementation(libs.slf4j.android) } val ktlintCheck by tasks.registering(JavaExec::class) { @@ -283,4 +285,8 @@ tasks.register("ktlintFormat") { "**.kts", "!**/build/**", ) -} \ No newline at end of file +} + +tasks.withType { + jvmArgs("-XX:+EnableDynamicAgentLoading") +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f18f2b70..a0f2aba6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -35,6 +35,7 @@ koin-annotation-bom = "2.1.0" ksp = "2.0.0-1.0.24" turbine = "1.2.1" coroutines = "1.10.2" +slf4j = "1.7.36" [libraries] androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" } @@ -122,6 +123,7 @@ koin-annotation-compiler = { module = "io.insert-koin:koin-ksp-compiler", versio turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" } kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } kotlinx-coroutines-tests = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } +slf4j-android = { module = "org.slf4j:slf4j-android", version.ref = "slf4j" } [bundles] androidx-lifecycle = ["androidx-lifecycle-runtime", "androidx-lifecycle-viewmodel", "androidx-lifecycle-viewmodel-compose"] From c9b1ef036881f56db34a2a874db7c5eb672e18eb Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Sat, 30 Aug 2025 14:13:07 +0700 Subject: [PATCH 062/116] feat(#225): Send sync duration in Firebase Analytics as a custom event and in Settings row (#131) * feat(#225): Send sync duration in Firebase Analytics as a custom event and in Settings row This commit introduces analytics tracking for the sync process. It includes: - `TimeProvider`: A utility class for getting the current time, allowing for easier testing. - `AnalyticsSource`: An interface for logging analytics events. - `FirebaseAnalyticsSource`: An implementation of `AnalyticsSource` that uses Firebase Analytics. - `SyncAnalyticsRepository`: A repository to manage and persist sync-related analytics data, and log events. - `startSync()`: Records the start time of a sync. - `stopSync()`: Records the stop time of a sync and accumulates the duration if the sync is paused/resumed. - `completeSync()`: Persists the total sync duration, end timestamp, and a unique ID. It then logs a "user_did_complete_sync" event with these details and the current block height. - `getLastSyncMetadata()`: Retrieves the metadata of the last completed sync. - Unit tests for the new classes. - Integration of `SyncAnalyticsRepository` into `SyncManager` to call the respective methods at the start, stop, and completion of the sync process. - `FakeSharedPreferences`: A testing utility for mocking SharedPreferences. * chore(#225): Move SyncMetadata formatting to Formatter class This commit introduces a `Formatter` class within `SyncAnalyticsRepository.SyncMetadata` to handle the formatting of sync metadata. The `getFormatted()` method has been removed from `SyncAnalyticsRepository.SyncMetadata` and its logic is now encapsulated in the `SyncMetadata.Formatter.format()` method. This change improves the separation of concerns and makes the formatting logic more testable. The `HomeSettingDrawerSheet` has been updated to use the new `Formatter` class. Unit tests have been added to `SyncAnalyticsRepositoryTest` to verify the correctness of the `SyncMetadata.Formatter`. --- .../repository/SyncAnalyticsRepository.kt | 106 ++++++++++ .../data/source/AnalyticsSource.kt | 6 + .../data/source/FirebaseAnalyticsSource.kt | 33 +++ .../data/source/PeerManagerSource.kt | 17 ++ .../tools/manager/SyncManager.java | 13 +- .../ui/screens/home/SettingsEvent.kt | 4 +- .../ui/screens/home/SettingsState.kt | 4 +- .../home/composable/HomeSettingDrawerSheet.kt | 14 +- .../java/com/brainwallet/util/TimeProvider.kt | 12 ++ .../repository/SyncAnalyticsRepositoryTest.kt | 192 ++++++++++++++++++ .../source/FirebaseAnalyticsSourceTest.kt | 46 +++++ .../data/source/PeerManagerSourceTest.kt | 42 ++++ .../brainwallet/util/FakeSharedPreferences.kt | 107 ++++++++++ .../com/brainwallet/util/TimeProviderTest.kt | 16 ++ 14 files changed, 606 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/data/repository/SyncAnalyticsRepository.kt create mode 100644 app/src/main/java/com/brainwallet/data/source/AnalyticsSource.kt create mode 100644 app/src/main/java/com/brainwallet/data/source/FirebaseAnalyticsSource.kt create mode 100644 app/src/main/java/com/brainwallet/data/source/PeerManagerSource.kt create mode 100644 app/src/main/java/com/brainwallet/util/TimeProvider.kt create mode 100644 app/src/test/java/com/brainwallet/data/repository/SyncAnalyticsRepositoryTest.kt create mode 100644 app/src/test/java/com/brainwallet/data/source/FirebaseAnalyticsSourceTest.kt create mode 100644 app/src/test/java/com/brainwallet/data/source/PeerManagerSourceTest.kt create mode 100644 app/src/test/java/com/brainwallet/util/FakeSharedPreferences.kt create mode 100644 app/src/test/java/com/brainwallet/util/TimeProviderTest.kt diff --git a/app/src/main/java/com/brainwallet/data/repository/SyncAnalyticsRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SyncAnalyticsRepository.kt new file mode 100644 index 00000000..3486dd02 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/SyncAnalyticsRepository.kt @@ -0,0 +1,106 @@ +package com.brainwallet.data.repository + +import android.content.SharedPreferences +import androidx.core.content.edit +import com.brainwallet.data.source.AnalyticsSource +import com.brainwallet.data.source.PeerManagerSource +import org.koin.core.annotation.Single +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale +import java.util.UUID + +@Single +class SyncAnalyticsRepository( + private val analyticsSource: AnalyticsSource, + private val peerManagerSource: PeerManagerSource, + private val prefs: SharedPreferences, +) { + fun startSync() { + // Record the start time of the current sync segment. + prefs.edit { + putLong(KEY_CURRENT_SYNC_START_TIMESTAMP, peerManagerSource.getLastBlockTimestamp()) + } + } + + fun stopSync() { + val start = prefs.getLong(KEY_CURRENT_SYNC_START_TIMESTAMP, 0L) + if (start != 0L) { + val duration = peerManagerSource.getLastBlockTimestamp() - start + val accumulated = prefs.getLong(KEY_ACCUMULATED_DURATION, 0L) + prefs.edit { + putLong(KEY_ACCUMULATED_DURATION, accumulated + duration) + remove(KEY_CURRENT_SYNC_START_TIMESTAMP) + } + } + } + + fun completeSync() { + // Capture the duration of the final segment. + stopSync() + + val totalDuration = prefs.getLong(KEY_ACCUMULATED_DURATION, 0L) + if (totalDuration == 0L) return + + val endTimestamp = peerManagerSource.getLastBlockTimestamp() + val endBlockHeight = peerManagerSource.getCurrentBlockHeight() + val uuid = UUID.randomUUID().toString() + val totalDurationInMillis = totalDuration * 1000 + + prefs.edit { + putString(KEY_LAST_UUID, uuid) + putLong(KEY_LAST_DURATION, totalDurationInMillis) + putLong(KEY_LAST_END, endTimestamp) + remove(KEY_ACCUMULATED_DURATION) + } + + val params = mapOf( + KEY_UUID to uuid, + KEY_DURATION_MILLIS to (totalDurationInMillis), + KEY_END_TIMESTAMP to endTimestamp, + KEY_END_BLOCK_HEIGHT to endBlockHeight + ) + analyticsSource.logEventWithParams(KEY_EVENT, params) + } + + fun getLastSyncMetadata(): SyncMetadata? { + val uuid = prefs.getString(KEY_LAST_UUID, null) ?: return null + val duration = prefs.getLong(KEY_LAST_DURATION, 0L) + val end = prefs.getLong(KEY_LAST_END, 0L) + return SyncMetadata(uuid, duration, end) + } + + data class SyncMetadata( + val uuid: String, + val durationMillis: Long, + val endTimestamp: Long + ) { + class Formatter( + private val dateFormat: SimpleDateFormat = SimpleDateFormat( + "MMMM dd, yyyy h:mm:ss a", + Locale.getDefault() + ) + ) { + fun format(syncMetadata: SyncMetadata): String { + val durationSeconds = syncMetadata.durationMillis / 1000.0 + val date = Date(syncMetadata.endTimestamp * 1000) + val dateString = dateFormat.format(date) + + return "Duration: %.1f seconds\nTimestamp: %s".format(durationSeconds, dateString) + } + } + } + + companion object { + private const val KEY_CURRENT_SYNC_START_TIMESTAMP = "current_sync_start_timestamp" + private const val KEY_ACCUMULATED_DURATION = "accumulated_sync_duration" + private const val KEY_LAST_UUID = "last_sync_uuid" + private const val KEY_LAST_DURATION = "last_sync_duration" + private const val KEY_LAST_END = "last_sync_end_timestamp" + private const val KEY_DURATION_MILLIS = "duration_millis" + private const val KEY_END_TIMESTAMP = "end_timestamp" + private const val KEY_END_BLOCK_HEIGHT = "end_block_height" + private const val KEY_UUID = "uuid" + private const val KEY_EVENT = "user_did_complete_sync" + } +} diff --git a/app/src/main/java/com/brainwallet/data/source/AnalyticsSource.kt b/app/src/main/java/com/brainwallet/data/source/AnalyticsSource.kt new file mode 100644 index 00000000..8449f188 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/source/AnalyticsSource.kt @@ -0,0 +1,6 @@ +package com.brainwallet.data.source + +interface AnalyticsSource { + fun logEvent(event: String) + fun logEventWithParams(event: String, params: Map) +} diff --git a/app/src/main/java/com/brainwallet/data/source/FirebaseAnalyticsSource.kt b/app/src/main/java/com/brainwallet/data/source/FirebaseAnalyticsSource.kt new file mode 100644 index 00000000..0360d489 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/source/FirebaseAnalyticsSource.kt @@ -0,0 +1,33 @@ +package com.brainwallet.data.source + +import android.content.Context +import android.os.Bundle +import com.google.firebase.analytics.FirebaseAnalytics +import org.koin.core.annotation.Single + +@Single +class FirebaseAnalyticsSource( + private val context: Context, + private val analytics: FirebaseAnalytics = FirebaseAnalytics.getInstance(context) +) : AnalyticsSource { + + override fun logEvent(event: String) { + analytics.logEvent(event, null) + } + + override fun logEventWithParams(event: String, params: Map) { + val bundle = Bundle().apply { + params.forEach { (key, value) -> + when (value) { + is String -> putString(key, value) + is Int -> putInt(key, value) + is Long -> putLong(key, value) + is Double -> putDouble(key, value) + is Boolean -> putBoolean(key, value) + // add more types if needed + } + } + } + analytics.logEvent(event, bundle) + } +} diff --git a/app/src/main/java/com/brainwallet/data/source/PeerManagerSource.kt b/app/src/main/java/com/brainwallet/data/source/PeerManagerSource.kt new file mode 100644 index 00000000..10eaf13b --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/source/PeerManagerSource.kt @@ -0,0 +1,17 @@ +package com.brainwallet.data.source + +import com.brainwallet.wallet.BRPeerManager +import org.koin.core.annotation.Single + +interface BRPeerManagerProxy { + fun getCurrentBlockHeight(): Int + fun getLastBlockTimestamp(): Long +} + +@Single +class PeerManagerSource( + private val proxy: BRPeerManagerProxy = object : BRPeerManagerProxy { + override fun getCurrentBlockHeight(): Int = BRPeerManager.getCurrentBlockHeight() + override fun getLastBlockTimestamp(): Long = BRPeerManager.getInstance().lastBlockTimestamp + } +) : BRPeerManagerProxy by proxy diff --git a/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java b/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java index ace9dcc1..c33fc2c5 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java @@ -1,5 +1,6 @@ package com.brainwallet.tools.manager; +import static com.brainwallet.data.source.RemoteConfigSource.KEY_FEATURE_SELECTED_PEERS_ENABLED; import static com.brainwallet.tools.manager.BRSharedPrefs.putSyncMetadata; import android.app.AlarmManager; @@ -9,6 +10,8 @@ import android.os.Build; import android.os.Bundle; +import com.brainwallet.data.repository.SyncAnalyticsRepository; +import com.brainwallet.data.source.RemoteConfigSource; import com.brainwallet.tools.listeners.SyncReceiver; import com.brainwallet.tools.util.BRConstants; import com.brainwallet.tools.util.Utils; @@ -16,6 +19,8 @@ import com.brainwallet.presenter.activities.BreadActivity; import com.brainwallet.wallet.BRPeerManager; +import org.koin.java.KoinJavaComponent; + import java.util.concurrent.TimeUnit; import timber.log.Timber; @@ -34,6 +39,10 @@ public static SyncManager getInstance() { private SyncManager() { } + public static SyncAnalyticsRepository getSyncAnalyticsRepository() { + return KoinJavaComponent.get(SyncAnalyticsRepository.class); + } + public synchronized void startSyncingProgressThread(Context app) { try { if (syncTask != null) { @@ -45,6 +54,7 @@ public synchronized void startSyncingProgressThread(Context app) { syncTask = null; } syncTask = new SyncProgressTask(); + getSyncAnalyticsRepository().startSync(); syncTask.start(); updateStartSyncData(app); } catch (IllegalThreadStateException ex) { @@ -59,10 +69,11 @@ private synchronized void updateStartSyncData(Context app) { private synchronized void markFinishedSyncData(Context app) { Timber.d("timber: || SYNC ELAPSE markFinish threadname:%s", Thread.currentThread().getName()); final double progress = BRPeerManager.syncProgress(BRSharedPrefs.getStartHeight(app)); + getSyncAnalyticsRepository().completeSync(); } public synchronized void stopSyncingProgressThread(Context app) { - + getSyncAnalyticsRepository().stopSync(); if (app == null) { Timber.i("timber: || stopSyncingProgressThread: ctx is null"); return; diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt index cf6b1d31..36ef087f 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt @@ -3,10 +3,12 @@ package com.brainwallet.ui.screens.home import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Language +import com.brainwallet.data.repository.SyncAnalyticsRepository + sealed class SettingsEvent { data class OnLoad( val shareAnalyticsDataEnabled: Boolean = false, - val lastSyncMetadata: String? = null, + val lastSyncMetadata: SyncAnalyticsRepository.SyncMetadata? = null, ) : SettingsEvent() object OnSecurityUpdatePinClick : SettingsEvent() object OnSecuritySeedPhraseClick : SettingsEvent() diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt index d0336bff..b1e82c75 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt @@ -7,6 +7,8 @@ import com.brainwallet.data.model.Language import com.brainwallet.data.model.toFeeOptions import com.brainwallet.tools.manager.FeeManager +import com.brainwallet.data.repository.SyncAnalyticsRepository + data class SettingsState( val darkMode: Boolean = true, val selectedLanguage: Language = Language.ENGLISH, @@ -19,7 +21,7 @@ data class SettingsState( val languageSelectorBottomSheetVisible: Boolean = false, val fiatSelectorBottomSheetVisible: Boolean = false, val shareAnalyticsDataEnabled: Boolean = false, - val lastSyncMetadata: String? = null, + val lastSyncMetadata: SyncAnalyticsRepository.SyncMetadata? = null, val currentFeeOptions: List = Fee.Default.toFeeOptions(), val selectedFeeType: String = FeeManager.LUXURY ) \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index d96cda42..fbb01438 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -28,6 +28,7 @@ import androidx.lifecycle.coroutineScope import androidx.lifecycle.findViewTreeLifecycleOwner import com.brainwallet.R import com.brainwallet.data.model.AppSetting +import com.brainwallet.data.repository.SyncAnalyticsRepository import com.brainwallet.tools.manager.BRSharedPrefs import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.screens.home.SettingsEvent @@ -48,12 +49,14 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import org.koin.compose.koinInject +import org.koin.compose.viewmodel.koinViewModel import org.koin.java.KoinJavaComponent.inject @Composable fun HomeSettingDrawerSheet( modifier: Modifier = Modifier, - viewModel: SettingsViewModel = koinInject() + syncAnalyticsRepository: SyncAnalyticsRepository = koinInject(), + viewModel: SettingsViewModel = koinViewModel() ) { val state by viewModel.state.collectAsState() val context = LocalContext.current @@ -61,7 +64,7 @@ fun HomeSettingDrawerSheet( LaunchedEffect(Unit) { viewModel.onEvent(SettingsEvent.OnLoad( shareAnalyticsDataEnabled = BRSharedPrefs.getShareData(context), //currently just load analytics share data here - lastSyncMetadata = BRSharedPrefs.getSyncMetadata(context), //currently just load sync metadata here + lastSyncMetadata = syncAnalyticsRepository.getLastSyncMetadata(), //currently just load sync metadata here )) } @@ -192,10 +195,15 @@ fun HomeSettingDrawerSheet( } item { + val description = state.lastSyncMetadata?.let { + SyncAnalyticsRepository.SyncMetadata.Formatter() + .format(it) + } ?: "No sync metadata" + SettingRowItem( modifier = Modifier.height(100.dp), title = stringResource(R.string.settings_title_sync_metadata), - description = state.lastSyncMetadata ?: "No sync metadata" + description = description ) } diff --git a/app/src/main/java/com/brainwallet/util/TimeProvider.kt b/app/src/main/java/com/brainwallet/util/TimeProvider.kt new file mode 100644 index 00000000..0fdebf7d --- /dev/null +++ b/app/src/main/java/com/brainwallet/util/TimeProvider.kt @@ -0,0 +1,12 @@ +package com.brainwallet.util + +import org.koin.core.annotation.Single + +@Single +class TimeProvider( + private val nowGetter: () -> Long = { System.currentTimeMillis() } +) { + fun now(): Long { + return nowGetter() + } +} diff --git a/app/src/test/java/com/brainwallet/data/repository/SyncAnalyticsRepositoryTest.kt b/app/src/test/java/com/brainwallet/data/repository/SyncAnalyticsRepositoryTest.kt new file mode 100644 index 00000000..0167e25f --- /dev/null +++ b/app/src/test/java/com/brainwallet/data/repository/SyncAnalyticsRepositoryTest.kt @@ -0,0 +1,192 @@ +package com.brainwallet.data.repository + +import android.content.SharedPreferences +import com.brainwallet.data.source.AnalyticsSource +import com.brainwallet.data.source.PeerManagerSource +import com.brainwallet.util.FakeSharedPreferences +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.mockkStatic +import io.mockk.slot +import io.mockk.unmockkAll +import io.mockk.verify +import org.junit.After +import org.junit.Before +import org.junit.Test +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale +import java.util.TimeZone +import java.util.UUID + +class SyncAnalyticsRepositoryTest { + private lateinit var prefs: SharedPreferences + + @MockK + private lateinit var analyticsSource: AnalyticsSource + + @MockK + private lateinit var peerManagerSource: PeerManagerSource + + private lateinit var repository: SyncAnalyticsRepository + + @Before + fun setUp() { + MockKAnnotations.init(this, relaxUnitFun = true) + prefs = FakeSharedPreferences() + repository = SyncAnalyticsRepository( + analyticsSource = analyticsSource, + peerManagerSource = peerManagerSource, + prefs = prefs + ) + } + + @After + fun tearDown() { + unmockkAll() + } + + @Test + fun `given sync started when startSync called then start timestamp stored`() { + every { peerManagerSource.getLastBlockTimestamp() } returns 1000L + + repository.startSync() + + val stored = prefs.getLong("current_sync_start_timestamp", -1L) + assert(stored == 1000L) { "expected 1000L but was $stored" } + } + + @Test + fun `given sync started and stopped when stopSync called then duration accumulated`() { + prefs.edit().putLong("current_sync_start_timestamp", 1000L).apply() + prefs.edit().putLong("accumulated_sync_duration", 200L).apply() + every { peerManagerSource.getLastBlockTimestamp() } returns 1500L + + repository.stopSync() + + val accumulated = prefs.getLong("accumulated_sync_duration", 0L) + val startRemoved = prefs.getLong("current_sync_start_timestamp", -1L) + assert(accumulated == 700L) { "expected 700L but was $accumulated" } + assert(startRemoved == -1L) { "expected current_sync_start_timestamp to be removed" } + } + + @Test + fun `given sync never started when stopSync called then nothing stored`() { + prefs.edit().putLong("current_sync_start_timestamp", 0L).apply() + + repository.stopSync() + + val accumulated = prefs.getLong("accumulated_sync_duration", 0L) + assert(accumulated == 0L) { "expected no accumulation but was $accumulated" } + } + + @Test + fun `given accumulated duration when completeSync called then metadata persisted and event logged`() { + prefs.edit().putLong("accumulated_sync_duration", 5000L).apply() + every { peerManagerSource.getLastBlockTimestamp() } returns 6000L + every { peerManagerSource.getCurrentBlockHeight() } returns 456 + + mockkStatic(UUID::class) + every { UUID.randomUUID().toString() } returns "uuid-123" + + repository.completeSync() + + val lastUuid = prefs.getString("last_sync_uuid", null) + val lastDuration = prefs.getLong("last_sync_duration", 0L) + val lastEnd = prefs.getLong("last_sync_end_timestamp", 0L) + val accumulatedCleared = prefs.getLong("accumulated_sync_duration", -1L) + + assert(lastUuid == "uuid-123") { "expected uuid-123 but was $lastUuid" } + assert(lastDuration == 5000000L) { "expected duration=5000000 but was $lastDuration" } + assert(lastEnd == 6000L) { "expected end=6000 but was $lastEnd" } + assert(accumulatedCleared == -1L) { "expected accumulated_sync_duration removed" } + + val paramsSlot = slot>() + + verify { + analyticsSource.logEventWithParams( + "user_did_complete_sync", + capture(paramsSlot) + ) + } + + val captured = paramsSlot.captured + println("captured: $captured") + + assert(captured["uuid"] == "uuid-123") { "uuid should match" } + assert(captured["duration_millis"] == 5000000L) { "duration should match" } + assert(captured["end_timestamp"] == 6000L) { "end timestamp should match" } + assert(captured["end_block_height"] == 456) { "end block height should match" } + } + + @Test + fun `given metadata stored when getLastSyncMetadata called then correct SyncMetadata returned`() { + prefs.edit() + .putString("last_sync_uuid", "uuid-999") + .putLong("last_sync_duration", 8888L) + .putLong("last_sync_end_timestamp", 9999L) + .apply() + + val metadata = repository.getLastSyncMetadata() + + assert(metadata != null) { "expected metadata to be not null" } + assert(metadata!!.uuid == "uuid-999") { "expected uuid=uuid-999 but was ${metadata.uuid}" } + assert(metadata.durationMillis == 8888L) { "expected duration=8888 but was ${metadata.durationMillis}" } + assert(metadata.endTimestamp == 9999L) { "expected endTimestamp=9999 but was ${metadata.endTimestamp}" } + } + + @Test + fun `given no metadata stored when getLastSyncMetadata called then null returned`() { + val metadata = repository.getLastSyncMetadata() + assert(metadata == null) { "expected metadata to be null" } + } + + @Test + fun `given sync metadata when format then return formatted string containing correct duration and timestamp`() { + val fixedDateFormat = SimpleDateFormat("MMMM dd, yyyy h:mm:ss a", Locale.US).apply { + timeZone = TimeZone.getTimeZone("UTC") + } + val formatter = SyncAnalyticsRepository.SyncMetadata.Formatter(fixedDateFormat) + + val syncMetadata = SyncAnalyticsRepository.SyncMetadata( + uuid = "1234", + durationMillis = 2500L, + endTimestamp = 1633072800L + ) + + val formattedOutput = formatter.format(syncMetadata) + + assert(formattedOutput.contains("Duration: 2.5 seconds")) { + "Expected formatted string to contain 'Duration: 2.5 seconds' but got '$formattedOutput'" + } + + val expectedDatePart = fixedDateFormat.format(Date(syncMetadata.endTimestamp * 1000)) + assert(formattedOutput.contains(expectedDatePart)) { + "Expected formatted string to contain '$expectedDatePart' but got '$formattedOutput'" + } + } + + @Test + fun `given sync metadata when format then return exactly formatted string with correct structure`() { + val fixedDateFormat = SimpleDateFormat("MMMM dd, yyyy h:mm:ss a", Locale.US).apply { + timeZone = TimeZone.getTimeZone("UTC") + } + val formatter = SyncAnalyticsRepository.SyncMetadata.Formatter(fixedDateFormat) + + val syncMetadata = SyncAnalyticsRepository.SyncMetadata( + uuid = "1234", + durationMillis = 2500L, + endTimestamp = 1633072800L + ) + + val actual = formatter.format(syncMetadata) + + val expectedDate = fixedDateFormat.format(Date(syncMetadata.endTimestamp * 1000)) + val expected = "Duration: 2.5 seconds\nTimestamp: $expectedDate" + + assert(actual == expected) { + "Expected exactly '$expected' but got '$actual'" + } + } +} diff --git a/app/src/test/java/com/brainwallet/data/source/FirebaseAnalyticsSourceTest.kt b/app/src/test/java/com/brainwallet/data/source/FirebaseAnalyticsSourceTest.kt new file mode 100644 index 00000000..c8d79346 --- /dev/null +++ b/app/src/test/java/com/brainwallet/data/source/FirebaseAnalyticsSourceTest.kt @@ -0,0 +1,46 @@ +package com.brainwallet.data.source + +import android.content.Context +import com.google.firebase.analytics.FirebaseAnalytics +import io.mockk.MockKAnnotations +import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.RelaxedMockK +import io.mockk.verify +import org.junit.Before +import org.junit.Test + +class FirebaseAnalyticsSourceTest { + + @RelaxedMockK + private lateinit var context: Context + + @MockK + private lateinit var firebaseAnalytics: FirebaseAnalytics + private lateinit var sut: FirebaseAnalyticsSource + + @Before + fun setUp() { + MockKAnnotations.init(this, relaxUnitFun = true) + sut = FirebaseAnalyticsSource(context, firebaseAnalytics) + } + + @Test + fun `given valid event name when logCustomEvent is called then event should be logged without params`() { + val eventName = "test_event" + + sut.logEvent(eventName) + + verify(exactly = 1) { firebaseAnalytics.logEvent(eventName, null) } + assert(true) { "Expected logEvent to be called with eventName=$eventName and params=null" } + } + + @Test + fun `given valid event name and params when logCustomEventWithParams is called then event should be logged with params`() { + val eventName = "test_event_with_params" + + sut.logEventWithParams(eventName, mapOf()) + + verify(exactly = 1) { firebaseAnalytics.logEvent(eventName, any()) } + assert(true) { "Expected logEvent to be called with eventName=$eventName and provided params" } + } +} diff --git a/app/src/test/java/com/brainwallet/data/source/PeerManagerSourceTest.kt b/app/src/test/java/com/brainwallet/data/source/PeerManagerSourceTest.kt new file mode 100644 index 00000000..a415847b --- /dev/null +++ b/app/src/test/java/com/brainwallet/data/source/PeerManagerSourceTest.kt @@ -0,0 +1,42 @@ +package com.brainwallet.data.source + +import io.mockk.every +import io.mockk.mockk +import org.junit.Before +import org.junit.Test + +class PeerManagerSourceTest { + + private lateinit var proxy: BRPeerManagerProxy + private lateinit var peerManagerSource: PeerManagerSource + + @Before + fun setUp() { + proxy = mockk() + peerManagerSource = PeerManagerSource(proxy) + } + + @Test + fun `Given proxy returns block height When calling getCurrentBlockHeight Then it should return expected block height`() { + val expectedHeight = 12345 + every { proxy.getCurrentBlockHeight() } returns expectedHeight + + val actualHeight = peerManagerSource.getCurrentBlockHeight() + + assert(actualHeight == expectedHeight) { + "Expected block height to be $expectedHeight but was $actualHeight" + } + } + + @Test + fun `Given proxy returns last block timestamp When calling getLastBlockTimestamp Then it should return expected timestamp`() { + val expectedTimestamp = 1699999999L + every { proxy.getLastBlockTimestamp() } returns expectedTimestamp + + val actualTimestamp = peerManagerSource.getLastBlockTimestamp() + + assert(actualTimestamp == expectedTimestamp) { + "Expected last block timestamp to be $expectedTimestamp but was $actualTimestamp" + } + } +} diff --git a/app/src/test/java/com/brainwallet/util/FakeSharedPreferences.kt b/app/src/test/java/com/brainwallet/util/FakeSharedPreferences.kt new file mode 100644 index 00000000..bebdffb3 --- /dev/null +++ b/app/src/test/java/com/brainwallet/util/FakeSharedPreferences.kt @@ -0,0 +1,107 @@ +package com.brainwallet.util + +import android.content.SharedPreferences + +class FakeSharedPreferences : SharedPreferences { + + private val data = mutableMapOf() + private val listeners = mutableSetOf() + + override fun getAll(): MutableMap = data.toMutableMap() + + override fun getString(key: String?, defValue: String?): String? = + data[key] as? String ?: defValue + + override fun getLong(key: String?, defValue: Long): Long = + (data[key] as? Long) ?: defValue + + override fun getInt(key: String?, defValue: Int): Int = + (data[key] as? Int) ?: defValue + + override fun getBoolean(key: String?, defValue: Boolean): Boolean = + (data[key] as? Boolean) ?: defValue + + override fun getFloat(key: String?, defValue: Float): Float = + (data[key] as? Float) ?: defValue + + override fun getStringSet(key: String?, defValues: MutableSet?): MutableSet? = + (data[key] as? MutableSet) ?: defValues + + override fun contains(key: String?): Boolean = data.containsKey(key) + + override fun edit(): SharedPreferences.Editor = FakeEditor() + + override fun registerOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) { + listener?.let { listeners.add(it) } + } + + override fun unregisterOnSharedPreferenceChangeListener(listener: SharedPreferences.OnSharedPreferenceChangeListener?) { + listeners.remove(listener) + } + + inner class FakeEditor : SharedPreferences.Editor { + private val temp = mutableMapOf() + private val toRemove = mutableSetOf() + private var clear = false + + override fun putString(key: String?, value: String?): SharedPreferences.Editor { + temp[key!!] = value + return this + } + + override fun putLong(key: String?, value: Long): SharedPreferences.Editor { + temp[key!!] = value + return this + } + + override fun putInt(key: String?, value: Int): SharedPreferences.Editor { + temp[key!!] = value + return this + } + + override fun putBoolean(key: String?, value: Boolean): SharedPreferences.Editor { + temp[key!!] = value + return this + } + + override fun putFloat(key: String?, value: Float): SharedPreferences.Editor { + temp[key!!] = value + return this + } + + override fun putStringSet( + key: String?, + values: MutableSet? + ): SharedPreferences.Editor { + temp[key!!] = values + return this + } + + override fun remove(key: String?): SharedPreferences.Editor { + toRemove.add(key!!) + return this + } + + override fun clear(): SharedPreferences.Editor { + clear = true + return this + } + + override fun commit(): Boolean { + apply() + return true + } + + override fun apply() { + if (clear) { + data.clear() + } + toRemove.forEach { data.remove(it) } + data.putAll(temp) + // notify listeners + (temp.keys + toRemove).forEach { key -> + listeners.forEach { it.onSharedPreferenceChanged(this@FakeSharedPreferences, key) } + } + } + } +} diff --git a/app/src/test/java/com/brainwallet/util/TimeProviderTest.kt b/app/src/test/java/com/brainwallet/util/TimeProviderTest.kt new file mode 100644 index 00000000..1278c010 --- /dev/null +++ b/app/src/test/java/com/brainwallet/util/TimeProviderTest.kt @@ -0,0 +1,16 @@ +package com.brainwallet.util + +import org.junit.Test + +class TimeProviderTest { + + @Test + fun `returns provided nowGetter value`() { + val fixedTime = 123456789L + val timeProvider = TimeProvider { fixedTime } + + val result = timeProvider.now() + + assert(result == fixedTime) { "Expected $fixedTime but got $result" } + } +} From 58f0cd8422ba2d74d9fe2217999ae78913ed26e6 Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Sat, 30 Aug 2025 15:23:29 +0700 Subject: [PATCH 063/116] feat(#234): Implement language-specific Firebase messaging topics (#132) This commit introduces the ability to subscribe and unsubscribe from Firebase messaging topics based on the user's selected language. Key changes: - Added `MessagingTopicDataSource` to fetch topic configurations from a JSON file. - Added `MessagingTopicRepository` to manage topic data. - Added `MessagingTopicUseCase` to handle subscription logic. - Added `LanguageSwitcherUseCase` to orchestrate language switching and topic subscription updates. - Integrated topic subscription updates into `SettingsViewModel` and `ChangeLanguageBottomSheet`. - Added a `topics.json` asset file containing the topic definitions. - Included unit tests for the new data source, repository, and use cases. - Initialized messaging topics on app startup in `BrainwalletApp`. --- .../java/com/brainwallet/BrainwalletApp.kt | 3 + .../repository/MessagingTopicRepository.kt | 20 ++++ .../data/source/MessagingTopicDataSource.kt | 29 +++++ .../domain/LanguageSwitcherUseCase.kt | 16 +++ .../domain/MessagingTopicUseCase.kt | 36 ++++++ .../language/ChangeLanguageBottomSheet.kt | 4 +- .../ui/screens/home/SettingsViewModel.kt | 4 +- .../MessagingTopicRepositoryTest.kt | 71 ++++++++++++ .../source/MessagingTopicDataSourceTest.kt | 108 ++++++++++++++++++ .../domain/LanguageSwitcherUseCaseTest.kt | 39 +++++++ .../domain/MessagingTopicUseCaseTest.kt | 66 +++++++++++ 11 files changed, 394 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/data/repository/MessagingTopicRepository.kt create mode 100644 app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt create mode 100644 app/src/main/java/com/brainwallet/domain/LanguageSwitcherUseCase.kt create mode 100644 app/src/main/java/com/brainwallet/domain/MessagingTopicUseCase.kt create mode 100644 app/src/test/java/com/brainwallet/data/repository/MessagingTopicRepositoryTest.kt create mode 100644 app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt create mode 100644 app/src/test/java/com/brainwallet/domain/LanguageSwitcherUseCaseTest.kt create mode 100644 app/src/test/java/com/brainwallet/domain/MessagingTopicUseCaseTest.kt diff --git a/app/src/main/java/com/brainwallet/BrainwalletApp.kt b/app/src/main/java/com/brainwallet/BrainwalletApp.kt index 9143a90f..e2f1db99 100644 --- a/app/src/main/java/com/brainwallet/BrainwalletApp.kt +++ b/app/src/main/java/com/brainwallet/BrainwalletApp.kt @@ -8,6 +8,7 @@ import android.content.res.Resources import com.appsflyer.AppsFlyerLib import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.di.AppModule +import com.brainwallet.domain.MessagingTopicUseCase import com.brainwallet.notification.NotificationHandler import com.brainwallet.presenter.activities.util.BRActivity import com.brainwallet.presenter.entities.ServiceItems @@ -32,6 +33,7 @@ open class BrainwalletApp : Application() { private val remoteConfigSource: RemoteConfigSource by inject() private val notificationHandler: NotificationHandler by inject() + private val messagingTopicHandler: MessagingTopicUseCase by inject() override fun onCreate() { super.onCreate() @@ -80,6 +82,7 @@ open class BrainwalletApp : Application() { modules(AppModule.dataModule, AppModule.module) } thread { remoteConfigSource.initialize() } + thread { messagingTopicHandler.initialize() } } // override fun attachBaseContext(base: Context) { diff --git a/app/src/main/java/com/brainwallet/data/repository/MessagingTopicRepository.kt b/app/src/main/java/com/brainwallet/data/repository/MessagingTopicRepository.kt new file mode 100644 index 00000000..25947009 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/MessagingTopicRepository.kt @@ -0,0 +1,20 @@ +package com.brainwallet.data.repository + +import com.brainwallet.data.model.Language +import com.brainwallet.data.source.MessagingTopicDataSource +import org.koin.core.annotation.Single + +@Single +class MessagingTopicRepository( + private val settingRepository: SettingRepository, + private val topicDataSource: MessagingTopicDataSource +) { + fun getCurrentTopics(): List { + val currentLanguage = settingRepository.getCurrentLanguage() + return topicDataSource.getTopicsByLanguageCode(currentLanguage.code) + } + + fun getTopicsByLanguage(language: Language): List { + return topicDataSource.getTopicsByLanguageCode(language.code) + } +} diff --git a/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt b/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt new file mode 100644 index 00000000..804b9aca --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt @@ -0,0 +1,29 @@ +package com.brainwallet.data.source + +import com.brainwallet.data.model.Language +import org.koin.core.annotation.Single + +@Single +class MessagingTopicDataSource( + private val supportedLanguages: List = Language.entries, + private val defaultLanguage: Language = Language.ENGLISH +) { + fun getTopicsByLanguageCode(languageCode: String): List { + val baseLanguageCode = getBaseLanguageCode(languageCode) + return listOf( + "initial_$baseLanguageCode", + "news_$baseLanguageCode", + "promo_$baseLanguageCode", + "warn_$baseLanguageCode" + ) + } + + private fun getBaseLanguageCode(languageCode: String): String { + val normalizedLanguageCode = languageCode.split("_", "-").first().lowercase() + val targetLanguage = supportedLanguages.find { + it.code.split("-").first().lowercase() == normalizedLanguageCode + } ?: defaultLanguage + + return targetLanguage.code.split("-").first().lowercase() + } +} diff --git a/app/src/main/java/com/brainwallet/domain/LanguageSwitcherUseCase.kt b/app/src/main/java/com/brainwallet/domain/LanguageSwitcherUseCase.kt new file mode 100644 index 00000000..e1464759 --- /dev/null +++ b/app/src/main/java/com/brainwallet/domain/LanguageSwitcherUseCase.kt @@ -0,0 +1,16 @@ +package com.brainwallet.domain + +import com.brainwallet.data.model.Language +import com.brainwallet.data.repository.SettingRepository +import org.koin.core.annotation.Single + +@Single +class LanguageSwitcherUseCase( + private val settingRepository: SettingRepository, + private val messagingTopicUseCase: MessagingTopicUseCase +) { + fun switchLanguage(newLanguage: Language) { + messagingTopicUseCase.subscribeByLanguage(newLanguage) + settingRepository.updateCurrentLanguage(newLanguage.code) + } +} diff --git a/app/src/main/java/com/brainwallet/domain/MessagingTopicUseCase.kt b/app/src/main/java/com/brainwallet/domain/MessagingTopicUseCase.kt new file mode 100644 index 00000000..7b1641cb --- /dev/null +++ b/app/src/main/java/com/brainwallet/domain/MessagingTopicUseCase.kt @@ -0,0 +1,36 @@ +package com.brainwallet.domain + +import com.brainwallet.data.model.Language +import com.brainwallet.data.repository.MessagingTopicRepository +import com.google.firebase.messaging.FirebaseMessaging +import org.koin.core.annotation.Single + +@Single +class MessagingTopicUseCase( + private val messagingTopicRepository: MessagingTopicRepository, + private val firebaseMessaging: FirebaseMessaging = FirebaseMessaging.getInstance() +) { + fun initialize() { + val topics = messagingTopicRepository.getCurrentTopics() + subscribeToTopics(topics) + } + + fun subscribeByLanguage(newLanguage: Language) { + val currentTopics = messagingTopicRepository.getCurrentTopics() + unsubscribeFromTopics(currentTopics) + val newTopics = messagingTopicRepository.getTopicsByLanguage(newLanguage) + subscribeToTopics(newTopics) + } + + private fun subscribeToTopics(topics: List) { + topics.forEach { topic -> + firebaseMessaging.subscribeToTopic(topic) + } + } + + private fun unsubscribeFromTopics(topics: List) { + topics.forEach { topic -> + firebaseMessaging.unsubscribeFromTopic(topic) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/presenter/language/ChangeLanguageBottomSheet.kt b/app/src/main/java/com/brainwallet/presenter/language/ChangeLanguageBottomSheet.kt index 77bb688b..a1ff0249 100644 --- a/app/src/main/java/com/brainwallet/presenter/language/ChangeLanguageBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/presenter/language/ChangeLanguageBottomSheet.kt @@ -10,6 +10,7 @@ import com.brainwallet.R import com.brainwallet.data.model.Language import com.brainwallet.data.repository.SettingRepository import com.brainwallet.databinding.ChangeLanguageBottomSheetBinding +import com.brainwallet.domain.LanguageSwitcherUseCase import com.brainwallet.navigation.LegacyNavigation import com.brainwallet.tools.util.Utils import com.brainwallet.tools.util.getString @@ -23,6 +24,7 @@ class ChangeLanguageBottomSheet : RoundedBottomSheetDialogFragment() { lateinit var binding: ChangeLanguageBottomSheetBinding private val settingRepository by inject() + private val languageSwitcherUseCase by inject() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -65,7 +67,7 @@ class ChangeLanguageBottomSheet : RoundedBottomSheetDialogFragment() { binding.okButton.setOnClickListener { if (settingRepository.getCurrentLanguage() != adapter.selectedLanguage()) { - settingRepository.updateCurrentLanguage(adapter.selectedLanguage().code) + languageSwitcherUseCase.switchLanguage(adapter.selectedLanguage()) LegacyNavigation.openComposeScreen( context = requireContext(), ) diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt index 46f5c426..75f59e71 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt @@ -8,6 +8,7 @@ import com.brainwallet.data.model.Language import com.brainwallet.data.model.toFeeOptions import com.brainwallet.data.repository.LtcRepository import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.domain.LanguageSwitcherUseCase import com.brainwallet.tools.manager.FeeManager import com.brainwallet.ui.BrainwalletViewModel import com.brainwallet.util.EventBus @@ -27,6 +28,7 @@ import org.koin.android.annotation.KoinViewModel @KoinViewModel class SettingsViewModel( private val settingRepository: SettingRepository, + private val languageSwitcherUseCase: LanguageSwitcherUseCase, private val ltcRepository: LtcRepository ) : BrainwalletViewModel() { @@ -127,7 +129,7 @@ class SettingsViewModel( ) }.let { viewModelScope.launch { - settingRepository.save(appSetting.value.copy(languageCode = event.language.code)) + languageSwitcherUseCase.switchLanguage(event.language) AppCompatDelegate.setApplicationLocales( LocaleListCompat.forLanguageTags( event.language.code diff --git a/app/src/test/java/com/brainwallet/data/repository/MessagingTopicRepositoryTest.kt b/app/src/test/java/com/brainwallet/data/repository/MessagingTopicRepositoryTest.kt new file mode 100644 index 00000000..9e221314 --- /dev/null +++ b/app/src/test/java/com/brainwallet/data/repository/MessagingTopicRepositoryTest.kt @@ -0,0 +1,71 @@ +package com.brainwallet.data.repository + +import com.brainwallet.data.model.Language +import com.brainwallet.data.source.MessagingTopicDataSource +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.verify +import org.junit.Before +import org.junit.Test + +class MessagingTopicRepositoryTest { + + @MockK + private lateinit var mockSettingRepository: SettingRepository + + @MockK + private lateinit var mockTopicDataSource: MessagingTopicDataSource + + private lateinit var repository: MessagingTopicRepository + + private lateinit var fakeIndonesianTopics: List + private lateinit var fakeEnglishTopics: List + + @Before + fun setUp() { + MockKAnnotations.init(this) + fakeIndonesianTopics = listOf("initial_in", "news_in", "promo_in", "warn_in") + fakeEnglishTopics = listOf("initial_en", "news_en", "promo_en", "warn_en") + repository = MessagingTopicRepository(mockSettingRepository, mockTopicDataSource) + } + + @Test + fun `given current language code is in when getCurrentTopics called then repository should return topics for Indonesian`() { + every { mockSettingRepository.getCurrentLanguage().code } returns "in" + every { mockTopicDataSource.getTopicsByLanguageCode("in") } returns fakeIndonesianTopics + + val result = repository.getCurrentTopics() + + assert(result == fakeIndonesianTopics) { + "Expected repository to return topics for Indonesian but got $result" + } + verify(exactly = 1) { mockTopicDataSource.getTopicsByLanguageCode("in") } + } + + @Test + fun `given language object when getTopicsByLanguage called then repository should return topics for that language`() { + val language = Language.INDONESIAN + every { mockTopicDataSource.getTopicsByLanguageCode(language.code) } returns fakeIndonesianTopics + + val result = repository.getTopicsByLanguage(language) + + assert(result == fakeIndonesianTopics) { + "Expected repository to return topics for Indonesian language but got $result" + } + verify(exactly = 1) { mockTopicDataSource.getTopicsByLanguageCode(language.code) } + } + + @Test + fun `given English language when getTopicsByLanguage called then repository should return English topics`() { + val language = Language.ENGLISH + every { mockTopicDataSource.getTopicsByLanguageCode(language.code) } returns fakeEnglishTopics + + val result = repository.getTopicsByLanguage(language) + + assert(result == fakeEnglishTopics) { + "Expected repository to return topics for English language but got $result" + } + verify(exactly = 1) { mockTopicDataSource.getTopicsByLanguageCode(language.code) } + } +} diff --git a/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt b/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt new file mode 100644 index 00000000..cea284d5 --- /dev/null +++ b/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt @@ -0,0 +1,108 @@ +package com.brainwallet.data.source + +import com.brainwallet.data.model.Language +import org.junit.Before +import org.junit.Test + +class MessagingTopicDataSourceTest { + private lateinit var dataSource: MessagingTopicDataSource + + @Before + fun setUp() { + dataSource = MessagingTopicDataSource() + } + + @Test + fun `given locale with underscore when getTopicsByLanguageCode called then it should extract base language only`() { + val result = dataSource.getTopicsByLanguageCode("fr_FR") + + val expectedTopics = listOf("initial_fr", "news_fr", "promo_fr", "warn_fr") + assert(result == expectedTopics) { + "Expected topics for French language from 'fr_FR' but got $result" + } + } + + @Test + fun `given locale with hyphen when getTopicsByLanguageCode called then it should extract base language only`() { + val result = dataSource.getTopicsByLanguageCode("zh-CN") + + val expectedTopics = listOf("initial_zh", "news_zh", "promo_zh", "warn_zh") + assert(result == expectedTopics) { + "Expected topics for Chinese language from 'zh-CN' but got $result" + } + } + + @Test + fun `given uppercase language code when getTopicsByLanguageCode called then it should normalize to lowercase`() { + val result = dataSource.getTopicsByLanguageCode("FR") + + val expectedTopics = listOf("initial_fr", "news_fr", "promo_fr", "warn_fr") + assert(result == expectedTopics) { + "Expected topics for French language from uppercase 'FR' but got $result" + } + } + + @Test + fun `given mixed case locale when getTopicsByLanguageCode called then it should normalize to lowercase base`() { + val result = dataSource.getTopicsByLanguageCode("Es_ES") + + val expectedTopics = listOf("initial_es", "news_es", "promo_es", "warn_es") + assert(result == expectedTopics) { + "Expected topics for Spanish language from 'Es_ES' but got $result" + } + } + + @Test + fun `given empty string when getTopicsByLanguageCode called then it should default to English`() { + val result = dataSource.getTopicsByLanguageCode("") + + val expectedTopics = listOf("initial_en", "news_en", "promo_en", "warn_en") + assert(result == expectedTopics) { + "Expected topics to default to English for empty string but got $result" + } + } + + @Test + fun `given unsupported language code when getTopicsByLanguageCode called then it should default to English`() { + val result = dataSource.getTopicsByLanguageCode("unsupported") + + val expectedTopics = listOf("initial_en", "news_en", "promo_en", "warn_en") + assert(result == expectedTopics) { + "Expected topics to default to English for unsupported language but got $result" + } + } + + @Test + fun `given all supported languages when getTopicsByLanguageCode called then it should return correct base language topics`() { + val testCases = mapOf( + "en" to "en", + "es" to "es", + "in" to "in", + "ar" to "ar", + "uk" to "uk", + "ru" to "ru", + "pt" to "pt", + "hi" to "hi", + "de" to "de", + "fa" to "fa", + "pa" to "pa", + "pl" to "pl", + "ko" to "ko", + "fr" to "fr", + "zh-TW" to "zh", + "zh-CN" to "zh", + "tr" to "tr", + "ja" to "ja", + "it" to "it", + "sv" to "sv" + ) + + testCases.forEach { (input, expectedBase) -> + val result = dataSource.getTopicsByLanguageCode(input) + val expectedTopics = listOf("initial_$expectedBase", "news_$expectedBase", "promo_$expectedBase", "warn_$expectedBase") + assert(result == expectedTopics) { + "Expected topics for '$input' to have base '$expectedBase' but got $result" + } + } + } +} diff --git a/app/src/test/java/com/brainwallet/domain/LanguageSwitcherUseCaseTest.kt b/app/src/test/java/com/brainwallet/domain/LanguageSwitcherUseCaseTest.kt new file mode 100644 index 00000000..15dd7efd --- /dev/null +++ b/app/src/test/java/com/brainwallet/domain/LanguageSwitcherUseCaseTest.kt @@ -0,0 +1,39 @@ +package com.brainwallet.domain + +import com.brainwallet.data.model.Language +import com.brainwallet.data.repository.SettingRepository +import io.mockk.MockKAnnotations +import io.mockk.impl.annotations.MockK +import io.mockk.verifyOrder +import org.junit.Before +import org.junit.Test + +class LanguageSwitcherUseCaseTest { + + private lateinit var useCase: LanguageSwitcherUseCase + + @MockK + private lateinit var mockSettingRepository: SettingRepository + + @MockK + private lateinit var mockMessagingTopicUseCase: MessagingTopicUseCase + + @Before + fun setUp() { + MockKAnnotations.init(this, relaxUnitFun = true) + useCase = LanguageSwitcherUseCase(mockSettingRepository, mockMessagingTopicUseCase) + } + + @Test + fun `given new language when switchLanguage called then it should subscribe by language and update current language`() { + val newLanguage = Language.FRENCH + + useCase.switchLanguage(newLanguage) + + // Order is important to make old subscribed language still valid + verifyOrder { + mockMessagingTopicUseCase.subscribeByLanguage(newLanguage) + mockSettingRepository.updateCurrentLanguage(newLanguage.code) + } + } +} diff --git a/app/src/test/java/com/brainwallet/domain/MessagingTopicUseCaseTest.kt b/app/src/test/java/com/brainwallet/domain/MessagingTopicUseCaseTest.kt new file mode 100644 index 00000000..a026737f --- /dev/null +++ b/app/src/test/java/com/brainwallet/domain/MessagingTopicUseCaseTest.kt @@ -0,0 +1,66 @@ +package com.brainwallet.domain + +import com.brainwallet.data.model.Language +import com.brainwallet.data.repository.MessagingTopicRepository +import com.google.firebase.messaging.FirebaseMessaging +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.RelaxedMockK +import io.mockk.verify +import org.junit.Before +import org.junit.Test + +class MessagingTopicUseCaseTest { + + private lateinit var useCase: MessagingTopicUseCase + + @MockK + private lateinit var mockRepository: MessagingTopicRepository + + @RelaxedMockK + private lateinit var mockFirebaseMessaging: FirebaseMessaging + private lateinit var currentTopics: List + private lateinit var newTopics: List + + @Before + fun setUp() { + MockKAnnotations.init(this) + currentTopics = listOf("initial_en", "news_en", "promo_en", "warn_en") + newTopics = listOf("initial_fr", "news_fr", "promo_fr", "warn_fr") + + useCase = MessagingTopicUseCase(mockRepository, mockFirebaseMessaging) + } + + @Test + fun `given current topics when initialize called then it should subscribe to all current topics`() { + every { mockRepository.getCurrentTopics() } returns currentTopics + + useCase.initialize() + + verify(exactly = 1) { mockFirebaseMessaging.subscribeToTopic("initial_en") } + verify(exactly = 1) { mockFirebaseMessaging.subscribeToTopic("news_en") } + verify(exactly = 1) { mockFirebaseMessaging.subscribeToTopic("promo_en") } + verify(exactly = 1) { mockFirebaseMessaging.subscribeToTopic("warn_en") } + } + + @Test + fun `given current topics and new language when subscribeByLanguage called then it should unsubscribe old and subscribe new`() { + every { mockRepository.getCurrentTopics() } returns currentTopics + every { mockRepository.getTopicsByLanguage(any()) } returns newTopics + + val newLanguage = Language.FRENCH + + useCase.subscribeByLanguage(newLanguage) + + verify(exactly = 1) { mockFirebaseMessaging.unsubscribeFromTopic("initial_en") } + verify(exactly = 1) { mockFirebaseMessaging.unsubscribeFromTopic("news_en") } + verify(exactly = 1) { mockFirebaseMessaging.unsubscribeFromTopic("promo_en") } + verify(exactly = 1) { mockFirebaseMessaging.unsubscribeFromTopic("warn_en") } + + verify(exactly = 1) { mockFirebaseMessaging.subscribeToTopic("initial_fr") } + verify(exactly = 1) { mockFirebaseMessaging.subscribeToTopic("news_fr") } + verify(exactly = 1) { mockFirebaseMessaging.subscribeToTopic("promo_fr") } + verify(exactly = 1) { mockFirebaseMessaging.subscribeToTopic("warn_fr") } + } +} From 4bb06cfa7c1a1a8815bbd77945dbb1972b48ddf8 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 30 Aug 2025 11:07:50 +0100 Subject: [PATCH 064/116] bump code --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index abf18b73..6f6d2220 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -21,7 +21,7 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 36 - versionCode = 202506295 + versionCode = 202506296 versionName = "v4.7.2" multiDexEnabled = true From 9f4908b4a438b85a226d00dcf0b2afe3cec6abdc Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Sat, 30 Aug 2025 17:33:14 +0700 Subject: [PATCH 065/116] chore(#234): normalize Indonesian language code to "id" (#133) The Indonesian language code "in" is normalized to "id" in `MessagingTopicDataSource` to align with the ISO 639-1 standard used by the backend. This ensures consistency in topic generation for Indonesian language users. Tests have been added to verify this normalization for both "in" and "in_ID" inputs. --- .../data/source/MessagingTopicDataSource.kt | 21 +++++++++- .../source/MessagingTopicDataSourceTest.kt | 38 +++++++++++++++++-- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt b/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt index 804b9aca..530d77a8 100644 --- a/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt @@ -18,12 +18,29 @@ class MessagingTopicDataSource( ) } + /** + * Note: Indonesian language code is normalized from "in" to "id" to maintain + * consistency with backend batch messaging server which uses ISO 639-1 standard. + * Supports both "in" and "id" as input for Indonesian language. + */ private fun getBaseLanguageCode(languageCode: String): String { val normalizedLanguageCode = languageCode.split("_", "-").first().lowercase() + + // Handle reverse mapping: if "id" is passed, treat it as Indonesian + val searchCode = when (normalizedLanguageCode) { + "id" -> "in" + else -> normalizedLanguageCode + } + val targetLanguage = supportedLanguages.find { - it.code.split("-").first().lowercase() == normalizedLanguageCode + it.code.split("-").first().lowercase() == searchCode } ?: defaultLanguage - return targetLanguage.code.split("-").first().lowercase() + val baseCode = targetLanguage.code.split("-").first().lowercase() + + return when (baseCode) { + "in" -> "id" + else -> baseCode + } } } diff --git a/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt b/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt index cea284d5..57e51bd5 100644 --- a/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt +++ b/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt @@ -1,6 +1,5 @@ package com.brainwallet.data.source -import com.brainwallet.data.model.Language import org.junit.Before import org.junit.Test @@ -72,12 +71,45 @@ class MessagingTopicDataSourceTest { } } + @Test + fun `given Indonesian language code when getTopicsByLanguageCode called then it should normalize to id for backend consistency`() { + val result = dataSource.getTopicsByLanguageCode("in") + + val expectedTopics = listOf("initial_id", "news_id", "promo_id", "warn_id") + assert(result == expectedTopics) { + "Expected Indonesian language code 'in' to be normalized to 'id' for backend consistency but got $result" + } + } + + @Test + fun `given Indonesian locale with region when getTopicsByLanguageCode called then it should normalize to id`() { + val result = dataSource.getTopicsByLanguageCode("in_ID") + + val expectedTopics = listOf("initial_id", "news_id", "promo_id", "warn_id") + assert(result == expectedTopics) { + "Expected Indonesian locale 'in_ID' to be normalized to 'id' for backend consistency but got $result" + } + } + + @Test + fun `given id language code when getTopicsByLanguageCode called then it should be recognized as Indonesian`() { + val result = dataSource.getTopicsByLanguageCode("id") + + val expectedTopics = listOf("initial_id", "news_id", "promo_id", "warn_id") + assert(result == expectedTopics) { + "Expected 'id' language code to be recognized as Indonesian and return Indonesian topics but got $result" + } + } + @Test fun `given all supported languages when getTopicsByLanguageCode called then it should return correct base language topics`() { val testCases = mapOf( "en" to "en", - "es" to "es", - "in" to "in", + "es" to "es", + // Check All possible indonesian combination + "in" to "id", + "in_ID" to "id", + "id" to "id", "ar" to "ar", "uk" to "uk", "ru" to "ru", From 4a27ae01cae576dd78b697388f2b3b08861eab58 Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Mon, 22 Sep 2025 19:06:17 +0700 Subject: [PATCH 066/116] Feat: Detekt and Test Plugins, (Including Create Detekt Baseline) (#136) * feat: integrate build logic submodule Integrates the `gruntsoftware-build-logic` Git submodule into the project. This change includes: - Adding the submodule to `.gitmodules`. - Including the build logic in `settings.gradle.kts`. - Applying build logic plugins (`test` and `detekt`) in `app/build.gradle.kts`. * chore(detekt): apply baseline rules * chore: Remove ktlint from project This commit removes the ktlint configuration and associated tasks from the `app/build.gradle.kts` file. It also removes the `pinterest-ktlint` dependency from the `gradle/libs.versions.toml` file. --- .gitmodules | 3 + app/build.gradle.kts | 61 +- .../flow/RecoverWalletScreenGrabsTest.kt | 16 +- .../java/com/brainwallet/BrainwalletApp.kt | 2 +- .../com/brainwallet/data/model/AppSetting.kt | 2 +- .../com/brainwallet/data/model/Country.kt | 2 +- .../brainwallet/data/model/CurrencyEntity.kt | 4 +- .../java/com/brainwallet/data/model/Fee.kt | 3 +- .../brainwallet/data/model/IntroLanguage.kt | 6 +- .../com/brainwallet/data/model/Language.kt | 3 +- .../data/model/MoonpayCurrencyLimit.kt | 2 +- .../data/model/QuickFiatAmountOption.kt | 3 +- .../FirebaseRemoteConfigRepository.kt | 1 - .../data/repository/LtcRepository.kt | 4 +- .../data/repository/LtcRepositoryImpl.kt | 14 +- .../repository/SelectedPeersRepository.kt | 2 +- .../repository/SelectedPeersRepositoryImpl.kt | 6 +- .../data/repository/SettingRepository.kt | 2 +- .../data/repository/SettingRepositoryImpl.kt | 1 - .../data/source/LocalCacheSource.kt | 2 +- .../data/source/MessagingTopicDataSource.kt | 12 +- .../data/source/RemoteApiSource.kt | 5 +- .../data/source/RemoteConfigSource.kt | 2 +- .../main/java/com/brainwallet/di/AppModule.kt | 19 +- .../domain/MessagingTopicUseCase.kt | 2 +- .../exceptions/CertificateChainNotFound.kt | 2 - .../PaymentRequestExpiredException.kt | 1 - .../navigation/LegacyNavigation.kt | 14 +- .../com/brainwallet/navigation/MainNav.kt | 6 +- .../navigation/MoonPayWidgeLauncher.kt | 35 +- .../java/com/brainwallet/navigation/Route.kt | 4 +- .../com/brainwallet/navigation/UiEffect.kt | 4 +- .../BrainwalletMessagingService.kt | 2 +- .../presenter/activities/PaperKeyActivity.kt | 2 +- .../activities/intro/RecoverActivity.kt | 16 +- .../presenter/base/BaseFragment.kt | 1 - .../presenter/entities/ServiceItems.kt | 2 +- .../presenter/entities/TransactionDataItem.kt | 16 +- .../fragments/FragmentBalanceSeedReminder.kt | 7 +- .../presenter/fragments/FragmentMoonpay.kt | 75 ++- .../presenter/fragments/FragmentSend.kt | 53 +- .../presenter/history/HistoryFragment.kt | 14 +- .../language/ChangeLanguageBottomSheet.kt | 2 +- .../presenter/language/LanguageAdapter.kt | 1 - .../tools/adapter/CountryLanguageAdapter.kt | 14 +- .../com/brainwallet/ui/BrainwalletActivity.kt | 12 +- .../brainwallet/ui/BrainwalletViewModel.kt | 4 +- .../ui/RoundedBottomSheetDialogFragment.kt | 1 - .../brainwallet/ui/composable/CircleButton.kt | 2 +- .../ui/composable/DarkModeToggleButton.kt | 2 +- .../brainwallet/ui/composable/LargeButton.kt | 2 +- .../ui/composable/LoadingDialog.kt | 3 +- .../brainwallet/ui/composable/MediumButton.kt | 8 +- .../ui/composable/MoonpayBuyButton.kt | 4 +- .../ui/composable/MoonpayBuyWidget.kt | 7 +- .../ui/composable/PasscodeKeypad.kt | 6 +- .../brainwallet/ui/composable/PinDotItem.kt | 4 +- .../brainwallet/ui/composable/SeedWordItem.kt | 18 +- .../ui/composable/SeedWordsLayout.kt | 4 +- .../brainwallet/ui/composable/WheelPicker.kt | 9 +- .../bottomsheet/FiatSelectorBottomSheet.kt | 83 +-- .../LanguageSelectorBottomSheet.kt | 6 +- .../screens/buylitecoin/BuyLitecoinEvent.kt | 2 +- .../screens/buylitecoin/BuyLitecoinScreen.kt | 7 +- .../buylitecoin/BuyLitecoinViewModel.kt | 8 +- .../brainwallet/ui/screens/home/HomeScreen.kt | 5 +- .../ui/screens/home/SettingsEvent.kt | 2 +- .../ui/screens/home/SettingsState.kt | 4 +- .../ui/screens/home/SettingsViewModel.kt | 2 +- .../home/composable/HomeSettingDrawerSheet.kt | 20 +- .../composable/settingsrows/CurrencyDetail.kt | 84 +-- .../composable/settingsrows/GamesDetail.kt | 7 +- .../composable/settingsrows/LanguageDetail.kt | 7 +- .../settingsrows/LitecoinBlockchainDetail.kt | 13 +- .../settingsrows/LockSettingRowItem.kt | 2 +- .../composable/settingsrows/SecurityDetail.kt | 8 +- .../composable/settingsrows/SettingRowItem.kt | 5 +- .../settingsrows/ThemeSettingRowItem.kt | 2 +- .../ui/screens/home/history/HistoryScreen.kt | 4 +- .../ui/screens/home/receive/ReceiveDialog.kt | 29 +- .../home/receive/ReceiveDialogEvent.kt | 2 +- .../home/receive/ReceiveDialogFragment.kt | 1 - .../home/receive/ReceiveDialogState.kt | 9 +- .../home/receive/ReceiveDialogViewModel.kt | 24 +- .../ui/screens/inputwords/InputWordsEvent.kt | 2 +- .../ui/screens/inputwords/InputWordsScreen.kt | 18 +- .../ui/screens/inputwords/InputWordsState.kt | 4 +- .../screens/inputwords/InputWordsViewModel.kt | 3 +- .../ui/screens/ready/ReadyEvent.kt | 2 +- .../ui/screens/ready/ReadyScreen.kt | 4 +- .../screens/setpasscode/SetPasscodeEvent.kt | 2 +- .../screens/setpasscode/SetPasscodeScreen.kt | 3 +- .../screens/setpasscode/SetPasscodeState.kt | 4 +- .../setpasscode/SetPasscodeViewModel.kt | 6 +- .../ui/screens/topup/TopUpScreen.kt | 7 +- .../ui/screens/unlock/UnLockEvent.kt | 2 +- .../ui/screens/unlock/UnLockScreen.kt | 13 +- .../ui/screens/unlock/UnLockState.kt | 4 +- .../ui/screens/unlock/UnLockViewModel.kt | 4 +- .../unlock/components/UnLockScreenBody.kt | 6 +- .../unlock/components/UnLockScreenFooter.kt | 8 +- .../ui/screens/welcome/WelcomeEvent.kt | 2 +- .../ui/screens/welcome/WelcomeScreen.kt | 13 +- .../ui/screens/welcome/WelcomeState.kt | 2 +- .../ui/screens/welcome/WelcomeViewModel.kt | 6 +- .../yourseedproveit/YourSeedProveItEvent.kt | 2 +- .../yourseedproveit/YourSeedProveItScreen.kt | 54 +- .../yourseedproveit/YourSeedProveItState.kt | 2 +- .../YourSeedProveItViewModel.kt | 2 +- .../yourseedwords/YourSeedWordsEvent.kt | 2 +- .../yourseedwords/YourSeedWordsScreen.kt | 9 +- .../yourseedwords/YourSeedWordsViewModel.kt | 2 +- .../java/com/brainwallet/ui/theme/Color.kt | 4 +- .../java/com/brainwallet/ui/theme/Font.kt | 9 +- .../java/com/brainwallet/ui/theme/Theme.kt | 19 +- .../java/com/brainwallet/ui/theme/Type.kt | 5 - .../java/com/brainwallet/util/EventBus.kt | 5 +- .../com/brainwallet/util/PermissionUtil.kt | 3 +- .../util/cryptography/CipherBox.kt | 10 +- .../util/cryptography/CipherStorage.kt | 10 +- .../util/cryptography/KeyStoreKeyGenerator.kt | 2 +- .../util/cryptography/KeyStoreManager.kt | 18 +- .../impl/KeyStoreKeyGeneratorImpl.kt | 3 +- .../worker/CurrencyUpdateWorker.kt | 6 +- .../com/brainwallet/worker/SyncBlockWorker.kt | 4 +- .../currency/BackupRateFetchTests.kt | 23 +- .../com/brainwallet/currency/CurrencyTests.kt | 7 +- .../java/com/brainwallet/data/BaseURLTests.kt | 13 +- .../FirebaseRemoteConfigRepositoryTest.kt | 5 +- .../source/MessagingTopicDataSourceTest.kt | 7 +- .../com/brainwallet/example/ExampleTest.kt | 4 +- .../notification/NotificationHandlerTest.kt | 10 +- .../tools/database/DatabaseTests.kt | 35 +- .../database/TransactionDataSourceTest.kt | 2 +- .../tools/security/BRKeyStoreTest.kt | 139 ++-- .../tools/security/NewKeyStoreTests.kt | 43 +- .../tools/security/ReplicatedKVStoreTest.kt | 4 +- .../brainwallet/tools/util/BRConstantsTest.kt | 113 ++-- .../brainwallet/tools/util/Bip39ReaderTest.kt | 4 +- .../tools/util/GoogleServicesTests.kt | 15 +- .../tools/util/LocaleHelperTest.kt | 4 +- .../tools/util/ProdAPIManagerTests.kt | 23 +- .../brainwallet/tools/util/SeedWordTests.kt | 42 +- .../ui/screens/unlock/UnLockViewModelTest.kt | 21 +- .../util/CurrencyDataGetterTest.kt | 16 +- build.gradle.kts | 10 +- config/detekt-app-baseline.xml | 620 ++++++++++++++++++ gradle/libs.versions.toml | 18 - gradle/wrapper/gradle-wrapper.properties | 2 +- gruntsoftware-build-logic | 1 + modules/games | 2 +- settings.gradle.kts | 6 + 152 files changed, 1384 insertions(+), 963 deletions(-) create mode 100644 config/detekt-app-baseline.xml create mode 160000 gruntsoftware-build-logic diff --git a/.gitmodules b/.gitmodules index bd038a83..cf382734 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,3 +8,6 @@ path = modules/games url = https://github.com/gruntsoftware/android-games.git update = none +[submodule "gruntsoftware-build-logic"] + path = gruntsoftware-build-logic + url = https://github.com/gruntsoftware/android-build-logic.git diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6f6d2220..059f36d6 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,14 +1,17 @@ import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties +import org.gradle.kotlin.dsl.grunt plugins { alias(libs.plugins.android.application) - alias(libs.plugins.jetbrains.kotlin.android) - alias(libs.plugins.jetbrains.kotlin.compose) + alias(grunt.plugins.jetbrains.kotlin.android) + alias(grunt.plugins.jetbrains.kotlin.compose) alias(libs.plugins.jetbrains.kotlin.kapt) - alias(libs.plugins.jetbrains.kotlin.serialization) + alias(grunt.plugins.jetbrains.kotlin.serialization) alias(libs.plugins.google.services) alias(libs.plugins.firebase.crashlytics) - alias(libs.plugins.ksp) + alias(grunt.plugins.ksp) + alias(grunt.plugins.buildlogic.test) + alias(grunt.plugins.buildlogic.detekt) } val localProperties = gradleLocalProperties(rootDir, providers) @@ -179,15 +182,7 @@ android { //TODO: rename output apk/bundle } -val ktlint by configurations.creating - dependencies { - ktlint(libs.pinterest.ktlint) { - attributes { - attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) - } - } - val gamesModule = findProject(":modules:games:content") if (gamesModule != null) { implementation(gamesModule) @@ -222,11 +217,11 @@ dependencies { implementation(libs.kotlinx.serialization.json) implementation(libs.kotlinx.coroutines.android) implementation (libs.airbnb.lottie.compose) - implementation(platform(libs.koin.bom)) - implementation(libs.bundles.koin) - implementation(platform(libs.koin.annotation.bom)) - implementation(libs.koin.annotation) - ksp(libs.koin.annotation.compiler) + implementation(platform(grunt.koin.bom)) + implementation(grunt.bundles.koin) + implementation(platform(grunt.koin.annotation.bom)) + implementation(grunt.koin.annotation) + ksp(grunt.koin.annotation.compiler) implementation(platform(libs.squareup.okhttp.bom)) implementation(libs.bundles.squareup.okhttp) @@ -255,38 +250,6 @@ dependencies { androidTestImplementation(libs.slf4j.android) } -val ktlintCheck by tasks.registering(JavaExec::class) { - group = LifecycleBasePlugin.VERIFICATION_GROUP - description = "Check Kotlin code style" - classpath = ktlint - mainClass.set("com.pinterest.ktlint.Main") - // see https://pinterest.github.io/ktlint/install/cli/#command-line-usage for more information - args( - "**/src/**/*.kt", - "**.kts", - "!**/build/**", - ) -} - -tasks.check { - dependsOn(ktlintCheck) -} - -tasks.register("ktlintFormat") { - group = LifecycleBasePlugin.VERIFICATION_GROUP - description = "Check Kotlin code style and format" - classpath = ktlint - mainClass.set("com.pinterest.ktlint.Main") - jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED") - // see https://pinterest.github.io/ktlint/install/cli/#command-line-usage for more information - args( - "-F", - "**/src/**/*.kt", - "**.kts", - "!**/build/**", - ) -} - tasks.withType { jvmArgs("-XX:+EnableDynamicAgentLoading") } diff --git a/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt b/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt index 56e381e6..a753067c 100644 --- a/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt +++ b/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt @@ -80,11 +80,9 @@ class RecoverWalletScreenGrabsTest { CleanStatusBar.disable() } - @OptIn(ExperimentalTestApi::class) @Test fun onRecoverFlowSuccess() { - composeTestRule.activityRule.scenario.onActivity { Screengrab.setDefaultScreenshotStrategy(FalconScreenshotStrategy(it)) } @@ -102,7 +100,7 @@ class RecoverWalletScreenGrabsTest { Screengrab.screenshot("2_input_words_screen") - //seed words input + // seed words input val editTextTags = (0..11).map { index -> "textFieldSeedWord$index" } val paperKey = BuildConfig.SCREENGRAB_PAPERKEY @@ -148,7 +146,7 @@ class RecoverWalletScreenGrabsTest { Screengrab.screenshot("6_main_screen") - //setting drawer + // setting drawer onView(withId(R.id.menuBut)).perform(click()) Screengrab.screenshot("7_setting_drawer_open") @@ -216,8 +214,7 @@ class RecoverWalletScreenGrabsTest { uiDevice.waitForIdle() Thread.sleep(1000) - - //tx send ui + // tx send ui onView(withId(R.id.nav_send)).perform(click()) onView(withId(R.id.amount_edit)).perform(click()) @@ -226,8 +223,7 @@ class RecoverWalletScreenGrabsTest { onView(withId(R.id.close_button)).perform(click()) - - //tx buy/receive ui + // tx buy/receive ui onView(withId(R.id.nav_receive)).perform(click()) Screengrab.screenshot("15_transaction_buy_receive") @@ -235,7 +231,6 @@ class RecoverWalletScreenGrabsTest { composeTestRule.onNodeWithTag("buttonClose").performClick() uiDevice.waitForIdle() - } private fun waitUntilReady() { @@ -262,5 +257,4 @@ class RecoverWalletScreenGrabsTest { } } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/BrainwalletApp.kt b/app/src/main/java/com/brainwallet/BrainwalletApp.kt index e2f1db99..b7183b08 100644 --- a/app/src/main/java/com/brainwallet/BrainwalletApp.kt +++ b/app/src/main/java/com/brainwallet/BrainwalletApp.kt @@ -136,7 +136,7 @@ open class BrainwalletApp : Application() { return context == null || activityCounter.get() <= 0 } - //call onStop on evert activity so + // call onStop on evert activity so @JvmStatic fun onStop(app: BRActivity?) { if (isBackgroundChecker != null) isBackgroundChecker!!.cancel() diff --git a/app/src/main/java/com/brainwallet/data/model/AppSetting.kt b/app/src/main/java/com/brainwallet/data/model/AppSetting.kt index 6510f7c2..c34575d0 100644 --- a/app/src/main/java/com/brainwallet/data/model/AppSetting.kt +++ b/app/src/main/java/com/brainwallet/data/model/AppSetting.kt @@ -9,4 +9,4 @@ data class AppSetting( -1f, "$" ) -) \ No newline at end of file +) diff --git a/app/src/main/java/com/brainwallet/data/model/Country.kt b/app/src/main/java/com/brainwallet/data/model/Country.kt index a24e3146..d4133d35 100644 --- a/app/src/main/java/com/brainwallet/data/model/Country.kt +++ b/app/src/main/java/com/brainwallet/data/model/Country.kt @@ -1,3 +1,3 @@ package com.brainwallet.data.model -data class Country(val name: String, val code: String) \ No newline at end of file +data class Country(val name: String, val code: String) diff --git a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt index a46406bc..0af21ac5 100644 --- a/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt +++ b/app/src/main/java/com/brainwallet/data/model/CurrencyEntity.kt @@ -6,7 +6,7 @@ import java.io.Serializable @kotlinx.serialization.Serializable data class CurrencyEntity( @JvmField - var code: String ="", + var code: String = "", @JvmField var name: String = "", @JvmField @@ -14,4 +14,4 @@ data class CurrencyEntity( var rate: Float = 0F, @JvmField var symbol: String = "" -) : Serializable \ No newline at end of file +) : Serializable diff --git a/app/src/main/java/com/brainwallet/data/model/Fee.kt b/app/src/main/java/com/brainwallet/data/model/Fee.kt index 28413fd9..36173be7 100644 --- a/app/src/main/java/com/brainwallet/data/model/Fee.kt +++ b/app/src/main/java/com/brainwallet/data/model/Fee.kt @@ -49,7 +49,6 @@ data class Fee( } } - data class FeeOption( @FeeType val type: String, @@ -90,5 +89,5 @@ fun FeeOption.getFiatFormatted(currencyEntity: CurrencyEntity): String { fun List.getSelectedIndex(selectedFeeType: String): Int { return indexOfFirst { it.type == selectedFeeType }.takeIf { it >= 0 } - ?: 2 //2 -> index of top, since we have [low,medium,top] + ?: 2 // 2 -> index of top, since we have [low,medium,top] } diff --git a/app/src/main/java/com/brainwallet/data/model/IntroLanguage.kt b/app/src/main/java/com/brainwallet/data/model/IntroLanguage.kt index 8585f6a4..3fae80bc 100644 --- a/app/src/main/java/com/brainwallet/data/model/IntroLanguage.kt +++ b/app/src/main/java/com/brainwallet/data/model/IntroLanguage.kt @@ -2,9 +2,9 @@ package com.brainwallet.data.model data class IntroLanguage( val code: String, - val name : String, - val desc : String, - val audio : Int, + val name: String, + val desc: String, + val audio: Int, val message: String, val lang: Language ) diff --git a/app/src/main/java/com/brainwallet/data/model/Language.kt b/app/src/main/java/com/brainwallet/data/model/Language.kt index 9a9d6c8c..c7d2426f 100644 --- a/app/src/main/java/com/brainwallet/data/model/Language.kt +++ b/app/src/main/java/com/brainwallet/data/model/Language.kt @@ -9,7 +9,7 @@ import java.util.Locale * Brainwallet localizations. Will be updated from time to time * based on business objectives */ -enum class Language ( +enum class Language( val code: String, val title: String, val desc: String, @@ -49,4 +49,3 @@ enum class Language ( } } } - diff --git a/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt b/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt index d8344438..06387ec9 100644 --- a/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt +++ b/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt @@ -21,4 +21,4 @@ data class MoonpayCurrencyLimit( @SerialName("minBuyAmount") val min: Float = 21f, @SerialName("maxBuyAmount") val max: Float = 29849f ) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/data/model/QuickFiatAmountOption.kt b/app/src/main/java/com/brainwallet/data/model/QuickFiatAmountOption.kt index 20dc3368..5617b8eb 100644 --- a/app/src/main/java/com/brainwallet/data/model/QuickFiatAmountOption.kt +++ b/app/src/main/java/com/brainwallet/data/model/QuickFiatAmountOption.kt @@ -1,6 +1,5 @@ package com.brainwallet.data.model - data class QuickFiatAmountOption( val symbol: String = "custom", val value: Float = -1f @@ -8,4 +7,4 @@ data class QuickFiatAmountOption( fun QuickFiatAmountOption.isCustom(): Boolean = symbol == "custom" && value == -1f -fun QuickFiatAmountOption.getFormattedText(): String = "${symbol}${value.toInt()}" \ No newline at end of file +fun QuickFiatAmountOption.getFormattedText(): String = "${symbol}${value.toInt()}" diff --git a/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt b/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt index 15d7323f..e932ae6d 100644 --- a/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt @@ -45,7 +45,6 @@ class FirebaseRemoteConfigRepository( override fun onError(error: FirebaseRemoteConfigException) { Timber.d("timber: [RemoteConfig] onError ${error.code} | ${error.message}") } - }) } diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index b6914b6f..d4912a53 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -19,7 +19,7 @@ interface LtcRepository { companion object { const val PREF_KEY_NETWORK_FEE_PER_KB = "network_fee_per_kb" const val PREF_KEY_NETWORK_FEE_PER_KB_CACHED_AT = "${PREF_KEY_NETWORK_FEE_PER_KB}_cached_at" - const val PREF_KEY_BUY_LIMITS_PREFIX = "buy_limits:" //e.g. buy_limits:usd + const val PREF_KEY_BUY_LIMITS_PREFIX = "buy_limits:" // e.g. buy_limits:usd const val PREF_KEY_BUY_LIMITS_PREFIX_CACHED_AT = "buy_limits_cached_at:" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt index 72730ccc..e5f975d1 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt @@ -26,12 +26,12 @@ class LtcRepositoryImpl( private val sharedPreferences: SharedPreferences, ) : LtcRepository { - //todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies + // todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies override suspend fun fetchRates(): List { return runCatching { val rates = remoteApiSource.getRates() - //legacy logic + // legacy logic FeeManager.updateFeePerKb(context) val selectedISO = BRSharedPrefs.getIsoSymbol(context) rates.forEachIndexed { index, currencyEntity -> @@ -41,11 +41,10 @@ class LtcRepositoryImpl( } } - //save to local + // save to local currencyDataSource.putCurrencies(rates) return rates }.getOrElse { currencyDataSource.getAllCurrencies(true) } - } /** @@ -54,13 +53,13 @@ class LtcRepositoryImpl( * * maybe need updaete core if we need to use dynamic fee? */ - override suspend fun fetchFeePerKb(): Fee = Fee.Default //using static fee + override suspend fun fetchFeePerKb(): Fee = Fee.Default // using static fee override suspend fun fetchLimits(baseCurrencyCode: String): MoonpayCurrencyLimit { return sharedPreferences.fetchWithCache( key = "${PREF_KEY_BUY_LIMITS_PREFIX}${baseCurrencyCode.lowercase()}", cachedAtKey = "${PREF_KEY_BUY_LIMITS_PREFIX_CACHED_AT}${baseCurrencyCode.lowercase()}", - cacheTimeMs = 5 * 60 * 1000, //5 minutes + cacheTimeMs = 5 * 60 * 1000, // 5 minutes fetchData = { remoteApiSource.getMoonpayCurrencyLimit(baseCurrencyCode) } @@ -83,11 +82,10 @@ class LtcRepositoryImpl( .buildUpon() .apply { if (BuildConfig.DEBUG) { - authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com + authority("buy-sandbox.moonpay.com") // replace base url from buy.moonpay.com } } .build() .toString() } - } diff --git a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt index 2d8513ff..2da53d6e 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepository.kt @@ -7,4 +7,4 @@ interface SelectedPeersRepository { companion object { const val LITECOIN_NODES_URL = "https://api.blockchair.com/litecoin/nodes" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepositoryImpl.kt index 454be2d2..e4f34076 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepositoryImpl.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SelectedPeersRepositoryImpl.kt @@ -44,7 +44,7 @@ class SelectedPeersRepositoryImpl( return suspendCoroutine { continuation -> okHttpClient.newCall(request).enqueue(object : Callback { override fun onFailure(call: Call, e: IOException) { - continuation.resume(emptySet()) //just return empty if failed or need hardcoded? + continuation.resume(emptySet()) // just return empty if failed or need hardcoded? } override fun onResponse(call: Call, response: Response) { @@ -60,7 +60,7 @@ class SelectedPeersRepositoryImpl( val dataObject = jsonElement.jsonObject["data"]?.jsonObject val nodesObject = dataObject?.get("nodes")?.jsonObject - //filter criteria + // filter criteria val requiredServices = 0x01 or 0x04 // NODE_NETWORK | NODE_BLOOM nodesObject?.entries @@ -72,7 +72,6 @@ class SelectedPeersRepositoryImpl( ?.map { it.key.replace(":9333", "") } ?.toSet().also { Timber.d("Total Selected Peers ${it?.size}") } ?: emptySet() - } ?: emptySet() sharedPreferences.edit { @@ -85,5 +84,4 @@ class SelectedPeersRepositoryImpl( }) } } - } diff --git a/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt index 484b5249..577781d2 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt @@ -38,4 +38,4 @@ interface SettingRepository { const val KEY_FIAT_CURRENCY_CODE = "fiat_currency_code" const val KEY_SELECTED_FEE_TYPE = "selected_fee_type" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt index fc862d72..71d8befb 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt @@ -70,7 +70,6 @@ class SettingRepositoryImpl( sharedPreferences.getString(KEY_SELECTED_FEE_TYPE, FeeManager.REGULAR) ?: FeeManager.REGULAR - private fun load(): AppSetting { return AppSetting( isDarkMode = sharedPreferences.getBoolean(KEY_IS_DARK_MODE, true), diff --git a/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt b/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt index e00a051e..8294c5fe 100644 --- a/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/LocalCacheSource.kt @@ -42,4 +42,4 @@ suspend inline fun SharedPreferences.fetchWithCache( }.getOrElse { cached ?: (defaultValue ?: throw it) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt b/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt index 530d77a8..23733158 100644 --- a/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt @@ -25,19 +25,19 @@ class MessagingTopicDataSource( */ private fun getBaseLanguageCode(languageCode: String): String { val normalizedLanguageCode = languageCode.split("_", "-").first().lowercase() - + // Handle reverse mapping: if "id" is passed, treat it as Indonesian val searchCode = when (normalizedLanguageCode) { "id" -> "in" else -> normalizedLanguageCode } - - val targetLanguage = supportedLanguages.find { - it.code.split("-").first().lowercase() == searchCode + + val targetLanguage = supportedLanguages.find { + it.code.split("-").first().lowercase() == searchCode } ?: defaultLanguage - + val baseCode = targetLanguage.code.split("-").first().lowercase() - + return when (baseCode) { "in" -> "id" else -> baseCode diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt index 4e0a1c02..ce5a3bb0 100644 --- a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt @@ -9,7 +9,7 @@ import retrofit2.http.GET import retrofit2.http.Query import retrofit2.http.QueryMap -//TODO +// TODO interface RemoteApiSource { @GET("v1/rates") @@ -32,5 +32,4 @@ interface RemoteApiSource { suspend fun getBuyQuote( @QueryMap params: Map ): GetMoonpayBuyQuoteResponse - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt index d39b04fb..0de62915 100644 --- a/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt @@ -11,4 +11,4 @@ interface RemoteConfigSource { fun getString(key: String): String fun getNumber(key: String): Double fun getBoolean(key: String): Boolean -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/di/AppModule.kt b/app/src/main/java/com/brainwallet/di/AppModule.kt index 3c9fd77c..07e6b8d4 100644 --- a/app/src/main/java/com/brainwallet/di/AppModule.kt +++ b/app/src/main/java/com/brainwallet/di/AppModule.kt @@ -42,7 +42,6 @@ object AppModule { single { provideSharedPreferences(context = androidApplication()) } } - private fun provideSharedPreferences( context: Context, name: String = "${BuildConfig.APPLICATION_ID}.prefs" @@ -60,14 +59,16 @@ object AppModule { .addHeader("Accept-Language", "en") chain.proceed(requestBuilder.build()) } - .addInterceptor(HttpLoggingInterceptor().apply { - setLevel( - when { - BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.BODY - else -> HttpLoggingInterceptor.Level.NONE - } - ) - }) + .addInterceptor( + HttpLoggingInterceptor().apply { + setLevel( + when { + BuildConfig.DEBUG -> HttpLoggingInterceptor.Level.BODY + else -> HttpLoggingInterceptor.Level.NONE + } + ) + } + ) .build() internal fun provideRetrofit( diff --git a/app/src/main/java/com/brainwallet/domain/MessagingTopicUseCase.kt b/app/src/main/java/com/brainwallet/domain/MessagingTopicUseCase.kt index 7b1641cb..64307d2f 100644 --- a/app/src/main/java/com/brainwallet/domain/MessagingTopicUseCase.kt +++ b/app/src/main/java/com/brainwallet/domain/MessagingTopicUseCase.kt @@ -33,4 +33,4 @@ class MessagingTopicUseCase( firebaseMessaging.unsubscribeFromTopic(topic) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/exceptions/CertificateChainNotFound.kt b/app/src/main/java/com/brainwallet/exceptions/CertificateChainNotFound.kt index f169cb8e..e98466f3 100644 --- a/app/src/main/java/com/brainwallet/exceptions/CertificateChainNotFound.kt +++ b/app/src/main/java/com/brainwallet/exceptions/CertificateChainNotFound.kt @@ -2,7 +2,6 @@ package com.brainwallet.exceptions import java.security.GeneralSecurityException - class CertificateChainNotFound : GeneralSecurityException { private constructor() : super() @@ -16,4 +15,3 @@ class CertificateChainNotFound : GeneralSecurityException { val TAG: String = CertificateChainNotFound::class.java.name } } - diff --git a/app/src/main/java/com/brainwallet/exceptions/PaymentRequestExpiredException.kt b/app/src/main/java/com/brainwallet/exceptions/PaymentRequestExpiredException.kt index 3f1f5ba9..625127cd 100644 --- a/app/src/main/java/com/brainwallet/exceptions/PaymentRequestExpiredException.kt +++ b/app/src/main/java/com/brainwallet/exceptions/PaymentRequestExpiredException.kt @@ -2,7 +2,6 @@ package com.brainwallet.exceptions import java.security.GeneralSecurityException - class PaymentRequestExpiredException : GeneralSecurityException { private constructor() : super() diff --git a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt index 21c82cda..1897844f 100644 --- a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt +++ b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt @@ -7,12 +7,11 @@ import com.brainwallet.R import com.brainwallet.presenter.activities.BreadActivity import com.brainwallet.ui.BrainwalletActivity import timber.log.Timber -import com.google.firebase.analytics.FirebaseAnalytics -//provide old navigation using intent activity +// provide old navigation using intent activity object LegacyNavigation { - //todo + // todo /** * wrapper for old `startBreadActivity` @@ -25,8 +24,11 @@ object LegacyNavigation { ) { Timber.i("timber: startBreadActivity: %s", from.javaClass.name) - val intent = if (auth) BrainwalletActivity.createIntent(from, Route.UnLock()) - else Intent(from, BreadActivity::class.java) + val intent = if (auth) { + BrainwalletActivity.createIntent(from, Route.UnLock()) + } else { + Intent(from, BreadActivity::class.java) + } intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) from.startActivity(intent) from.overridePendingTransition(R.anim.fade_up, R.anim.fade_down) @@ -46,7 +48,7 @@ object LegacyNavigation { } } - //open compose from old activity + // open compose from old activity @JvmStatic @JvmOverloads fun openComposeScreen( diff --git a/app/src/main/java/com/brainwallet/navigation/MainNav.kt b/app/src/main/java/com/brainwallet/navigation/MainNav.kt index ec2a8a06..0fe70d70 100644 --- a/app/src/main/java/com/brainwallet/navigation/MainNav.kt +++ b/app/src/main/java/com/brainwallet/navigation/MainNav.kt @@ -33,7 +33,7 @@ fun MainNavHost( ) { NavHost( navController = navController, - startDestination = startDestination //since we still have multiple activity, we just start from the param + startDestination = startDestination // since we still have multiple activity, we just start from the param ) { mainNavGraph( onNavigate = { @@ -118,7 +118,5 @@ fun NavGraphBuilder.mainNavGraph( BuyLitecoinScreen(onNavigate = onNavigate) } - //todo add more composable screens + // todo add more composable screens } - - diff --git a/app/src/main/java/com/brainwallet/navigation/MoonPayWidgeLauncher.kt b/app/src/main/java/com/brainwallet/navigation/MoonPayWidgeLauncher.kt index 7677a4de..c36ee5cf 100644 --- a/app/src/main/java/com/brainwallet/navigation/MoonPayWidgeLauncher.kt +++ b/app/src/main/java/com/brainwallet/navigation/MoonPayWidgeLauncher.kt @@ -45,20 +45,22 @@ class MoonPayWidgetLauncherViewModel( _isLoading.update { true } viewModelScope.launch(ioDispatcher) { val isDarkMode = settingRepository.isDarkMode() - _result.send(ltcRepository.runCatching { - val result = ltcRepository.fetchMoonpaySignedUrl( - params = params.toMutableMap().apply { - put("theme", if (isDarkMode) "dark" else "light") - } - ) - isDarkMode to result.toUri().buildUpon() - .apply { - if (BuildConfig.DEBUG) { - authority("buy-sandbox.moonpay.com")//replace base url from buy.moonpay.com + _result.send( + ltcRepository.runCatching { + val result = ltcRepository.fetchMoonpaySignedUrl( + params = params.toMutableMap().apply { + put("theme", if (isDarkMode) "dark" else "light") } - } - .build() - }) + ) + isDarkMode to result.toUri().buildUpon() + .apply { + if (BuildConfig.DEBUG) { + authority("buy-sandbox.moonpay.com") // replace base url from buy.moonpay.com + } + } + .build() + } + ) _isLoading.update { false } } } @@ -83,8 +85,11 @@ fun MoonPayWidgetLauncher( onSuccess = { (isDarkMode, uri) -> val intent = CustomTabsIntent.Builder() .setColorScheme( - if (isDarkMode) CustomTabsIntent.COLOR_SCHEME_DARK - else CustomTabsIntent.COLOR_SCHEME_LIGHT + if (isDarkMode) { + CustomTabsIntent.COLOR_SCHEME_DARK + } else { + CustomTabsIntent.COLOR_SCHEME_LIGHT + } ) .build() intent.launchUrl(context, uri) diff --git a/app/src/main/java/com/brainwallet/navigation/Route.kt b/app/src/main/java/com/brainwallet/navigation/Route.kt index 16f16dcf..005a11b3 100644 --- a/app/src/main/java/com/brainwallet/navigation/Route.kt +++ b/app/src/main/java/com/brainwallet/navigation/Route.kt @@ -3,7 +3,6 @@ package com.brainwallet.navigation import kotlinx.serialization.Serializable import java.io.Serializable as JavaSerializable - sealed class Route : JavaSerializable { @Serializable @@ -47,5 +46,4 @@ sealed class Route : JavaSerializable { @Serializable object BuyLitecoin : Route() - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/navigation/UiEffect.kt b/app/src/main/java/com/brainwallet/navigation/UiEffect.kt index 6e28b2e5..ee7cdf7b 100644 --- a/app/src/main/java/com/brainwallet/navigation/UiEffect.kt +++ b/app/src/main/java/com/brainwallet/navigation/UiEffect.kt @@ -18,8 +18,8 @@ sealed class UiEffect { } } - data class ShowDialog(val name: String): UiEffect() - data object ShowMoonPayDialog: UiEffect() + data class ShowDialog(val name: String) : UiEffect() + data object ShowMoonPayDialog : UiEffect() data class ShowMessage( val message: String, diff --git a/app/src/main/java/com/brainwallet/notification/BrainwalletMessagingService.kt b/app/src/main/java/com/brainwallet/notification/BrainwalletMessagingService.kt index 06cd68c7..7b5a6fc4 100644 --- a/app/src/main/java/com/brainwallet/notification/BrainwalletMessagingService.kt +++ b/app/src/main/java/com/brainwallet/notification/BrainwalletMessagingService.kt @@ -31,4 +31,4 @@ class BrainwalletMessagingService( Timber.d("timber: onNewToken $token") } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/presenter/activities/PaperKeyActivity.kt b/app/src/main/java/com/brainwallet/presenter/activities/PaperKeyActivity.kt index a50c94f2..d327d199 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/PaperKeyActivity.kt +++ b/app/src/main/java/com/brainwallet/presenter/activities/PaperKeyActivity.kt @@ -50,4 +50,4 @@ class PaperKeyActivity : BRActivity() { private fun onSavedItClick() { PostAuth.getInstance().onPhraseProveAuth(this, false) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/presenter/activities/intro/RecoverActivity.kt b/app/src/main/java/com/brainwallet/presenter/activities/intro/RecoverActivity.kt index 4293cb32..906229c9 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/intro/RecoverActivity.kt +++ b/app/src/main/java/com/brainwallet/presenter/activities/intro/RecoverActivity.kt @@ -20,13 +20,15 @@ class RecoverActivity : BRActivity() { val view = binding.root setContentView(view) - binding.sendButton.setOnClickListener(View.OnClickListener { - if (!BRAnimator.isClickAllowed()) return@OnClickListener - LegacyNavigation.openComposeScreen( - context = this@RecoverActivity, - destination = Route.InputWords() - ) - }) + binding.sendButton.setOnClickListener( + View.OnClickListener { + if (!BRAnimator.isClickAllowed()) return@OnClickListener + LegacyNavigation.openComposeScreen( + context = this@RecoverActivity, + destination = Route.InputWords() + ) + } + ) } override fun onResume() { diff --git a/app/src/main/java/com/brainwallet/presenter/base/BaseFragment.kt b/app/src/main/java/com/brainwallet/presenter/base/BaseFragment.kt index 2404b3cc..0a2380f5 100644 --- a/app/src/main/java/com/brainwallet/presenter/base/BaseFragment.kt +++ b/app/src/main/java/com/brainwallet/presenter/base/BaseFragment.kt @@ -5,7 +5,6 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import timber.log.Timber - abstract class BaseFragment

> : Fragment() { lateinit var presenter: P diff --git a/app/src/main/java/com/brainwallet/presenter/entities/ServiceItems.kt b/app/src/main/java/com/brainwallet/presenter/entities/ServiceItems.kt index fc9b1983..8a7ed360 100644 --- a/app/src/main/java/com/brainwallet/presenter/entities/ServiceItems.kt +++ b/app/src/main/java/com/brainwallet/presenter/entities/ServiceItems.kt @@ -7,4 +7,4 @@ enum class ServiceItems(val key: String) { AFDEVID("af-dev-id"), CLIENTCODE("client-code"), AGENTPUBKEY("agent-base64-pubkey") -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/presenter/entities/TransactionDataItem.kt b/app/src/main/java/com/brainwallet/presenter/entities/TransactionDataItem.kt index 010507e8..633de6e8 100644 --- a/app/src/main/java/com/brainwallet/presenter/entities/TransactionDataItem.kt +++ b/app/src/main/java/com/brainwallet/presenter/entities/TransactionDataItem.kt @@ -2,13 +2,19 @@ package com.brainwallet.presenter.entities import com.platform.entities.TxMetaData -///Refactored Transaction data item. Replaces TxItem +// /Refactored Transaction data item. Replaces TxItem class TransactionDataItem { - private var timeStamp = 0L; private var sentAmount = 0L; private var receivedAmount = 0L; - private var networkFee = 0L; private var opsFee = 0L; private var balanceAfterTransaction = 0L - private var toAddresses = arrayOf(); private var fromAddresses = arrayOf() - private var blockHeight = 0; private var transactionSize = 0 + private var timeStamp = 0L + private var sentAmount = 0L + private var receivedAmount = 0L + private var networkFee = 0L + private var opsFee = 0L + private var balanceAfterTransaction = 0L + private var toAddresses = arrayOf() + private var fromAddresses = arrayOf() + private var blockHeight = 0 + private var transactionSize = 0 private var isValidTransaction = false private var transactionHash = ByteArray(0) private var outputAmounts = LongArray(0) diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentBalanceSeedReminder.kt b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentBalanceSeedReminder.kt index b81b82eb..dfd7ed25 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentBalanceSeedReminder.kt +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentBalanceSeedReminder.kt @@ -1,7 +1,6 @@ package com.brainwallet.presenter.fragments import android.os.Bundle -import android.security.keystore.UserNotAuthenticatedException import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -11,7 +10,6 @@ import androidx.fragment.app.Fragment import com.brainwallet.R import com.brainwallet.tools.animation.BRAnimator import com.brainwallet.tools.manager.AnalyticsManager -import com.brainwallet.tools.manager.TxManager import com.brainwallet.tools.security.BRKeyStore import com.brainwallet.tools.util.BRConstants import timber.log.Timber @@ -73,15 +71,14 @@ class FragmentBalanceSeedReminder : Fragment() { private fun registerAnalyticsError(errorString: String) { Timber.d("Fragment Balance Seed: RegisterError : %s", errorString) val params = Bundle() - params.putString("lwa_error_message", errorString); + params.putString("lwa_error_message", errorString) AnalyticsManager.logCustomEventWithParams(BRConstants._20200112_ERR, params) } fun fetchSeedPhrase() { seedPhraseTextView.text = "NO_PHRASE" if (this.activity == null) { registerAnalyticsError("null_in_fragment_balance_fetch_seed") - } - else { + } else { seedPhraseTextView.text = runCatching { BRKeyStore.getPhrase(this.activity, 0) } .getOrNull()?.decodeToString() ?: "NO_PHRASE" } diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentMoonpay.kt b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentMoonpay.kt index ce0a4c20..87edd946 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentMoonpay.kt +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentMoonpay.kt @@ -1,6 +1,5 @@ package com.brainwallet.presenter.fragments -import android.content.res.ColorStateList import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -10,7 +9,6 @@ import android.webkit.WebView import android.webkit.WebViewClient import android.widget.ImageButton import android.widget.TextView -import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import com.brainwallet.R import com.brainwallet.tools.manager.BRClipboardManager @@ -18,48 +16,49 @@ import com.brainwallet.tools.manager.BRSharedPrefs class FragmentMoonpay : Fragment() { - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { - return inflater.inflate(R.layout.fragment_moonpay_temp, container, false) - } + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.fragment_moonpay_temp, container, false) + } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) - val webView = view.findViewById(R.id.web_view) - val buttonClose = view.findViewById(R.id.close_button) - val copyAddressButton = view.findViewById(R.id.copy_button) - var receiveAddressLabel = view.findViewById(R.id.receive_address) - val addressText = BRSharedPrefs.getReceiveAddress(context) + val webView = view.findViewById(R.id.web_view) + val buttonClose = view.findViewById(R.id.close_button) + val copyAddressButton = view.findViewById(R.id.copy_button) + var receiveAddressLabel = view.findViewById(R.id.receive_address) + val addressText = BRSharedPrefs.getReceiveAddress(context) - // buttonClose - receiveAddressLabel.setText(addressText) - receiveAddressLabel.setTextColor(receiveAddressLabel.getResources().getColor(R.color.midnight, null)); - webView.setInitialScale(80) - webView.settings.apply { - javaScriptEnabled = true - domStorageEnabled = true - cacheMode = WebSettings.LOAD_DEFAULT - setSupportZoom(true) - useWideViewPort = true - loadWithOverviewMode = true - } + // buttonClose + receiveAddressLabel.setText(addressText) + receiveAddressLabel.setTextColor(receiveAddressLabel.getResources().getColor(R.color.midnight, null)) + webView.setInitialScale(80) + webView.settings.apply { + javaScriptEnabled = true + domStorageEnabled = true + cacheMode = WebSettings.LOAD_DEFAULT + setSupportZoom(true) + useWideViewPort = true + loadWithOverviewMode = true + } - webView.webViewClient = WebViewClient() - webView.loadUrl("https://www.brainwallet.co/mobile-top-up.html") + webView.webViewClient = WebViewClient() + webView.loadUrl("https://www.brainwallet.co/mobile-top-up.html") - buttonClose.setOnClickListener { - parentFragmentManager.popBackStack() - } + buttonClose.setOnClickListener { + parentFragmentManager.popBackStack() + } - receiveAddressLabel.setOnClickListener { - BRClipboardManager.putClipboard(context, receiveAddressLabel.getText().toString()) - } + receiveAddressLabel.setOnClickListener { + BRClipboardManager.putClipboard(context, receiveAddressLabel.getText().toString()) + } - copyAddressButton.setOnClickListener { - BRClipboardManager.putClipboard(context, receiveAddressLabel.getText().toString()) - } + copyAddressButton.setOnClickListener { + BRClipboardManager.putClipboard(context, receiveAddressLabel.getText().toString()) } } +} diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt index 83d08dcb..1e550bca 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt @@ -48,24 +48,24 @@ import java.math.BigDecimal import java.math.RoundingMode import java.util.regex.Pattern -//TODO: make sure remove unused after refactor network fee move to HomeSettingDrawerSheet +// TODO: make sure remove unused after refactor network fee move to HomeSettingDrawerSheet class FragmentSend : Fragment() { - private lateinit var signalLayout: LinearLayout; + private lateinit var signalLayout: LinearLayout private lateinit var keyboardLayout: LinearLayout - private lateinit var scanButton: Button; - private lateinit var pasteButton: Button; - private lateinit var sendButton: Button; + private lateinit var scanButton: Button + private lateinit var pasteButton: Button + private lateinit var sendButton: Button private lateinit var isoCurrencySymbolButton: Button - private lateinit var commentEdit: EditText; - private lateinit var addressEdit: EditText; + private lateinit var commentEdit: EditText + private lateinit var addressEdit: EditText private lateinit var amountEdit: EditText - private lateinit var isoCurrencySymbolText: TextView; - private lateinit var balanceText: TextView; - private lateinit var feeText: TextView; - private lateinit var feeDescription: TextView; + private lateinit var isoCurrencySymbolText: TextView + private lateinit var balanceText: TextView + private lateinit var feeText: TextView + private lateinit var feeDescription: TextView private lateinit var warningText: TextView - private var amountLabelOn = true; - private var ignoreCleanup = false; + private var amountLabelOn = true + private var ignoreCleanup = false private var feeButtonsShown = false private var currentBalance: Long = 0 private var keyboardIndex = 0 @@ -104,19 +104,23 @@ class FragmentSend : Fragment() { // warningText = rootView.findViewById(R.id.warning_text) as TextView closeButton = rootView.findViewById(R.id.close_button) as ImageButton selectedIsoCurrencySymbol = - if (BRSharedPrefs.getPreferredLTC(context)) "LTC" else BRSharedPrefs.getIsoSymbol( - context - ) + if (BRSharedPrefs.getPreferredLTC(context)) { + "LTC" + } else { + BRSharedPrefs.getIsoSymbol( + context + ) + } amountBuilder = StringBuilder(0) setListeners() - /// Setup Currency Button that switches between LTC and the preferred fiat (e.g.; "USD") + // / Setup Currency Button that switches between LTC and the preferred fiat (e.g.; "USD") isoCurrencySymbolText.text = getString(R.string.Send_amountLabel) isoCurrencySymbolText.textSize = 18f isoCurrencySymbolText.setTextColor(requireContext().getColor(R.color.cheddar)) isoCurrencySymbolText.requestLayout() - /// Setup Fees Description + // / Setup Fees Description feeText.text = "" signalLayout.setOnTouchListener(SlideDetector(signalLayout) { animateClose() }) @@ -135,7 +139,7 @@ class FragmentSend : Fragment() { updateText() - //update fee + // update fee BRWalletManager.getInstance().setFeePerKb(FeeManager.getInstance().currentFeeValue) return rootView @@ -631,7 +635,7 @@ class FragmentSend : Fragment() { BRWalletManager.getInstance().feeForTransactionAmount(totalAmountToCalculateFees) } else { 0 - } //Amount is zero so network fee is also zero + } // Amount is zero so network fee is also zero val networkFeeForISOSymbol = BRExchange.getAmountFromLitoshis(activity, selectedISOSymbol, BigDecimal(networkFee)) .setScale(scaleValue, RoundingMode.HALF_UP) @@ -746,8 +750,10 @@ class FragmentSend : Fragment() { private fun loadMetaData() { ignoreCleanup = false if (!Utils.isNullOrEmpty(savedMemo)) commentEdit.setText(savedMemo) - if (!Utils.isNullOrEmpty(savedIsoCurrencySymbol)) selectedIsoCurrencySymbol = - savedIsoCurrencySymbol + if (!Utils.isNullOrEmpty(savedIsoCurrencySymbol)) { + selectedIsoCurrencySymbol = + savedIsoCurrencySymbol + } if (!Utils.isNullOrEmpty(savedAmount)) { amountBuilder = StringBuilder(savedAmount!!) Handler().postDelayed({ @@ -775,8 +781,7 @@ class FragmentSend : Fragment() { } } - -///DEV WIP +// /DEV WIP // val approximateNetworkFee = BRCurrency.getFormattedCurrencyString(activity, selectedISOSymbol, feeForISOSymbol) diff --git a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt index a3549362..61d29c0c 100644 --- a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt +++ b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt @@ -56,7 +56,7 @@ class HistoryFragment : } private fun registerAnalyticsError(errorString: String) { val params = Bundle() - params.putString("lwa_error_message", errorString); + params.putString("lwa_error_message", errorString) AnalyticsManager.logCustomEventWithParams(BRConstants._20200112_ERR, params) Timber.d("History Fragment: RegisterError : %s", errorString) } @@ -66,8 +66,7 @@ class HistoryFragment : if (this.activity == null) { registerAnalyticsError("null_in_history_fragment_on_resume") - } - else { + } else { TxManager.getInstance().onResume(this.activity) } } @@ -85,8 +84,7 @@ class HistoryFragment : BRExecutor.getInstance().forBackgroundTasks().execute { if (this.activity == null) { registerAnalyticsError("null_in_history_fragment_on_status_update") - } - else { + } else { TxManager.getInstance().updateTxList(this.activity) } } @@ -100,8 +98,7 @@ class HistoryFragment : BRExecutor.getInstance().forBackgroundTasks().execute { if (this.activity == null) { registerAnalyticsError("null_in_history_fragment_on_tx_added") - } - else { + } else { TxManager.getInstance().updateTxList(this.activity) } } @@ -110,8 +107,7 @@ class HistoryFragment : BRExecutor.getInstance().forLightWeightBackgroundTasks().execute { if (this.activity == null) { registerAnalyticsError("null_in_history_fragment_update_ui") - } - else { + } else { Thread.currentThread().name = Thread.currentThread().name + "HistoryFragment:updateUI" TxManager.getInstance().updateTxList(this.activity) } diff --git a/app/src/main/java/com/brainwallet/presenter/language/ChangeLanguageBottomSheet.kt b/app/src/main/java/com/brainwallet/presenter/language/ChangeLanguageBottomSheet.kt index a1ff0249..d01128c2 100644 --- a/app/src/main/java/com/brainwallet/presenter/language/ChangeLanguageBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/presenter/language/ChangeLanguageBottomSheet.kt @@ -116,7 +116,7 @@ class ChangeLanguageBottomSheet : RoundedBottomSheetDialogFragment() { return dialog } - //for now, need to provide [getLocale] + // for now, need to provide [getLocale] private fun getLocale(language: Language): Locale { val codes = language.code.split("-") return if (codes.size == 2) { diff --git a/app/src/main/java/com/brainwallet/presenter/language/LanguageAdapter.kt b/app/src/main/java/com/brainwallet/presenter/language/LanguageAdapter.kt index 0c65d12e..94cc47a6 100644 --- a/app/src/main/java/com/brainwallet/presenter/language/LanguageAdapter.kt +++ b/app/src/main/java/com/brainwallet/presenter/language/LanguageAdapter.kt @@ -8,7 +8,6 @@ import androidx.recyclerview.widget.RecyclerView import com.brainwallet.R import com.brainwallet.data.model.Language - class LanguageAdapter(val languages: Array) : RecyclerView.Adapter() { var selectedPosition = 0 diff --git a/app/src/main/java/com/brainwallet/tools/adapter/CountryLanguageAdapter.kt b/app/src/main/java/com/brainwallet/tools/adapter/CountryLanguageAdapter.kt index ad5c3292..a2313283 100644 --- a/app/src/main/java/com/brainwallet/tools/adapter/CountryLanguageAdapter.kt +++ b/app/src/main/java/com/brainwallet/tools/adapter/CountryLanguageAdapter.kt @@ -14,11 +14,11 @@ import androidx.recyclerview.widget.RecyclerView import com.brainwallet.R import com.brainwallet.data.model.IntroLanguage -class CountryLanguageAdapter(context: Context,val languages: Array) : RecyclerView.Adapter() { +class CountryLanguageAdapter(context: Context, val languages: Array) : RecyclerView.Adapter() { private var mCountryLang: Array? = null private var mInflater: LayoutInflater? = null - private var mSelectedItem = -1; - private var barlowFont : Typeface? = null + private var mSelectedItem = -1 + private var barlowFont: Typeface? = null private var mContext: Context? = null private var mediaPlayer: MediaPlayer? = null @@ -49,7 +49,6 @@ class CountryLanguageAdapter(context: Context,val languages: Array brDialogView.dismissWithAnimation() }, null, @@ -165,7 +163,6 @@ class BrainwalletActivity : BRActivity() { ) else -> Unit - } } @@ -176,7 +173,6 @@ class BrainwalletActivity : BRActivity() { .launchIn(lifecycleScope) } - /** * legacy logic, when the pin/passcode empty (not set) * then should go to setpasscode @@ -208,7 +204,7 @@ class BrainwalletActivity : BRActivity() { LegacyNavigation.startBreadActivity(this, false) } else { AuthManager.getInstance().authFail(this) - //for now just toast + // for now just toast Toast.makeText(this, R.string.incorrect_passcode, Toast.LENGTH_SHORT).show() } } @@ -274,4 +270,4 @@ class BrainwalletActivity : BRActivity() { putExtra(EXTRA_START_DESTINATION, startDestination) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt b/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt index 9d526ec7..167d6688 100644 --- a/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt @@ -34,7 +34,7 @@ abstract class BrainwalletViewModel : ViewModel() { protected fun handleError(t: Throwable) { val errorMessage = t.message ?: "Oops, something went wrong" - //todo more error handler + // todo more error handler if (t is retrofit2.HttpException) { val message = t.response()?.errorBody()?.string()?.let { @@ -69,4 +69,4 @@ abstract class BrainwalletViewModel : ViewModel() { data class LoadingState( val visible: Boolean = false, val message: String = "msg_please_wait" -) \ No newline at end of file +) diff --git a/app/src/main/java/com/brainwallet/ui/RoundedBottomSheetDialogFragment.kt b/app/src/main/java/com/brainwallet/ui/RoundedBottomSheetDialogFragment.kt index 426da376..72003e4b 100644 --- a/app/src/main/java/com/brainwallet/ui/RoundedBottomSheetDialogFragment.kt +++ b/app/src/main/java/com/brainwallet/ui/RoundedBottomSheetDialogFragment.kt @@ -2,7 +2,6 @@ package com.brainwallet.ui import android.app.Dialog import android.os.Bundle -import com.brainwallet.R import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment diff --git a/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt index 3c55100f..666a92fe 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt @@ -27,4 +27,4 @@ fun CircleButton( colors = colors, content = content ) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt index 2a9688d5..482bbc98 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt @@ -65,7 +65,7 @@ fun DarkModeToggleButton( private fun DarkModeToggleButtonPreview() { BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) { Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) { - DarkModeToggleButton(checked = isSystemInDarkTheme(), onCheckedChange = {}, ) + DarkModeToggleButton(checked = isSystemInDarkTheme(), onCheckedChange = {},) } } } diff --git a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt index 48721758..0128e17a 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt @@ -60,4 +60,4 @@ fun BorderedLargeButton( shape = shape, content = content ) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt index 8c6270ad..b8743e7b 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt @@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material3.Card -import androidx.compose.material3.CardDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -52,4 +51,4 @@ fun LoadingDialog( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt index 03946098..68560e0f 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt @@ -1,22 +1,16 @@ package com.brainwallet.ui.composable -import androidx.compose.foundation.border import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ButtonColors import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.FilledTonalButton import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.graphics.drawscope.ContentDrawScope import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.brainwallet.ui.screens.welcome.WelcomeScreen -import com.brainwallet.ui.theme.BrainwalletColors import com.brainwallet.ui.theme.BrainwalletTheme @Composable @@ -40,6 +34,7 @@ fun MediumTextButton( content = content ) } + @Preview @Composable fun MediumTextButtonPreview() { @@ -51,4 +46,3 @@ fun MediumTextButtonPreview() { content = TODO() ) } - \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt index e3513194..a5ccf28d 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt @@ -60,7 +60,5 @@ fun MoonpayBuyButton( ) } } - } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyWidget.kt b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyWidget.kt index 006e45bf..1568e678 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyWidget.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyWidget.kt @@ -1,6 +1,5 @@ package com.brainwallet.ui.composable - import android.annotation.SuppressLint import android.graphics.Bitmap import android.view.ViewGroup @@ -12,7 +11,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.viewinterop.AndroidView -//TODO: wip here +// TODO: wip here @SuppressLint("SetJavaScriptEnabled") @Composable @@ -45,12 +44,10 @@ fun MoonpayBuyWidget( super.onPageFinished(view, url) } } - } }, update = { it.loadUrl(signedUrl) } ) - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt b/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt index a0607cbc..adc97ab3 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt @@ -29,7 +29,7 @@ fun PasscodeKeypad( verticalArrangement = Arrangement.spacedBy(24.dp), maxItemsInEachRow = 3 ) { - //pin number button + // pin number button val modifierCircleButton = Modifier.size(75.dp) repeat(9) { index -> @@ -48,7 +48,7 @@ fun PasscodeKeypad( } // Bottom row with biometric, 0, and backspace - if (false) {//hardcoded false for now + if (false) { // hardcoded false for now CircleButton( modifier = modifierCircleButton, onClick = { @@ -108,4 +108,4 @@ fun PasscodeKeypad( sealed class PasscodeKeypadEvent { object OnDelete : PasscodeKeypadEvent() data class OnPressed(val digit: Int) : PasscodeKeypadEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt b/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt index 2cd0ad54..e216c993 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt @@ -24,5 +24,5 @@ fun PinDotItem( .background(if (checked) BrainwalletTheme.colors.content else Color.Transparent, CircleShape) .border(1.dp, BrainwalletTheme.colors.content, CircleShape), - ) -} \ No newline at end of file + ) +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt index 202f21f8..5663e9f5 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt @@ -66,7 +66,8 @@ fun SeedWordItem( @Composable fun SeedWordItemBox( - modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit + modifier: Modifier = Modifier, + content: @Composable RowScope.() -> Unit ) { Box(modifier = modifier) { Row( @@ -75,7 +76,8 @@ fun SeedWordItemBox( color = BrainwalletTheme.colors.background.copy(alpha = 0.3f), shape = MaterialTheme.shapes.extraLarge ) - .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically + .padding(horizontal = 16.dp), + verticalAlignment = Alignment.CenterVertically ) { content.invoke(this) } @@ -93,7 +95,9 @@ fun SeedWordItemTextField( ), keyboardOptions: KeyboardOptions = KeyboardOptions.Default, keyboardActions: KeyboardActions = KeyboardActions.Default, - cursorBrush: Brush = SolidColor(BrainwalletTheme.colors.content), //todo: change with materialtheme so it will be adapt automatically when switch darkmode + cursorBrush: Brush = SolidColor( + BrainwalletTheme.colors.content + ), // todo: change with materialtheme so it will be adapt automatically when switch darkmode prefix: @Composable (() -> Unit)? = null, ) { var suggestionsExpanded by remember { mutableStateOf(false) } @@ -135,7 +139,8 @@ fun SeedWordItemTextField( } } } - }) + } + ) DropdownMenu( modifier = Modifier @@ -162,10 +167,7 @@ fun SeedWordItemTextField( }) } } - } - } - -/// \ No newline at end of file +// / diff --git a/app/src/main/java/com/brainwallet/ui/composable/SeedWordsLayout.kt b/app/src/main/java/com/brainwallet/ui/composable/SeedWordsLayout.kt index a8f3d98c..23ae20d4 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/SeedWordsLayout.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/SeedWordsLayout.kt @@ -18,10 +18,10 @@ fun SeedWordsLayout( LazyVerticalGrid( modifier = modifier .height(220.dp), - columns = GridCells.Fixed(3), //fixed 3 + columns = GridCells.Fixed(3), // fixed 3 contentPadding = PaddingValues(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp), horizontalArrangement = Arrangement.spacedBy(8.dp), content = content ) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt b/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt index 27e9ce40..6094624e 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt @@ -94,7 +94,6 @@ fun VerticalWheelPicker( ) } - @Composable private fun WheelPicker( modifier: Modifier, @@ -201,9 +200,7 @@ private fun InternalWheelPicker( }, contentAlignment = Alignment.Center, ) { - val lazyListScope: LazyListScope.() -> Unit = { - repeat(unfocusedCount) { item(contentType = "placeholder") { ItemSizeBox( @@ -381,7 +378,7 @@ internal inline fun logMsg(debug: Boolean, block: () -> String) { } } -//default +// default /** * The default implementation of focus view in vertical. */ @@ -444,7 +441,7 @@ fun WheelPickerDisplayScope.DefaultWheelPickerDisplay( } } -//state +// state @Composable fun rememberWheelPickerState( initialIndex: Int = 0, @@ -631,4 +628,4 @@ class WheelPickerState internal constructor( restore = { WheelPickerState(initialIndex = it[0]) }, ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt index 3ce93ad0..818c0451 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt @@ -14,7 +14,6 @@ import androidx.compose.material.icons.filled.CheckCircle import androidx.compose.material3.Icon import androidx.compose.material3.ListItem import androidx.compose.material3.ListItemDefaults -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -42,7 +41,6 @@ fun FiatSelectorBottomSheet( val unselectedCircleSize = 20 val tinyPad = 2 - BrainwalletBottomSheet( onDismissRequest = onDismissRequest, ) { @@ -51,45 +49,50 @@ fun FiatSelectorBottomSheet( items( items = currencies ) { currency -> - ListItem(colors = ListItemDefaults.colors( - containerColor = BrainwalletTheme.colors.background, - headlineColor = BrainwalletTheme.colors.content, - ), modifier = Modifier.clickable { - onFiatSelect.invoke(currency) - }, headlineContent = { - Row { - Text( - modifier = Modifier.padding(tinyPad.dp), - text = currency.name, - style = BrainwalletTheme.typography.labelLarge - .copy(textAlign = TextAlign.Left) - ) - Spacer(modifier = Modifier.weight(1f)) - Text( - modifier = Modifier.padding(tinyPad.dp), - text = "${currency.code} (${currency.symbol})", - style = BrainwalletTheme.typography.labelLarge - .copy(textAlign = TextAlign.Left) - ) + ListItem( + colors = ListItemDefaults.colors( + containerColor = BrainwalletTheme.colors.background, + headlineColor = BrainwalletTheme.colors.content, + ), + modifier = Modifier.clickable { + onFiatSelect.invoke(currency) + }, + headlineContent = { + Row { + Text( + modifier = Modifier.padding(tinyPad.dp), + text = currency.name, + style = BrainwalletTheme.typography.labelLarge + .copy(textAlign = TextAlign.Left) + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + modifier = Modifier.padding(tinyPad.dp), + text = "${currency.code} (${currency.symbol})", + style = BrainwalletTheme.typography.labelLarge + .copy(textAlign = TextAlign.Left) + ) + } + }, + trailingContent = { + if (selectedCurrency.code == currency.code) { + Icon( + Icons.Default.CheckCircle, + contentDescription = null, + tint = BrainwalletTheme.colors.affirm + ) + } else { + Box( + modifier = Modifier + .size(unselectedCircleSize.dp) + .alpha(0.1f) + .clip(CircleShape) + .background(BrainwalletTheme.colors.content) + ) + } } - }, trailingContent = { - if (selectedCurrency.code == currency.code) { - Icon( - Icons.Default.CheckCircle, - contentDescription = null, - tint = BrainwalletTheme.colors.affirm - ) - } else { - Box( - modifier = Modifier - .size(unselectedCircleSize.dp) - .alpha(0.1f) - .clip(CircleShape) - .background(BrainwalletTheme.colors.content) - ) - } - }) + ) } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt index 997f06ae..d2aafa12 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt @@ -28,7 +28,7 @@ fun LanguageSelectorBottomSheet( ) { LazyColumn { val languages = Language.entries.toTypedArray() - val lastLanguageItem = languages[languages.size -1] + val lastLanguageItem = languages[languages.size - 1] val lastLanguageBottomPad = 16 items( items = languages @@ -42,7 +42,7 @@ fun LanguageSelectorBottomSheet( if (language.code.isNotBlank()) { onLanguageSelect.invoke(language) } - }.padding(bottom = if(language == lastLanguageItem) lastLanguageBottomPad.dp else 0.dp), + }.padding(bottom = if (language == lastLanguageItem) lastLanguageBottomPad.dp else 0.dp), headlineContent = { Text(language.title) }, @@ -59,4 +59,4 @@ fun LanguageSelectorBottomSheet( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt index 31e528fe..8a56442f 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt @@ -8,4 +8,4 @@ sealed class BuyLitecoinEvent { val fiatAmount: Float, val needFetch: Boolean = true ) : BuyLitecoinEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt index e1aa80a0..bb549542 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt @@ -35,7 +35,7 @@ import com.brainwallet.ui.composable.LargeButton import com.brainwallet.ui.theme.BrainwalletTheme import org.koin.compose.viewmodel.koinViewModel -//TODO: wip +// TODO: wip @Composable fun BuyLitecoinScreen( onNavigate: OnNavigate, @@ -82,7 +82,6 @@ fun BuyLitecoinScreen( .fillMaxSize(), contentAlignment = Alignment.TopCenter ) { - Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(24.dp) @@ -139,10 +138,8 @@ fun BuyLitecoinScreen( ) ) ) - } - LargeButton( modifier = Modifier.align(Alignment.BottomCenter), enabled = loadingState.visible.not(), @@ -163,4 +160,4 @@ fun BuyLitecoinScreen( } MoonPayWidgetLauncher(viewModel = moonPayWidgetLauncherViewModel) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt index 30975ab3..c2b438ec 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt @@ -52,7 +52,6 @@ class BuyLitecoinViewModel( onEvent(BuyLitecoinEvent.OnFiatAmountChange(it)) } } - } override fun onEvent(event: BuyLitecoinEvent) { @@ -78,11 +77,10 @@ class BuyLitecoinViewModel( } finally { onLoading(false) } - } is BuyLitecoinEvent.OnFiatAmountChange -> viewModelScope.launch { - //do validation + // do validation val (_, min, max) = state.value.moonpayCurrencyLimit.data.baseCurrency val errorStringId = when { event.fiatAmount < min -> R.string.buy_litecoin_fiat_amount_validation_min @@ -116,7 +114,6 @@ class BuyLitecoinViewModel( ltcAmount = result.data.quoteCurrencyAmount, ) } - } catch (e: Exception) { handleError(e) } finally { @@ -125,5 +122,4 @@ class BuyLitecoinViewModel( } } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/HomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/home/HomeScreen.kt index 754ea939..8fe18853 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/HomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/HomeScreen.kt @@ -24,7 +24,7 @@ import androidx.fragment.compose.rememberFragmentState import com.brainwallet.navigation.OnNavigate import com.brainwallet.presenter.history.HistoryFragment -//TODO: wip +// TODO: wip @Composable fun HomeScreen( onNavigate: OnNavigate @@ -37,7 +37,7 @@ fun HomeScreen( modifier = Modifier.padding(paddingValues) ) { val fragmentState = rememberFragmentState() - //using old fragment + // using old fragment AndroidFragment( fragmentState = fragmentState ) @@ -53,7 +53,6 @@ fun HomeTopBar() { }, actions = { IconButton(onClick = { - }) { Icon(Icons.Default.Menu, contentDescription = "menu") } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt index 36ef087f..76bd8feb 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt @@ -23,4 +23,4 @@ sealed class SettingsEvent { data class OnFiatChange(val currency: CurrencyEntity) : SettingsEvent() object OnBlockchainSyncClick : SettingsEvent() data class OnFeeTypeChange(val feeType: String) : SettingsEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt index b1e82c75..16719088 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt @@ -17,11 +17,11 @@ data class SettingsState( "US Dollar", -1f, "$" - ), //-1 = need to fetch + ), // -1 = need to fetch val languageSelectorBottomSheetVisible: Boolean = false, val fiatSelectorBottomSheetVisible: Boolean = false, val shareAnalyticsDataEnabled: Boolean = false, val lastSyncMetadata: SyncAnalyticsRepository.SyncMetadata? = null, val currentFeeOptions: List = Fee.Default.toFeeOptions(), val selectedFeeType: String = FeeManager.LUXURY -) \ No newline at end of file +) diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt index 75f59e71..9d73dcd4 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt @@ -183,4 +183,4 @@ class SettingsViewModel( const val LEGACY_EFFECT_ON_SEED_PHRASE = "onSeedPhrase" const val LEGACY_EFFECT_ON_SHARE_ANALYTICS_DATA_TOGGLE = "onShareAnalyticsDataToggle" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index fbb01438..76fd6b8a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -62,13 +62,17 @@ fun HomeSettingDrawerSheet( val context = LocalContext.current LaunchedEffect(Unit) { - viewModel.onEvent(SettingsEvent.OnLoad( - shareAnalyticsDataEnabled = BRSharedPrefs.getShareData(context), //currently just load analytics share data here - lastSyncMetadata = syncAnalyticsRepository.getLastSyncMetadata(), //currently just load sync metadata here - )) + viewModel.onEvent( + SettingsEvent.OnLoad( + shareAnalyticsDataEnabled = BRSharedPrefs.getShareData( + context + ), // currently just load analytics share data here + lastSyncMetadata = syncAnalyticsRepository.getLastSyncMetadata(), // currently just load sync metadata here + ) + ) } - /// Layout values + // / Layout values val headerPadding = 56 ModalDrawerSheet( @@ -112,7 +116,6 @@ fun HomeSettingDrawerSheet( ) } ) - } item { CurrencyDetail( @@ -223,7 +226,8 @@ fun HomeSettingDrawerSheet( */ class HomeSettingDrawerComposeView @JvmOverloads constructor( - context: Context, attrs: AttributeSet? = null + context: Context, + attrs: AttributeSet? = null ) : AbstractComposeView(context, attrs) { private val settingsViewModel: SettingsViewModel by inject(SettingsViewModel::class.java) @@ -247,4 +251,4 @@ class HomeSettingDrawerComposeView @JvmOverloads constructor( .onEach { onEach.invoke(it) } .launchIn(findViewTreeLifecycleOwner()!!.lifecycle.coroutineScope) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt index 83821a2f..7a5cc1a2 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt @@ -39,7 +39,7 @@ fun CurrencyDetail( ) { val context = LocalContext.current - /// Layout values + // / Layout values val closedHeight = 60 val expandedHeight = 100 val dividerThickness = 1 @@ -56,46 +56,50 @@ fun CurrencyDetail( items( items = CurrencyDataSource.getInstance(context).getAllCurrencies(true) ) { currency -> - ListItem(colors = ListItemDefaults.colors( - containerColor = BrainwalletTheme.colors.background, - headlineColor = BrainwalletTheme.colors.content, - ), modifier = Modifier.clickable { - onFiatSelect.invoke(currency) - }, headlineContent = { - Row { - Text( - modifier = Modifier.padding(tinyPad.dp), - text = currency.name, - style = MaterialTheme.typography.labelMedium - .copy(textAlign = TextAlign.Left) - ) - Spacer(modifier = Modifier.weight(1f)) - Text( - modifier = Modifier.padding(tinyPad.dp), - text = "${currency.code} (${currency.symbol})", - style = MaterialTheme.typography.labelMedium - .copy(textAlign = TextAlign.Left) - ) + ListItem( + colors = ListItemDefaults.colors( + containerColor = BrainwalletTheme.colors.background, + headlineColor = BrainwalletTheme.colors.content, + ), + modifier = Modifier.clickable { + onFiatSelect.invoke(currency) + }, + headlineContent = { + Row { + Text( + modifier = Modifier.padding(tinyPad.dp), + text = currency.name, + style = MaterialTheme.typography.labelMedium + .copy(textAlign = TextAlign.Left) + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + modifier = Modifier.padding(tinyPad.dp), + text = "${currency.code} (${currency.symbol})", + style = MaterialTheme.typography.labelMedium + .copy(textAlign = TextAlign.Left) + ) + } + }, + trailingContent = { + if (selectedCurrency.code == currency.code) { + Icon( + Icons.Default.CheckCircle, + contentDescription = null, + tint = BrainwalletTheme.colors.affirm + ) + } else { + Box( + modifier = Modifier + .size(unselectedCircleSize.dp) + .alpha(0.1f) + .clip(CircleShape) + .background(BrainwalletTheme.colors.content) + ) + } } - - }, trailingContent = { - if (selectedCurrency.code == currency.code) { - Icon( - Icons.Default.CheckCircle, - contentDescription = null, - tint = BrainwalletTheme.colors.affirm - ) - } else { - Box( - modifier = Modifier - .size(unselectedCircleSize.dp) - .alpha(0.1f) - .clip(CircleShape) - .background(BrainwalletTheme.colors.content) - ) - } - }) + ) } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/GamesDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/GamesDetail.kt index 02bb1132..8a8e3af0 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/GamesDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/GamesDetail.kt @@ -18,7 +18,7 @@ import com.brainwallet.R fun GamesDetail( modifier: Modifier = Modifier ) { - /// Layout values + // / Layout values val contentHeight = 60 val horizontalPadding = 14 @@ -30,7 +30,6 @@ fun GamesDetail( modifier = Modifier.padding(horizontal = horizontalPadding.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - Row( modifier = Modifier .height(contentHeight.dp), @@ -81,8 +80,6 @@ fun GamesDetail( Text(stringResource(R.string.game_buy_price_4, "TBD")) } } - } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt index 24046969..3445de6c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt @@ -26,7 +26,7 @@ import com.brainwallet.R import com.brainwallet.data.model.Language import com.brainwallet.ui.theme.BrainwalletTheme -//TODO +// TODO @Composable fun LanguageDetail( modifier: Modifier = Modifier, @@ -35,11 +35,10 @@ fun LanguageDetail( ) { val languages = Language.entries.toTypedArray() - /// Layout values + // / Layout values val expandedHeight = 150 val unselectedCircleSize = 20 - SettingRowItemExpandable( modifier = modifier, title = stringResource(R.string.settings_title_language) @@ -87,4 +86,4 @@ fun LanguageDetail( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt index 1c3e6ef8..93a46318 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt @@ -15,8 +15,6 @@ import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -32,7 +30,7 @@ import com.brainwallet.data.model.getSelectedIndex import com.brainwallet.ui.screens.home.SettingsEvent import com.brainwallet.ui.theme.BrainwalletTheme -//TODO +// TODO @Composable fun LitecoinBlockchainDetail( modifier: Modifier = Modifier, @@ -41,8 +39,7 @@ fun LitecoinBlockchainDetail( feeOptions: List, onEvent: (SettingsEvent) -> Unit, ) { - - /// Layout values + // / Layout values val contentHeight = 60 val horizontalPadding = 14 @@ -54,7 +51,6 @@ fun LitecoinBlockchainDetail( modifier = Modifier.padding(horizontal = horizontalPadding.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - Row( modifier = Modifier.height(contentHeight.dp), verticalAlignment = Alignment.CenterVertically @@ -82,7 +78,6 @@ fun LitecoinBlockchainDetail( ) { newSelectedIndex -> onEvent.invoke(SettingsEvent.OnFeeTypeChange(feeOptions[newSelectedIndex].type)) } - } } } @@ -114,7 +109,7 @@ private fun NetworkFeeSelector( fontWeight = FontWeight.Bold ) Text( - text = feeOptions[index].getFiatFormatted(selectedCurrency), //fiat? + text = feeOptions[index].getFiatFormatted(selectedCurrency), // fiat? fontSize = 12.sp ) } @@ -135,7 +130,5 @@ private fun NetworkFeeSelector( ) } } - - } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt index 871b466f..f65592ad 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt @@ -20,4 +20,4 @@ fun LockSettingRowItem( ) { Icon(Icons.Default.Lock, contentDescription = stringResource(R.string.settings_title_lock)) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SecurityDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SecurityDetail.kt index 84e86234..40eaf22e 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SecurityDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SecurityDetail.kt @@ -15,15 +15,14 @@ import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.ui.screens.home.SettingsEvent -//TODO +// TODO @Composable fun SecurityDetail( modifier: Modifier = Modifier, shareAnalyticsDataEnabled: Boolean = false, onEvent: (SettingsEvent) -> Unit ) { - - /// Layout values + // / Layout values val contentHeight = 60 val horizontalPadding = 14 @@ -88,7 +87,6 @@ fun SecurityDetail( Text(stringResource(if (shareAnalyticsDataEnabled) R.string.Button_yes else R.string.Button_no)) } } - } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt index 845e31c2..9df1bed1 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt @@ -65,13 +65,12 @@ fun SettingRowItemExpandable( ) { var expanded by remember { mutableStateOf(false) } - /// Layout values + // / Layout values val closedHeight = 60 val expandedHeight = 100 val dividerThickness = 1 val horizontalPadding = 14 - Column( modifier = modifier.background(BrainwalletTheme.colors.settingRowItemBackground(expanded)) ) { @@ -118,4 +117,4 @@ fun SettingRowItemExpandable( fun BrainwalletColors.settingRowItemBackground( expanded: Boolean = false -) = if (expanded) background else surface \ No newline at end of file +) = if (expanded) background else surface diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/ThemeSettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/ThemeSettingRowItem.kt index 98a8b1e5..d764bd58 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/ThemeSettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/ThemeSettingRowItem.kt @@ -29,4 +29,4 @@ fun ThemeSettingRowItem( } ) } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/history/HistoryScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/home/history/HistoryScreen.kt index c22aa8bc..988ad5f5 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/history/HistoryScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/history/HistoryScreen.kt @@ -3,8 +3,8 @@ package com.brainwallet.ui.screens.home.history import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable -//TODO: wip +// TODO: wip @Composable fun HistoryScreen() { Box {} -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt index 64f7446e..b50bdf51 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt @@ -171,7 +171,7 @@ private fun ReceiveDialog( ) { CenterAlignedTopAppBar( colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = BrainwalletTheme.colors.content //invert surface + containerColor = BrainwalletTheme.colors.content // invert surface ), expandedHeight = 56.dp, title = { @@ -208,8 +208,8 @@ private fun ReceiveDialog( } ) - //moonpay widget - //todo: revisit this later + // moonpay widget + // todo: revisit this later // AnimatedVisibility(visible = state.moonpayWidgetVisible()) { // state.moonpayBuySignedUrl?.let { signedUrl -> // MoonpayBuyWidget( @@ -219,8 +219,7 @@ private fun ReceiveDialog( // } // } - - //buy / receive + // buy / receive // AnimatedVisibility(visible = state.moonpayWidgetVisible().not()) { Column { Row( @@ -356,9 +355,11 @@ private fun ReceiveDialog( }, label = { Text( - text = if (quickFiatAmountOption.isCustom()) + text = if (quickFiatAmountOption.isCustom()) { stringResource(R.string.custom) - else quickFiatAmountOption.getFormattedText(), + } else { + quickFiatAmountOption.getFormattedText() + }, style = BrainwalletTheme.typography.bodyMedium.copy( color = BrainwalletTheme.colors.surface ) @@ -373,14 +374,15 @@ private fun ReceiveDialog( } } - AnimatedVisibility(visible = state.isQuickFiatAmountOptionCustom()) { OutlinedTextField( modifier = Modifier.fillMaxWidth(), prefix = { Text( text = state.selectedFiatCurrency.symbol, - style = BrainwalletTheme.typography.bodyMedium.copy(color = BrainwalletTheme.colors.surface) + style = BrainwalletTheme.typography.bodyMedium.copy( + color = BrainwalletTheme.colors.surface + ) ) }, trailingIcon = { @@ -390,7 +392,9 @@ private fun ReceiveDialog( Icon(Icons.Default.Done, contentDescription = null) } }, - textStyle = BrainwalletTheme.typography.bodyMedium.copy(color = BrainwalletTheme.colors.surface), + textStyle = BrainwalletTheme.typography.bodyMedium.copy( + color = BrainwalletTheme.colors.surface + ), value = "${if (state.fiatAmount < 1) "" else state.fiatAmount}", singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), @@ -412,9 +416,8 @@ private fun ReceiveDialog( modifier = Modifier.fillMaxWidth(), enabled = loadingState.visible.not(), onClick = { - - //todo: revisit this later - //viewModel.onEvent(ReceiveDialogEvent.OnMoonpayButtonClick) + // todo: revisit this later + // viewModel.onEvent(ReceiveDialogEvent.OnMoonpayButtonClick) onMoonPayLaunch( mapOf( "baseCurrencyCode" to state.selectedFiatCurrency.code, diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt index f1968756..7c090049 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt @@ -18,4 +18,4 @@ sealed class ReceiveDialogEvent { object OnMoonpayButtonClick : ReceiveDialogEvent() object OnSignedUrlClear : ReceiveDialogEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt index 6cfb2a19..c63a4d62 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt @@ -12,7 +12,6 @@ import androidx.compose.ui.platform.ComposeView import androidx.compose.ui.unit.dp import androidx.fragment.app.DialogFragment import androidx.fragment.app.FragmentManager -import androidx.fragment.app.viewModels import com.brainwallet.ui.theme.BrainwalletAppTheme import org.koin.compose.viewmodel.koinViewModel diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt index 745d172a..0cdb7854 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt @@ -9,7 +9,6 @@ import java.text.SimpleDateFormat import java.util.Date import java.util.Locale - data class ReceiveDialogState( val address: String = "", val qrBitmap: Bitmap? = null, @@ -24,7 +23,7 @@ data class ReceiveDialogState( val fiatAmount: Float = 0f, val ltcAmount: Float = 0f, val ratesUpdatedAt: Long = System.currentTimeMillis(), - val selectedQuickFiatAmountOptionIndex: Int = 1, //default is 10X, other [min, 10x, max, custom] + val selectedQuickFiatAmountOptionIndex: Int = 1, // default is 10X, other [min, 10x, max, custom] val errorFiatAmountStringId: Int? = null, val moonpayBuySignedUrl: String? = null, ) @@ -34,7 +33,7 @@ fun ReceiveDialogState.getSelectedFiatCurrencyIndex(): Int = fiatCurrencies fun ReceiveDialogState.getDefaultFiatAmount(): Float { val (_, min, max) = moonpayCurrencyLimit.data.baseCurrency - return min * 10 //default is 10X + return min * 10 // default is 10X } fun ReceiveDialogState.getRatesUpdatedAtFormatted(): String { @@ -56,6 +55,6 @@ fun ReceiveDialogState.getQuickFiatAmountOptions(): List } fun ReceiveDialogState.isQuickFiatAmountOptionCustom(): Boolean = - selectedQuickFiatAmountOptionIndex == 3 //3 will be custom + selectedQuickFiatAmountOptionIndex == 3 // 3 will be custom -fun ReceiveDialogState.moonpayWidgetVisible(): Boolean = moonpayBuySignedUrl != null \ No newline at end of file +fun ReceiveDialogState.moonpayWidgetVisible(): Boolean = moonpayBuySignedUrl != null diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt index e381351c..0df5bd51 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt @@ -23,7 +23,7 @@ import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch import org.koin.android.annotation.KoinViewModel -//todo: wip +// todo: wip @KoinViewModel class ReceiveDialogViewModel( private val settingRepository: SettingRepository, @@ -50,7 +50,7 @@ class ReceiveDialogViewModel( val address = BRSharedPrefs.getReceiveAddress(event.context) it.copy( address = address, - qrBitmap = QRUtils.generateQR(event.context, "litecoin:${address}"), + qrBitmap = QRUtils.generateQR(event.context, "litecoin:$address"), fiatCurrencies = CurrencyDataSource.getInstance(event.context) .getCurrenciesForBuy(), ) @@ -62,7 +62,7 @@ class ReceiveDialogViewModel( ) is ReceiveDialogEvent.OnFiatAmountChange -> viewModelScope.launch { - //do validation + // do validation val (_, min, max) = state.value.moonpayCurrencyLimit.data.baseCurrency val errorStringId = when { event.fiatAmount < min -> R.string.buy_litecoin_fiat_amount_validation_min @@ -96,13 +96,11 @@ class ReceiveDialogViewModel( ltcAmount = result.data.quoteCurrencyAmount, ) } - } catch (e: Exception) { handleError(e) } finally { onLoading(false) } - } is ReceiveDialogEvent.OnFiatCurrencyChange -> viewModelScope.launch { @@ -114,7 +112,7 @@ class ReceiveDialogViewModel( it.copy( selectedFiatCurrency = event.fiatCurrency, moonpayCurrencyLimit = currencyLimit, - selectedQuickFiatAmountOptionIndex = 1, //default to 10X + selectedQuickFiatAmountOptionIndex = 1, // default to 10X fiatAmount = it.getDefaultFiatAmount(), ) }.let { @@ -125,7 +123,6 @@ class ReceiveDialogViewModel( ) ) } - } catch (e: Exception) { handleError(e) } finally { @@ -136,8 +133,11 @@ class ReceiveDialogViewModel( is ReceiveDialogEvent.OnFiatAmountOptionIndexChange -> _state.updateAndGet { it.copy( selectedQuickFiatAmountOptionIndex = event.index, - fiatAmount = if (event.quickFiatAmountOption.isCustom()) it.fiatAmount - else event.quickFiatAmountOption.value + fiatAmount = if (event.quickFiatAmountOption.isCustom()) { + it.fiatAmount + } else { + event.quickFiatAmountOption.value + } ) }.let { if (event.quickFiatAmountOption.isCustom().not()) { @@ -161,18 +161,14 @@ class ReceiveDialogViewModel( ) _state.update { it.copy(moonpayBuySignedUrl = signedUrl) } - } catch (e: Exception) { handleError(e) } finally { - onLoading(false) - } - } ReceiveDialogEvent.OnSignedUrlClear -> _state.update { it.copy(moonpayBuySignedUrl = null) } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsEvent.kt index e12ea668..cdd3b110 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsEvent.kt @@ -18,4 +18,4 @@ sealed class InputWordsEvent { data class OnRestoreClick( val context: Context ) : InputWordsEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt index c17c2c58..52dbe051 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt @@ -1,5 +1,6 @@ @file:OptIn( - ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class, + ExperimentalMaterial3Api::class, + ExperimentalLayoutApi::class, ExperimentalComposeUiApi::class ) @@ -68,7 +69,7 @@ fun InputWordsScreen( viewModel: InputWordsViewModel = koinInject() ) { val state by viewModel.state.collectAsState() - val focusRequesters = List(12) { FocusRequester() } //12 seed words + val focusRequesters = List(12) { FocusRequester() } // 12 seed words val focusManager = LocalFocusManager.current val context = LocalContext.current val appSetting = AppSetting() @@ -78,7 +79,7 @@ fun InputWordsScreen( var mainBoxFactor = 0.5 val thirdOfScreenHeight = (screenHeight * mainBoxFactor).toInt() - //todo: the following sizing can be move to BrainwalletTheme + // todo: the following sizing can be move to BrainwalletTheme val leadTrailPadding = 24 val halfLeadTrailPadding = leadTrailPadding / 2 @@ -87,7 +88,6 @@ fun InputWordsScreen( val rowPadding = 8 val activeRowHeight = 70 - LaunchedEffect(Unit) { viewModel.onEvent(InputWordsEvent.OnLoad(source)) viewModel.uiEffect.collect { effect -> @@ -98,7 +98,7 @@ fun InputWordsScreen( } } - /// Layout values + // / Layout values val columnPadding = 16 val horizontalVerticalSpacing = 8 val spacerHeight = 48 @@ -174,7 +174,8 @@ fun InputWordsScreen( onValueChange = { viewModel.onEvent( InputWordsEvent.OnSeedWordItemChange( - index = index, text = it, + index = index, + text = it, ) ) }, @@ -185,9 +186,7 @@ fun InputWordsScreen( Text("${index + 1}") } ) - } - } Spacer(modifier = Modifier.height(8.dp)) @@ -219,7 +218,6 @@ fun InputWordsScreen( ) Spacer(modifier = Modifier.weight(0.5f)) - Text( text = stringResource(R.string.blockchain_litecoin), style = MaterialTheme.typography.titleMedium.copy(textAlign = TextAlign.Center) @@ -238,7 +236,6 @@ fun InputWordsScreen( focusManager.clearFocus() }, ) { - Text( text = stringResource(R.string.restore_my_brainwallet), fontSize = buttonMediumFontSize.sp, @@ -247,7 +244,6 @@ fun InputWordsScreen( } Spacer(modifier = Modifier.height(horizontalVerticalSpacing.dp)) - } } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsState.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsState.kt index eef233fb..811f5a98 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsState.kt @@ -6,7 +6,7 @@ data class InputWordsState( val source: Route.InputWords.Source? = null, val bip39Words: List = emptyList(), val suggestionsSeedWords: List = emptyList(), - val seedWords: SeedWords = (0..11).associateWith { "" } //12 seed words + val seedWords: SeedWords = (0..11).associateWith { "" } // 12 seed words ) typealias SeedWords = Map @@ -19,4 +19,4 @@ fun InputWordsState.isFrom(from: Route.InputWords.Source): Boolean { return source == from } -fun InputWordsState.isFromWelcome(): Boolean = source == null \ No newline at end of file +fun InputWordsState.isFromWelcome(): Boolean = source == null diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt index bfdd4aad..fd15aaf9 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt @@ -25,7 +25,7 @@ class InputWordsViewModel : BrainwalletViewModel() { val state: StateFlow = _state.asStateFlow() init { - //TODO: revisit later, please move to repository, for now just reuse the existing + // TODO: revisit later, please move to repository, for now just reuse the existing Bip39Reader.bip39List(BrainwalletApp.breadContext, Language.ENGLISH.code) .also { bip39Words -> _state.update { it.copy(bip39Words = bip39Words) } @@ -117,5 +117,4 @@ class InputWordsViewModel : BrainwalletViewModel() { const val EFFECT_LEGACY_RECOVER_WALLET_AUTH = "onRecoverWalletAuth" const val LEGACY_EFFECT_RESET_PIN = "onResetPin" } - } diff --git a/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyEvent.kt index 41b14a97..97b43976 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyEvent.kt @@ -4,4 +4,4 @@ import android.content.Context sealed class ReadyEvent { data class OnLoad(val context: Context) : ReadyEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyScreen.kt index 4be9e0dc..a34fea31 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/ready/ReadyScreen.kt @@ -2,7 +2,6 @@ package com.brainwallet.ui.screens.ready - import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -42,7 +41,6 @@ import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import org.koin.compose.koinInject - @Composable fun ReadyScreen( onNavigate: OnNavigate, @@ -54,7 +52,7 @@ fun ReadyScreen( viewModel.onEvent(ReadyEvent.OnLoad(context)) } - /// Layout values + // / Layout values val leadingCopyPadding = 18 val horizontalVerticalSpacing = 8 diff --git a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeEvent.kt index 356fae03..efcee0fd 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeEvent.kt @@ -4,4 +4,4 @@ sealed class SetPasscodeEvent { data class OnLoad(val passcode: List = emptyList()) : SetPasscodeEvent() data class OnDigitChange(val digit: Int) : SetPasscodeEvent() object OnDeleteDigit : SetPasscodeEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeScreen.kt index 482ae79b..d9314d39 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeScreen.kt @@ -60,7 +60,7 @@ fun SetPasscodeScreen( } } - /// Layout values + // / Layout values val leadingCopyPadding = 16 val horizontalVerticalSpacing = 8 @@ -151,6 +151,5 @@ fun SetPasscodeScreen( } Spacer(modifier = Modifier.weight(0.05f)) } - } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeState.kt b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeState.kt index c8286b67..abef68c8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeState.kt @@ -2,8 +2,8 @@ package com.brainwallet.ui.screens.setpasscode data class SetPasscodeState( val isConfirm: Boolean = false, - val passcode: List = List(4) { -1 }, //create 4 digit - val passcodeConfirm: List = List(4) { -1 }, //create 4 digit + val passcode: List = List(4) { -1 }, // create 4 digit + val passcodeConfirm: List = List(4) { -1 }, // create 4 digit val isUpdatePin: Boolean = false, ) diff --git a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeViewModel.kt index 982dd71d..625042c0 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeViewModel.kt @@ -64,7 +64,7 @@ class SetPasscodeViewModel : BrainwalletViewModel() { ) } }.also { - //if passcode all filled, then goto confirm + // if passcode all filled, then goto confirm if (it.isPasscodeFilled()) { sendUiEffect( UiEffect.Navigate( @@ -73,7 +73,7 @@ class SetPasscodeViewModel : BrainwalletViewModel() { ) } - //if passcode confirm all filled, then goto your seed words + // if passcode confirm all filled, then goto your seed words if (it.isMatchPasscode()) { viewModelScope.launch { EventBus.emit( @@ -97,4 +97,4 @@ class SetPasscodeViewModel : BrainwalletViewModel() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt index 7ef16b33..5f7d600d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt @@ -2,7 +2,6 @@ package com.brainwallet.ui.screens.topup - import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -30,7 +29,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.brainwallet.R -import com.brainwallet.navigation.LegacyNavigation import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect @@ -47,10 +45,9 @@ fun TopUpScreen( onNavigate: OnNavigate, viewModel: YourSeedProveItViewModel = viewModel() ) { - val context = LocalContext.current - /// Layout values + // / Layout values val leadingCopyPadding = 16 val buttonRowHeight = 55 val horizontalVerticalSpacing = 8 @@ -136,4 +133,4 @@ fun TopUpScreen( Spacer(modifier = Modifier.weight(0.05f)) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt index bd090257..cdec09a0 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt @@ -13,4 +13,4 @@ sealed class UnLockEvent { object OnDeletePinDigit : UnLockEvent() } -//todo \ No newline at end of file +// todo diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt index 204716e8..78065bd3 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt @@ -2,7 +2,6 @@ package com.brainwallet.ui.screens.unlock -import androidx.activity.ComponentActivity import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.padding @@ -97,10 +96,12 @@ private fun UnLockScreen( @Composable private fun UnLockScreenPreview() { BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) { - UnLockScreen(uiState = UnLockState( - isUpdatePin = true, - formattedCurrency = "$90.00", - formattedVersion = "v4.0.0 (202501201)" - )) + UnLockScreen( + uiState = UnLockState( + isUpdatePin = true, + formattedCurrency = "$90.00", + formattedVersion = "v4.0.0 (202501201)" + ) + ) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockState.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockState.kt index 7483e3ab..f657d08e 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockState.kt @@ -1,7 +1,7 @@ package com.brainwallet.ui.screens.unlock data class UnLockState( - val passcode: List = List(4) { -1 }, //4 digit passcode/pin + val passcode: List = List(4) { -1 }, // 4 digit passcode/pin val biometricEnabled: Boolean = false, val iso: String = "USD", val formattedCurrency: String = "", @@ -11,4 +11,4 @@ data class UnLockState( fun UnLockState.isPasscodeFilled(): Boolean = passcode.all { it > -1 } -//todo +// todo diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt index 0405c4ba..c183d675 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt @@ -46,9 +46,8 @@ class UnLockViewModel( pinDigits[index] = event.digit it.copy(passcode = pinDigits) }.also { - if (it.isPasscodeFilled() && it.isUpdatePin) { - //if update pin from drawer + // if update pin from drawer if (event.isValidPin.invoke(it.passcode.joinToString(""))) { sendUiEffect( UiEffect.Navigate( @@ -103,7 +102,6 @@ class UnLockViewModel( formattedCurrency = formattedCurrency, isUpdatePin = event.isUpdatePin ) - } } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt index cdf2f09c..7c63a0d4 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -69,17 +68,16 @@ fun UnLockScreenBody( digit = passcodeKeypadEvent.digit, isValidPin = { pin -> - //provide old logic here, its like on the BrainwalletActivity.onUnlock + // provide old logic here, its like on the BrainwalletActivity.onUnlock return@OnPinDigitChange AuthManager.getInstance() .checkAuth(pin, context).also { isValid -> if (isValid) { AuthManager.getInstance().authSuccess(context) AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) - } else { AuthManager.getInstance().authFail(context) - //for now just toast + // for now just toast Toast.makeText( context, R.string.incorrect_passcode, diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt index 733f2068..7d3fe6d2 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt @@ -39,9 +39,11 @@ fun UnLockScreenFooter( modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { - Row(modifier = Modifier - .padding(bottom = 24.dp) - .padding(horizontal = 85.dp)) { + Row( + modifier = Modifier + .padding(bottom = 24.dp) + .padding(horizontal = 85.dp) + ) { DarkModeToggleButton( checked = LocalDarkModeFlag.current, onCheckedChange = { diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeEvent.kt index d162ff2c..6d34726e 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeEvent.kt @@ -13,4 +13,4 @@ sealed class WelcomeEvent { object OnFiatButtonClick : WelcomeEvent() object OnFiatSelectorDismiss : WelcomeEvent() data class OnFiatChange(val currency: CurrencyEntity) : WelcomeEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index 3c9773fb..4b0ec8e1 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.systemBars import androidx.compose.foundation.layout.width @@ -76,7 +75,7 @@ fun WelcomeScreen( viewModel.onEvent(WelcomeEvent.OnLoad(context)) } - //todo: the following sizing can be move to BrainwalletTheme + // todo: the following sizing can be move to BrainwalletTheme // Global layout val buttonFontSize = 24 val thinButtonFontSize = 22 @@ -134,7 +133,6 @@ fun WelcomeScreen( ) } - Column( modifier = Modifier.align(Alignment.BottomCenter), horizontalAlignment = Alignment.CenterHorizontally, @@ -149,7 +147,6 @@ fun WelcomeScreen( horizontalArrangement = Arrangement.SpaceEvenly ) { - BrainwalletButton( modifier = Modifier .weight(1f) @@ -191,7 +188,6 @@ fun WelcomeScreen( color = BrainwalletTheme.colors.content ) } - } // Ready Button BorderedLargeButton( @@ -239,7 +235,7 @@ fun WelcomeScreen( } } - //language selector + // language selector if (state.languageSelectorBottomSheetVisible) { LanguageSelectorBottomSheet( selectedLanguage = state.selectedLanguage, @@ -256,7 +252,7 @@ fun WelcomeScreen( ) } - //fiat/currency selector + // fiat/currency selector if (state.fiatSelectorBottomSheetVisible) { FiatSelectorBottomSheet( selectedCurrency = state.selectedCurrency, @@ -270,9 +266,8 @@ fun WelcomeScreen( } } - @Preview @Composable fun WelcomeScreenPreview() { WelcomeScreen() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeState.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeState.kt index 415f1333..64ee8bef 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeState.kt @@ -11,7 +11,7 @@ data class WelcomeState( "US Dollar", -1f, "$" - ), //-1 = need to fetch + ), // -1 = need to fetch val languageSelectorBottomSheetVisible: Boolean = false, val fiatSelectorBottomSheetVisible: Boolean = false, ) diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeViewModel.kt index 47a282e0..14cd5cdd 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeViewModel.kt @@ -22,7 +22,7 @@ import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch import org.koin.android.annotation.KoinViewModel -//TODO: revisit this later +// TODO: revisit this later @KoinViewModel class WelcomeViewModel( private val settingRepository: SettingRepository @@ -98,7 +98,6 @@ class WelcomeViewModel( event.language.code ) ) - } } @@ -123,5 +122,4 @@ class WelcomeViewModel( } } } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt index b315d980..bd39aa9d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItEvent.kt @@ -16,4 +16,4 @@ sealed class YourSeedProveItEvent { object OnCompletedPaperKey : YourSeedProveItEvent() object OnClear : YourSeedProveItEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt index e505438c..0f126cf1 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt @@ -1,5 +1,6 @@ @file:OptIn( - ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class, + ExperimentalMaterial3Api::class, + ExperimentalLayoutApi::class, ExperimentalFoundationApi::class ) @@ -12,7 +13,6 @@ import android.view.View import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.draganddrop.dragAndDropSource import androidx.compose.foundation.draganddrop.dragAndDropTarget -import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -71,7 +71,7 @@ fun YourSeedProveItScreen( val state by viewModel.state.collectAsState() val context = LocalContext.current - /// Layout values + // / Layout values val columnPadding = 12 val horizontalVerticalSpacing = 8 val spacerHeight = 48 @@ -105,7 +105,8 @@ fun YourSeedProveItScreen( contentDescription = stringResource(R.string.back), ) } - }) + } + ) }, ) { paddingValues -> Column( @@ -118,12 +119,16 @@ fun YourSeedProveItScreen( verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), ) { Text( - text = stringResource(if (state.orderCorrected) R.string.you_saved_your_keys else R.string.you_saved_it_right), + text = stringResource( + if (state.orderCorrected) R.string.you_saved_your_keys else R.string.you_saved_it_right + ), style = MaterialTheme.typography.headlineSmall, ) Text( - text = stringResource(if (state.orderCorrected) R.string.you_saved_your_keys_desc else R.string.you_saved_it_right_desc), + text = stringResource( + if (state.orderCorrected) R.string.you_saved_your_keys_desc else R.string.you_saved_it_right_desc + ), style = MaterialTheme.typography.bodyMedium.copy( textAlign = TextAlign.Center, color = Color.Gray @@ -133,7 +138,9 @@ fun YourSeedProveItScreen( Spacer(modifier = Modifier.weight(0.1f)) SeedWordsLayout { - itemsIndexed(items = state.correctSeedWords.values.toList()) { index: Int, (expectedWord, actualWord): SeedWordItem -> + itemsIndexed( + items = state.correctSeedWords.values.toList() + ) { index: Int, (expectedWord, actualWord): SeedWordItem -> val label = if (expectedWord != actualWord && actualWord.isEmpty()) { "${index + 1}" } else { @@ -165,8 +172,7 @@ fun YourSeedProveItScreen( ) if (text.toString() == expectedWord) { clickAudioPlayer.start() // Success sound - } - else { + } else { errorAudioPlayer.start() // Success sound } return true @@ -198,19 +204,13 @@ fun YourSeedProveItScreen( SeedWordItem( modifier = Modifier .fillMaxWidth() - .dragAndDropSource { - detectTapGestures( - onPress = { - startTransfer( - DragAndDropTransferData( - clipData = ClipData.newPlainText( - "text", - word - ), - flags = View.DRAG_FLAG_GLOBAL - ) - ) - } + .dragAndDropSource { _ -> + DragAndDropTransferData( + clipData = ClipData.newPlainText( + "text", + word + ), + flags = View.DRAG_FLAG_GLOBAL ) }, label = word, @@ -222,12 +222,9 @@ fun YourSeedProveItScreen( } ) } - - } } - LargeButton( onClick = { if (state.orderCorrected) { @@ -238,11 +235,12 @@ fun YourSeedProveItScreen( }, ) { Text( - text = stringResource(if (state.orderCorrected) R.string.game_and_sync else R.string.reset_start_over).uppercase(), + text = stringResource( + if (state.orderCorrected) R.string.game_and_sync else R.string.reset_start_over + ).uppercase(), style = MaterialTheme.typography.labelLarge ) } - } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt index b69ac06b..4411d61a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItState.kt @@ -15,4 +15,4 @@ fun YourSeedProveItState.isWordUsedCorrectly(currentIndex: Int, currentWord: Str return correctSeedWords[currentIndex]?.let { seedWordItem -> seedWordItem.expected == currentWord && seedWordItem.actual == currentWord } ?: false -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt index 75f68797..2895cab6 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt @@ -64,4 +64,4 @@ class YourSeedProveItViewModel : BrainwalletViewModel() { const val LEGACY_EFFECT_ON_PAPERKEY_PROVED = "onPaperKeyProved" const val LEGACY_NAVIGATE_TO_HOME = "navigateToHome" } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsEvent.kt index ba2cbde0..aca60ecf 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsEvent.kt @@ -2,4 +2,4 @@ package com.brainwallet.ui.screens.yourseedwords sealed class YourSeedWordsEvent { data class OnSavedItClick(val seedWords: List) : YourSeedWordsEvent() -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt index 17bdaf18..1de5bab8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsScreen.kt @@ -44,7 +44,7 @@ fun YourSeedWordsScreen( seedWords: List, viewModel: YourSeedWordsViewModel = koinInject() ) { - /// Layout values + // / Layout values val columnPadding = 12 val horizontalVerticalSpacing = 8 val spacerHeight = 36 @@ -72,7 +72,8 @@ fun YourSeedWordsScreen( contentDescription = stringResource(R.string.back), ) } - }) + } + ) } ) { paddingValues -> Column( @@ -89,7 +90,7 @@ fun YourSeedWordsScreen( style = MaterialTheme.typography.headlineSmall, ) - //todo: yuana private key text need to open dialog? + // todo: yuana private key text need to open dialog? Text( modifier = Modifier .padding(top = leadingCopyPadding.dp), @@ -135,4 +136,4 @@ fun YourSeedWordsScreen( } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt index b85e71c7..80c313f3 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedwords/YourSeedWordsViewModel.kt @@ -17,4 +17,4 @@ class YourSeedWordsViewModel : BrainwalletViewModel() { } } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/theme/Color.kt b/app/src/main/java/com/brainwallet/ui/theme/Color.kt index 0066ec19..5381d211 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Color.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Color.kt @@ -12,7 +12,7 @@ val nearBlack = Color(0xFF151515) val lavender = Color(0xFFDDD5FA) val white = Color.White -//to make color darken, since we are not providing all colors for specific case +// to make color darken, since we are not providing all colors for specific case inline fun Color.darken(darkenBy: Float = 0.3f): Color { return copy( red = red * darkenBy, @@ -20,4 +20,4 @@ inline fun Color.darken(darkenBy: Float = 0.3f): Color { blue = blue * darkenBy, alpha = alpha ) -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/theme/Font.kt b/app/src/main/java/com/brainwallet/ui/theme/Font.kt index e78637b9..f7bdd2c9 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Font.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Font.kt @@ -1,17 +1,12 @@ package com.brainwallet.ui.theme -import androidx.compose.material3.Typography -import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.Font import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.googlefonts.Font -import androidx.compose.ui.text.googlefonts.GoogleFont -import androidx.compose.ui.unit.sp import com.brainwallet.R -class Font { -} +class Font val openSauceOneFamily = FontFamily( Font(R.font.open_sauce_one_light, FontWeight.Light), @@ -19,4 +14,4 @@ val openSauceOneFamily = FontFamily( Font(R.font.open_sauce_one_medium, FontWeight.Medium), Font(R.font.open_sauce_one_regular, FontWeight.Normal), Font(R.font.open_sauce_one_semi_bold, FontWeight.SemiBold) -) \ No newline at end of file +) diff --git a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt index 9b421ce5..4297ae79 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt @@ -13,7 +13,6 @@ import androidx.compose.ui.platform.ComposeView import com.brainwallet.data.model.AppSetting import com.brainwallet.data.model.Language - /** * define custom colors naming for brainwallet colors */ @@ -56,7 +55,7 @@ val LocalBrainwalletColors = staticCompositionLocalOf { } val LocalLanguageCode = staticCompositionLocalOf { - Language.ENGLISH.code //default + Language.ENGLISH.code // default } val LocalDarkModeFlag = staticCompositionLocalOf { @@ -66,7 +65,9 @@ val LocalDarkModeFlag = staticCompositionLocalOf { @Composable fun BrainwalletAppTheme( appSetting: AppSetting = AppSetting(), - content: @Composable() () -> Unit + content: + @Composable() + () -> Unit ) { val colors = if (appSetting.isDarkMode) darkColorScheme else lightColorScheme @@ -88,17 +89,19 @@ object BrainwalletTheme { get() = LocalBrainwalletColors.current val typography: Typography - @Composable @ReadOnlyComposable get() = MaterialTheme.typography + @Composable @ReadOnlyComposable + get() = MaterialTheme.typography val shapes: Shapes - @Composable @ReadOnlyComposable get() = MaterialTheme.shapes + @Composable @ReadOnlyComposable + get() = MaterialTheme.shapes - //todo: add typography, shape? for the design system + // todo: add typography, shape? for the design system } -//provide compose theme wrapper for transition +// provide compose theme wrapper for transition fun ComposeView.setContentWithTheme(content: @Composable () -> Unit) { setContent { BrainwalletAppTheme { content.invoke() } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/ui/theme/Type.kt b/app/src/main/java/com/brainwallet/ui/theme/Type.kt index 512017b1..f5df19e5 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Type.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Type.kt @@ -2,13 +2,8 @@ package com.brainwallet.ui.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.googlefonts.Font -import androidx.compose.ui.text.googlefonts.GoogleFont import androidx.compose.ui.unit.sp -import com.brainwallet.R - // DEV Dislike this because it block all options diff --git a/app/src/main/java/com/brainwallet/util/EventBus.kt b/app/src/main/java/com/brainwallet/util/EventBus.kt index 313358db..3fdb667c 100644 --- a/app/src/main/java/com/brainwallet/util/EventBus.kt +++ b/app/src/main/java/com/brainwallet/util/EventBus.kt @@ -19,14 +19,12 @@ object EventBus { _events.emit(event) } - sealed class Event { data class Message( val message: String, ) : Event() - - //provide this for old flow + // provide this for old flow data class LegacyPasscodeVerified( val passcode: List, ) : Event() @@ -36,4 +34,3 @@ object EventBus { ) : Event() } } - diff --git a/app/src/main/java/com/brainwallet/util/PermissionUtil.kt b/app/src/main/java/com/brainwallet/util/PermissionUtil.kt index 08b9f258..e7308dea 100644 --- a/app/src/main/java/com/brainwallet/util/PermissionUtil.kt +++ b/app/src/main/java/com/brainwallet/util/PermissionUtil.kt @@ -33,5 +33,4 @@ object PermissionUtil { launcher: ActivityResultLauncher, permission: String ) = launcher.launch(permission) - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/util/cryptography/CipherBox.kt b/app/src/main/java/com/brainwallet/util/cryptography/CipherBox.kt index 81565c1d..21a8f1df 100644 --- a/app/src/main/java/com/brainwallet/util/cryptography/CipherBox.kt +++ b/app/src/main/java/com/brainwallet/util/cryptography/CipherBox.kt @@ -6,7 +6,6 @@ import javax.crypto.Cipher import javax.crypto.spec.GCMParameterSpec import javax.crypto.spec.IvParameterSpec - interface CipherBox { fun initEncryptCipher( cipherAlgorithm: String, @@ -49,9 +48,11 @@ interface CipherBox { iv: ByteArray ): Cipher { val cipher = Cipher.getInstance(cipherAlgorithm) - val spec = if (cipherAlgorithm == BRKeyStore.NEW_CIPHER_ALGORITHM) + val spec = if (cipherAlgorithm == BRKeyStore.NEW_CIPHER_ALGORITHM) { GCMParameterSpec(128, iv) - else IvParameterSpec(iv) + } else { + IvParameterSpec(iv) + } cipher.init(Cipher.DECRYPT_MODE, secretKey, spec) return cipher } @@ -62,6 +63,5 @@ interface CipherBox { ): ByteArray { return cipher.doFinal(encryptedData) } - } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/util/cryptography/CipherStorage.kt b/app/src/main/java/com/brainwallet/util/cryptography/CipherStorage.kt index 93c43d33..f72f169e 100644 --- a/app/src/main/java/com/brainwallet/util/cryptography/CipherStorage.kt +++ b/app/src/main/java/com/brainwallet/util/cryptography/CipherStorage.kt @@ -100,7 +100,7 @@ class CipherStorageFile( ) : CipherStorage { override fun saveKey(secretKey: Key, aliasObject: AliasObject, data: ByteArray) { - //no-op + // no-op } override fun getKey(secretKey: Key, aliasObject: AliasObject): ByteArray? { @@ -123,7 +123,6 @@ class CipherStorageFile( ) return decryptedData - } override fun hasKey(aliasObject: AliasObject): Boolean { @@ -144,14 +143,13 @@ class CipherStorageFile( } override fun removeAll() { - //no-op + // no-op } private fun getFile(fileName: String): File = File(getFilePath(fileName)) private fun getFilePath(fileName: String): String { val filesDir = context.filesDir.absolutePath - return "${filesDir}${File.separator}${fileName}" + return "${filesDir}${File.separator}$fileName" } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreKeyGenerator.kt b/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreKeyGenerator.kt index c8aa3d92..070769a2 100644 --- a/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreKeyGenerator.kt +++ b/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreKeyGenerator.kt @@ -4,4 +4,4 @@ import javax.crypto.SecretKey interface KeyStoreKeyGenerator { fun generateKey(alias: String, isAuthRequired: Boolean, authTimeout: Int?): SecretKey -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreManager.kt b/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreManager.kt index 1223f2fb..029bece5 100644 --- a/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreManager.kt +++ b/app/src/main/java/com/brainwallet/util/cryptography/KeyStoreManager.kt @@ -36,7 +36,7 @@ class KeyStoreManager( try { val secretKey = keyGenerator.generateKey( alias = aliasObject.alias, - isAuthRequired = false, //if true need device auth + isAuthRequired = false, // if true need device auth authTimeout = BRKeyStore.AUTH_DURATION_SEC ) cipherStoragePref.saveKey( @@ -46,7 +46,7 @@ class KeyStoreManager( ) return true } catch (e: UserNotAuthenticatedException) { - //TODO: need auth? + // TODO: need auth? Timber.d("timber: KeyStoreManager.setData: ${e.message}") throw e } catch (e: Exception) { @@ -79,7 +79,7 @@ class KeyStoreManager( secretKey = keyGenerator.generateKey( alias = aliasObject.alias, - isAuthRequired = false, //if true need device auth + isAuthRequired = false, // if true need device auth authTimeout = BRKeyStore.AUTH_DURATION_SEC ) @@ -97,23 +97,24 @@ class KeyStoreManager( } } - /** * the following are the new format logic that stored on the shared preferences */ if (cipherStoragePref.hasKey(aliasObject).not()) { - Timber.d("timber: KeyStoreManager.getData new key in prefs not exists | ${aliasObject.alias}, ${aliasObject.datafileName}, ${aliasObject.ivFileName}") + Timber.d( + "timber: KeyStoreManager.getData new key in prefs not exists | ${aliasObject.alias}, ${aliasObject.datafileName}, ${aliasObject.ivFileName}" + ) return null } val decryptedData = cipherStoragePref.getKey(secretKey, aliasObject) - Timber.d("timber: KeyStoreManager.getData: decryptedData=${decryptedData}") + Timber.d("timber: KeyStoreManager.getData: decryptedData=$decryptedData") return decryptedData.also { Timber.d("timber: KeyStoreManager.getData key: $it") } } catch (e: UserNotAuthenticatedException) { - //TODO: need auth? + // TODO: need auth? Timber.d("timber: KeyStoreManager.getData: ${e.message}") throw e } catch (e: Exception) { @@ -128,5 +129,4 @@ class KeyStoreManager( fun getDataBlocking(aliasObject: AliasObject) = runBlocking { getData(aliasObject) } - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/util/cryptography/impl/KeyStoreKeyGeneratorImpl.kt b/app/src/main/java/com/brainwallet/util/cryptography/impl/KeyStoreKeyGeneratorImpl.kt index 8a14c8db..12910eef 100644 --- a/app/src/main/java/com/brainwallet/util/cryptography/impl/KeyStoreKeyGeneratorImpl.kt +++ b/app/src/main/java/com/brainwallet/util/cryptography/impl/KeyStoreKeyGeneratorImpl.kt @@ -44,7 +44,8 @@ class KeyStoreKeyGeneratorImpl : KeyStoreKeyGenerator { } private fun setUserAuth( - builder: KeyGenParameterSpec.Builder, authTimeout: Int? + builder: KeyGenParameterSpec.Builder, + authTimeout: Int? ) { builder.setUserAuthenticationRequired(true) if (authTimeout != null) { diff --git a/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt b/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt index d49b325b..ef69a1d0 100644 --- a/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt +++ b/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt @@ -25,10 +25,8 @@ class CurrencyUpdateWorker( job = scope.launch(Dispatchers.IO) { while (isActive) { ltcRepository.fetchRates() - delay(4000L) //4secs + delay(4000L) // 4secs } } } - - -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/worker/SyncBlockWorker.kt b/app/src/main/java/com/brainwallet/worker/SyncBlockWorker.kt index 56ffa2cf..73869f34 100644 --- a/app/src/main/java/com/brainwallet/worker/SyncBlockWorker.kt +++ b/app/src/main/java/com/brainwallet/worker/SyncBlockWorker.kt @@ -13,7 +13,7 @@ class SyncBlockWorker( params: WorkerParameters ) : CoroutineWorker(context, params) { - //todo: maybe need ongoing notification? + // todo: maybe need ongoing notification? override suspend fun doWork(): Result { BRWalletManager.getInstance().initWallet(applicationContext) @@ -30,4 +30,4 @@ class SyncBlockWorker( ) .build() } -} \ No newline at end of file +} diff --git a/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt b/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt index 9e997f57..72c4d9d6 100644 --- a/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt +++ b/app/src/test/java/com/brainwallet/currency/BackupRateFetchTests.kt @@ -1,25 +1,6 @@ package com.brainwallet.currency -import android.app.Activity -import android.content.Context -import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.presenter.activities.util.ActivityUTILS -import com.brainwallet.tools.util.BRConstants -import com.brainwallet.tools.util.Utils -import com.platform.APIClient -import io.mockk.every -import io.mockk.mockk -import io.mockk.mockkObject -import io.mockk.mockkStatic -import io.mockk.spyk -import okhttp3.Protocol -import okhttp3.Request -import okhttp3.Response -import okhttp3.ResponseBody.Companion.toResponseBody -import org.junit.Before -import org.junit.Test - -//TODO: need update this test after refactor +// TODO: need update this test after refactor class BackupRateFetchTests { // private val remoteConfigSource: RemoteConfigSource = mockk() // private lateinit var apiManager: BRApiManager @@ -90,4 +71,4 @@ class BackupRateFetchTests { // .build() // // } -} \ No newline at end of file +} diff --git a/app/src/test/java/com/brainwallet/currency/CurrencyTests.kt b/app/src/test/java/com/brainwallet/currency/CurrencyTests.kt index 6be7752e..6692d623 100644 --- a/app/src/test/java/com/brainwallet/currency/CurrencyTests.kt +++ b/app/src/test/java/com/brainwallet/currency/CurrencyTests.kt @@ -38,21 +38,21 @@ class CurrencyTests { @Test fun `invoke CurrencyDataSource instance and getAllCurrencies, should return the correct number of currencies`() { - //The actual number of currencies is 174. The 0 is a placeholder and needs to be replaced with a db query. + // The actual number of currencies is 174. The 0 is a placeholder and needs to be replaced with a db query. mockCursorDataFromDatabase() assertEquals(currencyDataSource?.getAllCurrencies(false)?.count(), 0) } @Test fun `invoke CurrencyDataSource instance and Brainwallet filtered Fiats, should return the correct number of Brainwallet currencies`() { - //The actual number of BW currencies is 16. The 0 is a placeholder and needs to be replaced with a db query. + // The actual number of BW currencies is 16. The 0 is a placeholder and needs to be replaced with a db query. mockCursorDataFromDatabase() assertEquals(currencyDataSource?.getAllCurrencies(true)?.count(), 0) } @Test fun `invoke CurrencyDataSource instance and Brainwallet filtered Fiats for Buy, should return the correct number of supported currencies (moonpay)`() { - //The actual number of BW currencies is 16. The 0 is a placeholder and needs to be replaced with a db query. + // The actual number of BW currencies is 16. The 0 is a placeholder and needs to be replaced with a db query. mockCursorDataFromDatabase() assertEquals(currencyDataSource?.currenciesForBuy?.count(), 0) } @@ -65,7 +65,6 @@ class CurrencyTests { @Test fun `invoke CurrencyDataSource instance database, should return currency by ISO`() { - val expected = CurrencyEntity("USD", "USD", 110.345f, "$") mockCursorDataFromDatabase(isEmpty = false, expected = expected) diff --git a/app/src/test/java/com/brainwallet/data/BaseURLTests.kt b/app/src/test/java/com/brainwallet/data/BaseURLTests.kt index f0423f90..8f6f4a68 100644 --- a/app/src/test/java/com/brainwallet/data/BaseURLTests.kt +++ b/app/src/test/java/com/brainwallet/data/BaseURLTests.kt @@ -1,15 +1,6 @@ package com.brainwallet.data -import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.tools.util.BRConstants -import io.mockk.every -import io.mockk.mockk -import io.mockk.spyk -import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Test - -//TODO: need update this test after refactor +// TODO: need update this test after refactor class BaseURLTests { // private val remoteConfigSource: RemoteConfigSource = mockk() @@ -29,5 +20,3 @@ class BaseURLTests { // assertEquals(BRConstants.BW_API_PROD_HOST, actual) // } } - - diff --git a/app/src/test/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepositoryTest.kt b/app/src/test/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepositoryTest.kt index 6c98db43..163a8c90 100644 --- a/app/src/test/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepositoryTest.kt +++ b/app/src/test/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepositoryTest.kt @@ -43,8 +43,9 @@ class FirebaseRemoteConfigRepositoryTest { @Test fun `call getString, then should return with expected config value`() { - - every { firebaseRemoteConfig.getString(any()) } returns """ + every { + firebaseRemoteConfig.getString(any()) + } returns """ {"enabled":false,"title":"brainwallet-co-android repository","url":"https://github.com/brainwallet-co/android"} """.trimIndent() val actual = diff --git a/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt b/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt index 57e51bd5..c8f05b02 100644 --- a/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt +++ b/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt @@ -131,7 +131,12 @@ class MessagingTopicDataSourceTest { testCases.forEach { (input, expectedBase) -> val result = dataSource.getTopicsByLanguageCode(input) - val expectedTopics = listOf("initial_$expectedBase", "news_$expectedBase", "promo_$expectedBase", "warn_$expectedBase") + val expectedTopics = listOf( + "initial_$expectedBase", + "news_$expectedBase", + "promo_$expectedBase", + "warn_$expectedBase" + ) assert(result == expectedTopics) { "Expected topics for '$input' to have base '$expectedBase' but got $result" } diff --git a/app/src/test/java/com/brainwallet/example/ExampleTest.kt b/app/src/test/java/com/brainwallet/example/ExampleTest.kt index e6742770..f6313d6d 100644 --- a/app/src/test/java/com/brainwallet/example/ExampleTest.kt +++ b/app/src/test/java/com/brainwallet/example/ExampleTest.kt @@ -68,7 +68,6 @@ class ExampleTest { } } - @Test fun `calc invoked with valid mocked values, should return correct value as expected and verify by order`() { val dependencyOne = mockk() @@ -103,7 +102,6 @@ class ExampleTest { assertEquals(expected, result) coVerify { system.fetch() } } - } class DependencyOne(val value: Int) @@ -122,4 +120,4 @@ class SystemUnderTest( delay(3000) return listOf(dependencyOne.value, dependencyTwo.value) } -} \ No newline at end of file +} diff --git a/app/src/test/java/com/brainwallet/notification/NotificationHandlerTest.kt b/app/src/test/java/com/brainwallet/notification/NotificationHandlerTest.kt index c8a5813e..f79c1cc6 100644 --- a/app/src/test/java/com/brainwallet/notification/NotificationHandlerTest.kt +++ b/app/src/test/java/com/brainwallet/notification/NotificationHandlerTest.kt @@ -19,7 +19,6 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test - class NotificationHandlerTest { @MockK @@ -56,7 +55,6 @@ class NotificationHandlerTest { @Test fun `invoke handleMessageReceived with data not contains key brainwallet, then should return false`() { - val remoteMessage = RemoteMessage(Bundle()) every { MessagePayloadKeys.extractDeveloperDefinedPayload(any()) } returns arrayMapOf() @@ -68,7 +66,6 @@ class NotificationHandlerTest { @Test fun `invoke handleMessageReceived with valid data & notification, then should return true`() { - val mapData = mapOf( MessageNotificationKeys.TITLE to "Hello There!", MessageNotificationKeys.BODY to "This is Body!", @@ -92,8 +89,8 @@ class NotificationHandlerTest { "body" to "This is Body!" ) - //dev: filtering until a multi OS test is decided - //todo: revisit, test still fail because specific platform API e.g. android.app.Notification$Builder + // dev: filtering until a multi OS test is decided + // todo: revisit, test still fail because specific platform API e.g. android.app.Notification$Builder val testOSVersionString = System.getProperty("os.version")?.toString() val testOSVersion = System.getProperty("os.version")?.split(".")?.first()?.toInt() val successMessage = @@ -108,5 +105,4 @@ class NotificationHandlerTest { assertEquals(failMessage, true, actual) } } - -} \ No newline at end of file +} diff --git a/app/src/test/java/com/brainwallet/tools/database/DatabaseTests.kt b/app/src/test/java/com/brainwallet/tools/database/DatabaseTests.kt index 3b8821d0..74c29cb4 100644 --- a/app/src/test/java/com/brainwallet/tools/database/DatabaseTests.kt +++ b/app/src/test/java/com/brainwallet/tools/database/DatabaseTests.kt @@ -1,28 +1,27 @@ package com.brainwallet.tools.database -class DatabaseTests { -} +class DatabaseTests // TODO: Reopen in Kotlin mocckk // TODO: BRSQLiteHelper.BRAINWALLET_FIAT_CODES Test -//package com.brainwallet.analytics; -//import androidx.test.ext.junit.runners.AndroidJUnit4; -//import android.util.Log; -//import androidx.test.ext.junit.rules.ActivityScenarioRule; +// package com.brainwallet.analytics; +// import androidx.test.ext.junit.runners.AndroidJUnit4; +// import android.util.Log; +// import androidx.test.ext.junit.rules.ActivityScenarioRule; // -//import com.breadwallet.presenter.activities.intro.IntroActivity; -//import com.breadwallet.tools.util.BRConstants; +// import com.breadwallet.presenter.activities.intro.IntroActivity; +// import com.breadwallet.tools.util.BRConstants; // -//import org.junit.After; -//import org.junit.Assert; -//import org.junit.Before; -//import org.junit.Rule; -//import org.junit.Test; -//import org.junit.runner.RunWith; +// import org.junit.After; +// import org.junit.Assert; +// import org.junit.Before; +// import org.junit.Rule; +// import org.junit.Test; +// import org.junit.runner.RunWith; // -//import java.net.URI; +// import java.net.URI; // -//@Deprecated -//@RunWith(AndroidJUnit4.class) +// @Deprecated +// @RunWith(AndroidJUnit4.class) // public class ConstantsTests { // public static final String TAG = ConstantsTests.class.getName(); // @Rule @@ -82,4 +81,4 @@ class DatabaseTests { // Assert.assertSame(BRConstants._20241006_DRR,"did_request_rating"); // Assert.assertSame(BRConstants._20241006_UCR,"user_completed_rating"); // } -//} +// } diff --git a/app/src/test/java/com/brainwallet/tools/database/TransactionDataSourceTest.kt b/app/src/test/java/com/brainwallet/tools/database/TransactionDataSourceTest.kt index b9c88df3..5d8d9468 100644 --- a/app/src/test/java/com/brainwallet/tools/database/TransactionDataSourceTest.kt +++ b/app/src/test/java/com/brainwallet/tools/database/TransactionDataSourceTest.kt @@ -1,3 +1,3 @@ package com.brainwallet.tools.database -class TransactionDataSourceTest {} +class TransactionDataSourceTest diff --git a/app/src/test/java/com/brainwallet/tools/security/BRKeyStoreTest.kt b/app/src/test/java/com/brainwallet/tools/security/BRKeyStoreTest.kt index 56a86052..29b66ac6 100644 --- a/app/src/test/java/com/brainwallet/tools/security/BRKeyStoreTest.kt +++ b/app/src/test/java/com/brainwallet/tools/security/BRKeyStoreTest.kt @@ -1,62 +1,50 @@ package com.brainwallet.tools.security // -//import com.breadwallet.presenter.activities.intro.WriteDownActivity -//import com.breadwallet.tools.threads.BRExecutor -//import com.breadwallet.tools.util.BRConstants -//import com.brainwallet.example.DependencyOne -//import com.brainwallet.example.DependencyTwo -//import com.brainwallet.example.SystemUnderTest -//import com.platform.entities.TxMetaData -//import com.platform.interfaces.KVStoreAdaptor -//import com.platform.kvstore.CompletionObject -//import com.platform.kvstore.ReplicatedKVStore -//import com.platform.sqlite.KVItem -//import com.platform.sqlite.PlatformSqliteHelper -//import com.platform.tools.KVStoreManager -//import org.junit.After -//import org.junit.Assert -//import org.junit.Before -//import org.junit.ClassRule -//import org.junit.Test -//import org.junit.runner.RunWith -//import java.util.Arrays -//import java.util.concurrent.atomic.AtomicInteger -import io.mockk.coVerify -import io.mockk.every -import io.mockk.mockk -import io.mockk.spyk -import io.mockk.verify -import io.mockk.verifyOrder -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking -import org.junit.Assert.assertEquals -import org.junit.Test -// -class BRKeyStoreTest { - -} +// import com.breadwallet.presenter.activities.intro.WriteDownActivity +// import com.breadwallet.tools.threads.BRExecutor +// import com.breadwallet.tools.util.BRConstants +// import com.brainwallet.example.DependencyOne +// import com.brainwallet.example.DependencyTwo +// import com.brainwallet.example.SystemUnderTest +// import com.platform.entities.TxMetaData +// import com.platform.interfaces.KVStoreAdaptor +// import com.platform.kvstore.CompletionObject +// import com.platform.kvstore.ReplicatedKVStore +// import com.platform.sqlite.KVItem +// import com.platform.sqlite.PlatformSqliteHelper +// import com.platform.tools.KVStoreManager +// import org.junit.After +// import org.junit.Assert +// import org.junit.Before +// import org.junit.ClassRule +// import org.junit.Test +// import org.junit.runner.RunWith +// import java.util.Arrays +// import java.util.concurrent.atomic.AtomicInteger +// +class BRKeyStoreTest // from com.brainwallet.security; -//package com.brainwallet.security; +// package com.brainwallet.security; // -//import android.security.keystore.UserNotAuthenticatedException; -//import androidx.test.rule.ActivityTestRule; -//import androidx.test.ext.junit.runners.AndroidJUnit4; +// import android.security.keystore.UserNotAuthenticatedException; +// import androidx.test.rule.ActivityTestRule; +// import androidx.test.ext.junit.runners.AndroidJUnit4; // -//import com.breadwallet.presenter.activities.settings.TestActivity; -//import com.breadwallet.tools.security.BRKeyStore; -//import com.breadwallet.tools.threads.BRExecutor; +// import com.breadwallet.presenter.activities.settings.TestActivity; +// import com.breadwallet.tools.security.BRKeyStore; +// import com.breadwallet.tools.threads.BRExecutor; // -//import org.junit.Assert; -//import org.junit.Rule; -//import org.junit.Test; -//import org.junit.runner.RunWith; +// import org.junit.Assert; +// import org.junit.Rule; +// import org.junit.Test; +// import org.junit.runner.RunWith; // -//import java.io.File; +// import java.io.File; // -//import static com.breadwallet.tools.security.BRKeyStore.aliasObjectMap; +// import static com.breadwallet.tools.security.BRKeyStore.aliasObjectMap; // -//@RunWith(AndroidJUnit4.class) +// @RunWith(AndroidJUnit4.class) // public class KeyStoreTests { // public static final String TAG = KeyStoreTests.class.getName(); // @@ -358,13 +346,12 @@ class BRKeyStoreTest { // Assert.assertFalse(new File(BRKeyStore.getFilePath(aliasObjectMap.get(alias).ivFileName, mActivityRule.getActivity())).exists()); // } // -//} - +// } -//TODO: Transcode and add Kotlin tests. Copied from legacy Java BRKeyStoreTest -////@RunWith(androidx.test.ext.junit.runners.AndroidJUnit4::class) -////@LargeTest -//fun `add invoked with valid mocked values, should return correct value as expected`() { +// TODO: Transcode and add Kotlin tests. Copied from legacy Java BRKeyStoreTest +// //@RunWith(androidx.test.ext.junit.runners.AndroidJUnit4::class) +// //@LargeTest +// fun `add invoked with valid mocked values, should return correct value as expected`() { // val dependencyOne = mockk() // val dependencyTwo = mockk() // @@ -380,7 +367,7 @@ class BRKeyStoreTest { // dependencyOne.value // dependencyTwo.value // } -//} +// } // // // class MockUpAdapter : KVStoreAdaptor { @@ -800,16 +787,16 @@ class BRKeyStoreTest { // // @Test // fun testSyncPreventsAnotherConcurrentSync() { -//// boolean success = store.syncAllKeys(); -//// new Thread(new Runnable() { -//// @Override -//// public void run() { -//// boolean success = store.syncAllKeys(); -//// Assert.assertTrue(success); -//// Assert.assertFalse(success); -//// } -//// }).start(); -//// Assert.assertTrue(success); +// // boolean success = store.syncAllKeys(); +// // new Thread(new Runnable() { +// // @Override +// // public void run() { +// // boolean success = store.syncAllKeys(); +// // Assert.assertTrue(success); +// // Assert.assertFalse(success); +// // } +// // }).start(); +// // Assert.assertTrue(success); // } // // @Test @@ -986,14 +973,14 @@ class BRKeyStoreTest { // Assert.assertEquals(mds.size.toLong(), 1) // // // Assert.assertEquals(mds.(0).blockHeight, 123); -//// Assert.assertEquals(mds.get(0).classVersion, 3); -//// Assert.assertEquals(mds.get(0).comment, "hehey !"); -//// Assert.assertEquals(mds.get(0).creationTime, 21324); -//// Assert.assertEquals(mds.get(0).deviceId, "someDevice2324"); -//// Assert.assertEquals(mds.get(0).fee, 234); -//// Assert.assertEquals(mds.get(0).txSize, 23423); -//// Assert.assertEquals(mds.get(0).exchangeCurrency, "curr"); -//// Assert.assertEquals(mds.get(0).exchangeRate, 23.4343, 0); +// // Assert.assertEquals(mds.get(0).classVersion, 3); +// // Assert.assertEquals(mds.get(0).comment, "hehey !"); +// // Assert.assertEquals(mds.get(0).creationTime, 21324); +// // Assert.assertEquals(mds.get(0).deviceId, "someDevice2324"); +// // Assert.assertEquals(mds.get(0).fee, 234); +// // Assert.assertEquals(mds.get(0).txSize, 23423); +// // Assert.assertEquals(mds.get(0).exchangeCurrency, "curr"); +// // Assert.assertEquals(mds.get(0).exchangeRate, 23.4343, 0); // } // // @Test @@ -1054,6 +1041,6 @@ class BRKeyStoreTest { // private val remote: KVStoreAdaptor = MockUpAdapter() // private var store: ReplicatedKVStore? = null // } -//} +// } // -//} \ No newline at end of file +// } diff --git a/app/src/test/java/com/brainwallet/tools/security/NewKeyStoreTests.kt b/app/src/test/java/com/brainwallet/tools/security/NewKeyStoreTests.kt index 878c8899..45241f7f 100644 --- a/app/src/test/java/com/brainwallet/tools/security/NewKeyStoreTests.kt +++ b/app/src/test/java/com/brainwallet/tools/security/NewKeyStoreTests.kt @@ -1,37 +1,26 @@ package com.brainwallet.tools.security -import io.mockk.coVerify -import io.mockk.every -import io.mockk.mockk -import io.mockk.spyk -import io.mockk.verify -import io.mockk.verifyOrder -import kotlinx.coroutines.delay -import kotlinx.coroutines.runBlocking -import org.junit.Assert.assertEquals -import org.junit.Test -class NewKeyStoreTests { -} +class NewKeyStoreTests // package com.brainwallet.security // android.app.Activity; -//import android.app.Activity; -//import android.security.keystore.UserNotAuthenticatedException; -//import androidx.test.rule.ActivityTestRule; -//import androidx.test.ext.junit.runners.AndroidJUnit4; +// import android.app.Activity; +// import android.security.keystore.UserNotAuthenticatedException; +// import androidx.test.rule.ActivityTestRule; +// import androidx.test.ext.junit.runners.AndroidJUnit4; // -//import com.breadwallet.presenter.activities.settings.TestActivity; -//import com.breadwallet.tools.security.BRKeyStore; +// import com.breadwallet.presenter.activities.settings.TestActivity; +// import com.breadwallet.tools.security.BRKeyStore; // -//import org.junit.Assert; -//import org.junit.Before; -//import org.junit.Rule; -//import org.junit.Test; -//import org.junit.runner.RunWith; +// import org.junit.Assert; +// import org.junit.Before; +// import org.junit.Rule; +// import org.junit.Test; +// import org.junit.runner.RunWith; // -//import static com.breadwallet.tools.security.BRKeyStore.PHRASE_ALIAS; -//import static com.breadwallet.tools.security.BRKeyStore.aliasObjectMap; +// import static com.breadwallet.tools.security.BRKeyStore.PHRASE_ALIAS; +// import static com.breadwallet.tools.security.BRKeyStore.aliasObjectMap; // -//@RunWith(AndroidJUnit4.class) +// @RunWith(AndroidJUnit4.class) // public class NewKeyStoreTests { // public static final String TAG = NewKeyStoreTests.class.getName(); // @@ -187,4 +176,4 @@ class NewKeyStoreTests { // // } // -//} +// } diff --git a/app/src/test/java/com/brainwallet/tools/security/ReplicatedKVStoreTest.kt b/app/src/test/java/com/brainwallet/tools/security/ReplicatedKVStoreTest.kt index b29d4ecf..2b65b3ec 100644 --- a/app/src/test/java/com/brainwallet/tools/security/ReplicatedKVStoreTest.kt +++ b/app/src/test/java/com/brainwallet/tools/security/ReplicatedKVStoreTest.kt @@ -1,4 +1,4 @@ package com.brainwallet.tools.security -//TODO: pls fill this -class ReplicatedKVStoreTest \ No newline at end of file +// TODO: pls fill this +class ReplicatedKVStoreTest diff --git a/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt b/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt index 1f6fee1b..9559dd8b 100644 --- a/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt +++ b/app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt @@ -5,57 +5,57 @@ import org.junit.Assert.assertSame import org.junit.Test -//TODO: migrate from [com.brainwallet.analytics.ConstantsTests] +// TODO: migrate from [com.brainwallet.analytics.ConstantsTests] class BRConstantsTest { @Test fun `validate Litecoin symbol constant`() { - assertSame(BRConstants.litecoinLowercase,"ł") - assertSame(BRConstants.litecoinUppercase,"Ł") + assertSame(BRConstants.litecoinLowercase, "ł") + assertSame(BRConstants.litecoinUppercase, "Ł") } @Test - fun `validate App external URL constant`(){ - assertSame(BRConstants.TWITTER_LINK,"https://twitter.com/Brainwallet_App") - assertSame(BRConstants.INSTAGRAM_LINK,"https://www.instagram.com/brainwalletapp") - assertSame(BRConstants.WEB_LINK,"https://brainwallet.co") - assertSame(BRConstants.TOS_LINK,"https://brainwallet.co/privacy-policy.html") - assertSame(BRConstants.MOBILE_MP_LINK,"https://brainwallet.co/mobile-top-up.html") - assertSame(BRConstants.BITREFILL_AFFILIATE_LINK,"https://www.bitrefill.com/") + fun `validate App external URL constant`() { + assertSame(BRConstants.TWITTER_LINK, "https://twitter.com/Brainwallet_App") + assertSame(BRConstants.INSTAGRAM_LINK, "https://www.instagram.com/brainwalletapp") + assertSame(BRConstants.WEB_LINK, "https://brainwallet.co") + assertSame(BRConstants.TOS_LINK, "https://brainwallet.co/privacy-policy.html") + assertSame(BRConstants.MOBILE_MP_LINK, "https://brainwallet.co/mobile-top-up.html") + assertSame(BRConstants.BITREFILL_AFFILIATE_LINK, "https://www.bitrefill.com/") } @Test - fun `validate Firebase Analytics constants`(){ - assertSame(BRConstants._20191105_AL,"app_launched"); - assertSame(BRConstants._20191105_VSC,"visit_send_controller"); - assertSame(BRConstants._20202116_VRC,"visit_receive_controller"); - assertSame(BRConstants._20191105_DSL,"did_send_ltc"); - assertSame(BRConstants._20191105_DTBT,"did_tap_buy_tab"); - assertSame(BRConstants._20200111_RNI,"rate_not_initialized"); - assertSame(BRConstants._20200111_FNI,"feeperkb_not_initialized"); - assertSame(BRConstants._20200111_TNI,"transaction_not_initialized"); - assertSame(BRConstants._20200111_WNI,"wallet_not_initialized"); - assertSame(BRConstants._20200111_PNI,"phrase_not_initialized"); - assertSame(BRConstants._20200111_UTST,"unable_to_sign_transaction"); - assertSame(BRConstants._20200112_ERR,"brainwallet_android_error"); - assertSame(BRConstants._20200112_DSR,"did_start_resync"); - assertSame(BRConstants._20200125_DSRR,"did_show_review_request"); - assertSame(BRConstants._20201118_DTGS,"did_tap_get_support"); - assertSame(BRConstants._20200217_DUWP,"did_unlock_with_pin"); - assertSame(BRConstants._20200217_DUWB,"did_unlock_with_biometrics"); - assertSame(BRConstants._20201121_SIL,"started_IFPS_lookup"); - assertSame(BRConstants._20201121_DRIA,"did_resolve_IPFS_address"); - assertSame(BRConstants._20201121_FRIA,"failed_resolve_IPFS_address"); - assertSame(BRConstants._20200207_DTHB,"did_tap_header_balance"); - assertSame(BRConstants._20210427_HCIEEH,"heartbeat_check_if_event_even_happens"); - assertSame(BRConstants._20220822_UTOU,"user_tapped_on_ud"); - assertSame(BRConstants._20230131_NENR,"no_error_nominal_response"); - assertSame(BRConstants._20230407_DCS,"did_complete_sync"); - assertSame(BRConstants._20240123_RAGI,"registered_android_general_interest"); - assertSame(BRConstants._20231225_UAP,"user_accepted_push"); - assertSame(BRConstants._20240101_US,"user_signup"); - assertSame(BRConstants._20241006_DRR,"did_request_rating"); - assertSame(BRConstants._20241006_UCR,"user_completed_rating"); + fun `validate Firebase Analytics constants`() { + assertSame(BRConstants._20191105_AL, "app_launched") + assertSame(BRConstants._20191105_VSC, "visit_send_controller") + assertSame(BRConstants._20202116_VRC, "visit_receive_controller") + assertSame(BRConstants._20191105_DSL, "did_send_ltc") + assertSame(BRConstants._20191105_DTBT, "did_tap_buy_tab") + assertSame(BRConstants._20200111_RNI, "rate_not_initialized") + assertSame(BRConstants._20200111_FNI, "feeperkb_not_initialized") + assertSame(BRConstants._20200111_TNI, "transaction_not_initialized") + assertSame(BRConstants._20200111_WNI, "wallet_not_initialized") + assertSame(BRConstants._20200111_PNI, "phrase_not_initialized") + assertSame(BRConstants._20200111_UTST, "unable_to_sign_transaction") + assertSame(BRConstants._20200112_ERR, "brainwallet_android_error") + assertSame(BRConstants._20200112_DSR, "did_start_resync") + assertSame(BRConstants._20200125_DSRR, "did_show_review_request") + assertSame(BRConstants._20201118_DTGS, "did_tap_get_support") + assertSame(BRConstants._20200217_DUWP, "did_unlock_with_pin") + assertSame(BRConstants._20200217_DUWB, "did_unlock_with_biometrics") + assertSame(BRConstants._20201121_SIL, "started_IFPS_lookup") + assertSame(BRConstants._20201121_DRIA, "did_resolve_IPFS_address") + assertSame(BRConstants._20201121_FRIA, "failed_resolve_IPFS_address") + assertSame(BRConstants._20200207_DTHB, "did_tap_header_balance") + assertSame(BRConstants._20210427_HCIEEH, "heartbeat_check_if_event_even_happens") + assertSame(BRConstants._20220822_UTOU, "user_tapped_on_ud") + assertSame(BRConstants._20230131_NENR, "no_error_nominal_response") + assertSame(BRConstants._20230407_DCS, "did_complete_sync") + assertSame(BRConstants._20240123_RAGI, "registered_android_general_interest") + assertSame(BRConstants._20231225_UAP, "user_accepted_push") + assertSame(BRConstants._20240101_US, "user_signup") + assertSame(BRConstants._20241006_DRR, "did_request_rating") + assertSame(BRConstants._20241006_UCR, "user_completed_rating") } @Test @@ -64,25 +64,24 @@ class BRConstantsTest { } } - -//import androidx.test.ext.junit.runners.AndroidJUnit4; -//import android.util.Log; -//import androidx.test.ext.junit.rules.ActivityScenarioRule; +// import androidx.test.ext.junit.runners.AndroidJUnit4; +// import android.util.Log; +// import androidx.test.ext.junit.rules.ActivityScenarioRule; // -//import com.breadwallet.presenter.activities.intro.IntroActivity; -//import com.breadwallet.tools.util.BRConstants; +// import com.breadwallet.presenter.activities.intro.IntroActivity; +// import com.breadwallet.tools.util.BRConstants; // -//import org.junit.After; -//import org.junit.Assert; -//import org.junit.Before; -//import org.junit.Rule; -//import org.junit.Test; -//import org.junit.runner.RunWith; +// import org.junit.After; +// import org.junit.Assert; +// import org.junit.Before; +// import org.junit.Rule; +// import org.junit.Test; +// import org.junit.runner.RunWith; // -//import java.net.URI; +// import java.net.URI; // -//@Deprecated -//@RunWith(AndroidJUnit4.class) +// @Deprecated +// @RunWith(AndroidJUnit4.class) // public class ConstantsTests { // public static final String TAG = ConstantsTests.class.getName(); // @Rule @@ -141,4 +140,4 @@ class BRConstantsTest { // Assert.assertSame(BRConstants._20241006_DRR,"did_request_rating"); // Assert.assertSame(BRConstants._20241006_UCR,"user_completed_rating"); // } -//} +// } diff --git a/app/src/test/java/com/brainwallet/tools/util/Bip39ReaderTest.kt b/app/src/test/java/com/brainwallet/tools/util/Bip39ReaderTest.kt index 72a84af3..b1739d81 100644 --- a/app/src/test/java/com/brainwallet/tools/util/Bip39ReaderTest.kt +++ b/app/src/test/java/com/brainwallet/tools/util/Bip39ReaderTest.kt @@ -1,4 +1,4 @@ package com.brainwallet.tools.util -//TODO: pls fill this -class Bip39ReaderTest \ No newline at end of file +// TODO: pls fill this +class Bip39ReaderTest diff --git a/app/src/test/java/com/brainwallet/tools/util/GoogleServicesTests.kt b/app/src/test/java/com/brainwallet/tools/util/GoogleServicesTests.kt index 0bac9bbb..176d080f 100644 --- a/app/src/test/java/com/brainwallet/tools/util/GoogleServicesTests.kt +++ b/app/src/test/java/com/brainwallet/tools/util/GoogleServicesTests.kt @@ -1,16 +1,10 @@ package com.brainwallet.tools.util -import io.mockk.every -import io.mockk.Runs -import io.mockk.just -import io.mockk.mockk -import io.mockk.spyk import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder import java.io.File - class GoogleServicesTest { private lateinit var googleServicesJSONFile: File @@ -23,16 +17,17 @@ class GoogleServicesTest { fun setUp() { // Create a temporary file with specific contents googleServicesJSONFile = temporaryFolder.newFile("google-services.json") - googleServicesJSONFile.writeText("\"{\\n \\\"project_info\\\": {\\n \\\"project_number\\\": \\\"837833052833\\\",\\n \\\"project_id\\\": \\\"brainwallet-mobile\\\"\\n }\\n}\"") + googleServicesJSONFile.writeText( + "\"{\\n \\\"project_info\\\": {\\n \\\"project_number\\\": \\\"837833052833\\\",\\n \\\"project_id\\\": \\\"brainwallet-mobile\\\"\\n }\\n}\"" + ) } @Test fun `read GoogleServices file`() { - } + @Test fun `read GoogleServices file and parse into a JSON object , should return the correct project_id`() { - // val projectInfo = json.getAsJsonObject("project_info") // assertEquals("brainwallet-mobile", projectInfo.get("project_id").asString) } @@ -42,4 +37,4 @@ class GoogleServicesTest { // val projectInfo = json.getAsJsonObject("project_info") // assertEquals("837833052833", projectInfo.get("project_number").asString) } -} \ No newline at end of file +} diff --git a/app/src/test/java/com/brainwallet/tools/util/LocaleHelperTest.kt b/app/src/test/java/com/brainwallet/tools/util/LocaleHelperTest.kt index 52cab56b..b102b988 100644 --- a/app/src/test/java/com/brainwallet/tools/util/LocaleHelperTest.kt +++ b/app/src/test/java/com/brainwallet/tools/util/LocaleHelperTest.kt @@ -70,7 +70,5 @@ class LocaleHelperTest { it ) } - - } -} \ No newline at end of file +} diff --git a/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt b/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt index 1dfee111..27654c8f 100644 --- a/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt +++ b/app/src/test/java/com/brainwallet/tools/util/ProdAPIManagerTests.kt @@ -1,25 +1,6 @@ package com.brainwallet.tools.util -import android.app.Activity -import android.content.Context -import com.brainwallet.data.source.RemoteConfigSource -import com.brainwallet.presenter.activities.util.ActivityUTILS -import com.platform.APIClient -import io.mockk.every -import io.mockk.mockk -import io.mockk.mockkObject -import io.mockk.mockkStatic -import io.mockk.spyk -import io.mockk.verifyAll -import okhttp3.Protocol -import okhttp3.Request -import okhttp3.Response -import okhttp3.ResponseBody.Companion.toResponseBody -import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Test - -//TODO: need update this test after refactor +// TODO: need update this test after refactor class ProdAPIManagerTests { // private val remoteConfigSource: RemoteConfigSource = mockk() // private lateinit var apiManager: BRApiManager @@ -105,4 +86,4 @@ class ProdAPIManagerTests { // } // // } -} \ No newline at end of file +} diff --git a/app/src/test/java/com/brainwallet/tools/util/SeedWordTests.kt b/app/src/test/java/com/brainwallet/tools/util/SeedWordTests.kt index 17c902c2..b4662acc 100644 --- a/app/src/test/java/com/brainwallet/tools/util/SeedWordTests.kt +++ b/app/src/test/java/com/brainwallet/tools/util/SeedWordTests.kt @@ -1,36 +1,34 @@ package com.brainwallet.tools.util - -class SeedWordTests { -} +class SeedWordTests // // -//package com.brainwallet -//import android.util.Log; +// package com.brainwallet +// import android.util.Log; // -//import com.breadwallet.tools.util.Bip39Reader; -//import com.breadwallet.wallet.BRWalletManager; +// import com.breadwallet.tools.util.Bip39Reader; +// import com.breadwallet.wallet.BRWalletManager; // -//import org.apache.commons.io.IOUtils; -//import org.junit.Assert; -//import org.junit.Test; -//import org.junit.runner.RunWith; +// import org.apache.commons.io.IOUtils; +// import org.junit.Assert; +// import org.junit.Test; +// import org.junit.runner.RunWith; // -//import java.io.IOException; -//import java.io.InputStream; -//import java.util.ArrayList; -//import java.util.Arrays; -//import java.util.List; +// import java.io.IOException; +// import java.io.InputStream; +// import java.util.ArrayList; +// import java.util.Arrays; +// import java.util.List; // -//import static org.hamcrest.Matchers.is; -//import static org.hamcrest.Matchers.notNullValue; -//import static org.junit.Assert.assertThat; +// import static org.hamcrest.Matchers.is; +// import static org.hamcrest.Matchers.notNullValue; +// import static org.junit.Assert.assertThat; // -//import androidx.test.ext.junit.runners.AndroidJUnit4; -//import androidx.test.filters.LargeTest; +// import androidx.test.ext.junit.runners.AndroidJUnit4; +// import androidx.test.filters.LargeTest; // -//@RunWith(AndroidJUnit4.class) +// @RunWith(AndroidJUnit4.class) // @LargeTest // // public class PaperKeyTests { diff --git a/app/src/test/java/com/brainwallet/ui/screens/unlock/UnLockViewModelTest.kt b/app/src/test/java/com/brainwallet/ui/screens/unlock/UnLockViewModelTest.kt index fe266cc9..0faa3974 100644 --- a/app/src/test/java/com/brainwallet/ui/screens/unlock/UnLockViewModelTest.kt +++ b/app/src/test/java/com/brainwallet/ui/screens/unlock/UnLockViewModelTest.kt @@ -144,7 +144,8 @@ class UnLockViewModelTest { viewModel.onEvent( UnLockEvent.OnPinDigitChange( digit = index + 1, - isValidPin = { false }) + isValidPin = { false } + ) ) awaitItem() } @@ -170,7 +171,8 @@ class UnLockViewModelTest { viewModel.onEvent( UnLockEvent.OnPinDigitChange( digit = index + 1, - isValidPin = { true }) + isValidPin = { true } + ) ) awaitItem() } @@ -178,7 +180,8 @@ class UnLockViewModelTest { viewModel.onEvent( UnLockEvent.OnPinDigitChange( digit = 4, - isValidPin = { true }) + isValidPin = { true } + ) ) awaitItem() } @@ -210,7 +213,8 @@ class UnLockViewModelTest { viewModel.onEvent( UnLockEvent.OnPinDigitChange( digit = index + 1, - isValidPin = { false }) + isValidPin = { false } + ) ) awaitItem() } @@ -222,9 +226,11 @@ class UnLockViewModelTest { testScheduler.advanceUntilIdle() coVerify { - EventBus.emit(match { event -> - event.passcode == listOf(1, 2, 3, 4) - }) + EventBus.emit( + match { event -> + event.passcode == listOf(1, 2, 3, 4) + } + ) } } @@ -294,7 +300,6 @@ class UnLockViewModelTest { } } - @Test fun `given OnLoad event with null currency when processed then state remains unchanged`() = runTest { diff --git a/app/src/test/java/com/brainwallet/util/CurrencyDataGetterTest.kt b/app/src/test/java/com/brainwallet/util/CurrencyDataGetterTest.kt index 0bdf4cd0..c05c12bf 100644 --- a/app/src/test/java/com/brainwallet/util/CurrencyDataGetterTest.kt +++ b/app/src/test/java/com/brainwallet/util/CurrencyDataGetterTest.kt @@ -92,8 +92,8 @@ class CurrencyDataGetterTest { val currencyCode = "GBP" val amount = BigDecimal("123.45") val expectedFormattedString = "£123.45" - every { - mockFormattedCurrencyStringGetter.invoke(mockContext, currencyCode, amount) + every { + mockFormattedCurrencyStringGetter.invoke(mockContext, currencyCode, amount) } returns expectedFormattedString val actualFormattedString = currencyDataGetter.getFormattedCurrencyString(currencyCode, amount) @@ -101,8 +101,8 @@ class CurrencyDataGetterTest { assert(actualFormattedString == expectedFormattedString) { "Expected formatted currency '$expectedFormattedString' but was '$actualFormattedString'" } - verify(exactly = 1) { - mockFormattedCurrencyStringGetter.invoke(mockContext, currencyCode, amount) + verify(exactly = 1) { + mockFormattedCurrencyStringGetter.invoke(mockContext, currencyCode, amount) } } @@ -110,16 +110,16 @@ class CurrencyDataGetterTest { fun `given invalid currency code when getting formatted string then returns null`() { val invalidCurrencyCode = "INVALID" val amount = BigDecimal("100.00") - every { - mockFormattedCurrencyStringGetter.invoke(mockContext, invalidCurrencyCode, amount) + every { + mockFormattedCurrencyStringGetter.invoke(mockContext, invalidCurrencyCode, amount) } returns null val actualFormattedString = currencyDataGetter.getFormattedCurrencyString(invalidCurrencyCode, amount) assert(actualFormattedString == null) { "Expected null for invalid currency code '$invalidCurrencyCode' but was '$actualFormattedString'" } - verify(exactly = 1) { - mockFormattedCurrencyStringGetter.invoke(mockContext, invalidCurrencyCode, amount) + verify(exactly = 1) { + mockFormattedCurrencyStringGetter.invoke(mockContext, invalidCurrencyCode, amount) } } } diff --git a/build.gradle.kts b/build.gradle.kts index a34bb719..29ba64f1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,13 +3,15 @@ plugins { alias(libs.plugins.android.application) apply false alias(libs.plugins.android.library) apply false - alias(libs.plugins.jetbrains.kotlin.android) apply false - alias(libs.plugins.jetbrains.kotlin.compose) apply false + alias(grunt.plugins.jetbrains.kotlin.android) apply false + alias(grunt.plugins.jetbrains.kotlin.compose) apply false alias(libs.plugins.jetbrains.kotlin.kapt) apply false - alias(libs.plugins.jetbrains.kotlin.serialization) apply false + alias(grunt.plugins.jetbrains.kotlin.serialization) apply false alias(libs.plugins.google.services) apply false alias(libs.plugins.firebase.crashlytics) apply false - alias(libs.plugins.ksp) apply false + alias(grunt.plugins.ksp) apply false + alias(grunt.plugins.detekt) apply true + alias(grunt.plugins.buildlogic.detekt) apply true } tasks.register("clean", Delete::class) { diff --git a/config/detekt-app-baseline.xml b/config/detekt-app-baseline.xml new file mode 100644 index 00000000..9dc8375b --- /dev/null +++ b/config/detekt-app-baseline.xml @@ -0,0 +1,620 @@ + + + + + AnnotationOnSeparateLine:Theme.kt$@Composable() + AnnotationOnSeparateLine:Theme.kt$BrainwalletTheme$@Composable @ReadOnlyComposable + ArgumentListWrapping:CountryLanguageAdapter.kt$CountryLanguageAdapter$( mContext!!, Uri.parse("android.resource://" + mContext?.packageName + "/" + selectedAudio())) + ArgumentListWrapping:CountryLanguageAdapter.kt$CountryLanguageAdapter$(mContext!!, Uri.parse("android.resource://" + mContext?.packageName + "/" + selectedAudio())) + ArgumentListWrapping:GoogleServicesTests.kt$GoogleServicesTest$( "\"{\\n \\\"project_info\\\": {\\n \\\"project_number\\\": \\\"837833052833\\\",\\n \\\"project_id\\\": \\\"brainwallet-mobile\\\"\\n }\\n}\"") + ArgumentListWrapping:GoogleServicesTests.kt$GoogleServicesTest$("\"{\\n \\\"project_info\\\": {\\n \\\"project_number\\\": \\\"837833052833\\\",\\n \\\"project_id\\\": \\\"brainwallet-mobile\\\"\\n }\\n}\"") + ArgumentListWrapping:HomeSettingDrawerSheet.kt$( context) + ArgumentListWrapping:HomeSettingDrawerSheet.kt$(context) + ArgumentListWrapping:InputWordsScreen.kt$( ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class, ExperimentalComposeUiApi::class ) + ArgumentListWrapping:InputWordsScreen.kt$( index = index, text = it, ) + ArgumentListWrapping:KeyStoreManager.kt$KeyStoreManager$( "timber: KeyStoreManager.getData new key in prefs not exists | ${aliasObject.alias}, ${aliasObject.datafileName}, ${aliasObject.ivFileName}") + ArgumentListWrapping:KeyStoreManager.kt$KeyStoreManager$("timber: KeyStoreManager.getData new key in prefs not exists | ${aliasObject.alias}, ${aliasObject.datafileName}, ${aliasObject.ivFileName}") + ArgumentListWrapping:MessagingTopicDataSourceTest.kt$MessagingTopicDataSourceTest$( "initial_$expectedBase", "news_$expectedBase", "promo_$expectedBase", "warn_$expectedBase") + ArgumentListWrapping:MessagingTopicDataSourceTest.kt$MessagingTopicDataSourceTest$("initial_$expectedBase", "news_$expectedBase", "promo_$expectedBase", "warn_$expectedBase") + ArgumentListWrapping:ReceiveDialog.kt$( color = BrainwalletTheme.colors.surface) + ArgumentListWrapping:ReceiveDialog.kt$(color = BrainwalletTheme.colors.surface) + ArgumentListWrapping:SeedWordItem.kt$( BrainwalletTheme.colors.content) + ArgumentListWrapping:SeedWordItem.kt$( modifier = modifier .background( color = BrainwalletTheme.colors.background.copy(alpha = 0.3f), shape = MaterialTheme.shapes.extraLarge ) .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically ) + ArgumentListWrapping:SeedWordItem.kt$(BrainwalletTheme.colors.content) + ArgumentListWrapping:UnLockScreenFooter.kt$( modifier = Modifier .padding(bottom = 24.dp) .padding(horizontal = 85.dp)) + ArgumentListWrapping:UnLockScreenFooter.kt$(modifier = Modifier .padding(bottom = 24.dp) .padding(horizontal = 85.dp)) + ArgumentListWrapping:YourSeedProveItScreen.kt$( ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class, ExperimentalFoundationApi::class ) + ArgumentListWrapping:YourSeedProveItScreen.kt$( if (state.orderCorrected) R.string.game_and_sync else R.string.reset_start_over) + ArgumentListWrapping:YourSeedProveItScreen.kt$( if (state.orderCorrected) R.string.you_saved_your_keys else R.string.you_saved_it_right) + ArgumentListWrapping:YourSeedProveItScreen.kt$( if (state.orderCorrected) R.string.you_saved_your_keys_desc else R.string.you_saved_it_right_desc) + ArgumentListWrapping:YourSeedProveItScreen.kt$( items = state.correctSeedWords.values.toList()) + ArgumentListWrapping:YourSeedProveItScreen.kt$( navigationIcon = { IconButton( onClick = { onNavigate.invoke(UiEffect.Navigate.Back()) }, ) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(R.string.back), ) } }) + ArgumentListWrapping:YourSeedProveItScreen.kt$(if (state.orderCorrected) R.string.game_and_sync else R.string.reset_start_over) + ArgumentListWrapping:YourSeedProveItScreen.kt$(if (state.orderCorrected) R.string.you_saved_your_keys else R.string.you_saved_it_right) + ArgumentListWrapping:YourSeedProveItScreen.kt$(if (state.orderCorrected) R.string.you_saved_your_keys_desc else R.string.you_saved_it_right_desc) + ArgumentListWrapping:YourSeedProveItScreen.kt$(items = state.correctSeedWords.values.toList()) + CommentSpacing:BRConstantsTest.kt$//@Deprecated + CommentSpacing:BRConstantsTest.kt$//@RunWith(AndroidJUnit4.class) + CommentSpacing:BRConstantsTest.kt$//import android.util.Log; + CommentSpacing:BRConstantsTest.kt$//import androidx.test.ext.junit.rules.ActivityScenarioRule; + CommentSpacing:BRConstantsTest.kt$//import androidx.test.ext.junit.runners.AndroidJUnit4; + CommentSpacing:BRConstantsTest.kt$//import com.breadwallet.presenter.activities.intro.IntroActivity; + CommentSpacing:BRConstantsTest.kt$//import com.breadwallet.tools.util.BRConstants; + CommentSpacing:BRConstantsTest.kt$//import java.net.URI; + CommentSpacing:BRConstantsTest.kt$//import org.junit.After; + CommentSpacing:BRConstantsTest.kt$//import org.junit.Assert; + CommentSpacing:BRConstantsTest.kt$//import org.junit.Before; + CommentSpacing:BRConstantsTest.kt$//import org.junit.Rule; + CommentSpacing:BRConstantsTest.kt$//import org.junit.Test; + CommentSpacing:BRConstantsTest.kt$//import org.junit.runner.RunWith; + CommentSpacing:BRConstantsTest.kt$//} + CommentSpacing:BRConstantsTest.kt$BRConstantsTest$//TODO: migrate from [com.brainwallet.analytics.ConstantsTests] + CommentSpacing:BRKeyStoreTest.kt$//// @Override + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertEquals(mds.get(0).classVersion, 3); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertEquals(mds.get(0).comment, "hehey !"); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertEquals(mds.get(0).creationTime, 21324); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertEquals(mds.get(0).deviceId, "someDevice2324"); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertEquals(mds.get(0).exchangeCurrency, "curr"); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertEquals(mds.get(0).exchangeRate, 23.4343, 0); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertEquals(mds.get(0).fee, 234); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertEquals(mds.get(0).txSize, 23423); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertFalse(success); + CommentSpacing:BRKeyStoreTest.kt$//// Assert.assertTrue(success); + CommentSpacing:BRKeyStoreTest.kt$//// boolean success = store.syncAllKeys(); + CommentSpacing:BRKeyStoreTest.kt$//// new Thread(new Runnable() { + CommentSpacing:BRKeyStoreTest.kt$//// public void run() { + CommentSpacing:BRKeyStoreTest.kt$//// } + CommentSpacing:BRKeyStoreTest.kt$//// }).start(); + CommentSpacing:BRKeyStoreTest.kt$////@LargeTest + CommentSpacing:BRKeyStoreTest.kt$////@RunWith(androidx.test.ext.junit.runners.AndroidJUnit4::class) + CommentSpacing:BRKeyStoreTest.kt$//@RunWith(AndroidJUnit4.class) + CommentSpacing:BRKeyStoreTest.kt$//TODO: Transcode and add Kotlin tests. Copied from legacy Java BRKeyStoreTest + CommentSpacing:BRKeyStoreTest.kt$//fun `add invoked with valid mocked values, should return correct value as expected`() { + CommentSpacing:BRKeyStoreTest.kt$//import android.security.keystore.UserNotAuthenticatedException; + CommentSpacing:BRKeyStoreTest.kt$//import androidx.test.ext.junit.runners.AndroidJUnit4; + CommentSpacing:BRKeyStoreTest.kt$//import androidx.test.rule.ActivityTestRule; + CommentSpacing:BRKeyStoreTest.kt$//import com.brainwallet.example.DependencyOne + CommentSpacing:BRKeyStoreTest.kt$//import com.brainwallet.example.DependencyTwo + CommentSpacing:BRKeyStoreTest.kt$//import com.brainwallet.example.SystemUnderTest + CommentSpacing:BRKeyStoreTest.kt$//import com.breadwallet.presenter.activities.intro.WriteDownActivity + CommentSpacing:BRKeyStoreTest.kt$//import com.breadwallet.presenter.activities.settings.TestActivity; + CommentSpacing:BRKeyStoreTest.kt$//import com.breadwallet.tools.security.BRKeyStore; + CommentSpacing:BRKeyStoreTest.kt$//import com.breadwallet.tools.threads.BRExecutor + CommentSpacing:BRKeyStoreTest.kt$//import com.breadwallet.tools.threads.BRExecutor; + CommentSpacing:BRKeyStoreTest.kt$//import com.breadwallet.tools.util.BRConstants + CommentSpacing:BRKeyStoreTest.kt$//import com.platform.entities.TxMetaData + CommentSpacing:BRKeyStoreTest.kt$//import com.platform.interfaces.KVStoreAdaptor + CommentSpacing:BRKeyStoreTest.kt$//import com.platform.kvstore.CompletionObject + CommentSpacing:BRKeyStoreTest.kt$//import com.platform.kvstore.ReplicatedKVStore + CommentSpacing:BRKeyStoreTest.kt$//import com.platform.sqlite.KVItem + CommentSpacing:BRKeyStoreTest.kt$//import com.platform.sqlite.PlatformSqliteHelper + CommentSpacing:BRKeyStoreTest.kt$//import com.platform.tools.KVStoreManager + CommentSpacing:BRKeyStoreTest.kt$//import java.io.File; + CommentSpacing:BRKeyStoreTest.kt$//import java.util.Arrays + CommentSpacing:BRKeyStoreTest.kt$//import java.util.concurrent.atomic.AtomicInteger + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.After + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.Assert + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.Assert; + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.Before + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.ClassRule + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.Rule; + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.Test + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.Test; + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.runner.RunWith + CommentSpacing:BRKeyStoreTest.kt$//import org.junit.runner.RunWith; + CommentSpacing:BRKeyStoreTest.kt$//import static com.breadwallet.tools.security.BRKeyStore.aliasObjectMap; + CommentSpacing:BRKeyStoreTest.kt$//package com.brainwallet.security; + CommentSpacing:BRKeyStoreTest.kt$//} + CommentSpacing:BackupRateFetchTests.kt$BackupRateFetchTests$//TODO: need update this test after refactor + CommentSpacing:BaseURLTests.kt$BaseURLTests$//TODO: need update this test after refactor + CommentSpacing:Bip39ReaderTest.kt$Bip39ReaderTest$//TODO: pls fill this + CommentSpacing:BrainwalletActivity.kt$BrainwalletActivity$/// Ergo; Route.TopUp + CommentSpacing:BrainwalletActivity.kt$BrainwalletActivity$///DEV: Test / Dev Composable Shortcut swap to launch + CommentSpacing:BrainwalletActivity.kt$BrainwalletActivity$//for now just toast + CommentSpacing:BrainwalletApp.kt$BrainwalletApp.Companion$//call onStop on evert activity so + CommentSpacing:BrainwalletViewModel.kt$BrainwalletViewModel$//todo more error handler + CommentSpacing:BuyLitecoinScreen.kt$//TODO: wip + CommentSpacing:BuyLitecoinViewModel.kt$BuyLitecoinViewModel$//do validation + CommentSpacing:ChangeLanguageBottomSheet.kt$ChangeLanguageBottomSheet$//for now, need to provide [getLocale] + CommentSpacing:CipherStorage.kt$CipherStorageFile$//no-op + CommentSpacing:Color.kt$//to make color darken, since we are not providing all colors for specific case + CommentSpacing:CurrencyDetail.kt$/// Layout values + CommentSpacing:CurrencyTests.kt$CurrencyTests$//The actual number of BW currencies is 16. The 0 is a placeholder and needs to be replaced with a db query. + CommentSpacing:CurrencyTests.kt$CurrencyTests$//The actual number of currencies is 174. The 0 is a placeholder and needs to be replaced with a db query. + CommentSpacing:CurrencyUpdateWorker.kt$CurrencyUpdateWorker$//4secs + CommentSpacing:DatabaseTests.kt$//@Deprecated + CommentSpacing:DatabaseTests.kt$//@RunWith(AndroidJUnit4.class) + CommentSpacing:DatabaseTests.kt$//import android.util.Log; + CommentSpacing:DatabaseTests.kt$//import androidx.test.ext.junit.rules.ActivityScenarioRule; + CommentSpacing:DatabaseTests.kt$//import androidx.test.ext.junit.runners.AndroidJUnit4; + CommentSpacing:DatabaseTests.kt$//import com.breadwallet.presenter.activities.intro.IntroActivity; + CommentSpacing:DatabaseTests.kt$//import com.breadwallet.tools.util.BRConstants; + CommentSpacing:DatabaseTests.kt$//import java.net.URI; + CommentSpacing:DatabaseTests.kt$//import org.junit.After; + CommentSpacing:DatabaseTests.kt$//import org.junit.Assert; + CommentSpacing:DatabaseTests.kt$//import org.junit.Before; + CommentSpacing:DatabaseTests.kt$//import org.junit.Rule; + CommentSpacing:DatabaseTests.kt$//import org.junit.Test; + CommentSpacing:DatabaseTests.kt$//import org.junit.runner.RunWith; + CommentSpacing:DatabaseTests.kt$//package com.brainwallet.analytics; + CommentSpacing:DatabaseTests.kt$//} + CommentSpacing:EventBus.kt$EventBus.Event.LegacyPasscodeVerified$//provide this for old flow + CommentSpacing:Fee.kt$//2 -> index of top, since we have [low,medium,top] + CommentSpacing:FragmentSend.kt$///DEV WIP + CommentSpacing:FragmentSend.kt$FragmentSend$/// Setup Currency Button that switches between LTC and the preferred fiat (e.g.; "USD") + CommentSpacing:FragmentSend.kt$FragmentSend$/// Setup Fees Description + CommentSpacing:FragmentSend.kt$FragmentSend$//Amount is zero so network fee is also zero + CommentSpacing:FragmentSend.kt$FragmentSend$//TODO: make sure remove unused after refactor network fee move to HomeSettingDrawerSheet + CommentSpacing:FragmentSend.kt$FragmentSend$//update fee + CommentSpacing:GamesDetail.kt$/// Layout values + CommentSpacing:HistoryScreen.kt$//TODO: wip + CommentSpacing:HomeScreen.kt$//TODO: wip + CommentSpacing:HomeScreen.kt$//using old fragment + CommentSpacing:HomeSettingDrawerSheet.kt$/// Layout values + CommentSpacing:HomeSettingDrawerSheet.kt$//currently just load analytics share data here + CommentSpacing:HomeSettingDrawerSheet.kt$//currently just load sync metadata here + CommentSpacing:InputWordsScreen.kt$/// Layout values + CommentSpacing:InputWordsScreen.kt$//12 seed words + CommentSpacing:InputWordsScreen.kt$//todo: the following sizing can be move to BrainwalletTheme + CommentSpacing:InputWordsState.kt$InputWordsState$//12 seed words + CommentSpacing:InputWordsViewModel.kt$InputWordsViewModel$//TODO: revisit later, please move to repository, for now just reuse the existing + CommentSpacing:KeyStoreManager.kt$KeyStoreManager$//TODO: need auth? + CommentSpacing:KeyStoreManager.kt$KeyStoreManager$//if true need device auth + CommentSpacing:LanguageDetail.kt$/// Layout values + CommentSpacing:LanguageDetail.kt$//TODO + CommentSpacing:LegacyNavigation.kt$LegacyNavigation$//open compose from old activity + CommentSpacing:LegacyNavigation.kt$LegacyNavigation$//provide old navigation using intent activity + CommentSpacing:LegacyNavigation.kt$LegacyNavigation$//todo + CommentSpacing:LitecoinBlockchainDetail.kt$/// Layout values + CommentSpacing:LitecoinBlockchainDetail.kt$//TODO + CommentSpacing:LitecoinBlockchainDetail.kt$//fiat? + CommentSpacing:LtcRepository.kt$LtcRepository.Companion$//e.g. buy_limits:usd + CommentSpacing:LtcRepositoryImpl.kt$LtcRepositoryImpl$//5 minutes + CommentSpacing:LtcRepositoryImpl.kt$LtcRepositoryImpl$//legacy logic + CommentSpacing:LtcRepositoryImpl.kt$LtcRepositoryImpl$//replace base url from buy.moonpay.com + CommentSpacing:LtcRepositoryImpl.kt$LtcRepositoryImpl$//save to local + CommentSpacing:LtcRepositoryImpl.kt$LtcRepositoryImpl$//todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies + CommentSpacing:LtcRepositoryImpl.kt$LtcRepositoryImpl$//using static fee + CommentSpacing:MainNav.kt$//since we still have multiple activity, we just start from the param + CommentSpacing:MainNav.kt$//todo add more composable screens + CommentSpacing:MoonPayWidgeLauncher.kt$MoonPayWidgetLauncherViewModel$//replace base url from buy.moonpay.com + CommentSpacing:MoonpayBuyWidget.kt$//TODO: wip here + CommentSpacing:NewKeyStoreTests.kt$//@RunWith(AndroidJUnit4.class) + CommentSpacing:NewKeyStoreTests.kt$//import android.app.Activity; + CommentSpacing:NewKeyStoreTests.kt$//import android.security.keystore.UserNotAuthenticatedException; + CommentSpacing:NewKeyStoreTests.kt$//import androidx.test.ext.junit.runners.AndroidJUnit4; + CommentSpacing:NewKeyStoreTests.kt$//import androidx.test.rule.ActivityTestRule; + CommentSpacing:NewKeyStoreTests.kt$//import com.breadwallet.presenter.activities.settings.TestActivity; + CommentSpacing:NewKeyStoreTests.kt$//import com.breadwallet.tools.security.BRKeyStore; + CommentSpacing:NewKeyStoreTests.kt$//import org.junit.Assert; + CommentSpacing:NewKeyStoreTests.kt$//import org.junit.Before; + CommentSpacing:NewKeyStoreTests.kt$//import org.junit.Rule; + CommentSpacing:NewKeyStoreTests.kt$//import org.junit.Test; + CommentSpacing:NewKeyStoreTests.kt$//import org.junit.runner.RunWith; + CommentSpacing:NewKeyStoreTests.kt$//import static com.breadwallet.tools.security.BRKeyStore.PHRASE_ALIAS; + CommentSpacing:NewKeyStoreTests.kt$//import static com.breadwallet.tools.security.BRKeyStore.aliasObjectMap; + CommentSpacing:NewKeyStoreTests.kt$//} + CommentSpacing:NotificationHandlerTest.kt$NotificationHandlerTest$//dev: filtering until a multi OS test is decided + CommentSpacing:NotificationHandlerTest.kt$NotificationHandlerTest$//todo: revisit, test still fail because specific platform API e.g. android.app.Notification$Builder + CommentSpacing:PasscodeKeypad.kt$//hardcoded false for now + CommentSpacing:PasscodeKeypad.kt$//pin number button + CommentSpacing:ProdAPIManagerTests.kt$ProdAPIManagerTests$//TODO: need update this test after refactor + CommentSpacing:ReadyScreen.kt$/// Layout values + CommentSpacing:ReceiveDialog.kt$//buy / receive + CommentSpacing:ReceiveDialog.kt$//invert surface + CommentSpacing:ReceiveDialog.kt$//moonpay widget + CommentSpacing:ReceiveDialog.kt$//todo: revisit this later + CommentSpacing:ReceiveDialog.kt$//viewModel.onEvent(ReceiveDialogEvent.OnMoonpayButtonClick) + CommentSpacing:ReceiveDialogState.kt$//3 will be custom + CommentSpacing:ReceiveDialogState.kt$//default is 10X + CommentSpacing:ReceiveDialogState.kt$ReceiveDialogState$//default is 10X, other [min, 10x, max, custom] + CommentSpacing:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$//default to 10X + CommentSpacing:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$//do validation + CommentSpacing:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$//todo: wip + CommentSpacing:RemoteApiSource.kt$RemoteApiSource$//TODO + CommentSpacing:ReplicatedKVStoreTest.kt$ReplicatedKVStoreTest$//TODO: pls fill this + CommentSpacing:SecurityDetail.kt$/// Layout values + CommentSpacing:SecurityDetail.kt$//TODO + CommentSpacing:SeedWordItem.kt$/// + CommentSpacing:SeedWordItem.kt$//todo: change with materialtheme so it will be adapt automatically when switch darkmode + CommentSpacing:SeedWordTests.kt$//@RunWith(AndroidJUnit4.class) + CommentSpacing:SeedWordTests.kt$//import android.util.Log; + CommentSpacing:SeedWordTests.kt$//import androidx.test.ext.junit.runners.AndroidJUnit4; + CommentSpacing:SeedWordTests.kt$//import androidx.test.filters.LargeTest; + CommentSpacing:SeedWordTests.kt$//import com.breadwallet.tools.util.Bip39Reader; + CommentSpacing:SeedWordTests.kt$//import com.breadwallet.wallet.BRWalletManager; + CommentSpacing:SeedWordTests.kt$//import java.io.IOException; + CommentSpacing:SeedWordTests.kt$//import java.io.InputStream; + CommentSpacing:SeedWordTests.kt$//import java.util.ArrayList; + CommentSpacing:SeedWordTests.kt$//import java.util.Arrays; + CommentSpacing:SeedWordTests.kt$//import java.util.List; + CommentSpacing:SeedWordTests.kt$//import org.apache.commons.io.IOUtils; + CommentSpacing:SeedWordTests.kt$//import org.junit.Assert; + CommentSpacing:SeedWordTests.kt$//import org.junit.Test; + CommentSpacing:SeedWordTests.kt$//import org.junit.runner.RunWith; + CommentSpacing:SeedWordTests.kt$//import static org.hamcrest.Matchers.is; + CommentSpacing:SeedWordTests.kt$//import static org.hamcrest.Matchers.notNullValue; + CommentSpacing:SeedWordTests.kt$//import static org.junit.Assert.assertThat; + CommentSpacing:SeedWordTests.kt$//package com.brainwallet + CommentSpacing:SeedWordsLayout.kt$//fixed 3 + CommentSpacing:SelectedPeersRepositoryImpl.kt$SelectedPeersRepositoryImpl.<no name provided>$//filter criteria + CommentSpacing:SelectedPeersRepositoryImpl.kt$SelectedPeersRepositoryImpl.<no name provided>$//just return empty if failed or need hardcoded? + CommentSpacing:SetPasscodeScreen.kt$/// Layout values + CommentSpacing:SetPasscodeState.kt$SetPasscodeState$//create 4 digit + CommentSpacing:SetPasscodeViewModel.kt$SetPasscodeViewModel$//if passcode all filled, then goto confirm + CommentSpacing:SetPasscodeViewModel.kt$SetPasscodeViewModel$//if passcode confirm all filled, then goto your seed words + CommentSpacing:SettingRowItem.kt$/// Layout values + CommentSpacing:SettingsState.kt$SettingsState$//-1 = need to fetch + CommentSpacing:SyncBlockWorker.kt$SyncBlockWorker$//todo: maybe need ongoing notification? + CommentSpacing:Theme.kt$//default + CommentSpacing:Theme.kt$//provide compose theme wrapper for transition + CommentSpacing:Theme.kt$BrainwalletTheme$//todo: add typography, shape? for the design system + CommentSpacing:TopUpScreen.kt$/// Layout values + CommentSpacing:TransactionDataItem.kt$TransactionDataItem$///Refactored Transaction data item. Replaces TxItem + CommentSpacing:UnLockEvent.kt$//todo + CommentSpacing:UnLockScreenBody.kt$//for now just toast + CommentSpacing:UnLockScreenBody.kt$//provide old logic here, its like on the BrainwalletActivity.onUnlock + CommentSpacing:UnLockState.kt$//todo + CommentSpacing:UnLockState.kt$UnLockState$//4 digit passcode/pin + CommentSpacing:UnLockViewModel.kt$UnLockViewModel$//if update pin from drawer + CommentSpacing:WelcomeScreen.kt$//fiat/currency selector + CommentSpacing:WelcomeScreen.kt$//language selector + CommentSpacing:WelcomeScreen.kt$//todo: the following sizing can be move to BrainwalletTheme + CommentSpacing:WelcomeState.kt$WelcomeState$//-1 = need to fetch + CommentSpacing:WelcomeViewModel.kt$WelcomeViewModel$//TODO: revisit this later + CommentSpacing:WheelPicker.kt$//default + CommentSpacing:WheelPicker.kt$//state + CommentSpacing:YourSeedProveItScreen.kt$/// Layout values + CommentSpacing:YourSeedWordsScreen.kt$/// Layout values + CommentSpacing:YourSeedWordsScreen.kt$//todo: yuana private key text need to open dialog? + ComposableParamOrder:CurrencyDetail.kt$CurrencyDetail + ComposableParamOrder:Foundation.kt$BrainwalletTopAppBar + ComposableParamOrder:LanguageDetail.kt$LanguageDetail + ComposableParamOrder:LargeButton.kt$BorderedLargeButton + ComposableParamOrder:LargeButton.kt$LargeButton + ComposableParamOrder:LitecoinBlockchainDetail.kt$LitecoinBlockchainDetail + ComposableParamOrder:MainNav.kt$MainNavHost + ComposableParamOrder:MediumButton.kt$MediumTextButton + ComposableParamOrder:SeedWordItem.kt$SeedWordItem + ComposableParamOrder:SeedWordItem.kt$SeedWordItemTextField + ComposableParamOrder:SettingRowItem.kt$SettingRowItem + ComposableParamOrder:SettingRowItem.kt$SettingRowItemExpandable + ComposableParamOrder:WheelPicker.kt$ItemSizeBox + ComposableParamOrder:WheelPicker.kt$SafeBox + ComposableParamOrder:WheelPicker.kt$VerticalWheelPicker + FinalNewline:AppSetting.kt$com.brainwallet.data.model.AppSetting.kt + FinalNewline:BRKeyStoreTest.kt$com.brainwallet.tools.security.BRKeyStoreTest.kt + FinalNewline:BackupRateFetchTests.kt$com.brainwallet.currency.BackupRateFetchTests.kt + FinalNewline:Bip39ReaderTest.kt$com.brainwallet.tools.util.Bip39ReaderTest.kt + FinalNewline:BrainwalletActivity.kt$com.brainwallet.ui.BrainwalletActivity.kt + FinalNewline:BrainwalletMessagingService.kt$com.brainwallet.notification.BrainwalletMessagingService.kt + FinalNewline:BrainwalletViewModel.kt$com.brainwallet.ui.BrainwalletViewModel.kt + FinalNewline:BuyLitecoinEvent.kt$com.brainwallet.ui.screens.buylitecoin.BuyLitecoinEvent.kt + FinalNewline:BuyLitecoinScreen.kt$com.brainwallet.ui.screens.buylitecoin.BuyLitecoinScreen.kt + FinalNewline:BuyLitecoinViewModel.kt$com.brainwallet.ui.screens.buylitecoin.BuyLitecoinViewModel.kt + FinalNewline:CipherBox.kt$com.brainwallet.util.cryptography.CipherBox.kt + FinalNewline:CipherStorage.kt$com.brainwallet.util.cryptography.CipherStorage.kt + FinalNewline:CircleButton.kt$com.brainwallet.ui.composable.CircleButton.kt + FinalNewline:Color.kt$com.brainwallet.ui.theme.Color.kt + FinalNewline:Country.kt$com.brainwallet.data.model.Country.kt + FinalNewline:CurrencyDetail.kt$com.brainwallet.ui.screens.home.composable.settingsrows.CurrencyDetail.kt + FinalNewline:CurrencyEntity.kt$com.brainwallet.data.model.CurrencyEntity.kt + FinalNewline:CurrencyUpdateWorker.kt$com.brainwallet.worker.CurrencyUpdateWorker.kt + FinalNewline:ExampleTest.kt$com.brainwallet.example.ExampleTest.kt + FinalNewline:FiatSelectorBottomSheet.kt$com.brainwallet.ui.composable.bottomsheet.FiatSelectorBottomSheet.kt + FinalNewline:Font.kt$com.brainwallet.ui.theme.Font.kt + FinalNewline:GamesDetail.kt$com.brainwallet.ui.screens.home.composable.settingsrows.GamesDetail.kt + FinalNewline:GoogleServicesTests.kt$com.brainwallet.tools.util.GoogleServicesTests.kt + FinalNewline:HistoryScreen.kt$com.brainwallet.ui.screens.home.history.HistoryScreen.kt + FinalNewline:HomeSettingDrawerSheet.kt$com.brainwallet.ui.screens.home.composable.HomeSettingDrawerSheet.kt + FinalNewline:InputWordsEvent.kt$com.brainwallet.ui.screens.inputwords.InputWordsEvent.kt + FinalNewline:InputWordsState.kt$com.brainwallet.ui.screens.inputwords.InputWordsState.kt + FinalNewline:KeyStoreKeyGenerator.kt$com.brainwallet.util.cryptography.KeyStoreKeyGenerator.kt + FinalNewline:KeyStoreManager.kt$com.brainwallet.util.cryptography.KeyStoreManager.kt + FinalNewline:LanguageDetail.kt$com.brainwallet.ui.screens.home.composable.settingsrows.LanguageDetail.kt + FinalNewline:LanguageSelectorBottomSheet.kt$com.brainwallet.ui.composable.bottomsheet.LanguageSelectorBottomSheet.kt + FinalNewline:LargeButton.kt$com.brainwallet.ui.composable.LargeButton.kt + FinalNewline:LoadingDialog.kt$com.brainwallet.ui.composable.LoadingDialog.kt + FinalNewline:LocalCacheSource.kt$com.brainwallet.data.source.LocalCacheSource.kt + FinalNewline:LocaleHelperTest.kt$com.brainwallet.tools.util.LocaleHelperTest.kt + FinalNewline:LockSettingRowItem.kt$com.brainwallet.ui.screens.home.composable.settingsrows.LockSettingRowItem.kt + FinalNewline:LtcRepository.kt$com.brainwallet.data.repository.LtcRepository.kt + FinalNewline:MessagingTopicUseCase.kt$com.brainwallet.domain.MessagingTopicUseCase.kt + FinalNewline:MoonpayBuyButton.kt$com.brainwallet.ui.composable.MoonpayBuyButton.kt + FinalNewline:MoonpayBuyWidget.kt$com.brainwallet.ui.composable.MoonpayBuyWidget.kt + FinalNewline:MoonpayCurrencyLimit.kt$com.brainwallet.data.model.MoonpayCurrencyLimit.kt + FinalNewline:NotificationHandlerTest.kt$com.brainwallet.notification.NotificationHandlerTest.kt + FinalNewline:PaperKeyActivity.kt$com.brainwallet.presenter.activities.PaperKeyActivity.kt + FinalNewline:PasscodeKeypad.kt$com.brainwallet.ui.composable.PasscodeKeypad.kt + FinalNewline:PermissionUtil.kt$com.brainwallet.util.PermissionUtil.kt + FinalNewline:PinDotItem.kt$com.brainwallet.ui.composable.PinDotItem.kt + FinalNewline:ProdAPIManagerTests.kt$com.brainwallet.tools.util.ProdAPIManagerTests.kt + FinalNewline:QuickFiatAmountOption.kt$com.brainwallet.data.model.QuickFiatAmountOption.kt + FinalNewline:ReadyEvent.kt$com.brainwallet.ui.screens.ready.ReadyEvent.kt + FinalNewline:ReceiveDialogEvent.kt$com.brainwallet.ui.screens.home.receive.ReceiveDialogEvent.kt + FinalNewline:ReceiveDialogState.kt$com.brainwallet.ui.screens.home.receive.ReceiveDialogState.kt + FinalNewline:ReceiveDialogViewModel.kt$com.brainwallet.ui.screens.home.receive.ReceiveDialogViewModel.kt + FinalNewline:RemoteApiSource.kt$com.brainwallet.data.source.RemoteApiSource.kt + FinalNewline:RemoteConfigSource.kt$com.brainwallet.data.source.RemoteConfigSource.kt + FinalNewline:ReplicatedKVStoreTest.kt$com.brainwallet.tools.security.ReplicatedKVStoreTest.kt + FinalNewline:Route.kt$com.brainwallet.navigation.Route.kt + FinalNewline:SecurityDetail.kt$com.brainwallet.ui.screens.home.composable.settingsrows.SecurityDetail.kt + FinalNewline:SeedWordItem.kt$com.brainwallet.ui.composable.SeedWordItem.kt + FinalNewline:SeedWordsLayout.kt$com.brainwallet.ui.composable.SeedWordsLayout.kt + FinalNewline:SelectedPeersRepository.kt$com.brainwallet.data.repository.SelectedPeersRepository.kt + FinalNewline:ServiceItems.kt$com.brainwallet.presenter.entities.ServiceItems.kt + FinalNewline:SetPasscodeEvent.kt$com.brainwallet.ui.screens.setpasscode.SetPasscodeEvent.kt + FinalNewline:SetPasscodeViewModel.kt$com.brainwallet.ui.screens.setpasscode.SetPasscodeViewModel.kt + FinalNewline:SettingRepository.kt$com.brainwallet.data.repository.SettingRepository.kt + FinalNewline:SettingRowItem.kt$com.brainwallet.ui.screens.home.composable.settingsrows.SettingRowItem.kt + FinalNewline:SettingsEvent.kt$com.brainwallet.ui.screens.home.SettingsEvent.kt + FinalNewline:SettingsState.kt$com.brainwallet.ui.screens.home.SettingsState.kt + FinalNewline:SettingsViewModel.kt$com.brainwallet.ui.screens.home.SettingsViewModel.kt + FinalNewline:SyncBlockWorker.kt$com.brainwallet.worker.SyncBlockWorker.kt + FinalNewline:Theme.kt$com.brainwallet.ui.theme.Theme.kt + FinalNewline:ThemeSettingRowItem.kt$com.brainwallet.ui.screens.home.composable.settingsrows.ThemeSettingRowItem.kt + FinalNewline:TopUpScreen.kt$com.brainwallet.ui.screens.topup.TopUpScreen.kt + FinalNewline:UnLockEvent.kt$com.brainwallet.ui.screens.unlock.UnLockEvent.kt + FinalNewline:WelcomeEvent.kt$com.brainwallet.ui.screens.welcome.WelcomeEvent.kt + FinalNewline:WelcomeScreen.kt$com.brainwallet.ui.screens.welcome.WelcomeScreen.kt + FinalNewline:WelcomeViewModel.kt$com.brainwallet.ui.screens.welcome.WelcomeViewModel.kt + FinalNewline:WheelPicker.kt$com.brainwallet.ui.composable.WheelPicker.kt + FinalNewline:YourSeedProveItEvent.kt$com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItEvent.kt + FinalNewline:YourSeedProveItScreen.kt$com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItScreen.kt + FinalNewline:YourSeedProveItState.kt$com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItState.kt + FinalNewline:YourSeedProveItViewModel.kt$com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel.kt + FinalNewline:YourSeedWordsEvent.kt$com.brainwallet.ui.screens.yourseedwords.YourSeedWordsEvent.kt + FinalNewline:YourSeedWordsScreen.kt$com.brainwallet.ui.screens.yourseedwords.YourSeedWordsScreen.kt + FinalNewline:YourSeedWordsViewModel.kt$com.brainwallet.ui.screens.yourseedwords.YourSeedWordsViewModel.kt + FunctionStartOfBodySpacing:BRConstantsTest.kt$BRConstantsTest$@Test fun `validate App external URL constant`() + FunctionStartOfBodySpacing:BRConstantsTest.kt$BRConstantsTest$@Test fun `validate Firebase Analytics constants`() + Indentation:AppModule.kt$AppModule$ + Indentation:CurrencyDetail.kt$ + Indentation:FiatSelectorBottomSheet.kt$ + Indentation:FragmentMoonpay.kt$FragmentMoonpay$ + Indentation:FragmentSend.kt$FragmentSend$ + Indentation:HomeSettingDrawerSheet.kt$ + Indentation:MoonPayWidgeLauncher.kt$MoonPayWidgetLauncherViewModel$ + Indentation:PinDotItem.kt$ + Indentation:RecoverActivity.kt$RecoverActivity$ + Indentation:UnLockScreen.kt$ + Indentation:UnLockScreenFooter.kt$ + Indentation:UnLockViewModelTest.kt$UnLockViewModelTest$ + MaxLineLength:CountryLanguageAdapter.kt$CountryLanguageAdapter$class + MaxLineLength:FragmentSend.kt$FragmentSend$if + MaxLineLength:HomeSettingDrawerSheet.kt$lastSyncMetadata = syncAnalyticsRepository.getLastSyncMetadata() + MaxLineLength:KeyStoreManager.kt$KeyStoreManager$"timber: KeyStoreManager.getData new key in prefs not exists | ${aliasObject.alias}, ${aliasObject.datafileName}, ${aliasObject.ivFileName}" + MaxLineLength:YourSeedProveItViewModel.kt$YourSeedProveItViewModel$orderCorrected = correctSeedWords.all { (_, seedWordItem) -> seedWordItem.expected == seedWordItem.actual } + MaximumLineLength:CountryLanguageAdapter.kt$CountryLanguageAdapter$class + MaximumLineLength:FragmentSend.kt$FragmentSend$ + MaximumLineLength:HomeSettingDrawerSheet.kt$ + MaximumLineLength:KeyStoreManager.kt$KeyStoreManager$ + MaximumLineLength:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$ + MaximumLineLength:YourSeedProveItViewModel.kt$YourSeedProveItViewModel$ + ModifierMissing:BuyLitecoinScreen.kt$BuyLitecoinScreen + ModifierMissing:FiatSelectorBottomSheet.kt$FiatSelectorBottomSheet + ModifierMissing:HistoryScreen.kt$HistoryScreen + ModifierMissing:HomeScreen.kt$HomeBottomNavBar + ModifierMissing:HomeScreen.kt$HomeScreen + ModifierMissing:HomeScreen.kt$HomeTopBar + ModifierMissing:InputWordsScreen.kt$InputWordsScreen + ModifierMissing:LanguageSelectorBottomSheet.kt$LanguageSelectorBottomSheet + ModifierMissing:LoadingDialog.kt$LoadingDialog + ModifierMissing:PasscodeKeypad.kt$PasscodeKeypad + ModifierMissing:ReadyScreen.kt$ReadyScreen + ModifierMissing:SetPasscodeScreen.kt$SetPasscodeScreen + ModifierMissing:ThemeSettingRowItem.kt$ThemeSettingRowItem + ModifierMissing:TopUpScreen.kt$TopUpScreen + ModifierMissing:WelcomeScreen.kt$WelcomeScreen + ModifierMissing:WheelPicker.kt$DefaultWheelPickerDisplay + ModifierMissing:YourSeedProveItScreen.kt$YourSeedProveItScreen + ModifierMissing:YourSeedWordsScreen.kt$YourSeedWordsScreen + ModifierReused:SeedWordItem.kt$Box(modifier = modifier) { Row( modifier = modifier .background( color = BrainwalletTheme.colors.background.copy(alpha = 0.3f), shape = MaterialTheme.shapes.extraLarge ) .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically ) { content.invoke(this) } } + ModifierReused:SeedWordItem.kt$Row( modifier = modifier .background( color = BrainwalletTheme.colors.background.copy(alpha = 0.3f), shape = MaterialTheme.shapes.extraLarge ) .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically ) { content.invoke(this) } + ModifierWithoutDefault:WheelPicker.kt$modifier + MultiLineIfElse:CipherBox.kt$CipherBox.Impl$GCMParameterSpec(128, iv) + MultiLineIfElse:CipherBox.kt$CipherBox.Impl$IvParameterSpec(iv) + MultiLineIfElse:FragmentSend.kt$FragmentSend$"LTC" + MultiLineIfElse:FragmentSend.kt$FragmentSend$BRSharedPrefs.getIsoSymbol( context ) + MultiLineIfElse:FragmentSend.kt$FragmentSend$selectedIsoCurrencySymbol = savedIsoCurrencySymbol + MultiLineIfElse:LegacyNavigation.kt$LegacyNavigation$BrainwalletActivity.createIntent(from, Route.UnLock()) + MultiLineIfElse:LegacyNavigation.kt$LegacyNavigation$Intent(from, BreadActivity::class.java) + MultiLineIfElse:MoonPayWidgeLauncher.kt$CustomTabsIntent.COLOR_SCHEME_DARK + MultiLineIfElse:MoonPayWidgeLauncher.kt$CustomTabsIntent.COLOR_SCHEME_LIGHT + MultiLineIfElse:ReceiveDialog.kt$quickFiatAmountOption.getFormattedText() + MultiLineIfElse:ReceiveDialog.kt$stringResource(R.string.custom) + MultiLineIfElse:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$event.quickFiatAmountOption.value + MultiLineIfElse:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$it.fiatAmount + NoBlankLineBeforeRbrace:BrainwalletActivity.kt$BrainwalletActivity$ + NoBlankLineBeforeRbrace:BuyLitecoinScreen.kt$ + NoBlankLineBeforeRbrace:BuyLitecoinViewModel.kt$BuyLitecoinViewModel$ + NoBlankLineBeforeRbrace:CipherBox.kt$CipherBox.Impl$ + NoBlankLineBeforeRbrace:CipherStorage.kt$CipherStorageFile$ + NoBlankLineBeforeRbrace:CurrencyDetail.kt$ + NoBlankLineBeforeRbrace:CurrencyUpdateWorker.kt$CurrencyUpdateWorker$ + NoBlankLineBeforeRbrace:ExampleTest.kt$ExampleTest$ + NoBlankLineBeforeRbrace:FirebaseRemoteConfigRepository.kt$FirebaseRemoteConfigRepository.<no name provided>$ + NoBlankLineBeforeRbrace:GamesDetail.kt$ + NoBlankLineBeforeRbrace:HomeScreen.kt$ + NoBlankLineBeforeRbrace:HomeSettingDrawerSheet.kt$ + NoBlankLineBeforeRbrace:InputWordsScreen.kt$ + NoBlankLineBeforeRbrace:InputWordsViewModel.kt$InputWordsViewModel$ + NoBlankLineBeforeRbrace:KeyStoreManager.kt$KeyStoreManager$ + NoBlankLineBeforeRbrace:LitecoinBlockchainDetail.kt$ + NoBlankLineBeforeRbrace:LocaleHelperTest.kt$LocaleHelperTest$ + NoBlankLineBeforeRbrace:LtcRepositoryImpl.kt$LtcRepositoryImpl$ + NoBlankLineBeforeRbrace:MoonpayBuyButton.kt$ + NoBlankLineBeforeRbrace:MoonpayBuyWidget.kt$ + NoBlankLineBeforeRbrace:NotificationHandlerTest.kt$NotificationHandlerTest$ + NoBlankLineBeforeRbrace:PermissionUtil.kt$PermissionUtil$ + NoBlankLineBeforeRbrace:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$ + NoBlankLineBeforeRbrace:RemoteApiSource.kt$RemoteApiSource$ + NoBlankLineBeforeRbrace:Route.kt$Route$ + NoBlankLineBeforeRbrace:SecurityDetail.kt$ + NoBlankLineBeforeRbrace:SeedWordItem.kt$ + NoBlankLineBeforeRbrace:SelectedPeersRepositoryImpl.kt$SelectedPeersRepositoryImpl$ + NoBlankLineBeforeRbrace:SelectedPeersRepositoryImpl.kt$SelectedPeersRepositoryImpl.<no name provided>$ + NoBlankLineBeforeRbrace:SetPasscodeScreen.kt$ + NoBlankLineBeforeRbrace:UnLockScreenBody.kt$ + NoBlankLineBeforeRbrace:UnLockViewModel.kt$UnLockViewModel$ + NoBlankLineBeforeRbrace:WelcomeScreen.kt$ + NoBlankLineBeforeRbrace:WelcomeViewModel.kt$WelcomeViewModel$ + NoBlankLineBeforeRbrace:YourSeedProveItScreen.kt$ + NoConsecutiveBlankLines:AppModule.kt$AppModule$ + NoConsecutiveBlankLines:BRConstantsTest.kt$ + NoConsecutiveBlankLines:BRKeyStoreTest.kt$ + NoConsecutiveBlankLines:BaseFragment.kt$ + NoConsecutiveBlankLines:BaseURLTests.kt$ + NoConsecutiveBlankLines:BrainwalletActivity.kt$ + NoConsecutiveBlankLines:BrainwalletActivity.kt$BrainwalletActivity$ + NoConsecutiveBlankLines:BuyLitecoinScreen.kt$ + NoConsecutiveBlankLines:CertificateChainNotFound.kt$ + NoConsecutiveBlankLines:CipherBox.kt$ + NoConsecutiveBlankLines:CountryLanguageAdapter.kt$CountryLanguageAdapter$ + NoConsecutiveBlankLines:EventBus.kt$ + NoConsecutiveBlankLines:EventBus.kt$EventBus$ + NoConsecutiveBlankLines:EventBus.kt$EventBus.Event$ + NoConsecutiveBlankLines:ExampleTest.kt$ExampleTest$ + NoConsecutiveBlankLines:Fee.kt$ + NoConsecutiveBlankLines:FiatSelectorBottomSheet.kt$ + NoConsecutiveBlankLines:FragmentSend.kt$ + NoConsecutiveBlankLines:GoogleServicesTests.kt$ + NoConsecutiveBlankLines:InputWordsScreen.kt$ + NoConsecutiveBlankLines:KeyStoreManager.kt$KeyStoreManager$ + NoConsecutiveBlankLines:Language.kt$ + NoConsecutiveBlankLines:LanguageAdapter.kt$ + NoConsecutiveBlankLines:LanguageDetail.kt$ + NoConsecutiveBlankLines:LocaleHelperTest.kt$LocaleHelperTest$ + NoConsecutiveBlankLines:MainNav.kt$ + NoConsecutiveBlankLines:MoonpayBuyWidget.kt$ + NoConsecutiveBlankLines:NotificationHandlerTest.kt$ + NoConsecutiveBlankLines:PaymentRequestExpiredException.kt$ + NoConsecutiveBlankLines:QuickFiatAmountOption.kt$ + NoConsecutiveBlankLines:ReadyScreen.kt$ + NoConsecutiveBlankLines:ReceiveDialog.kt$ + NoConsecutiveBlankLines:ReceiveDialogState.kt$ + NoConsecutiveBlankLines:Route.kt$ + NoConsecutiveBlankLines:SeedWordItem.kt$ + NoConsecutiveBlankLines:SeedWordTests.kt$ + NoConsecutiveBlankLines:SettingRepositoryImpl.kt$SettingRepositoryImpl$ + NoConsecutiveBlankLines:SettingRowItem.kt$ + NoConsecutiveBlankLines:Theme.kt$ + NoConsecutiveBlankLines:TopUpScreen.kt$ + NoConsecutiveBlankLines:Type.kt$ + NoConsecutiveBlankLines:UnLockViewModelTest.kt$UnLockViewModelTest$ + NoConsecutiveBlankLines:WelcomeScreen.kt$ + NoConsecutiveBlankLines:WheelPicker.kt$ + NoConsecutiveBlankLines:YourSeedProveItScreen.kt$ + NoEmptyClassBody:BRKeyStoreTest.kt$BRKeyStoreTest${ } + NoEmptyClassBody:DatabaseTests.kt$DatabaseTests${ } + NoEmptyClassBody:Font.kt$Font${ } + NoEmptyClassBody:NewKeyStoreTests.kt$NewKeyStoreTests${ } + NoEmptyClassBody:SeedWordTests.kt$SeedWordTests${ } + NoEmptyClassBody:TransactionDataSourceTest.kt$TransactionDataSourceTest${} + NoEmptyFirstLineInMethodBlock:BuyLitecoinScreen.kt$ + NoEmptyFirstLineInMethodBlock:CurrencyTests.kt$CurrencyTests$ + NoEmptyFirstLineInMethodBlock:FirebaseRemoteConfigRepositoryTest.kt$FirebaseRemoteConfigRepositoryTest$ + NoEmptyFirstLineInMethodBlock:GamesDetail.kt$ + NoEmptyFirstLineInMethodBlock:GoogleServicesTests.kt$GoogleServicesTest$ + NoEmptyFirstLineInMethodBlock:InputWordsScreen.kt$ + NoEmptyFirstLineInMethodBlock:LitecoinBlockchainDetail.kt$ + NoEmptyFirstLineInMethodBlock:NotificationHandlerTest.kt$NotificationHandlerTest$ + NoEmptyFirstLineInMethodBlock:ReceiveDialog.kt$ + NoEmptyFirstLineInMethodBlock:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$ + NoEmptyFirstLineInMethodBlock:SecurityDetail.kt$ + NoEmptyFirstLineInMethodBlock:TopUpScreen.kt$ + NoEmptyFirstLineInMethodBlock:UnLockViewModel.kt$UnLockViewModel$ + NoEmptyFirstLineInMethodBlock:WelcomeScreen.kt$ + NoEmptyFirstLineInMethodBlock:WheelPicker.kt$ + NoMultipleSpaces:Fee.kt$ + NoSemicolons:BRConstantsTest.kt$BRConstantsTest$; + NoSemicolons:CountryLanguageAdapter.kt$CountryLanguageAdapter$; + NoSemicolons:FragmentBalanceSeedReminder.kt$FragmentBalanceSeedReminder$; + NoSemicolons:FragmentMoonpay.kt$FragmentMoonpay$; + NoSemicolons:FragmentSend.kt$FragmentSend$; + NoSemicolons:HistoryFragment.kt$HistoryFragment$; + NoSemicolons:TransactionDataItem.kt$TransactionDataItem$; + NoTrailingSpaces:CurrencyDataGetterTest.kt$CurrencyDataGetterTest$ + NoTrailingSpaces:MediumButton.kt$ + NoTrailingSpaces:MessagingTopicDataSource.kt$MessagingTopicDataSource$ + NoTrailingSpaces:ReplicatedKVStoreTest.kt$ + NoUnusedImports:BRKeyStoreTest.kt$com.brainwallet.tools.security.BRKeyStoreTest.kt + NoUnusedImports:BackupRateFetchTests.kt$com.brainwallet.currency.BackupRateFetchTests.kt + NoUnusedImports:BaseURLTests.kt$com.brainwallet.data.BaseURLTests.kt + NoUnusedImports:FiatSelectorBottomSheet.kt$com.brainwallet.ui.composable.bottomsheet.FiatSelectorBottomSheet.kt + NoUnusedImports:Font.kt$com.brainwallet.ui.theme.Font.kt + NoUnusedImports:FragmentBalanceSeedReminder.kt$com.brainwallet.presenter.fragments.FragmentBalanceSeedReminder.kt + NoUnusedImports:FragmentMoonpay.kt$com.brainwallet.presenter.fragments.FragmentMoonpay.kt + NoUnusedImports:GoogleServicesTests.kt$com.brainwallet.tools.util.GoogleServicesTests.kt + NoUnusedImports:LegacyNavigation.kt$com.brainwallet.navigation.LegacyNavigation.kt + NoUnusedImports:LitecoinBlockchainDetail.kt$com.brainwallet.ui.screens.home.composable.settingsrows.LitecoinBlockchainDetail.kt + NoUnusedImports:LoadingDialog.kt$com.brainwallet.ui.composable.LoadingDialog.kt + NoUnusedImports:MediumButton.kt$com.brainwallet.ui.composable.MediumButton.kt + NoUnusedImports:NewKeyStoreTests.kt$com.brainwallet.tools.security.NewKeyStoreTests.kt + NoUnusedImports:ProdAPIManagerTests.kt$com.brainwallet.tools.util.ProdAPIManagerTests.kt + NoUnusedImports:ReceiveDialogFragment.kt$com.brainwallet.ui.screens.home.receive.ReceiveDialogFragment.kt + NoUnusedImports:RoundedBottomSheetDialogFragment.kt$com.brainwallet.ui.RoundedBottomSheetDialogFragment.kt + NoUnusedImports:TopUpScreen.kt$com.brainwallet.ui.screens.topup.TopUpScreen.kt + NoUnusedImports:Type.kt$com.brainwallet.ui.theme.Type.kt + NoUnusedImports:UnLockScreen.kt$com.brainwallet.ui.screens.unlock.UnLockScreen.kt + NoUnusedImports:UnLockScreenBody.kt$com.brainwallet.ui.screens.unlock.components.UnLockScreenBody.kt + NoUnusedImports:WelcomeScreen.kt$com.brainwallet.ui.screens.welcome.WelcomeScreen.kt + NoWildcardImports:FragmentBalanceSeedReminder.kt$import android.widget.* + ParameterListWrapping:FragmentMoonpay.kt$FragmentMoonpay$( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ) + ParameterListWrapping:HomeSettingDrawerSheet.kt$HomeSettingDrawerComposeView$( context: Context, attrs: AttributeSet? = null ) + ParameterListWrapping:KeyStoreKeyGeneratorImpl.kt$KeyStoreKeyGeneratorImpl$( builder: KeyGenParameterSpec.Builder, authTimeout: Int? ) + ParameterListWrapping:SeedWordItem.kt$( modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) + SerialVersionUIDInSerializableClass:CurrencyEntity.kt$CurrencyEntity : Serializable + SpacingAroundColon:CountryLanguageAdapter.kt$CountryLanguageAdapter$: + SpacingAroundColon:IntroLanguage.kt$IntroLanguage$: + SpacingAroundColon:UiEffect.kt$UiEffect.ShowDialog$: + SpacingAroundColon:UiEffect.kt$UiEffect.ShowMoonPayDialog$: + SpacingAroundComma:BRConstantsTest.kt$BRConstantsTest$, + SpacingAroundComma:CountryLanguageAdapter.kt$CountryLanguageAdapter$, + SpacingAroundCurly:BRConstantsTest.kt$BRConstantsTest${ + SpacingAroundKeyword:CountryLanguageAdapter.kt$CountryLanguageAdapter$if + SpacingAroundKeyword:FragmentBalanceSeedReminder.kt$FragmentBalanceSeedReminder$else + SpacingAroundKeyword:HistoryFragment.kt$HistoryFragment$else + SpacingAroundKeyword:LanguageSelectorBottomSheet.kt$if + SpacingAroundKeyword:YourSeedProveItScreen.kt$<no name provided>$else + SpacingAroundOperators:CurrencyEntity.kt$CurrencyEntity$= + SpacingAroundOperators:LanguageSelectorBottomSheet.kt$- + SpacingAroundParens:DarkModeToggleButton.kt$) + SpacingAroundParens:Language.kt$Language$( + SpacingBetweenDeclarationsWithAnnotations:GoogleServicesTests.kt$GoogleServicesTest$@Test fun `read GoogleServices file and parse into a JSON object , should return the correct project_id`() + SpacingBetweenDeclarationsWithAnnotations:MediumButton.kt$@Preview @Composable fun MediumTextButtonPreview() + StringTemplate:CipherStorage.kt$CipherStorageFile$${fileName} + StringTemplate:KeyStoreManager.kt$KeyStoreManager$${decryptedData} + StringTemplate:ReceiveDialogViewModel.kt$ReceiveDialogViewModel$${address} + UnstableCollections:LitecoinBlockchainDetail.kt$List<FeeOption> + UnstableCollections:PasscodeIndicator.kt$List<Int> + UnstableCollections:SeedWordItem.kt$List<String> + UnstableCollections:SetPasscodeScreen.kt$List<Int> + UnstableCollections:UnLockScreenBody.kt$List<Int> + UnstableCollections:YourSeedProveItScreen.kt$List<String> + UnstableCollections:YourSeedWordsScreen.kt$List<String> + UnusedPrivateMember:BrainWalletLogo.kt$@PreviewLightDark @Composable private fun BrainWalletLogoPreview() + UnusedPrivateMember:DarkModeToggleButton.kt$@PreviewLightDark @Composable private fun DarkModeToggleButtonPreview() + UnusedPrivateMember:PaperKeyActivity.kt$PaperKeyActivity$private fun onSavedItClick() + UnusedPrivateMember:ReceiveDialog.kt$@PreviewLightDark @Composable private fun ReceiveDialogPreview() + UnusedPrivateMember:UnLockScreen.kt$@PreviewLightDark @Composable private fun UnLockScreenPreview() + UnusedPrivateMember:UnLockScreenBody.kt$@PreviewLightDark @Composable private fun UnLockScreenBodyPreview() + UnusedPrivateMember:UnLockScreenFooter.kt$@PreviewLightDark @Composable private fun UnLockScreenFooterPreview() + UnusedPrivateMember:UnLockScreenHeader.kt$@PreviewLightDark @Composable private fun UnLockScreenHeaderPreview() + WildcardImport:FragmentBalanceSeedReminder.kt$import android.widget.* + Wrapping:AppModule.kt$AppModule$( + Wrapping:CurrencyDetail.kt$( + Wrapping:CurrencyDetail.kt$(colors = ListItemDefaults.colors( containerColor = BrainwalletTheme.colors.background, headlineColor = BrainwalletTheme.colors.content, ), modifier = Modifier.clickable { onFiatSelect.invoke(currency) }, headlineContent = { Row { Text( modifier = Modifier.padding(tinyPad.dp), text = currency.name, style = MaterialTheme.typography.labelMedium .copy(textAlign = TextAlign.Left) ) Spacer(modifier = Modifier.weight(1f)) Text( modifier = Modifier.padding(tinyPad.dp), text = "${currency.code} (${currency.symbol})", style = MaterialTheme.typography.labelMedium .copy(textAlign = TextAlign.Left) ) } }, trailingContent = { if (selectedCurrency.code == currency.code) { Icon( Icons.Default.CheckCircle, contentDescription = null, tint = BrainwalletTheme.colors.affirm ) } else { Box( modifier = Modifier .size(unselectedCircleSize.dp) .alpha(0.1f) .clip(CircleShape) .background(BrainwalletTheme.colors.content) ) } }) + Wrapping:FiatSelectorBottomSheet.kt$( + Wrapping:FiatSelectorBottomSheet.kt$(colors = ListItemDefaults.colors( containerColor = BrainwalletTheme.colors.background, headlineColor = BrainwalletTheme.colors.content, ), modifier = Modifier.clickable { onFiatSelect.invoke(currency) }, headlineContent = { Row { Text( modifier = Modifier.padding(tinyPad.dp), text = currency.name, style = BrainwalletTheme.typography.labelLarge .copy(textAlign = TextAlign.Left) ) Spacer(modifier = Modifier.weight(1f)) Text( modifier = Modifier.padding(tinyPad.dp), text = "${currency.code} (${currency.symbol})", style = BrainwalletTheme.typography.labelLarge .copy(textAlign = TextAlign.Left) ) } }, trailingContent = { if (selectedCurrency.code == currency.code) { Icon( Icons.Default.CheckCircle, contentDescription = null, tint = BrainwalletTheme.colors.affirm ) } else { Box( modifier = Modifier .size(unselectedCircleSize.dp) .alpha(0.1f) .clip(CircleShape) .background(BrainwalletTheme.colors.content) ) } }) + Wrapping:FirebaseRemoteConfigRepositoryTest.kt$FirebaseRemoteConfigRepositoryTest$firebaseRemoteConfig.getString(any()) + Wrapping:HomeSettingDrawerSheet.kt$( + Wrapping:MoonPayWidgeLauncher.kt$MoonPayWidgetLauncherViewModel$( + Wrapping:RecoverActivity.kt$RecoverActivity$( + Wrapping:SeedWordItem.kt$( + Wrapping:TransactionDataItem.kt$TransactionDataItem$; + Wrapping:UnLockScreen.kt$( + Wrapping:UnLockViewModelTest.kt$UnLockViewModelTest$( + Wrapping:YourSeedWordsScreen.kt$( + + diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a0f2aba6..f963471d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,4 @@ [versions] -kotlin = "2.0.0" agp = "8.7.3" androidx-core-ktx = "1.12.0" androidx-appcompat = "1.6.1" @@ -30,9 +29,6 @@ jakewarthon-timber = "4.7.1" eclipse-jetty = "9.2.19.v20160908" junit = "4.13.2" mockk = "1.13.13" -koin-bom = "4.0.2" -koin-annotation-bom = "2.1.0" -ksp = "2.0.0-1.0.24" turbine = "1.2.1" coroutines = "1.10.2" slf4j = "1.7.36" @@ -109,17 +105,8 @@ unstoppable-domain = "com.unstoppabledomains:resolution:5.0.0" razir-progressbutton = "com.github.razir.progressbutton:progressbutton:2.1.0" junit = { module = "junit:junit", version.ref = "junit" } mockk = { module = "io.mockk:mockk", version.ref = "mockk" } -pinterest-ktlint = "com.pinterest.ktlint:ktlint-cli:1.5.0" fastlane-screengrab = "tools.fastlane:screengrab:2.1.1" airbnb-lottie-compose = "com.airbnb.android:lottie-compose:6.5.2" -koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koin-bom" } -koin-android = { module = "io.insert-koin:koin-android" } -koin-android-compat = { module = "io.insert-koin:koin-android-compat" } -koin-compose = { module = "io.insert-koin:koin-compose" } -koin-compose-viewmodel = { module = "io.insert-koin:koin-compose-viewmodel" } -koin-annotation-bom = { module = "io.insert-koin:koin-annotations-bom", version.ref = "koin-annotation-bom" } -koin-annotation = { module = "io.insert-koin:koin-annotations" } -koin-annotation-compiler = { module = "io.insert-koin:koin-ksp-compiler", version.ref = "koin-annotation-bom" } turbine = { module = "app.cash.turbine:turbine", version.ref = "turbine" } kotlinx-coroutines-android = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-android", version.ref = "coroutines" } kotlinx-coroutines-tests = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" } @@ -136,17 +123,12 @@ google-play-review = ["google-play-review", "google-play-review-ktx"] eclipse-jetty = ["eclipse-jetty-webapp", "eclipse-jetty-websocket", "eclipse-jetty-continuation"] android-test = ["androidx-test-core", "androidx-test-core-ktx", "androidx-test-rules","androidx-test-espresso-core", "androidx-test-junit-ext","androidx-test-juniext-ext-ktx", "androidx-test-runner", "androidx-test-uiautomator"] androidx-compose-ui-test = ["androidx-compose-ui-test-junit4", "androidx-compose-ui-test-manifest"] -koin = ["koin-android", "koin-android-compat", "koin-compose", "koin-compose-viewmodel"] squareup-retrofit = ["squareup-retrofit", "squareup-retrofit-kotlinx-serialization-json"] squareup-okhttp = ["squareup-okhttp", "squareup-okhttp-logging-interceptor"] [plugins] android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } -jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } -jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } jetbrains-kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version = "2.1.0" } -jetbrains-kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } google-services = { id = "com.google.gms.google-services", version = "4.4.2" } firebase-crashlytics = { id = "com.google.firebase.crashlytics", version = "3.0.2" } -ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 9355b415..d4081da4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gruntsoftware-build-logic b/gruntsoftware-build-logic new file mode 160000 index 00000000..3830b9c8 --- /dev/null +++ b/gruntsoftware-build-logic @@ -0,0 +1 @@ +Subproject commit 3830b9c8e48b54654344de74e3340721103a0388 diff --git a/modules/games b/modules/games index b2cc09df..b9522c15 160000 --- a/modules/games +++ b/modules/games @@ -1 +1 @@ -Subproject commit b2cc09df06d90baa9836b8789c38de569e2e8f8f +Subproject commit b9522c15843722d9689459ec4935f69aad86faa1 diff --git a/settings.gradle.kts b/settings.gradle.kts index 2ee160e5..053ae2b8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,4 +1,5 @@ pluginManagement { + includeBuild("gruntsoftware-build-logic") repositories { google { content { @@ -29,6 +30,11 @@ dependencyResolutionManagement { logger.lifecycle("⚠️ Submodule catalog 'games' not loaded — file not found: $gamesToml") } } + versionCatalogs { + create("grunt") { + from(files("gruntsoftware-build-logic/gradle/libs.versions.toml")) + } + } } rootProject.name = "Brainwallet Android" From 3285d8e727da02c2d79e011042e8265e12664b98 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 29 Sep 2025 16:58:26 +0100 Subject: [PATCH 067/116] Chore/renamed gp module (#140) * Fixed the Git Submodule references * updated gitmodules config * create private gp submodule * Update settings.gradle.kts * chore: Migrate build logic to version catalog and update submodules This commit migrates the project's build logic to use a centralized version catalog (`grunt`) and updates submodule references. Specific changes include: * **Submodule Updates:** * Updated `gruntsoftware-build-logic` submodule pointer. * Updated `modules/private-general-purpose` submodule pointer. * **Build Configuration (`settings.gradle.kts`):** * Removed the conditional loading of the `games` version catalog. * Added a `grunt` version catalog loaded from `gruntsoftware-build-logic/gradle/libs.versions.toml`. * Changed the included module from `:modules:private-general-purpose:content` to `:modules:private-general-purpose:games`. * Removed conditional inclusion logic for `:modules:private-general-purpose:content`. * **Root `build.gradle.kts`:** * Updated plugin aliases from `libs.plugins.android.*` to `grunt.plugins.android.*`. * **App `build.gradle.kts`:** * Updated plugin alias for `com.android.application` from `libs` to `grunt`. * Updated the `games` module dependency to `implementation(project(":modules:private-general-purpose:games"))` and removed the conditional logic for `findProject(":modules:games:content")`. * Updated various dependencies to use the `grunt` version catalog (e.g., `grunt.androidx.core.ktx`, `grunt.androidx.compose.bom`, `grunt.bundles.androidx.compose`, `grunt.material`). * **Version Catalog (`gradle/libs.versions.toml`):** * Removed versions for `agp` and `androidx-core-ktx`. * Removed versions for `androidx-compose-bom`, `androidx-activity-compose`, and `androidx-fragment-compose`. * Removed `androidx-core` library alias. * Removed various `androidx-compose` library aliases and the `androidx-compose` bundle. * Removed `android-application` and `android-library` plugin aliases. * ci: Configure GitHub token for submodules in CircleCI This commit updates the CircleCI configuration to include a step that configures a GitHub token. This token will be used for authenticating access to submodules during the build process. * refactor: Update module paths for 'games' This commit refactors the project structure by moving the 'games' module. - The 'games' module path in `settings.gradle.kts` is changed from `:modules:private-general-purpose:games` to `:games` and its `projectDir` is set to `modules/private-general-purpose/games`. - The dependency path in `app/build.gradle.kts` for the 'games' module is updated from `project(":modules:private-general-purpose:games")` to `project(":games")`. The submodule references for `gruntsoftware-build-logic` and `modules/private-general-purpose` were also updated. --------- Co-authored-by: Joseph Sanjaya --- .circleci/config.yml | 7 +++++-- .gitmodules | 7 +++---- app/build.gradle.kts | 21 ++++++++------------- build.gradle.kts | 4 ++-- gradle/libs.versions.toml | 22 ---------------------- gruntsoftware-build-logic | 2 +- modules/games | 1 - modules/private-general-purpose | 1 + settings.gradle.kts | 20 ++------------------ 9 files changed, 22 insertions(+), 63 deletions(-) delete mode 160000 modules/games create mode 160000 modules/private-general-purpose diff --git a/.circleci/config.yml b/.circleci/config.yml index c074e195..a639a553 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -54,8 +54,11 @@ commands: EOL ls && cat local.properties - run: - name: "Initialize submodule" - command: "git submodule init && git submodule update --init --recursive" + name: Rewrite .gitmodules with token + command: | + sed -i "s#https://github.com/#https://${GH_TOKEN}@github.com/#g" .gitmodules + git submodule sync --recursive + git submodule update --init --recursive - android/restore_gradle_cache # Define a job to be invoked later in a workflow. diff --git a/.gitmodules b/.gitmodules index cf382734..e276968c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,10 +4,9 @@ [submodule "app/src/main/jni/core"] path = app/src/main/jni/core url = https://github.com/brainwallet-co/core.git -[submodule "modules/games"] - path = modules/games - url = https://github.com/gruntsoftware/android-games.git - update = none +[submodule "modules/private-general-purpose"] + path = modules/private-general-purpose + url = https://github.com/gruntsoftware/android-private-general-purpose.git [submodule "gruntsoftware-build-logic"] path = gruntsoftware-build-logic url = https://github.com/gruntsoftware/android-build-logic.git diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 059f36d6..6e0a10b7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,7 +2,7 @@ import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties import org.gradle.kotlin.dsl.grunt plugins { - alias(libs.plugins.android.application) + alias(grunt.plugins.android.application) alias(grunt.plugins.jetbrains.kotlin.android) alias(grunt.plugins.jetbrains.kotlin.compose) alias(libs.plugins.jetbrains.kotlin.kapt) @@ -183,15 +183,9 @@ android { } dependencies { - val gamesModule = findProject(":modules:games:content") - if (gamesModule != null) { - implementation(gamesModule) - } else { - logger.lifecycle("⚠️ Submodule ':modules:games:content' not found — skipping dependency") - } - + implementation(project(":games")) implementation("androidx.webkit:webkit:1.9.0") - implementation(libs.androidx.core) + implementation(grunt.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.androidx.legacy.support) implementation(libs.androidx.recyclerview) @@ -204,8 +198,9 @@ dependencies { implementation(libs.bundles.androidx.lifecycle) implementation(libs.androidx.work) implementation(libs.androidx.browser) - implementation(platform(libs.androidx.compose.bom)) - implementation(libs.bundles.androidx.compose) + implementation(platform(grunt.androidx.compose.bom)) + implementation(grunt.bundles.androidx.compose) + implementation(grunt.material) implementation(libs.google.material) implementation(libs.google.zxing) implementation(platform(libs.firebase.bom)) @@ -243,8 +238,8 @@ dependencies { testImplementation(libs.slf4j.android) testImplementation(libs.kotlinx.coroutines.tests) - androidTestImplementation(platform(libs.androidx.compose.bom)) - androidTestImplementation(libs.bundles.androidx.compose.ui.test) + androidTestImplementation(platform(grunt.androidx.compose.bom)) + androidTestImplementation(grunt.bundles.androidx.compose.ui.test) androidTestImplementation(libs.bundles.android.test) androidTestImplementation(libs.fastlane.screengrab) androidTestImplementation(libs.slf4j.android) diff --git a/build.gradle.kts b/build.gradle.kts index 29ba64f1..10c78c65 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,8 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - alias(libs.plugins.android.application) apply false - alias(libs.plugins.android.library) apply false + alias(grunt.plugins.android.application) apply false + alias(grunt.plugins.android.library) apply false alias(grunt.plugins.jetbrains.kotlin.android) apply false alias(grunt.plugins.jetbrains.kotlin.compose) apply false alias(libs.plugins.jetbrains.kotlin.kapt) apply false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f963471d..909da555 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,6 +1,4 @@ [versions] -agp = "8.7.3" -androidx-core-ktx = "1.12.0" androidx-appcompat = "1.6.1" androidx-legacy-support = "1.0.0" androidx-recyclerview = "1.3.2" @@ -12,9 +10,6 @@ androidx-browser = "1.7.0" androidx-navigation = "2.8.7" #androidx-test-ext = "1.2.1" androidx-lifecycle = "2.7.0" -androidx-compose-bom = "2025.01.00" -androidx-activity-compose = "1.9.3" -androidx-fragment-compose = "1.8.5" androidx-work = "2.9.1" google-material = "1.11.0" google-zxing = "3.5.2" @@ -34,7 +29,6 @@ coroutines = "1.10.2" slf4j = "1.7.36" [libraries] -androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core-ktx" } androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } androidx-legacy-support = { module = "androidx.legacy:legacy-support-v13", version.ref = "androidx-legacy-support" } androidx-navigation-fragment = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "androidx-navigation" } @@ -56,18 +50,6 @@ androidx-test-rules = "androidx.test:rules:1.6.1" androidx-test-junit-ext = "androidx.test.ext:junit:1.2.1" androidx-test-juniext-ext-ktx = "androidx.test.ext:junit-ktx:1.2.1" androidx-test-uiautomator = "androidx.test.uiautomator:uiautomator:2.3.0" -androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = "androidx-compose-bom" } -androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" } -androidx-fragment-compose = { module = "androidx.fragment:fragment-compose", version.ref = "androidx-fragment-compose" } -androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" } -androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } -androidx-compose-ui-text-google-fonts = { group = "androidx.compose.ui", name = "ui-text-google-fonts" } -androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } -androidx-compose-navigation = { group = "androidx.navigation", name = "navigation-compose"} -androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } -androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } -androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } -androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-work = { module = "androidx.work:work-runtime-ktx", version.ref = "androidx-work" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.7.1" } google-zxing = { module = "com.google.zxing:core", version.ref = "google-zxing" } @@ -115,20 +97,16 @@ slf4j-android = { module = "org.slf4j:slf4j-android", version.ref = "slf4j" } [bundles] androidx-lifecycle = ["androidx-lifecycle-runtime", "androidx-lifecycle-viewmodel", "androidx-lifecycle-viewmodel-compose"] androidx-navigation = ["androidx-navigation-fragment", "androidx-navigation-ui"] -androidx-compose = ["androidx-activity-compose", "androidx-compose-ui", "androidx-compose-ui-graphics", "androidx-compose-ui-tooling", "androidx-compose-ui-tooling-preview", "androidx-compose-material3", "androidx-compose-ui-text-google-fonts", "androidx-compose-navigation", "androidx-fragment-compose"] firebase = ["firebase-analytics", "firebase-crashlytics", "firebase-crashlytics-ndk", "firebase-messaging", "firebase-inappmessaging", "firebase-config"] google-play-asset-delivery = ["google-play-asset-delivery", "google-play-asset-delivery-ktx"] google-play-feature-delivery = ["google-play-feature-delivery", "google-play-feature-delivery-ktx"] google-play-review = ["google-play-review", "google-play-review-ktx"] eclipse-jetty = ["eclipse-jetty-webapp", "eclipse-jetty-websocket", "eclipse-jetty-continuation"] android-test = ["androidx-test-core", "androidx-test-core-ktx", "androidx-test-rules","androidx-test-espresso-core", "androidx-test-junit-ext","androidx-test-juniext-ext-ktx", "androidx-test-runner", "androidx-test-uiautomator"] -androidx-compose-ui-test = ["androidx-compose-ui-test-junit4", "androidx-compose-ui-test-manifest"] squareup-retrofit = ["squareup-retrofit", "squareup-retrofit-kotlinx-serialization-json"] squareup-okhttp = ["squareup-okhttp", "squareup-okhttp-logging-interceptor"] [plugins] -android-application = { id = "com.android.application", version.ref = "agp" } -android-library = { id = "com.android.library", version.ref = "agp" } jetbrains-kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version = "2.1.0" } google-services = { id = "com.google.gms.google-services", version = "4.4.2" } firebase-crashlytics = { id = "com.google.firebase.crashlytics", version = "3.0.2" } diff --git a/gruntsoftware-build-logic b/gruntsoftware-build-logic index 3830b9c8..1f89f0ba 160000 --- a/gruntsoftware-build-logic +++ b/gruntsoftware-build-logic @@ -1 +1 @@ -Subproject commit 3830b9c8e48b54654344de74e3340721103a0388 +Subproject commit 1f89f0ba6985c09b26b4b966234f67afca5e5808 diff --git a/modules/games b/modules/games deleted file mode 160000 index b9522c15..00000000 --- a/modules/games +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b9522c15843722d9689459ec4935f69aad86faa1 diff --git a/modules/private-general-purpose b/modules/private-general-purpose new file mode 160000 index 00000000..70098b18 --- /dev/null +++ b/modules/private-general-purpose @@ -0,0 +1 @@ +Subproject commit 70098b18f18f031426dc891ac0c48f4c15775912 diff --git a/settings.gradle.kts b/settings.gradle.kts index 053ae2b8..caa876d3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -19,17 +19,6 @@ dependencyResolutionManagement { google() mavenCentral() } - - versionCatalogs { - val gamesToml = file("modules/games/gradle/libs.versions.toml") - if (gamesToml.exists()) { - create("games") { - from(files(gamesToml)) - } - } else { - logger.lifecycle("⚠️ Submodule catalog 'games' not loaded — file not found: $gamesToml") - } - } versionCatalogs { create("grunt") { from(files("gruntsoftware-build-logic/gradle/libs.versions.toml")) @@ -40,10 +29,5 @@ dependencyResolutionManagement { rootProject.name = "Brainwallet Android" include(":app") include(":install_time_asset_pack") - -val gamesDir = file("modules/games/content") -if (gamesDir.exists()) { - include(":modules:games:content") -} else { - logger.lifecycle("⚠️ Submodule ':modules:games:content' not included — folder not found: $gamesDir") -} \ No newline at end of file +include(":games") +project(":games").projectDir = file("modules/private-general-purpose/games") From 94459d0d95146da9a4085c199d3120b8c2616c12 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 23 Sep 2025 17:12:03 +0100 Subject: [PATCH 068/116] create private gp submodule --- modules/private-general-purpose | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/private-general-purpose b/modules/private-general-purpose index 70098b18..a64b5517 160000 --- a/modules/private-general-purpose +++ b/modules/private-general-purpose @@ -1 +1 @@ -Subproject commit 70098b18f18f031426dc891ac0c48f4c15775912 +Subproject commit a64b551768e6024632bc901b6822602c2d3d397b From 13c39a031677fc048ca67d66dffede3952eac17d Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 23 Sep 2025 17:50:41 +0100 Subject: [PATCH 069/116] Update settings.gradle.kts --- settings.gradle.kts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index caa876d3..6bc2ea34 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,5 +29,10 @@ dependencyResolutionManagement { rootProject.name = "Brainwallet Android" include(":app") include(":install_time_asset_pack") -include(":games") -project(":games").projectDir = file("modules/private-general-purpose/games") + +val privateGeneralPurpDir = file("modules/private-general-purpose/content") +if (privateGeneralPurpDir.exists()) { + include(":modules:private-general-purpose:content") +} else { + logger.lifecycle("⚠️ Submodule ':modules:private-general-purpose:content' not included — folder not found: $privateGeneralPurpDir") +} \ No newline at end of file From c0683adcff59f57a6e700d34d21fb6b2eb961c40 Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Wed, 24 Sep 2025 23:32:24 +0700 Subject: [PATCH 070/116] chore: Migrate build logic to version catalog and update submodules This commit migrates the project's build logic to use a centralized version catalog (`grunt`) and updates submodule references. Specific changes include: * **Submodule Updates:** * Updated `gruntsoftware-build-logic` submodule pointer. * Updated `modules/private-general-purpose` submodule pointer. * **Build Configuration (`settings.gradle.kts`):** * Removed the conditional loading of the `games` version catalog. * Added a `grunt` version catalog loaded from `gruntsoftware-build-logic/gradle/libs.versions.toml`. * Changed the included module from `:modules:private-general-purpose:content` to `:modules:private-general-purpose:games`. * Removed conditional inclusion logic for `:modules:private-general-purpose:content`. * **Root `build.gradle.kts`:** * Updated plugin aliases from `libs.plugins.android.*` to `grunt.plugins.android.*`. * **App `build.gradle.kts`:** * Updated plugin alias for `com.android.application` from `libs` to `grunt`. * Updated the `games` module dependency to `implementation(project(":modules:private-general-purpose:games"))` and removed the conditional logic for `findProject(":modules:games:content")`. * Updated various dependencies to use the `grunt` version catalog (e.g., `grunt.androidx.core.ktx`, `grunt.androidx.compose.bom`, `grunt.bundles.androidx.compose`, `grunt.material`). * **Version Catalog (`gradle/libs.versions.toml`):** * Removed versions for `agp` and `androidx-core-ktx`. * Removed versions for `androidx-compose-bom`, `androidx-activity-compose`, and `androidx-fragment-compose`. * Removed `androidx-core` library alias. * Removed various `androidx-compose` library aliases and the `androidx-compose` bundle. * Removed `android-application` and `android-library` plugin aliases. --- app/build.gradle.kts | 2 +- settings.gradle.kts | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 6e0a10b7..39f3d801 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -183,7 +183,7 @@ android { } dependencies { - implementation(project(":games")) + implementation(project(":modules:private-general-purpose:games")) implementation("androidx.webkit:webkit:1.9.0") implementation(grunt.androidx.core.ktx) implementation(libs.androidx.appcompat) diff --git a/settings.gradle.kts b/settings.gradle.kts index 6bc2ea34..f5eee3df 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,10 +29,4 @@ dependencyResolutionManagement { rootProject.name = "Brainwallet Android" include(":app") include(":install_time_asset_pack") - -val privateGeneralPurpDir = file("modules/private-general-purpose/content") -if (privateGeneralPurpDir.exists()) { - include(":modules:private-general-purpose:content") -} else { - logger.lifecycle("⚠️ Submodule ':modules:private-general-purpose:content' not included — folder not found: $privateGeneralPurpDir") -} \ No newline at end of file +include(":modules:private-general-purpose:games") From 2fcb1b22de58afd976ef4b04590418592d38364d Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Mon, 6 Oct 2025 00:27:15 +0700 Subject: [PATCH 071/116] feat(deps): add kotlin-immutable dependency This commit adds the `kotlinx-collections-immutable` library, version 0.4.0, to the project's dependencies. --- app/build.gradle.kts | 20 +++- app/proguard-rules.pro | 2 + app/src/main/AndroidManifest.xml | 9 +- .../java/com/brainwallet/BrainwalletApp.kt | 23 ---- .../brainwallet/initializer/AppInitializer.kt | 49 ++++++++ .../presenter/history/HistoryFooter.kt | 112 ++++++++++++++++++ .../presenter/history/HistoryFragment.kt | 27 ++++- .../history/HistoryFragmentViewModel.kt | 45 +++++++ .../brainwallet/tools/manager/TxManager.java | 23 +++- .../ui/composable/BrainWalletLogo.kt | 4 +- .../brainwallet/ui/composable/CircleButton.kt | 2 +- .../ui/composable/DarkModeToggleButton.kt | 2 +- .../brainwallet/ui/composable/Foundation.kt | 2 +- .../brainwallet/ui/composable/LargeButton.kt | 2 +- .../ui/composable/LoadingDialog.kt | 2 +- .../brainwallet/ui/composable/MediumButton.kt | 2 +- .../ui/composable/MoonpayBuyButton.kt | 6 +- .../brainwallet/ui/composable/PinDotItem.kt | 2 +- .../brainwallet/ui/composable/SeedWordItem.kt | 4 +- .../bottomsheet/FiatSelectorBottomSheet.kt | 2 +- .../LanguageSelectorBottomSheet.kt | 2 +- .../screens/buylitecoin/BuyLitecoinScreen.kt | 2 +- .../home/composable/HomeSettingDrawerSheet.kt | 2 +- .../composable/settingsrows/CurrencyDetail.kt | 2 +- .../composable/settingsrows/LanguageDetail.kt | 2 +- .../settingsrows/LitecoinBlockchainDetail.kt | 2 +- .../composable/settingsrows/SettingRowItem.kt | 4 +- .../ui/screens/home/receive/ReceiveDialog.kt | 2 +- .../ui/screens/inputwords/InputWordsScreen.kt | 2 +- .../unlock/components/UnLockScreenBody.kt | 2 +- .../unlock/components/UnLockScreenFooter.kt | 4 +- .../unlock/components/UnLockScreenHeader.kt | 2 +- .../ui/screens/welcome/WelcomeScreen.kt | 2 +- .../java/com/brainwallet/ui/theme/Color.kt | 23 ---- .../java/com/brainwallet/ui/theme/Font.kt | 17 --- .../java/com/brainwallet/ui/theme/Theme.kt | 100 ++-------------- .../java/com/brainwallet/ui/theme/Type.kt | 86 -------------- .../res/drawable/arrow_down_bold_circle.xml | 8 -- .../res/drawable/arrow_up_bold_circle.xml | 8 -- app/src/main/res/layout/fragment_history.xml | 29 ++++- app/src/main/res/values-ar/strings.xml | 3 + app/src/main/res/values-de/strings.xml | 3 + app/src/main/res/values-es/strings.xml | 3 + app/src/main/res/values-fa/strings.xml | 1 + app/src/main/res/values-fr/strings.xml | 3 + app/src/main/res/values-hi/strings.xml | 3 + app/src/main/res/values-in/strings.xml | 3 + app/src/main/res/values-it/strings.xml | 3 + app/src/main/res/values-ja/strings.xml | 3 + app/src/main/res/values-ko/strings.xml | 3 + app/src/main/res/values-pa/strings.xml | 1 + app/src/main/res/values-pl/strings.xml | 1 + app/src/main/res/values-pt/strings.xml | 3 + app/src/main/res/values-ru/strings.xml | 3 + app/src/main/res/values-sv/strings.xml | 3 + app/src/main/res/values-tr/strings.xml | 3 + app/src/main/res/values-uk/strings.xml | 3 + app/src/main/res/values-zh-rCN/strings.xml | 3 + app/src/main/res/values-zh-rTW/strings.xml | 3 + app/src/main/res/values/strings.xml | 1 + .../initializer/AppInitializerTest.kt | 56 +++++++++ .../history/HistoryFragmentViewModelTest.kt | 39 ++++++ gradle.properties | 2 +- gruntsoftware-build-logic | 2 +- settings.gradle.kts | 6 +- 65 files changed, 492 insertions(+), 306 deletions(-) create mode 100644 app/src/main/java/com/brainwallet/initializer/AppInitializer.kt create mode 100644 app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt create mode 100644 app/src/main/java/com/brainwallet/presenter/history/HistoryFragmentViewModel.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/theme/Color.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/theme/Font.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/theme/Type.kt delete mode 100755 app/src/main/res/drawable/arrow_down_bold_circle.xml delete mode 100755 app/src/main/res/drawable/arrow_up_bold_circle.xml create mode 100644 app/src/test/java/com/brainwallet/initializer/AppInitializerTest.kt create mode 100644 app/src/test/java/com/brainwallet/presenter/history/HistoryFragmentViewModelTest.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 39f3d801..c82c7258 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -164,13 +164,17 @@ android { viewBinding = true compose = true } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.valueOf("VERSION_${grunt.versions.jvm.target.get()}") + targetCompatibility = JavaVersion.valueOf("VERSION_${grunt.versions.jvm.target.get()}") } - kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8.toString() + kotlin { + jvmToolchain(grunt.versions.jvm.target.get().toInt()) + compilerOptions { + jvmTarget.set( + org.jetbrains.kotlin.gradle.dsl.JvmTarget.fromTarget(grunt.versions.jvm.target.get()) + ) + } } packaging { @@ -183,9 +187,12 @@ android { } dependencies { - implementation(project(":modules:private-general-purpose:games")) + implementation(project(":games")) + implementation(project(":iap")) + implementation(project(":core")) implementation("androidx.webkit:webkit:1.9.0") implementation(grunt.androidx.core.ktx) + implementation(grunt.app.startup) implementation(libs.androidx.appcompat) implementation(libs.androidx.legacy.support) implementation(libs.androidx.recyclerview) @@ -200,6 +207,7 @@ dependencies { implementation(libs.androidx.browser) implementation(platform(grunt.androidx.compose.bom)) implementation(grunt.bundles.androidx.compose) + implementation(grunt.kotlin.immutable) implementation(grunt.material) implementation(libs.google.material) implementation(libs.google.zxing) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 44883644..8fd81126 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -41,6 +41,8 @@ -dontwarn org.slf4j.impl.StaticMDCBinder -dontwarn org.slf4j.impl.StaticMarkerBinder -dontwarn java.lang.reflect.AnnotatedType +-dontwarn com.google.api.client.http.** +-dontwarn org.joda.time.** -keepclasseswithmembernames class * { native ; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 303a4051..c5746a4d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -52,7 +52,14 @@ tools:replace="android:fullBackupContent,android:allowBackup"> - + + + , KoinComponent { + + override fun create(context: Context) { + componentProvider.run { + loadKoinModules() + thread { remoteConfigSource.initialize() } + thread { messagingTopicHandler.initialize() } + } + } + + override fun dependencies(): List?>?> { + return listOf(KoinInitializer::class.java) + } + + companion object { + interface Components : KoinComponent { + val messagingTopicHandler: MessagingTopicUseCase + val remoteConfigSource: RemoteConfigSource + fun loadKoinModules() + } + } +} diff --git a/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt b/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt new file mode 100644 index 00000000..4d6ec867 --- /dev/null +++ b/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt @@ -0,0 +1,112 @@ +package com.brainwallet.presenter.history + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.data.model.AppSetting +import com.brainwallet.ui.composable.BorderedLargeButton +import com.brainwallet.ui.theme.BrainwalletAppTheme +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.util.BaseViewModel +import ltd.grunt.brainwallet.iap.presentation.model.ExportedTransaction +import ltd.grunt.brainwallet.iap.presentation.screen.ExportTrxSheet +import org.koin.android.annotation.KoinViewModel +import org.koin.compose.viewmodel.koinViewModel +import org.orbitmvi.orbit.compose.collectAsState + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun HistoryFooter( + exportedTransactions: PersistentList, + modifier: Modifier = Modifier, + viewModel: HistoryFooterViewModel = koinViewModel() +) { + val showSheet by viewModel.collectAsState() + AnimatedVisibility( + exportedTransactions.isNotEmpty(), + modifier = modifier + .fillMaxWidth() + .wrapContentHeight() + .padding(vertical = 16.dp) + ) { + HistoryFooter( + showSheet = showSheet, + exportedTransactions = exportedTransactions, + onClick = viewModel::onClick + ) + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun HistoryFooter( + showSheet: Boolean, + exportedTransactions: PersistentList, + modifier: Modifier = Modifier, + onClick: () -> Unit = {} +) { + val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + Box( + modifier + .fillMaxWidth() + .wrapContentHeight() + ) { + BorderedLargeButton( + onClick = onClick, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 32.dp) + ) { + Text( + text = stringResource(R.string.cta_export_transaction), + fontSize = 16.sp, + fontWeight = FontWeight.Thin, + ) + } + } + + if (showSheet) { + ModalBottomSheet( + sheetState = sheetState, + containerColor = BrainwalletTheme.colors.surface, + contentColor = BrainwalletTheme.colors.content, + onDismissRequest = onClick + ) { + ExportTrxSheet( + transactions = exportedTransactions, + modifier = Modifier.fillMaxWidth() + ) + } + } +} + +@Composable +@PreviewLightDark +fun HistoryFooterPreview() { + BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) { + HistoryFooter(exportedTransactions = persistentListOf(), showSheet = false) + } +} + +@KoinViewModel +class HistoryFooterViewModel : BaseViewModel(false) { + fun onClick() = intent { reduce { !state } } +} diff --git a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt index 61d29c0c..48dfe14d 100644 --- a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt +++ b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.compose.runtime.getValue import com.brainwallet.databinding.FragmentHistoryBinding import com.brainwallet.presenter.activities.BreadActivity import com.brainwallet.presenter.base.BaseFragment @@ -14,10 +15,13 @@ import com.brainwallet.tools.manager.TxManager import com.brainwallet.tools.sqlite.TransactionDataSource.OnTxAddedListener import com.brainwallet.tools.threads.BRExecutor import com.brainwallet.tools.util.BRConstants +import com.brainwallet.ui.theme.setContentWithTheme import com.brainwallet.wallet.BRPeerManager import com.brainwallet.wallet.BRPeerManager.OnTxStatusUpdate import com.brainwallet.wallet.BRWalletManager import com.brainwallet.wallet.BRWalletManager.OnBalanceChanged +import org.koin.androidx.viewmodel.ext.android.viewModel +import org.orbitmvi.orbit.compose.collectAsState import timber.log.Timber class HistoryFragment : @@ -28,6 +32,7 @@ class HistoryFragment : OnTxAddedListener, HistoryView { lateinit var binding: FragmentHistoryBinding + private val viewModel: HistoryFragmentViewModel by viewModel() override fun onCreateView( inflater: LayoutInflater, @@ -40,6 +45,10 @@ class HistoryFragment : override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.composeView.setContentWithTheme { + val exportedTransaction by viewModel.collectAsState() + HistoryFooter(exportedTransactions = exportedTransaction) + } TxManager.getInstance().init(requireActivity() as BreadActivity, binding.recyclerView) } @@ -54,12 +63,14 @@ class HistoryFragment : BRPeerManager.getInstance().removeListener(this) BRSharedPrefs.removeListener(this) } + private fun registerAnalyticsError(errorString: String) { val params = Bundle() params.putString("lwa_error_message", errorString) AnalyticsManager.logCustomEventWithParams(BRConstants._20200112_ERR, params) Timber.d("History Fragment: RegisterError : %s", errorString) } + override fun onResume() { super.onResume() addObservers() @@ -85,7 +96,9 @@ class HistoryFragment : if (this.activity == null) { registerAnalyticsError("null_in_history_fragment_on_status_update") } else { - TxManager.getInstance().updateTxList(this.activity) + TxManager.getInstance().updateTxList(this.activity) { + viewModel.updateTx(it.orEmpty()) + } } } } @@ -99,17 +112,23 @@ class HistoryFragment : if (this.activity == null) { registerAnalyticsError("null_in_history_fragment_on_tx_added") } else { - TxManager.getInstance().updateTxList(this.activity) + TxManager.getInstance().updateTxList(this.activity) { + viewModel.updateTx(it.orEmpty()) + } } } } + private fun updateUI() { BRExecutor.getInstance().forLightWeightBackgroundTasks().execute { if (this.activity == null) { registerAnalyticsError("null_in_history_fragment_update_ui") } else { - Thread.currentThread().name = Thread.currentThread().name + "HistoryFragment:updateUI" - TxManager.getInstance().updateTxList(this.activity) + Thread.currentThread().name = + Thread.currentThread().name + "HistoryFragment:updateUI" + TxManager.getInstance().updateTxList(this.activity) { + viewModel.updateTx(it.orEmpty()) + } } } } diff --git a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragmentViewModel.kt b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragmentViewModel.kt new file mode 100644 index 00000000..63c9d605 --- /dev/null +++ b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragmentViewModel.kt @@ -0,0 +1,45 @@ +package com.brainwallet.presenter.history + +import com.brainwallet.presenter.entities.TxItem +import kotlinx.collections.immutable.PersistentList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toPersistentList +import ltd.grunt.brainwallet.core.presentation.util.BaseViewModel +import ltd.grunt.brainwallet.iap.presentation.model.ExportedTransaction +import org.koin.android.annotation.KoinViewModel +import org.koin.core.annotation.Factory + +@KoinViewModel +class HistoryFragmentViewModel( + private val mapper: ExportedTransactionsMapper +) : BaseViewModel, List>(persistentListOf()) { + + fun updateTx(items: List?) { + if (items == null) return + intent { + reduce { mapper(items) } + } + } +} + +@Factory +class ExportedTransactionsMapper { + + operator fun invoke(txItems: List): PersistentList { + return mapToExportedTransactions(txItems) + } + + private fun mapToExportedTransactions(txItems: List): PersistentList { + return txItems.map { + ExportedTransaction( + timeStamp = it.timeStamp, + blockHeight = it.blockHeight, + txHashReversed = it.txReversed, + sent = it.sent, + received = it.received, + fee = it.fee, + to = it.to.toList() + ) + }.toPersistentList() + } +} diff --git a/app/src/main/java/com/brainwallet/tools/manager/TxManager.java b/app/src/main/java/com/brainwallet/tools/manager/TxManager.java index 54455d3b..e54395d3 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/TxManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/TxManager.java @@ -8,23 +8,25 @@ import android.util.AttributeSet; import android.view.View; +import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.brainwallet.presenter.activities.BreadActivity; +import com.brainwallet.presenter.entities.TxItem; import com.brainwallet.tools.adapter.TransactionListAdapter; import com.brainwallet.tools.animation.BRAnimator; import com.brainwallet.tools.listeners.RecyclerItemClickListener; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.presenter.activities.BreadActivity; -import com.brainwallet.presenter.entities.TxItem; import com.brainwallet.wallet.BRPeerManager; import com.brainwallet.wallet.BRWalletManager; import java.util.Arrays; import java.util.LinkedList; import java.util.List; +import java.util.function.Consumer; import timber.log.Timber; @@ -143,13 +145,20 @@ private void showNextPrompt(Activity app) { @WorkerThread public synchronized void updateTxList(final Context app) { + updateTxList(app, null); + } + + @WorkerThread + public synchronized void updateTxList(final Context app, @Nullable final Consumer> callback) { long start = System.currentTimeMillis(); final TxItem[] arr = BRWalletManager.getInstance().getTransactions(); final List items = arr == null ? null : new LinkedList<>(Arrays.asList(arr)); long took = (System.currentTimeMillis() - start); - if (took > 500) + if (took > 500) { Timber.d("timber: updateTxList: took: %s", took); + } + if (adapter != null) { ((Activity) app).runOnUiThread(new Runnable() { @Override @@ -158,8 +167,16 @@ public void run() { txList.setAdapter(adapter); adapter.notifyDataSetChanged(); Timber.d("timber: updateTxList: %s", currentPrompt); + + if (callback != null) { + callback.accept(items); + } } }); + } else { + if (callback != null) { + callback.accept(items); + } } } diff --git a/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt b/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt index b22a053c..4c53fa62 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt @@ -11,8 +11,8 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import com.brainwallet.R import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.brainwallet.ui.theme.BrainwalletTheme -import com.brainwallet.ui.theme.LocalDarkModeFlag +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.LocalDarkModeFlag @Composable fun BrainWalletLogo(modifier: Modifier = Modifier) { diff --git a/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt index 666a92fe..dc24a323 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt @@ -6,7 +6,7 @@ import androidx.compose.material3.IconButtonColors import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun CircleButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt index 482bbc98..308be7b5 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun DarkModeToggleButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt index 16f92a0e..330cd9e0 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt @@ -21,7 +21,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun BrainwalletScaffold( diff --git a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt index 0128e17a..0c96e2ed 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt @@ -12,7 +12,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun LargeButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt index b8743e7b..edacc989 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.brainwallet.R -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun LoadingDialog( diff --git a/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt index 68560e0f..df333d04 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun MediumTextButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt index a5ccf28d..87fe88e3 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt @@ -17,9 +17,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.brainwallet.R -import com.brainwallet.ui.theme.BrainwalletTheme -import com.brainwallet.ui.theme.lavender -import com.brainwallet.ui.theme.nearBlack +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.lavender +import ltd.grunt.brainwallet.core.presentation.theme.nearBlack @Composable fun MoonpayBuyButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt b/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt index e216c993..f3206c0f 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt @@ -10,7 +10,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun PinDotItem( diff --git a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt index 5663e9f5..4857bbb8 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt @@ -36,8 +36,8 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.window.PopupProperties -import com.brainwallet.ui.theme.BrainwalletTheme -import com.brainwallet.ui.theme.chilli +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.chilli @Composable fun SeedWordItem( diff --git a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt index 818c0451..eb312605 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.ui.composable.BrainwalletBottomSheet -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import androidx.compose.foundation.layout.size import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip diff --git a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt index d2aafa12..a0607ce4 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.brainwallet.data.model.Language import com.brainwallet.ui.composable.BrainwalletBottomSheet -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun LanguageSelectorBottomSheet( diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt index bb549542..30fc88db 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt @@ -32,7 +32,7 @@ import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.LargeButton -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import org.koin.compose.viewmodel.koinViewModel // TODO: wip diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index 76fd6b8a..569f1b2f 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -42,7 +42,7 @@ import com.brainwallet.ui.screens.home.composable.settingsrows.SecurityDetail import com.brainwallet.ui.screens.home.composable.settingsrows.SettingRowItem import com.brainwallet.ui.screens.home.composable.settingsrows.ThemeSettingRowItem import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import com.brainwallet.util.EventBus import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt index 7a5cc1a2..ea51289b 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt @@ -29,7 +29,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.tools.sqlite.CurrencyDataSource -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun CurrencyDetail( diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt index 3445de6c..f4564d1c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.Language -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme // TODO @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt index 93a46318..4f94cff7 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt @@ -28,7 +28,7 @@ import com.brainwallet.data.model.FeeOption import com.brainwallet.data.model.getFiatFormatted import com.brainwallet.data.model.getSelectedIndex import com.brainwallet.ui.screens.home.SettingsEvent -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme // TODO @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt index 9df1bed1..5e6e0b7d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt @@ -22,8 +22,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import com.brainwallet.ui.theme.BrainwalletColors -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletColors +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme /** * main composable for [SettingRowItem] and [SettingRowItemExpandable] diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt index b50bdf51..3a9c82de 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt @@ -70,7 +70,7 @@ import com.brainwallet.ui.composable.WheelPickerFocusVertical import com.brainwallet.ui.composable.WheelPickerState import com.brainwallet.ui.composable.rememberWheelPickerState import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.delay import kotlinx.coroutines.flow.debounce diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt index 52dbe051..6171ea6a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt @@ -59,7 +59,7 @@ import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.SeedWordItemTextField -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import org.koin.compose.koinInject @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt index 7c63a0d4..5134bc3a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt @@ -31,7 +31,7 @@ import com.brainwallet.ui.composable.PasscodeKeypad import com.brainwallet.ui.composable.PasscodeKeypadEvent import com.brainwallet.ui.screens.unlock.UnLockEvent import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import com.google.common.collect.ImmutableList @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt index 7d3fe6d2..ccfa96fd 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt @@ -26,8 +26,8 @@ import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.composable.DarkModeToggleButton import com.brainwallet.ui.screens.unlock.UnLockEvent import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.brainwallet.ui.theme.BrainwalletTheme -import com.brainwallet.ui.theme.LocalDarkModeFlag +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.LocalDarkModeFlag @Composable fun UnLockScreenFooter( diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt index 81aa128e..5bdcee03 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.composable.BrainWalletLogo import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun UnLockScreenHeader( diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index 4b0ec8e1..90a21963 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -54,7 +54,7 @@ import com.brainwallet.ui.composable.BrainwalletButton import com.brainwallet.ui.composable.DarkModeToggleButton import com.brainwallet.ui.composable.bottomsheet.FiatSelectorBottomSheet import com.brainwallet.ui.composable.bottomsheet.LanguageSelectorBottomSheet -import com.brainwallet.ui.theme.BrainwalletTheme +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import org.koin.compose.koinInject @Composable diff --git a/app/src/main/java/com/brainwallet/ui/theme/Color.kt b/app/src/main/java/com/brainwallet/ui/theme/Color.kt deleted file mode 100644 index 5381d211..00000000 --- a/app/src/main/java/com/brainwallet/ui/theme/Color.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.brainwallet.ui.theme - -import androidx.compose.ui.graphics.Color - -val midnight = Color(0xFF0F0853) -val grape = Color(0xFF402DAE) -val cheddar = Color(0xFFFFAE00) -val chilli = Color(0xFFCE3025) -val pesto = Color(0xFF25AA2C) -val blue = Color(0xFF2968F2) -val nearBlack = Color(0xFF151515) -val lavender = Color(0xFFDDD5FA) -val white = Color.White - -// to make color darken, since we are not providing all colors for specific case -inline fun Color.darken(darkenBy: Float = 0.3f): Color { - return copy( - red = red * darkenBy, - green = green * darkenBy, - blue = blue * darkenBy, - alpha = alpha - ) -} diff --git a/app/src/main/java/com/brainwallet/ui/theme/Font.kt b/app/src/main/java/com/brainwallet/ui/theme/Font.kt deleted file mode 100644 index f7bdd2c9..00000000 --- a/app/src/main/java/com/brainwallet/ui/theme/Font.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.brainwallet.ui.theme - -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.googlefonts.Font -import com.brainwallet.R - -class Font - -val openSauceOneFamily = FontFamily( - Font(R.font.open_sauce_one_light, FontWeight.Light), - Font(R.font.open_sauce_one_bold, FontWeight.Bold), - Font(R.font.open_sauce_one_medium, FontWeight.Medium), - Font(R.font.open_sauce_one_regular, FontWeight.Normal), - Font(R.font.open_sauce_one_semi_bold, FontWeight.SemiBold) -) diff --git a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt index 4297ae79..9262ac02 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt @@ -1,105 +1,29 @@ package com.brainwallet.ui.theme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Shapes -import androidx.compose.material3.Typography import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.Immutable -import androidx.compose.runtime.ReadOnlyComposable -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.ComposeView +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.brainwallet.data.model.AppSetting -import com.brainwallet.data.model.Language - -/** - * define custom colors naming for brainwallet colors - */ -@Immutable -data class BrainwalletColors( - val surface: Color = Color.Unspecified, - val background: Color = Color.Unspecified, - val content: Color = Color.Unspecified, - val border: Color = Color.Unspecified, - val info: Color = Color.Unspecified, - val affirm: Color = Color.Unspecified, - val warn: Color = Color.Unspecified, - val error: Color = Color.Unspecified -) - -private val darkColorScheme = BrainwalletColors( - surface = midnight, - background = grape, - content = white, - border = white, - info = blue, - affirm = pesto, - warn = cheddar, - error = chilli -) - -private val lightColorScheme = BrainwalletColors( - surface = white, - background = lavender, - content = midnight, - border = midnight, - info = blue, - affirm = pesto, - warn = cheddar, - error = chilli -) - -val LocalBrainwalletColors = staticCompositionLocalOf { - BrainwalletColors() -} - -val LocalLanguageCode = staticCompositionLocalOf { - Language.ENGLISH.code // default -} - -val LocalDarkModeFlag = staticCompositionLocalOf { - false -} +import com.brainwallet.data.repository.SettingRepository +import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import org.koin.compose.koinInject @Composable fun BrainwalletAppTheme( - appSetting: AppSetting = AppSetting(), + appSetting: AppSetting = koinInject().settings.collectAsStateWithLifecycle( + AppSetting() + ).value, content: @Composable() () -> Unit ) { - val colors = if (appSetting.isDarkMode) darkColorScheme else lightColorScheme - - CompositionLocalProvider( - LocalBrainwalletColors provides colors, - LocalLanguageCode provides appSetting.languageCode, - LocalDarkModeFlag provides appSetting.isDarkMode, - ) { - MaterialTheme( - typography = AppTypography, - content = content - ) - } -} - -object BrainwalletTheme { - val colors: BrainwalletColors - @Composable - get() = LocalBrainwalletColors.current - - val typography: Typography - @Composable @ReadOnlyComposable - get() = MaterialTheme.typography - - val shapes: Shapes - @Composable @ReadOnlyComposable - get() = MaterialTheme.shapes - - // todo: add typography, shape? for the design system + BrainwalletTheme( + darkTheme = appSetting.isDarkMode, + languageCode = appSetting.languageCode, + content = content + ) } -// provide compose theme wrapper for transition fun ComposeView.setContentWithTheme(content: @Composable () -> Unit) { setContent { BrainwalletAppTheme { content.invoke() } diff --git a/app/src/main/java/com/brainwallet/ui/theme/Type.kt b/app/src/main/java/com/brainwallet/ui/theme/Type.kt deleted file mode 100644 index f5df19e5..00000000 --- a/app/src/main/java/com/brainwallet/ui/theme/Type.kt +++ /dev/null @@ -1,86 +0,0 @@ -package com.brainwallet.ui.theme - -import androidx.compose.material3.Typography -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - -// DEV Dislike this because it block all options - -val AppTypography = Typography( - displayLarge = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.SemiBold, - fontSize = 57.sp - ), - displayMedium = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 45.sp - ), - displaySmall = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 36.sp - ), - headlineLarge = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 32.sp - ), - headlineMedium = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 28.sp - ), - headlineSmall = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 24.sp - ), - titleLarge = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 22.sp - ), - titleMedium = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Medium, - fontSize = 16.sp - ), - titleSmall = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Medium, - fontSize = 14.sp - ), - bodyLarge = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 16.sp - ), - bodyMedium = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 14.sp - ), - bodySmall = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Normal, - fontSize = 12.sp - ), - labelLarge = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.SemiBold, - fontSize = 14.sp - ), - labelMedium = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Medium, - fontSize = 12.sp - ), - labelSmall = TextStyle( - fontFamily = openSauceOneFamily, - fontWeight = FontWeight.Thin, - fontSize = 11.sp - ) -) diff --git a/app/src/main/res/drawable/arrow_down_bold_circle.xml b/app/src/main/res/drawable/arrow_down_bold_circle.xml deleted file mode 100755 index 4c04920f..00000000 --- a/app/src/main/res/drawable/arrow_down_bold_circle.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/arrow_up_bold_circle.xml b/app/src/main/res/drawable/arrow_up_bold_circle.xml deleted file mode 100755 index 64e1b225..00000000 --- a/app/src/main/res/drawable/arrow_up_bold_circle.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_history.xml b/app/src/main/res/layout/fragment_history.xml index 16a36f3f..e8fa0f81 100644 --- a/app/src/main/res/layout/fragment_history.xml +++ b/app/src/main/res/layout/fragment_history.xml @@ -1,20 +1,25 @@ - + @@ -24,6 +29,10 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintBottom_toTopOf="@id/composeView" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" android:fontFamily="@font/open_sauce_one_regular" android:text="@string/TransactionDetails.emptyMessage" android:textColor="@color/cheddar" @@ -31,5 +40,13 @@ android:visibility="gone" tools:visibility="visible" /> - + + + \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 82a13420..75647b14 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -451,4 +451,7 @@ الشراء باستخدام Moonpay العنوان الجديد شراء / تلقي + مخصص + إعادة تعيين / البدء من جديد + تصدير بيانات المعاملة diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index cd1386df..db03ad26 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -812,4 +812,7 @@ Kaufen Sie mit Moonpay Neue Adresse Kaufen / Empfangen + Benutzerdefiniert + Zurücksetzen / Neu starten + Transaktionsdaten exportieren diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index e4363ff4..6e6dd3ce 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -811,4 +811,7 @@ Compra con Moonpay Nueva dirección Comprar / Recibir + Personalizado + Restablecer / Empezar de nuevo + Exportar datos de transacciones diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index b70bfedc..f285405e 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -849,4 +849,5 @@ خرید / دریافت سفارشی بازنشانی / شروع مجدد + صادرات داده‌های تراکنش \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 92b63a25..7099ce82 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -812,4 +812,7 @@ Acheter avec Moonpay Nouvelle adresse Acheter / Recevoir + Personnalisé + Réinitialiser / Recommencer + Exporter les données de transaction diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 73407e9f..b83cddfc 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -450,4 +450,7 @@ मूनपे से खरीदें नया पता खरीदें/प्राप्त करें + कस्टम + रीसेट / फिर से शुरू करें + लेन-देन डेटा निर्यात करें diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index e89fb5f4..100ac176 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -814,4 +814,7 @@ Beli dengan Moonpay Alamat Baru Beli / Terima + Kustom + Atur Ulang / Mulai Lagi + Ekspor Data Transaksi diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3a15ed68..a396107d 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -812,4 +812,7 @@ Acquista con Moonpay Nuovo indirizzo Acquista/Ricevi + Personalizzato + Reimposta / Ricomincia + Esporta dati transazione diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 097163d0..5a0847f8 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -812,4 +812,7 @@ Moonpay で購入する 新しい住所 買う/受け取る + カスタム + リセット / やり直す + 取引データをエクスポート diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index aafc1c57..8ab41f26 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -812,4 +812,7 @@ 문페이로 구매하세요 새 주소 구매 / 받기 + 사용자 정의 + 재설정 / 다시 시작 + 거래 데이터 내보내기 diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml index 98248e3e..4d3c031c 100644 --- a/app/src/main/res/values-pa/strings.xml +++ b/app/src/main/res/values-pa/strings.xml @@ -843,4 +843,5 @@ خرید / وصول حسب ضرورت ری سیٹ / دوبارہ شروع کریں + ਟ੍ਰਾਂਜ਼ੈਕਸ਼ਨ ਡਾਟਾ ਐਕਸਪੋਰਟ ਕਰੋ \ No newline at end of file diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index fe6e4805..092b1556 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -838,4 +838,5 @@ Kup / Odbierz Niestandardowe Reset / Rozpocznij od nowa + Eksportuj dane transakcji \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index dcbb7c14..9dae9e99 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -811,4 +811,7 @@ Compre com Moonpay Novo endereço Comprar / Receber + Personalizado + Redefinir / Recomeçar + Exportar dados da transação diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ad65ef57..b940b62d 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -812,4 +812,7 @@ Купить с помощью Moonpay Новый адрес Купить/получить + Пользовательский + Сбросить / Начать заново + Экспорт данных транзакции diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 6e155cf2..d9c2168c 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -450,4 +450,7 @@ Köp med Moonpay Ny adress Köp/ta emot + Anpassad + Återställ / Börja om + Exportera transaktionsdata diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 71f767b1..2c18e0c0 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -836,4 +836,7 @@ Moonpay ile satın alın Yeni Adres Satın Al / Al + Özel + Sıfırla / Baştan Başla + İşlem verilerini dışa aktar diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 311e84e9..43e4002e 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -819,4 +819,7 @@ Купуйте за допомогою Moonpay Нова адреса Купити / Отримати + Користувацький + Скинути / Почати спочатку + Експортувати дані транзакцій diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index e43d6b0f..44a2a357 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -812,4 +812,7 @@ 使用 Moonpay 购买 新地址 购买/接收 + 自定义 + 重置 / 重新开始 + 导出交易数据 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 8e29fb69..d64101af 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -812,4 +812,7 @@ 使用 Moonpay 購買 新地址 購買/接收 + 自訂 + 重設 / 重新開始 + 匯出交易資料 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cb798919..1b5bfa86 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -858,4 +858,5 @@ Buy / Receive Custom Reset / Start Over + Export Transaction Data diff --git a/app/src/test/java/com/brainwallet/initializer/AppInitializerTest.kt b/app/src/test/java/com/brainwallet/initializer/AppInitializerTest.kt new file mode 100644 index 00000000..0d952ac1 --- /dev/null +++ b/app/src/test/java/com/brainwallet/initializer/AppInitializerTest.kt @@ -0,0 +1,56 @@ +package com.brainwallet.initializer + +import android.content.Context +import com.brainwallet.data.source.RemoteConfigSource +import com.brainwallet.domain.MessagingTopicUseCase +import io.mockk.MockKAnnotations +import io.mockk.every +import io.mockk.impl.annotations.MockK +import io.mockk.impl.annotations.RelaxedMockK +import io.mockk.verify +import ltd.grunt.brainwallet.core.presentation.KoinInitializer +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +class AppInitializerTest { + + @MockK + lateinit var messagingTopicHandler: MessagingTopicUseCase + + @MockK + lateinit var remoteConfigSource: RemoteConfigSource + + @RelaxedMockK + lateinit var context: Context + + @MockK + private lateinit var components: AppInitializer.Companion.Components + private lateinit var initializer: AppInitializer + + @BeforeEach + fun setup() { + MockKAnnotations.init(this, relaxUnitFun = true) + every { + components.messagingTopicHandler + } returns messagingTopicHandler + every { + components.remoteConfigSource + } returns remoteConfigSource + initializer = AppInitializer(components) + } + + @Test + fun `should initialize remoteConfigSource and messagingTopicHandler`() { + initializer.create(context) + + verify { components.loadKoinModules() } + verify { remoteConfigSource.initialize() } + verify { messagingTopicHandler.initialize() } + } + + @Test + fun `dependencies should include KoinInitializer`() { + val deps = initializer.dependencies() + assert(deps.contains(KoinInitializer::class.java)) + } +} diff --git a/app/src/test/java/com/brainwallet/presenter/history/HistoryFragmentViewModelTest.kt b/app/src/test/java/com/brainwallet/presenter/history/HistoryFragmentViewModelTest.kt new file mode 100644 index 00000000..58cd102a --- /dev/null +++ b/app/src/test/java/com/brainwallet/presenter/history/HistoryFragmentViewModelTest.kt @@ -0,0 +1,39 @@ +package com.brainwallet.presenter.history + +import com.brainwallet.presenter.entities.TxItem +import io.mockk.every +import io.mockk.mockk +import kotlinx.collections.immutable.persistentListOf +import kotlinx.coroutines.test.runTest +import ltd.grunt.brainwallet.iap.presentation.model.ExportedTransaction +import org.junit.Test +import org.orbitmvi.orbit.test.test + +class HistoryFragmentViewModelTest { + + private val mapper: ExportedTransactionsMapper = mockk() + + @Test + fun `when onEvent with txItems then state contains mapped ExportedTransactions`() = runTest { + val viewModel = HistoryFragmentViewModel(mapper) + val txItem1 = mockk(relaxed = true) + val txItem2 = mockk(relaxed = true) + + val exported1 = mockk() + val exported2 = mockk() + + every { mapper(listOf(txItem1)) } returns persistentListOf(exported1) + every { mapper(listOf(txItem1, txItem2)) } returns persistentListOf(exported1, exported2) + + viewModel.test(this, initialState = persistentListOf()) { + viewModel.updateTx(listOf(txItem1)) + expectState { + persistentListOf(exported1) + } + viewModel.updateTx(listOf(txItem1, txItem2)) + expectState { + persistentListOf(exported1, exported2) + } + } + } +} diff --git a/gradle.properties b/gradle.properties index 1b263f95..e6321d0c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,4 +16,4 @@ org.gradle.jvmargs=-Xmx10248m org.gradle.daemon=true android.useAndroidX=true android.enableJetifier=true - +android.nonTransitiveRClass=false diff --git a/gruntsoftware-build-logic b/gruntsoftware-build-logic index 1f89f0ba..2b00192e 160000 --- a/gruntsoftware-build-logic +++ b/gruntsoftware-build-logic @@ -1 +1 @@ -Subproject commit 1f89f0ba6985c09b26b4b966234f67afca5e5808 +Subproject commit 2b00192e99ee10540a49782c7d02dfc3e79c8afe diff --git a/settings.gradle.kts b/settings.gradle.kts index f5eee3df..25b6aadb 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,4 +29,8 @@ dependencyResolutionManagement { rootProject.name = "Brainwallet Android" include(":app") include(":install_time_asset_pack") -include(":modules:private-general-purpose:games") +include(":core", ":games", ":iap", ":general-purpose-app") +project(":general-purpose-app").projectDir = file("modules/private-general-purpose/app") +project(":core").projectDir = file("modules/private-general-purpose/core") +project(":games").projectDir = file("modules/private-general-purpose/games") +project(":iap").projectDir = file("modules/private-general-purpose/iap") From 631b4f6fb050d06b4cd888a30842fb218e308cc4 Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Wed, 8 Oct 2025 16:11:12 +0700 Subject: [PATCH 072/116] refactor(app): Relocate core module imports Updates the import paths for the core presentation module from `ltd.grunt.brainwallet.core.presentation` to `com.grunt.brainwallet.core.presentation`. This refactoring touches multiple UI components and initializers across the `app` module to align with the new package structure. Additionally, this commit corrects a typo in `SeedWordItem.kt`, changing the error color variable from `chilli` to `chili` to match the theme definition. Finally, the submodule pointer for `private-general-purpose` is updated. --- .../java/com/brainwallet/initializer/AppInitializer.kt | 2 +- .../com/brainwallet/presenter/history/HistoryFooter.kt | 8 ++++---- .../presenter/history/HistoryFragmentViewModel.kt | 4 ++-- .../java/com/brainwallet/ui/composable/BrainWalletLogo.kt | 4 ++-- .../java/com/brainwallet/ui/composable/CircleButton.kt | 2 +- .../com/brainwallet/ui/composable/DarkModeToggleButton.kt | 2 +- .../main/java/com/brainwallet/ui/composable/Foundation.kt | 2 +- .../java/com/brainwallet/ui/composable/LargeButton.kt | 2 +- .../java/com/brainwallet/ui/composable/LoadingDialog.kt | 2 +- .../java/com/brainwallet/ui/composable/MediumButton.kt | 2 +- .../com/brainwallet/ui/composable/MoonpayBuyButton.kt | 6 +++--- .../main/java/com/brainwallet/ui/composable/PinDotItem.kt | 2 +- .../java/com/brainwallet/ui/composable/SeedWordItem.kt | 6 +++--- .../ui/composable/bottomsheet/FiatSelectorBottomSheet.kt | 2 +- .../composable/bottomsheet/LanguageSelectorBottomSheet.kt | 2 +- .../ui/screens/buylitecoin/BuyLitecoinScreen.kt | 2 +- .../ui/screens/home/composable/HomeSettingDrawerSheet.kt | 2 +- .../home/composable/settingsrows/CurrencyDetail.kt | 2 +- .../home/composable/settingsrows/LanguageDetail.kt | 2 +- .../composable/settingsrows/LitecoinBlockchainDetail.kt | 4 +--- .../home/composable/settingsrows/SettingRowItem.kt | 4 ++-- .../brainwallet/ui/screens/home/receive/ReceiveDialog.kt | 2 +- .../brainwallet/ui/screens/inputwords/InputWordsScreen.kt | 2 +- .../ui/screens/unlock/components/UnLockScreenBody.kt | 2 +- .../ui/screens/unlock/components/UnLockScreenFooter.kt | 4 ++-- .../ui/screens/unlock/components/UnLockScreenHeader.kt | 2 +- .../com/brainwallet/ui/screens/welcome/WelcomeScreen.kt | 2 +- app/src/main/java/com/brainwallet/ui/theme/Theme.kt | 2 +- .../com/brainwallet/initializer/AppInitializerTest.kt | 2 +- .../presenter/history/HistoryFragmentViewModelTest.kt | 2 +- modules/private-general-purpose | 2 +- 31 files changed, 42 insertions(+), 44 deletions(-) diff --git a/app/src/main/java/com/brainwallet/initializer/AppInitializer.kt b/app/src/main/java/com/brainwallet/initializer/AppInitializer.kt index 30fbcbde..9095b8d0 100644 --- a/app/src/main/java/com/brainwallet/initializer/AppInitializer.kt +++ b/app/src/main/java/com/brainwallet/initializer/AppInitializer.kt @@ -5,7 +5,7 @@ import androidx.startup.Initializer import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.di.AppModule import com.brainwallet.domain.MessagingTopicUseCase -import ltd.grunt.brainwallet.core.presentation.KoinInitializer +import com.grunt.brainwallet.core.presentation.KoinInitializer import org.koin.core.component.KoinComponent import org.koin.core.component.inject import org.koin.core.context.loadKoinModules diff --git a/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt b/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt index 4d6ec867..f097c88f 100644 --- a/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt +++ b/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt @@ -24,10 +24,10 @@ import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.theme.BrainwalletAppTheme import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme -import ltd.grunt.brainwallet.core.presentation.util.BaseViewModel -import ltd.grunt.brainwallet.iap.presentation.model.ExportedTransaction -import ltd.grunt.brainwallet.iap.presentation.screen.ExportTrxSheet +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.util.BaseViewModel +import com.grunt.brainwallet.iap.presentation.model.ExportedTransaction +import com.grunt.brainwallet.iap.presentation.screen.ExportTrxSheet import org.koin.android.annotation.KoinViewModel import org.koin.compose.viewmodel.koinViewModel import org.orbitmvi.orbit.compose.collectAsState diff --git a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragmentViewModel.kt b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragmentViewModel.kt index 63c9d605..882edd44 100644 --- a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragmentViewModel.kt +++ b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragmentViewModel.kt @@ -4,8 +4,8 @@ import com.brainwallet.presenter.entities.TxItem import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toPersistentList -import ltd.grunt.brainwallet.core.presentation.util.BaseViewModel -import ltd.grunt.brainwallet.iap.presentation.model.ExportedTransaction +import com.grunt.brainwallet.core.presentation.util.BaseViewModel +import com.grunt.brainwallet.iap.presentation.model.ExportedTransaction import org.koin.android.annotation.KoinViewModel import org.koin.core.annotation.Factory diff --git a/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt b/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt index 4c53fa62..07d09852 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt @@ -11,8 +11,8 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import com.brainwallet.R import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.theme.BrainwalletAppTheme -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme -import ltd.grunt.brainwallet.core.presentation.theme.LocalDarkModeFlag +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.LocalDarkModeFlag @Composable fun BrainWalletLogo(modifier: Modifier = Modifier) { diff --git a/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt index dc24a323..8b489d0f 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt @@ -6,7 +6,7 @@ import androidx.compose.material3.IconButtonColors import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun CircleButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt index 308be7b5..c9cd756e 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.theme.BrainwalletAppTheme -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun DarkModeToggleButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt index 330cd9e0..5de35133 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt @@ -21,7 +21,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun BrainwalletScaffold( diff --git a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt index 0c96e2ed..4d17fe74 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt @@ -12,7 +12,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun LargeButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt index edacc989..566970c6 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.brainwallet.R -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun LoadingDialog( diff --git a/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt index df333d04..28140bab 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun MediumTextButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt index 87fe88e3..2c91d5a0 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt @@ -17,9 +17,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.brainwallet.R -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme -import ltd.grunt.brainwallet.core.presentation.theme.lavender -import ltd.grunt.brainwallet.core.presentation.theme.nearBlack +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.lavender +import com.grunt.brainwallet.core.presentation.theme.nearBlack @Composable fun MoonpayBuyButton( diff --git a/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt b/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt index f3206c0f..e6d4f392 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt @@ -10,7 +10,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun PinDotItem( diff --git a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt index 4857bbb8..c174922c 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt @@ -36,8 +36,8 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.window.PopupProperties -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme -import ltd.grunt.brainwallet.core.presentation.theme.chilli +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.chili @Composable fun SeedWordItem( @@ -53,7 +53,7 @@ fun SeedWordItem( .weight(1f), text = label, style = MaterialTheme.typography.bodyMedium, - color = if (isError) chilli else BrainwalletTheme.colors.content, + color = if (isError) chili else BrainwalletTheme.colors.content, overflow = TextOverflow.Ellipsis, maxLines = 1 ) diff --git a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt index eb312605..c1a7010e 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.ui.composable.BrainwalletBottomSheet -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import androidx.compose.foundation.layout.size import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip diff --git a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt index a0607ce4..80e6dec2 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.brainwallet.data.model.Language import com.brainwallet.ui.composable.BrainwalletBottomSheet -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun LanguageSelectorBottomSheet( diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt index 30fc88db..c909fb86 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt @@ -32,7 +32,7 @@ import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.LargeButton -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import org.koin.compose.viewmodel.koinViewModel // TODO: wip diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt index 569f1b2f..bb70ddca 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt @@ -42,7 +42,7 @@ import com.brainwallet.ui.screens.home.composable.settingsrows.SecurityDetail import com.brainwallet.ui.screens.home.composable.settingsrows.SettingRowItem import com.brainwallet.ui.screens.home.composable.settingsrows.ThemeSettingRowItem import com.brainwallet.ui.theme.BrainwalletAppTheme -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import com.brainwallet.util.EventBus import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt index ea51289b..cc792a6b 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt @@ -29,7 +29,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.tools.sqlite.CurrencyDataSource -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun CurrencyDetail( diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt index f4564d1c..c9f7211d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.Language -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme // TODO @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt index 4f94cff7..324c0276 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt @@ -14,8 +14,6 @@ import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -28,7 +26,7 @@ import com.brainwallet.data.model.FeeOption import com.brainwallet.data.model.getFiatFormatted import com.brainwallet.data.model.getSelectedIndex import com.brainwallet.ui.screens.home.SettingsEvent -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme // TODO @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt index 5e6e0b7d..a312e1df 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt @@ -22,8 +22,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletColors -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletColors +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme /** * main composable for [SettingRowItem] and [SettingRowItemExpandable] diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt index 3a9c82de..7d71701d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt @@ -70,7 +70,7 @@ import com.brainwallet.ui.composable.WheelPickerFocusVertical import com.brainwallet.ui.composable.WheelPickerState import com.brainwallet.ui.composable.rememberWheelPickerState import com.brainwallet.ui.theme.BrainwalletAppTheme -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.delay import kotlinx.coroutines.flow.debounce diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt index 6171ea6a..d3c839fd 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt @@ -59,7 +59,7 @@ import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.SeedWordItemTextField -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import org.koin.compose.koinInject @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt index 5134bc3a..ca279e29 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt @@ -31,7 +31,7 @@ import com.brainwallet.ui.composable.PasscodeKeypad import com.brainwallet.ui.composable.PasscodeKeypadEvent import com.brainwallet.ui.screens.unlock.UnLockEvent import com.brainwallet.ui.theme.BrainwalletAppTheme -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import com.google.common.collect.ImmutableList @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt index ccfa96fd..74352675 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt @@ -26,8 +26,8 @@ import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.composable.DarkModeToggleButton import com.brainwallet.ui.screens.unlock.UnLockEvent import com.brainwallet.ui.theme.BrainwalletAppTheme -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme -import ltd.grunt.brainwallet.core.presentation.theme.LocalDarkModeFlag +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.LocalDarkModeFlag @Composable fun UnLockScreenFooter( diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt index 5bdcee03..fd01ce6a 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.composable.BrainWalletLogo import com.brainwallet.ui.theme.BrainwalletAppTheme -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme @Composable fun UnLockScreenHeader( diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index 90a21963..4261a557 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -54,7 +54,7 @@ import com.brainwallet.ui.composable.BrainwalletButton import com.brainwallet.ui.composable.DarkModeToggleButton import com.brainwallet.ui.composable.bottomsheet.FiatSelectorBottomSheet import com.brainwallet.ui.composable.bottomsheet.LanguageSelectorBottomSheet -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import org.koin.compose.koinInject @Composable diff --git a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt index 9262ac02..8e624813 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt @@ -5,7 +5,7 @@ import androidx.compose.ui.platform.ComposeView import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.brainwallet.data.model.AppSetting import com.brainwallet.data.repository.SettingRepository -import ltd.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import org.koin.compose.koinInject @Composable diff --git a/app/src/test/java/com/brainwallet/initializer/AppInitializerTest.kt b/app/src/test/java/com/brainwallet/initializer/AppInitializerTest.kt index 0d952ac1..238e5481 100644 --- a/app/src/test/java/com/brainwallet/initializer/AppInitializerTest.kt +++ b/app/src/test/java/com/brainwallet/initializer/AppInitializerTest.kt @@ -8,7 +8,7 @@ import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.impl.annotations.RelaxedMockK import io.mockk.verify -import ltd.grunt.brainwallet.core.presentation.KoinInitializer +import com.grunt.brainwallet.core.presentation.KoinInitializer import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test diff --git a/app/src/test/java/com/brainwallet/presenter/history/HistoryFragmentViewModelTest.kt b/app/src/test/java/com/brainwallet/presenter/history/HistoryFragmentViewModelTest.kt index 58cd102a..417b32f4 100644 --- a/app/src/test/java/com/brainwallet/presenter/history/HistoryFragmentViewModelTest.kt +++ b/app/src/test/java/com/brainwallet/presenter/history/HistoryFragmentViewModelTest.kt @@ -5,7 +5,7 @@ import io.mockk.every import io.mockk.mockk import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.test.runTest -import ltd.grunt.brainwallet.iap.presentation.model.ExportedTransaction +import com.grunt.brainwallet.iap.presentation.model.ExportedTransaction import org.junit.Test import org.orbitmvi.orbit.test.test diff --git a/modules/private-general-purpose b/modules/private-general-purpose index a64b5517..8c366827 160000 --- a/modules/private-general-purpose +++ b/modules/private-general-purpose @@ -1 +1 @@ -Subproject commit a64b551768e6024632bc901b6822602c2d3d397b +Subproject commit 8c366827c82519e30841517eb0e314f3468e707b From 279fa233354b9af6bbf6578d0c8b73f95c3da5d5 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 9 Oct 2025 21:16:30 +0100 Subject: [PATCH 073/116] build bump --- app/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c82c7258..a534b577 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -24,8 +24,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 36 - versionCode = 202506296 - versionName = "v4.7.2" + versionCode = 202506298 + versionName = "v4.8.0" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") From 779f47f53bce1c0695bdbfd65d480626deb62382 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 9 Oct 2025 21:44:56 +0100 Subject: [PATCH 074/116] removed cruft --- app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt | 1 - app/src/main/java/com/brainwallet/BrainwalletApp.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt b/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt index 1e76d09e..a753067c 100644 --- a/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt +++ b/app/src/androidTest/kotlin/flow/RecoverWalletScreenGrabsTest.kt @@ -83,7 +83,6 @@ class RecoverWalletScreenGrabsTest { @OptIn(ExperimentalTestApi::class) @Test fun onRecoverFlowSuccess() { - composeTestRule.activityRule.scenario.onActivity { Screengrab.setDefaultScreenshotStrategy(FalconScreenshotStrategy(it)) } diff --git a/app/src/main/java/com/brainwallet/BrainwalletApp.kt b/app/src/main/java/com/brainwallet/BrainwalletApp.kt index 51f9d6c8..41da34c0 100644 --- a/app/src/main/java/com/brainwallet/BrainwalletApp.kt +++ b/app/src/main/java/com/brainwallet/BrainwalletApp.kt @@ -19,7 +19,6 @@ import timber.log.Timber.DebugTree import java.util.Timer import java.util.TimerTask import java.util.concurrent.atomic.AtomicInteger -import kotlin.concurrent.thread open class BrainwalletApp : Application() { From 05813ad6736572407e5184e04cd2f681adbe49dc Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Fri, 10 Oct 2025 08:36:50 +0700 Subject: [PATCH 075/116] chore(submodules): remove bugged games repository --- modules/games | 1 - 1 file changed, 1 deletion(-) delete mode 160000 modules/games diff --git a/modules/games b/modules/games deleted file mode 160000 index b2cc09df..00000000 --- a/modules/games +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b2cc09df06d90baa9836b8789c38de569e2e8f8f From 67000e9c8e8622e60b36a5ce0ca400d5016d4951 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Fri, 10 Oct 2025 08:22:05 +0100 Subject: [PATCH 076/116] bump code --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a534b577..8d9f1fc7 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -24,7 +24,7 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 36 - versionCode = 202506298 + versionCode = 202506299 versionName = "v4.8.0" multiDexEnabled = true From 83f1b85a88d3a5573f0af2a79bc7083f487bd211 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Mon, 13 Oct 2025 13:55:09 +0100 Subject: [PATCH 077/116] Release/v4.8.0 (#147) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🚀[Release v4.4.7] Merge into Main (#70) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.0] Merge into Main (#78) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.4] Merge into Main (#87) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * Updated README * code bump * chore: open bread activity first then open moonpay widget (#88) * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.5] Merge into Main (#101) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Update build.gradle.kts --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.0] Merge into Main (#104) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * version bump * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.1] Merge into Main (#107) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * build bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.2] Merge into Main (#110) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * Removed unused audio files * polished tests * removed unused asset pack * code bump * code bump * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * broke out completion of the seed phrase and navigation - Feedback was a user could complete seed phrase and not tap "Game and Sync" - Forced users to start all over - Saved a correct seed phrase confirmation into memory * code bump * fix for https://console.firebase.google.com/project/brainwallet-mobile/crashlytics/app/android:ltd.grunt.brainwallet/issues/1386f366ab35e9112a6b742d629bb0be?time=last-seven-days&types=crash&sessionEventKey=685DA96C00BF00015A7AFEA30E0DB49C_2098799426616143441 * measure where users tap * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly * Cleaned commented out BuyLitecoinscreen * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.7.0] Merge into Main (#115) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly (#111) * Upgrade targetSdk 36 (#113) * chore: change drawable with density for brainwallet_logotype_white * chore: adjustment WelcomeScreen.kt * chore: adjustment for targetSdk 36 also support 16KB page size * bump clean extra semicolon * Update pro-guard-rules * Updated the version --------- Co-authored-by: andhikayuana * 🚀[Release v4.7.2] Merge into Main (#128) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly (#111) * Upgrade targetSdk 36 (#113) * chore: change drawable with density for brainwallet_logotype_white * chore: adjustment WelcomeScreen.kt * chore: adjustment for targetSdk 36 also support 16KB page size * feat(#195): adopt koin annotation for dependency injection (#120) * Create PULL_REQUEST_TEMPLATE.md Create PULL_REQUEST_TEMPLATE.md * bump for test (#121) * bump for test * Updated the template * polishes * feat(#174): initiate games module (#119) * Force pushed the version and code bump and catch up with Prod. * Updated games module to v1.1.0 * Updated the games submodule * Renamed and tested with user skips --------- Co-authored-by: andhikayuana Co-authored-by: Joseph Sanjaya * Release/v4.7.2 202506296 (#134) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly (#111) * Upgrade targetSdk 36 (#113) * chore: change drawable with density for brainwallet_logotype_white * chore: adjustment WelcomeScreen.kt * chore: adjustment for targetSdk 36 also support 16KB page size * feat(#195): adopt koin annotation for dependency injection (#120) * Create PULL_REQUEST_TEMPLATE.md Create PULL_REQUEST_TEMPLATE.md * bump for test (#121) * bump for test * Updated the template * polishes * feat(#174): initiate games module (#119) * Force pushed the version and code bump and catch up with Prod. * 🚀[Release v4.7.2] Merge into Develop (#127) * 🚀[Release v4.4.7] Merge into Main (#70) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.0] Merge into Main (#78) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.4] Merge into Main (#87) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * Updated README * code bump * chore: open bread activity first then open moonpay widget (#88) * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.5.5] Merge into Main (#101) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Update build.gradle.kts --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.0] Merge into Main (#104) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * version bump * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.1] Merge into Main (#107) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * build bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.6.2] Merge into Main (#110) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * Removed unused audio files * polished tests * removed unused asset pack * code bump * code bump * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * broke out completion of the seed phrase and navigation - Feedback was a user could complete seed phrase and not tap "Game and Sync" - Forced users to start all over - Saved a correct seed phrase confirmation into memory * code bump * fix for https://console.firebase.google.com/project/brainwallet-mobile/crashlytics/app/android:ltd.grunt.brainwallet/issues/1386f366ab35e9112a6b742d629bb0be?time=last-seven-days&types=crash&sessionEventKey=685DA96C00BF00015A7AFEA30E0DB49C_2098799426616143441 * measure where users tap * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly * Cleaned commented out BuyLitecoinscreen * code bump --------- Co-authored-by: andhikayuana * 🚀[Release v4.7.0] Merge into Main (#115) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal * Update issue templates * updated core changes per @andhikayuana * Rename .java to .kt * chore: refactor BRApiManager & APIClient * chore: remove unused part at APIClient * feat: wip new peer discovery * feat: implement selected peer ip address from cache (fetched from API) * feat: implement selected peer ip address from cache (fetched from API) * feat: filter out peers with NODE_NETWORK, NODE_BLOOM * fix: race condition when clear shared prefs values after wipeAll * Updating the core library from the new peer discovery (v4.2.0) * Chore/revert pre peer discovery (Android) (#69) * chore: update core submodule * chore: resolve conflict * Update build.gradle.kts version and code bump * chore: for now at BRPeerManager.wrapConnectV2 only using connect, since the core using hardcoded peers * fix: fix write down confirm screen (#63) * fix: fix write down confirm screen * fix: fix allow seed word item not unique * chore: cherry picked and adjust from - f2fa8e1e4fb9c7429fa86461b24b4463a7969ecf - 98644c425b2fdae7b8b424708fb1a61ad983a9d8 - 93969278da8f95adc0c9f0f8411c8a27876a4d77 - 7ad4b9853b7d1bf7ddbaa576242d8800615a48fb - 8e57d2a67420565b40b753dec5a533776da4821f * fix: fix crash can't parse response inside LtcRepository.fetchRates * fix: fix crash (failed parse) when SelectedPeersRepository.fetchSelectedPeers got unsuccessful response * code bump * fix: ConcurrentModificationException at BRPeerManager.txStatusUpdate * feat: implement new API * code bump --------- Co-authored-by: Kerry Washington * feat: remove unused activity (ImportActivity) at AndroidManifest.xml (#71) * fix: fix crash IllegalStateException: cannot make a new request because the previous response is still open (#73) * code bump * Feat/move tx fee (#74) * chore: add new translations at strings.xml * feat: move network fee to HomeSettingDrawerSheet & remove unused code * fix: fix dismiss allow state loss (#76) * fix: fix typo at strings.xml (#75) * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * version and code bump * Added support url (#81) - changed the language - code bump * version and code bump * Revert from eda0f532 & cherry pick (#86) * version bump * feat: new UI for receive and topup flow (moonpay integration) (#72) * feat: [WIP][UI] new UI for receive and topup flow * feat: [WIP][UI] implement copy address and some refactor * feat: replace webview using CustomTabsIntent from androidx.browser * feat: replace webview using CustomTabsIntent from androidx.browser * feat: add PickerWheel * chore: rename param at QRUtils.generateQR * chore: revert default startDestination at BrainwalletActivity * feat: wip moonpay integration * feat: wip moonpay integration * chore: new UI for ReceiveDialog * chore: parse error from response API at BrainwalletViewModel * chore: add /moonpay/buy-quote and remove dev base url * chore: make LegacyNavigation.showMoonPayWidget receive params for the widget url * chore: add GetMoonpayBuyQuoteResponse * chore: wip moonpay integration to call buy-quote * fix: fix wheel picker for IDR at ReceiveDialog * fix: fix invalid signature * feat: moonpay integration at onboarding flow at BuyLitecoinScreen also fix some stuffs * chore: replace base url for moonpay buy integration when debug * chore: introduce LocalCacheSource.kt and cache fetch limits * chore: adjustment receive dialog UI - debounce fiat currency to 2s - increment in 10 - remove decimal places - default value to 10% of range * chore: reorder bottom navigation item and add new strings * chore: add new translations * chore: refactor UI for buy and receive dialog * chore: cleanup ReceiveDialogViewModel * chore: using MoonpayBuyWidget * chore: adjustment moonpaywidget * chore: for now moonpay widget using CustomTabsIntent * chore: set allowSpend to false when recommend rescan click * fix: add delete transaction data from local database * Removed chatty event * chore: add analytics at BRWalletManager.publishCallback * chore: make sure calculation and static fee same as iOS, add setting for selected fee type --------- Co-authored-by: Kerry Washington * build bump * chore: open bread activity first then open moonpay widget (#88) * Adjustment for circleci (#89) * chore: wip adjustment for screengrab * chore: [circleci] adjust config.yml * chore: [circleci] update config.yml, Fastfile, Gemfile.lock, RecoverWalletScreenGrabsTest.kt * chore: [circleci] for now just unit-test * fix: android: Footer version label is obfuscated (#92) * fix: android: Footer version label is obfuscated * fix: [#92] android: Footer version label is obfuscated * fix: You saved it right screen reset button covers words (#93) * fix: [#84] change seed words layout to lazy vertical grid * fix: [#84] refactor seed words layout * tiny resizing (#94) * code and version bump * change break (#97) adds a android user agent and externalID * build code number fix: [#96] remove bottom_nav_menu_us and just using bottom_nav_menu for consistency (#98) * fix: [#137] fix: Reset fiat options in Buy / Receive modal (#99) * Chore/update device data (#100) * change break adds a android user agent and externalID * Update ReceiveDialogViewModel.kt * chore: refactor request params for fetchMoonpaySignedUrl --------- Co-authored-by: andhikayuana * Add agent string obfuscation (#103) * updated metadata (#105) * chore: remove screen lock detection (#106) * 🧰 Fx/seed words UI polish (#108) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * ❇️ Feat/add polish punjabi farsi (#109) * changed to tap * Added instruction label -added localizations * Added 'empty string for when confirm is completed * version and code bump * fix typo replaced click file with mp3 added error sound * added 3 languages * Removed unused audio files * polished tests * removed unused asset pack * code bump * fix: fix YourSeedProveItState.isWordUsedCorrectly (#111) * Upgrade targetSdk 36 (#113) * chore: change drawable with density for brainwallet_logotype_white * chore: adjustment WelcomeScreen.kt * chore: adjustment for targetSdk 36 also support 16KB page size * bump clean extra semicolon * Update pro-guard-rules * Updated the version --------- Co-authored-by: andhikayuana * Updated games module to v1.1.0 * Updated the games submodule * Renamed and tested with user skips --------- Co-authored-by: andhikayuana * Fix(#227): Crash when launching MoonPay Widget (#126) Refactored the MoonPay widget integration to a dedicated Composable (`MoonPayWidgetLauncher`) to ensure proper state handling and loading behavior. - Added `MoonPayWidgetLauncher.kt` with Composable and ViewModel for managing signed URL fetch and Custom Tab launch. - Ensures loading state covers the whole screen, preventing UI crashes. - Removed legacy static method `LegacyNavigation.showMoonPayWidget`. - Updated `ReceiveDialog.kt` and `BuyLitecoinScreen.kt` to use the new Composable. - Minor cleanup in `LegacyNavigation.kt`. * feat(#138): Improve Unlock Screen UI and add dark mode toggle (#122) * Redesign welcome screen (#123) * Redesign welcome screen * Redesign ready screen * 🚀[Release v4.7.2] Merge into Develop (#127) * 🚀[Release v4.4.7] Merge into Main (#70) * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * Add version and code to welcome screen * reset padding * Revert "Updated the APIManager" This reverts commit 4e252ac29cfb6c3ab26ae5ea4a8f6de154311f2e. # Conflicts: # app/src/main/java/com/brainwallet/tools/manager/APIManager.kt * Reverted the Kotlin APIManager. * fix: fix crash when FragmentSignal dismissed * fix: fix sync after wipe * fix: fix wrong lifecycle to trigger callback at FragmentSignal … * build bump * removed cruft * chore(submodules): remove bugged games repository --------- Co-authored-by: andhikayuana Co-authored-by: Joseph Sanjaya Co-authored-by: Josi Kie <54074780+josikie@users.noreply.github.com> --- app/build.gradle.kts | 4 ++-- .../com/brainwallet/data/source/MessagingTopicDataSource.kt | 1 - .../{source => repository}/FirebaseAnalyticsSourceTest.kt | 0 .../{source => repository}/MessagingTopicDataSourceTest.kt | 0 .../data/{source => repository}/PeerManagerSourceTest.kt | 0 5 files changed, 2 insertions(+), 3 deletions(-) rename app/src/test/java/com/brainwallet/data/{source => repository}/FirebaseAnalyticsSourceTest.kt (100%) rename app/src/test/java/com/brainwallet/data/{source => repository}/MessagingTopicDataSourceTest.kt (100%) rename app/src/test/java/com/brainwallet/data/{source => repository}/PeerManagerSourceTest.kt (100%) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c82c7258..a534b577 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -24,8 +24,8 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 36 - versionCode = 202506296 - versionName = "v4.7.2" + versionCode = 202506298 + versionName = "v4.8.0" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") diff --git a/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt b/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt index 23733158..7e170786 100644 --- a/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/MessagingTopicDataSource.kt @@ -25,7 +25,6 @@ class MessagingTopicDataSource( */ private fun getBaseLanguageCode(languageCode: String): String { val normalizedLanguageCode = languageCode.split("_", "-").first().lowercase() - // Handle reverse mapping: if "id" is passed, treat it as Indonesian val searchCode = when (normalizedLanguageCode) { "id" -> "in" diff --git a/app/src/test/java/com/brainwallet/data/source/FirebaseAnalyticsSourceTest.kt b/app/src/test/java/com/brainwallet/data/repository/FirebaseAnalyticsSourceTest.kt similarity index 100% rename from app/src/test/java/com/brainwallet/data/source/FirebaseAnalyticsSourceTest.kt rename to app/src/test/java/com/brainwallet/data/repository/FirebaseAnalyticsSourceTest.kt diff --git a/app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt b/app/src/test/java/com/brainwallet/data/repository/MessagingTopicDataSourceTest.kt similarity index 100% rename from app/src/test/java/com/brainwallet/data/source/MessagingTopicDataSourceTest.kt rename to app/src/test/java/com/brainwallet/data/repository/MessagingTopicDataSourceTest.kt diff --git a/app/src/test/java/com/brainwallet/data/source/PeerManagerSourceTest.kt b/app/src/test/java/com/brainwallet/data/repository/PeerManagerSourceTest.kt similarity index 100% rename from app/src/test/java/com/brainwallet/data/source/PeerManagerSourceTest.kt rename to app/src/test/java/com/brainwallet/data/repository/PeerManagerSourceTest.kt From d5b14db18bd3209c8322cce1400b8be2dfa5ac7f Mon Sep 17 00:00:00 2001 From: Joseph Sanjaya Date: Sun, 19 Oct 2025 01:53:34 +0700 Subject: [PATCH 078/116] bug(crashlytics): Remove InputWordsActivity from AndroidManifest --- app/src/main/AndroidManifest.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c5746a4d..4792105d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -174,11 +174,7 @@ android:exported="true" android:launchMode="singleTask" android:screenOrientation="portrait" /> - + Date: Wed, 22 Oct 2025 14:04:55 +0700 Subject: [PATCH 079/116] fix(crashlytics): resolve ReEnterPinActivity crashes and deprecation warnings (#148) * fix: resolve ReEnterPinActivity crashes and deprecation warnings - Add missing VIBRATE permission to prevent SecurityException crashes - Fix API compatibility issues with activity transitions (API 29+ support) - Remove unnecessary SDK version checks for vibration (min SDK is 29) refactor: modernize ReEnterPinActivity navigation handling - Replace deprecated onBackPressed with OnBackPressedDispatcher - Update activity transitions to use modern overrideActivityTransition (API 34+) with fallback - Update SetPinActivity to use new ReEnterPinActivity.createIntent() method - Remove legacy Java ReEnterPinActivity and update AndroidManifest references - Clean up BreadActivity references to removed legacy activity * Refactor: Remove legacy PIN activities and layouts This commit removes the legacy PIN management activities (`SetPinActivity`, `ReEnterPinActivity`, `UpdatePinActivity`) and their associated layouts and tests. The functionality for setting, re-entering, and updating the PIN has been consolidated and moved into a modern, composable architecture. Specific changes include: - Deletion of `SetPinActivity`, `UpdatePinActivity`, and their XML layout `activity_pin_template.xml`. - Deletion of the Kotlin-based `ReEnterPinActivity` and its associated MVI components (Intent, State, SideEffect, ViewModel) and unit tests. - Removal of references to these deleted activities from `AndroidManifest.xml` and other parts of the codebase like `PromptManager` and `SecurityCenterActivity`. - Update of `tools:context` attributes in several XML layouts that were incorrectly pointing to `SetPinActivity`. - `PromptManager` and `SecurityCenterActivity` are updated to navigate to the new `BrainwalletActivity` with an `UnLock` route for PIN-related actions. - Cleaned up related code in `BreadActivity` and `ActivityUTILS`. --- app/src/main/AndroidManifest.xml | 21 +- .../presenter/activities/BreadActivity.java | 4 +- .../activities/ReEnterPinActivity.java | 177 --------------- .../presenter/activities/SetPinActivity.java | 146 ------------- .../activities/UpdatePinActivity.java | 204 ------------------ .../settings/SecurityCenterActivity.java | 8 +- .../activities/util/ActivityUTILS.java | 5 +- .../tools/manager/PromptManager.java | 8 +- .../com/brainwallet/ui/composable/PinDot.kt | 56 +++++ .../ui/composable/PinInputComponent.kt | 115 ++++++++++ .../ui/composable/PinInputState.kt | 41 ++++ .../brainwallet/ui/composable/PinKeyboard.kt | 150 +++++++++++++ app/src/main/res/layout/activity_about.xml | 2 +- app/src/main/res/layout/activity_advanced.xml | 2 +- .../res/layout/activity_display_currency.xml | 2 +- app/src/main/res/layout/activity_nodes.xml | 2 +- .../main/res/layout/activity_notification.xml | 2 +- .../main/res/layout/activity_pin_template.xml | 121 ----------- app/src/main/res/layout/activity_settings.xml | 2 +- .../main/res/layout/activity_share_data.xml | 2 +- .../main/res/layout/activity_spend_limit.xml | 2 +- .../res/layout/activity_sync_blockchain.xml | 2 +- 22 files changed, 391 insertions(+), 683 deletions(-) delete mode 100644 app/src/main/java/com/brainwallet/presenter/activities/ReEnterPinActivity.java delete mode 100644 app/src/main/java/com/brainwallet/presenter/activities/SetPinActivity.java delete mode 100644 app/src/main/java/com/brainwallet/presenter/activities/UpdatePinActivity.java create mode 100644 app/src/main/java/com/brainwallet/ui/composable/PinDot.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/PinInputComponent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/PinInputState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/PinKeyboard.kt delete mode 100644 app/src/main/res/layout/activity_pin_template.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4792105d..45e9d663 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,7 @@ + @@ -94,26 +95,14 @@ android:name="android.app.searchable" android:resource="@xml/searchable" /> - + - - + + - \ No newline at end of file + diff --git a/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java index 2fd05ab0..7a82beeb 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java @@ -135,8 +135,6 @@ protected void onCreate(Bundle savedInstanceState) { primaryPrice.setTextSize(PRIMARY_TEXT_SIZE); secondaryPrice.setTextSize(SECONDARY_TEXT_SIZE); - finishActivities(SetPinActivity.introSetPitActivity, ReEnterPinActivity.reEnterPinActivity); - onConnectionChanged(InternetManager.getInstance().isConnected(this)); updateUI(); @@ -544,4 +542,4 @@ public void addNotificationBar() { barFlipper.addView(view); barFlipper.setDisplayedChild(1); } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/brainwallet/presenter/activities/ReEnterPinActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/ReEnterPinActivity.java deleted file mode 100644 index 3fcdcea9..00000000 --- a/app/src/main/java/com/brainwallet/presenter/activities/ReEnterPinActivity.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.brainwallet.presenter.activities; - -import android.os.Bundle; -import android.os.Handler; -import android.view.View; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.brainwallet.R; -import com.brainwallet.presenter.activities.util.BRActivity; -import com.brainwallet.presenter.customviews.BRKeyboard; -import com.brainwallet.presenter.interfaces.BROnSignalCompletion; -import com.brainwallet.tools.animation.BRAnimator; -import com.brainwallet.tools.animation.SpringAnimator; -import com.brainwallet.tools.security.AuthManager; -import com.brainwallet.tools.security.PostAuth; -import com.brainwallet.tools.util.Utils; - -import timber.log.Timber; - -public class ReEnterPinActivity extends BRActivity { - private BRKeyboard keyboard; - public static ReEnterPinActivity reEnterPinActivity; - private View dot1; - private View dot2; - private View dot3; - private View dot4; - private StringBuilder pin = new StringBuilder(); - private TextView title; - private int pinLimit = 4; - private String firstPIN; - private boolean isPressAllowed = true; - private LinearLayout pinLayout; - public static boolean appVisible = false; - private static ReEnterPinActivity app; - - public static ReEnterPinActivity getApp() { - return app; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_pin_template); - - keyboard = (BRKeyboard) findViewById(R.id.brkeyboard); - pinLayout = (LinearLayout) findViewById(R.id.pinLayout); - - ImageButton faq = (ImageButton) findViewById(R.id.faq_button); - //TODO: all views are using the layout of this button. Views should be refactored without it - // Hiding until layouts are built. - - title = (TextView) findViewById(R.id.title); - title.setText(getString(R.string.UpdatePin_createTitleConfirm)); - firstPIN = getIntent().getExtras().getString("pin"); - if (Utils.isNullOrEmpty(firstPIN)) { - throw new RuntimeException("first PIN is required"); - } - reEnterPinActivity = this; - - dot1 = findViewById(R.id.dot1); - dot2 = findViewById(R.id.dot2); - dot3 = findViewById(R.id.dot3); - dot4 = findViewById(R.id.dot4); - - keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() { - @Override - public void onClick(String key) { - handleClick(key); - } - }); - keyboard.setShowDot(false); - } - - @Override - protected void onResume() { - super.onResume(); - updateDots(); - appVisible = true; - app = this; - isPressAllowed = true; - } - - @Override - protected void onPause() { - super.onPause(); - appVisible = false; - } - - private void handleClick(String key) { - if (!isPressAllowed) return; - if (key == null) { - Timber.d("timber: handleClick: key is null! "); - return; - } - - if (key.isEmpty()) { - handleDeleteClick(); - } else if (Character.isDigit(key.charAt(0))) { - handleDigitClick(Integer.parseInt(key.substring(0, 1))); - } else { - Timber.d("timber: handleClick: oops: %s", key); - } - } - - - private void handleDigitClick(Integer dig) { - if (pin.length() < pinLimit) - pin.append(dig); - updateDots(); - } - - private void handleDeleteClick() { - if (pin.length() > 0) - pin.deleteCharAt(pin.length() - 1); - updateDots(); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right); - } - - private void updateDots() { - int selectedDots = pin.length(); - - dot1.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); - selectedDots--; - dot2.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); - selectedDots--; - dot3.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); - selectedDots--; - dot4.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); - selectedDots--; - - if (pin.length() == 4) { - verifyPin(); - } - } - - private void verifyPin() { - if (firstPIN.equalsIgnoreCase(pin.toString())) { - AuthManager.getInstance().authSuccess(this); - isPressAllowed = false; - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - pin = new StringBuilder(); - updateDots(); - } - }, 200); - AuthManager.getInstance().setPinCode(pin.toString(), this); - if (getIntent().getBooleanExtra("noPin", false)) { - BRAnimator.startBreadActivity(this, false); - } else { - BRAnimator.showBreadSignal(this, getString(R.string.Alerts_pinSet), getString(R.string.UpdatePin_createInstruction), R.drawable.ic_check_mark_white, new BROnSignalCompletion() { - @Override - public void onComplete() { - PostAuth.getInstance().onCreateWalletAuth(ReEnterPinActivity.this, false); - } - }); - } - } else { - AuthManager.getInstance().authFail(this); - Timber.d("timber: verifyPin: FAIL: firs: %s, reEnter: %s ", firstPIN, pin); - SpringAnimator.failShakeAnimation(this, pinLayout); - pin = new StringBuilder(); - } - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - } -} diff --git a/app/src/main/java/com/brainwallet/presenter/activities/SetPinActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/SetPinActivity.java deleted file mode 100644 index 887ac96d..00000000 --- a/app/src/main/java/com/brainwallet/presenter/activities/SetPinActivity.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.brainwallet.presenter.activities; - -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.view.View; -import android.widget.ImageButton; -import android.widget.TextView; - -import com.brainwallet.R; -import com.brainwallet.presenter.activities.util.BRActivity; -import com.brainwallet.presenter.customviews.BRKeyboard; -import com.brainwallet.tools.manager.BRSharedPrefs; - -import timber.log.Timber; - -public class SetPinActivity extends BRActivity { - private BRKeyboard keyboard; - public static SetPinActivity introSetPitActivity; - private View dot1; - private View dot2; - private View dot3; - private View dot4; - - private ImageButton faq; - private StringBuilder pin = new StringBuilder(); - private int pinLimit = 4; - private boolean startingNextActivity; - private TextView title; - public static boolean appVisible = false; - private static SetPinActivity app; - - public static SetPinActivity getApp() { - return app; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_pin_template); - - keyboard = (BRKeyboard) findViewById(R.id.brkeyboard); - title = (TextView) findViewById(R.id.title); - - - //TODO: all views are using the layout of this button. Views should be refactored without it - // Hiding until layouts are built. - faq = (ImageButton) findViewById(R.id.faq_button); - dot1 = findViewById(R.id.dot1); - dot2 = findViewById(R.id.dot2); - dot3 = findViewById(R.id.dot3); - dot4 = findViewById(R.id.dot4); - - keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() { - @Override - public void onClick(String key) { - handleClick(key); - } - }); - keyboard.setShowDot(false); - } - - @Override - protected void onResume() { - super.onResume(); - updateDots(); - introSetPitActivity = this; - appVisible = true; - app = this; - } - - @Override - protected void onPause() { - super.onPause(); - appVisible = false; - } - - private void handleClick(String key) { - if (key == null) { - Timber.d("timber: handleClick: key is null! "); - return; - } - - if (key.isEmpty()) { - handleDeleteClick(); - } else if (Character.isDigit(key.charAt(0))) { - handleDigitClick(Integer.parseInt(key.substring(0, 1))); - } else { - Timber.d("timber: handleClick: oops: %s", key); - } - } - - - private void handleDigitClick(Integer dig) { - if (pin.length() < pinLimit) - pin.append(dig); - updateDots(); - } - - private void handleDeleteClick() { - if (pin.length() > 0) - pin.deleteCharAt(pin.length() - 1); - updateDots(); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right); - } - - private void updateDots() { - int selectedDots = pin.length(); - dot1.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); - selectedDots--; - dot2.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); - selectedDots--; - dot3.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); - selectedDots--; - dot4.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); - selectedDots--; - - if (pin.length() ==4) { - if (startingNextActivity) return; - startingNextActivity = true; - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - Intent intent = new Intent(SetPinActivity.this, ReEnterPinActivity.class); - intent.putExtra("pin", pin.toString()); - intent.putExtra("noPin", getIntent().getBooleanExtra("noPin", false)); - startActivity(intent); - overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left); - pin = new StringBuilder(""); - startingNextActivity = false; - } - }, 100); - } - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - - } -} diff --git a/app/src/main/java/com/brainwallet/presenter/activities/UpdatePinActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/UpdatePinActivity.java deleted file mode 100644 index b595bd77..00000000 --- a/app/src/main/java/com/brainwallet/presenter/activities/UpdatePinActivity.java +++ /dev/null @@ -1,204 +0,0 @@ -package com.brainwallet.presenter.activities; - -import static com.brainwallet.tools.util.BRConstants.BW_PIN_LENGTH; - -import android.os.Bundle; -import android.os.Handler; -import android.view.View; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.TextView; - -import com.brainwallet.R; -import com.brainwallet.presenter.activities.util.BRActivity; -import com.brainwallet.presenter.customviews.BRKeyboard; -import com.brainwallet.presenter.interfaces.BROnSignalCompletion; -import com.brainwallet.tools.animation.BRAnimator; -import com.brainwallet.tools.animation.SpringAnimator; -import com.brainwallet.tools.security.AuthManager; -import com.brainwallet.tools.security.BRKeyStore; - -import timber.log.Timber; - -public class UpdatePinActivity extends BRActivity { - private BRKeyboard keyboard; - private View dot1; - private View dot2; - private View dot3; - private View dot4; - private StringBuilder pin = new StringBuilder(); - private int pinLimit = 4; - // private boolean allowInserting = true; - private TextView title; - private TextView description; - int mode = ENTER_PIN; - public static final int ENTER_PIN = 1; - public static final int ENTER_NEW_PIN = 2; - public static final int RE_ENTER_NEW_PIN = 3; - - private ImageButton faq; - private LinearLayout pinLayout; - private String curNewPin = ""; - public static boolean appVisible = false; - private static UpdatePinActivity app; - - public static UpdatePinActivity getApp() { - return app; - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_pin_template); - - keyboard = (BRKeyboard) findViewById(R.id.brkeyboard); - title = (TextView) findViewById(R.id.title); - description = (TextView) findViewById(R.id.description); - pinLayout = (LinearLayout) findViewById(R.id.pinLayout); - if (BRKeyStore.getPinCode(this).length() == BW_PIN_LENGTH) pinLimit = BW_PIN_LENGTH; - setMode(ENTER_PIN); - title.setText(getString(R.string.UpdatePin_updateTitle)); - dot1 = findViewById(R.id.dot1); - dot2 = findViewById(R.id.dot2); - dot3 = findViewById(R.id.dot3); - dot4 = findViewById(R.id.dot4); - - //TODO: all views are using the layout of this button. Views should be refactored without it - // Hiding until layouts are built. - faq = (ImageButton) findViewById(R.id.faq_button); - - keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() { - @Override - public void onClick(String key) { - handleClick(key); - } - }); - keyboard.setShowDot(false); - - } - - @Override - protected void onResume() { - super.onResume(); - updateDots(); - appVisible = true; - app = this; - } - - @Override - protected void onPause() { - super.onPause(); - appVisible = false; - } - - private void handleClick(String key) { - if (key == null) { - Timber.d("timber: handleClick: key is null! "); - return; - } - - if (key.isEmpty()) { - handleDeleteClick(); - } else if (Character.isDigit(key.charAt(0))) { - handleDigitClick(Integer.parseInt(key.substring(0, 1))); - } else { - Timber.d("timber: handleClick: oops: %s", key); - } - } - - - private void handleDigitClick(Integer dig) { - if (pin.length() < pinLimit) - pin.append(dig); - updateDots(); - } - - private void handleDeleteClick() { - if (pin.length() > 0) - pin.deleteCharAt(pin.length() - 1); - updateDots(); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right); - } - - private void updateDots() { - - AuthManager.getInstance().updateDots(this, pinLimit, pin.toString(), dot1, dot2, dot3, dot4, R.drawable.ic_pin_dot_gray, new AuthManager.OnPinSuccess() { - @Override - public void onSuccess() { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - goNext(); - } - }, 100); - } - }); - } - - private void goNext() { - switch (mode) { - case ENTER_PIN: - if (AuthManager.getInstance().checkAuth(pin.toString(), this)) { - setMode(ENTER_NEW_PIN); - pinLimit = 4; - } else { - SpringAnimator.failShakeAnimation(this, pinLayout); - } - pin = new StringBuilder(); - updateDots(); - break; - case ENTER_NEW_PIN: - setMode(RE_ENTER_NEW_PIN); - curNewPin = pin.toString(); - pin = new StringBuilder(); - updateDots(); - break; - - case RE_ENTER_NEW_PIN: - if (curNewPin.equalsIgnoreCase(pin.toString())) { - AuthManager.getInstance().setPinCode(pin.toString(), this); - BRAnimator.showBreadSignal(this, getString(R.string.Alerts_pinSet), getString(R.string.UpdatePin_caption), R.drawable.ic_check_mark_white, new BROnSignalCompletion() { - @Override - public void onComplete() { - BRAnimator.startBreadActivity(UpdatePinActivity.this, false); - } - }); - } else { - SpringAnimator.failShakeAnimation(this, pinLayout); - setMode(ENTER_NEW_PIN); - pinLimit = BRKeyStore.getPinCode(this).length(); - } - pin = new StringBuilder(); - updateDots(); - break; - } - } - - private void setMode(int mode) { - String text = ""; - this.mode = mode; - switch (mode) { - case ENTER_PIN: - text = getString(R.string.UpdatePin_enterCurrent); - break; - case ENTER_NEW_PIN: - text = getString(R.string.UpdatePin_enterNew); - break; - case RE_ENTER_NEW_PIN: - text = getString(R.string.UpdatePin_reEnterNew); - break; - } - description.setText(text); - SpringAnimator.springView(description); - } - - @Override - protected void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - } -} diff --git a/app/src/main/java/com/brainwallet/presenter/activities/settings/SecurityCenterActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/settings/SecurityCenterActivity.java index 6929f188..8d7fa3d1 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/settings/SecurityCenterActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/settings/SecurityCenterActivity.java @@ -21,7 +21,8 @@ import androidx.annotation.Nullable; import com.brainwallet.R; -import com.brainwallet.presenter.activities.UpdatePinActivity; +import com.brainwallet.navigation.Route; +import com.brainwallet.ui.BrainwalletActivity; import com.brainwallet.presenter.activities.intro.WriteDownActivity; import com.brainwallet.presenter.activities.util.ActivityUTILS; import com.brainwallet.presenter.activities.util.BRActivity; @@ -152,7 +153,10 @@ private void updateList() { isPinSet ? R.drawable.ic_check_mark_blue : R.drawable.ic_check_mark_grey, new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(SecurityCenterActivity.this, UpdatePinActivity.class); + Intent intent = BrainwalletActivity.createIntent( + SecurityCenterActivity.this, + new Route.UnLock(true) + ); startActivity(intent); overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left); } diff --git a/app/src/main/java/com/brainwallet/presenter/activities/util/ActivityUTILS.java b/app/src/main/java/com/brainwallet/presenter/activities/util/ActivityUTILS.java index 2ab77397..56fc3ded 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/util/ActivityUTILS.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/util/ActivityUTILS.java @@ -9,7 +9,7 @@ import com.brainwallet.R; import com.brainwallet.presenter.activities.DisabledActivity; -import com.brainwallet.presenter.activities.SetPinActivity; + import com.brainwallet.ui.BrainwalletActivity; import java.util.List; @@ -20,8 +20,7 @@ public class ActivityUTILS { //return true if the app does need to show the disabled wallet screen public static boolean isAppSafe(Activity app) { -// return app instanceof SetPinActivity || app instanceof InputWordsActivity; - return app instanceof SetPinActivity || app instanceof BrainwalletActivity; + return app instanceof BrainwalletActivity; } public static void showWalletDisabled(Activity app) { diff --git a/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java b/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java index a716d7f7..6eed34f7 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java @@ -13,7 +13,8 @@ import com.brainwallet.tools.security.BRKeyStore; import com.brainwallet.tools.threads.BRExecutor; import com.brainwallet.R; -import com.brainwallet.presenter.activities.UpdatePinActivity; +import com.brainwallet.navigation.Route; +import com.brainwallet.ui.BrainwalletActivity; import com.brainwallet.wallet.BRPeerManager; public class PromptManager { @@ -74,7 +75,10 @@ public PromptInfo promptInfo(final Activity app, PromptItem item) { return new PromptInfo(app.getString(R.string.Prompts_UpgradePin_title), app.getString(R.string.Prompts_UpgradePin_body), new View.OnClickListener() { @Override public void onClick(View v) { - Intent intent = new Intent(app, UpdatePinActivity.class); + Intent intent = BrainwalletActivity.createIntent( + app, + new Route.UnLock(true) + ); app.startActivity(intent); app.overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left); } diff --git a/app/src/main/java/com/brainwallet/ui/composable/PinDot.kt b/app/src/main/java/com/brainwallet/ui/composable/PinDot.kt new file mode 100644 index 00000000..74a48d0f --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/PinDot.kt @@ -0,0 +1,56 @@ +package com.brainwallet.ui.composable + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme + +@Composable +fun PinDot( + isFilled: Boolean, + modifier: Modifier = Modifier +) { + Box( + modifier = modifier + .size(32.dp) + .background( + color = if (isFilled) { + BrainwalletTheme.colors.content + } else { + Color.Transparent + }, + shape = CircleShape + ) + .border( + width = 2.dp, + color = BrainwalletTheme.colors.content.copy(alpha = 0.6f), + shape = CircleShape + ) + ) +} + +@Preview(name = "Light Theme - Empty") +@Preview(name = "Dark Theme - Empty", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun PinDotEmptyPreview() { + BrainwalletTheme(darkTheme = false) { + PinDot(isFilled = false) + } +} + +@Preview(name = "Light Theme - Filled") +@Preview(name = "Dark Theme - Filled", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun PinDotFilledPreview() { + BrainwalletTheme(darkTheme = false) { + PinDot(isFilled = true) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/PinInputComponent.kt b/app/src/main/java/com/brainwallet/ui/composable/PinInputComponent.kt new file mode 100644 index 00000000..ab4d5fd4 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/PinInputComponent.kt @@ -0,0 +1,115 @@ +package com.brainwallet.ui.composable + +import android.content.res.Configuration +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme + +@Composable +fun PinInputComponent( + pinState: PinInputState, + onPinComplete: (String) -> Unit, + modifier: Modifier = Modifier, + maxLength: Int = 4 +) { + LaunchedEffect(pinState.isComplete) { + if (pinState.isComplete) { + onPinComplete(pinState.getPinAsString()) + } + } + + Column( + modifier = modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(32.dp) + ) { + // PIN dots display + Row( + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + repeat(maxLength) { index -> + PinDot( + isFilled = index < pinState.pinLength + ) + } + } + + Spacer(modifier = Modifier.height(16.dp)) + + // PIN keyboard + PinKeyboard( + onDigitClick = { digit -> + pinState.addDigit(digit) + }, + onDeleteClick = { + pinState.deleteDigit() + } + ) + } +} + +@Composable +fun PinInputComponent( + onPinComplete: (String) -> Unit, + modifier: Modifier = Modifier, + maxLength: Int = 4 +) { + val pinState = rememberPinInputState(maxLength = maxLength) + + PinInputComponent( + pinState = pinState, + onPinComplete = onPinComplete, + modifier = modifier, + maxLength = maxLength + ) +} + +@Preview(name = "Light Theme - Empty") +@Preview(name = "Dark Theme - Empty", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun PinInputComponentEmptyPreview() { + BrainwalletTheme(darkTheme = false) { + Column( + modifier = Modifier.padding(16.dp) + ) { + val pinState = rememberPinInputState() + PinInputComponent( + pinState = pinState, + onPinComplete = { } + ) + } + } +} + +@Preview(name = "Light Theme - Partial") +@Preview(name = "Dark Theme - Partial", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun PinInputComponentPartialPreview() { + BrainwalletTheme(darkTheme = false) { + Column( + modifier = Modifier.padding(16.dp) + ) { + val pinState = rememberPinInputState() + // Simulate partial input + pinState.addDigit(1) + pinState.addDigit(2) + + PinInputComponent( + pinState = pinState, + onPinComplete = { } + ) + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/PinInputState.kt b/app/src/main/java/com/brainwallet/ui/composable/PinInputState.kt new file mode 100644 index 00000000..93b3ebca --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/PinInputState.kt @@ -0,0 +1,41 @@ +package com.brainwallet.ui.composable + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue + +@Stable +class PinInputState(private val maxLength: Int = 4) { + var pin by mutableStateOf("") + private set + + val pinLength: Int get() = pin.length + val isComplete: Boolean get() = pin.length == maxLength + val isEmpty: Boolean get() = pin.isEmpty() + + fun addDigit(digit: Int) { + if (pin.length < maxLength && digit in 0..9) { + pin += digit.toString() + } + } + + fun deleteDigit() { + if (pin.isNotEmpty()) { + pin = pin.dropLast(1) + } + } + + fun clear() { + pin = "" + } + + fun getPinAsString(): String = pin +} + +@Composable +fun rememberPinInputState(maxLength: Int = 4): PinInputState { + return remember { PinInputState(maxLength) } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/PinKeyboard.kt b/app/src/main/java/com/brainwallet/ui/composable/PinKeyboard.kt new file mode 100644 index 00000000..431e8014 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/PinKeyboard.kt @@ -0,0 +1,150 @@ +package com.brainwallet.ui.composable + +import android.content.res.Configuration +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ArrowBack +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButtonDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme + +@Composable +fun PinKeyboard( + onDigitClick: (Int) -> Unit, + onDeleteClick: () -> Unit, + modifier: Modifier = Modifier +) { + Column( + modifier = modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(24.dp) + ) { + // First row: 1, 2, 3 + Row( + horizontalArrangement = Arrangement.spacedBy(24.dp) + ) { + repeat(3) { index -> + val number = index + 1 + PinKeyboardButton( + onClick = { onDigitClick(number) }, + modifier = Modifier.testTag("keypad$number") + ) { + Text( + text = number.toString(), + style = MaterialTheme.typography.headlineMedium, + ) + } + } + } + + // Second row: 4, 5, 6 + Row( + horizontalArrangement = Arrangement.spacedBy(24.dp) + ) { + repeat(3) { index -> + val number = index + 4 + PinKeyboardButton( + onClick = { onDigitClick(number) }, + modifier = Modifier.testTag("keypad$number") + ) { + Text( + text = number.toString(), + style = MaterialTheme.typography.headlineMedium, + ) + } + } + } + + // Third row: 7, 8, 9 + Row( + horizontalArrangement = Arrangement.spacedBy(24.dp) + ) { + repeat(3) { index -> + val number = index + 7 + PinKeyboardButton( + onClick = { onDigitClick(number) }, + modifier = Modifier.testTag("keypad$number") + ) { + Text( + text = number.toString(), + style = MaterialTheme.typography.headlineMedium, + ) + } + } + } + + // Fourth row: empty, 0, delete + Row( + horizontalArrangement = Arrangement.spacedBy(24.dp) + ) { + // Empty space + Spacer(modifier = Modifier.size(75.dp)) + + // Zero button + PinKeyboardButton( + onClick = { onDigitClick(0) }, + modifier = Modifier.testTag("keypad0") + ) { + Text( + text = "0", + style = MaterialTheme.typography.headlineMedium, + ) + } + + // Delete button + PinKeyboardButton( + onClick = onDeleteClick, + colors = IconButtonDefaults.filledIconButtonColors( + containerColor = Color.Transparent + ) + ) { + Icon( + Icons.AutoMirrored.Filled.ArrowBack, + contentDescription = "Delete", + tint = BrainwalletTheme.colors.content + ) + } + } + } +} + +@Composable +private fun PinKeyboardButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + colors: androidx.compose.material3.IconButtonColors = IconButtonDefaults.filledIconButtonColors(), + content: @Composable () -> Unit +) { + CircleButton( + modifier = modifier.size(75.dp), + onClick = onClick, + colors = colors, + content = content + ) +} + +@Preview(name = "Light Theme") +@Preview(name = "Dark Theme", uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +private fun PinKeyboardPreview() { + BrainwalletTheme(darkTheme = false) { + PinKeyboard( + onDigitClick = { }, + onDeleteClick = { } + ) + } +} diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index eadf7662..14b960e3 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -5,7 +5,7 @@ android:id="@+id/activity_intro_set_pit" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.brainwallet.presenter.activities.SetPinActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml index 1b7328c8..99a89208 100644 --- a/app/src/main/res/layout/activity_settings.xml +++ b/app/src/main/res/layout/activity_settings.xml @@ -5,7 +5,7 @@ android:id="@+id/activity_intro_set_pit" android:layout_width="match_parent" android:layout_height="match_parent" - tools:context="com.brainwallet.presenter.activities.SetPinActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> + tools:context=".presenter.activities.settings.SettingsActivity"> Date: Wed, 22 Oct 2025 19:48:12 +0700 Subject: [PATCH 080/116] Remove resizability and orientation restrictions in our app (#146) * Remove resizability and orientation restrictions in our apps to support large screen devices * Remove resizability and orientation restrictions in bread activity * Lock the unlockscreen composable to potrait --- app/src/main/AndroidManifest.xml | 40 +++++++++---------- .../ui/screens/unlock/UnLockScreen.kt | 10 +++++ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 45e9d663..7f7fd339 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -65,7 +65,6 @@ @@ -77,7 +76,6 @@ android:name=".presenter.activities.BreadActivity" android:exported="true" android:launchMode="singleTask" - android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan"> @@ -107,57 +105,57 @@ android:name=".presenter.activities.LoginActivity" android:exported="true" android:launchMode="singleTask" - android:screenOrientation="portrait" /> + /> + /> + /> + /> + /> + /> + /> + /> + /> + /> + /> + /> + /> + /> + /> + /> + /> Date: Fri, 14 Nov 2025 16:11:23 +0700 Subject: [PATCH 081/116] build: Build secp256k1 as a static library and add ABI splits (#149) This commit refactors the native build process and enhances library loading. Key changes: - `CMakeLists.txt` is updated to build `secp256k1` as a separate static library. This modularizes the build and allows for specific optimization flags. - Architecture-specific optimizations (`-O3 -ffast-math`) are now applied to both `core-lib` and `secp256k1` for the `arm64-v8a` ABI. - In `build.gradle.kts`, ABI splitting is enabled to create smaller, architecture-specific APKs. - `BRActivity.java` is updated with improved error handling for native library loading. It now includes more detailed logging and a fallback mechanism to load the library from an explicit path if the standard `System.loadLibrary` call fails. --- app/CMakeLists.txt | 29 +++++++++++++++++++ app/build.gradle.kts | 3 ++ .../presenter/activities/util/BRActivity.java | 8 ++++- 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index d17111b0..27142a3f 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -4,6 +4,9 @@ cmake_minimum_required(VERSION 3.4.1) +# Define the project +project(brainwallet-core) + # Specifies a library name, specifies whether the library is STATIC or # SHARED, and provides relative paths to the source code. You can # define multiple libraries by adding multiple add_library() commands, @@ -84,11 +87,37 @@ include_directories(src/main/secp/secp256k1/src/) include_directories(src/main/secp/secp256k1/) include_directories(src/main/secp/) +# Build secp256k1 as a static library first +add_library(secp256k1 STATIC + src/main/secp/secp256k1/src/secp256k1.c) + +target_include_directories(secp256k1 PRIVATE + src/main/secp/secp256k1/ + src/main/secp/secp256k1/src/ + src/main/secp/secp256k1/include/) + +target_compile_definitions(secp256k1 PRIVATE + USE_NUM_NONE=1 + USE_FIELD_INV_BUILTIN=1 + USE_SCALAR_INV_BUILTIN=1 + HAVE___INT128=1 + USE_FIELD_5X52=1 + USE_SCALAR_4X64=1 + ENABLE_MODULE_RECOVERY=1 + ENABLE_MODULE_ECDH=1) + # support compiling 16 KB-aligned: https://developer.android.com/guide/practices/page-sizes#cmake target_link_options(core-lib PRIVATE "-Wl,-z,max-page-size=16384") +# Architecture-specific optimizations +if(${ANDROID_ABI} STREQUAL "arm64-v8a") + target_compile_options(core-lib PRIVATE -O3 -ffast-math) + target_compile_options(secp256k1 PRIVATE -O3 -ffast-math) +endif() + # add lib dependencies target_link_libraries( core-lib + secp256k1 android log) \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 8d9f1fc7..a6166d65 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -156,6 +156,9 @@ android { language { enableSplit = false } + abi { + enableSplit = true + } } buildFeatures { diff --git a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java index df68dc39..0081d7d0 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java @@ -35,7 +35,13 @@ public class BRActivity extends AppCompatActivity { static { - System.loadLibrary(BRConstants.NATIVE_LIB_NAME); + try { + System.loadLibrary(BRConstants.NATIVE_LIB_NAME); + timber.log.Timber.d("Successfully loaded %s", BRConstants.NATIVE_LIB_NAME); + } catch (UnsatisfiedLinkError e) { + timber.log.Timber.e(e, "Failed to load %s on ABI: %s", BRConstants.NATIVE_LIB_NAME, android.os.Build.SUPPORTED_ABIS[0]); + throw e; + } } private SettingRepository settingRepository = (SettingRepository) KoinJavaComponent.inject(SettingRepository.class).getValue(); From aeb5ab5ba0a1f71f31e6f782fb801f202dcbc2f0 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 7 Feb 2026 07:03:27 +0000 Subject: [PATCH 082/116] version bump (#159) Reviewing the code for a update --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a6166d65..3c19fc21 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -24,7 +24,7 @@ android { applicationId = "ltd.grunt.brainwallet" minSdk = 29 targetSdk = 36 - versionCode = 202506299 + versionCode = 202506301 versionName = "v4.8.0" multiDexEnabled = true From 8cabf2a8e12e504b4048fb7c51ad5cdfea923afb Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sat, 7 Feb 2026 14:05:00 +0000 Subject: [PATCH 083/116] Revert "build: Build secp256k1 as a static library and add ABI splits (#149)" This reverts commit 2f06f5cbd6369e8112111edfb6078a43ad58d19b. --- app/CMakeLists.txt | 29 ------------------- app/build.gradle.kts | 3 -- .../presenter/activities/util/BRActivity.java | 8 +---- 3 files changed, 1 insertion(+), 39 deletions(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 27142a3f..d17111b0 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -4,9 +4,6 @@ cmake_minimum_required(VERSION 3.4.1) -# Define the project -project(brainwallet-core) - # Specifies a library name, specifies whether the library is STATIC or # SHARED, and provides relative paths to the source code. You can # define multiple libraries by adding multiple add_library() commands, @@ -87,37 +84,11 @@ include_directories(src/main/secp/secp256k1/src/) include_directories(src/main/secp/secp256k1/) include_directories(src/main/secp/) -# Build secp256k1 as a static library first -add_library(secp256k1 STATIC - src/main/secp/secp256k1/src/secp256k1.c) - -target_include_directories(secp256k1 PRIVATE - src/main/secp/secp256k1/ - src/main/secp/secp256k1/src/ - src/main/secp/secp256k1/include/) - -target_compile_definitions(secp256k1 PRIVATE - USE_NUM_NONE=1 - USE_FIELD_INV_BUILTIN=1 - USE_SCALAR_INV_BUILTIN=1 - HAVE___INT128=1 - USE_FIELD_5X52=1 - USE_SCALAR_4X64=1 - ENABLE_MODULE_RECOVERY=1 - ENABLE_MODULE_ECDH=1) - # support compiling 16 KB-aligned: https://developer.android.com/guide/practices/page-sizes#cmake target_link_options(core-lib PRIVATE "-Wl,-z,max-page-size=16384") -# Architecture-specific optimizations -if(${ANDROID_ABI} STREQUAL "arm64-v8a") - target_compile_options(core-lib PRIVATE -O3 -ffast-math) - target_compile_options(secp256k1 PRIVATE -O3 -ffast-math) -endif() - # add lib dependencies target_link_libraries( core-lib - secp256k1 android log) \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3c19fc21..f7266ec2 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -156,9 +156,6 @@ android { language { enableSplit = false } - abi { - enableSplit = true - } } buildFeatures { diff --git a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java index 0081d7d0..df68dc39 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java @@ -35,13 +35,7 @@ public class BRActivity extends AppCompatActivity { static { - try { - System.loadLibrary(BRConstants.NATIVE_LIB_NAME); - timber.log.Timber.d("Successfully loaded %s", BRConstants.NATIVE_LIB_NAME); - } catch (UnsatisfiedLinkError e) { - timber.log.Timber.e(e, "Failed to load %s on ABI: %s", BRConstants.NATIVE_LIB_NAME, android.os.Build.SUPPORTED_ABIS[0]); - throw e; - } + System.loadLibrary(BRConstants.NATIVE_LIB_NAME); } private SettingRepository settingRepository = (SettingRepository) KoinJavaComponent.inject(SettingRepository.class).getValue(); From 0a46627a2704f760ea19ac89bcbc3ca5ef9d945e Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 8 Feb 2026 14:49:09 +0000 Subject: [PATCH 084/116] Techdebt/adjust build logic (#161) * Renaming the build logic repo * rename the location of the build logic * reset the path * updated the build logic and private gp * updated the private gp * Paired with @kcw-grunt, @josikie to verify the android build logic and private repo. --------- Co-authored-by: josikie --- .gitmodules | 4 ++-- README.md | 3 +++ android-build-logic | 1 + app/build.gradle.kts | 42 ++++++++++++++++----------------- gruntsoftware-build-logic | 1 - modules/private-general-purpose | 2 +- settings.gradle.kts | 4 ++-- 7 files changed, 30 insertions(+), 27 deletions(-) create mode 160000 android-build-logic delete mode 160000 gruntsoftware-build-logic diff --git a/.gitmodules b/.gitmodules index e276968c..b9973416 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,6 +7,6 @@ [submodule "modules/private-general-purpose"] path = modules/private-general-purpose url = https://github.com/gruntsoftware/android-private-general-purpose.git -[submodule "gruntsoftware-build-logic"] - path = gruntsoftware-build-logic +[submodule "android-build-logic"] + path = android-build-logic url = https://github.com/gruntsoftware/android-build-logic.git diff --git a/README.md b/README.md index 0c961d8d..f508e2aa 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,6 @@ Brainwallet is a easy and fun way to use your crypto (Litecoin) and memorize you - v4.5.4 - Added new MP Buy UI + +### Dev notes +- Paired with @kcw-grunt, @josikie to verify the android build logic and private repo. diff --git a/android-build-logic b/android-build-logic new file mode 160000 index 00000000..f16c2999 --- /dev/null +++ b/android-build-logic @@ -0,0 +1 @@ +Subproject commit f16c29991b1e865af15b00a4d6c3a6f294a15d28 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index f7266ec2..9bbab904 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -53,12 +53,12 @@ android { keyAlias = localProperties.getProperty("DEBUG_KEY_ALIAS") keyPassword = localProperties.getProperty("DEBUG_KEY_PASSWORD") } - val release by creating { - storeFile = file(localProperties.getProperty("RELEASE_STORE_FILE")) - storePassword = localProperties.getProperty("RELEASE_STORE_PASSWORD") - keyAlias = localProperties.getProperty("RELEASE_KEY_ALIAS") - keyPassword = localProperties.getProperty("RELEASE_KEY_PASSWORD") - } +// val release by creating { +// storeFile = file(localProperties.getProperty("RELEASE_STORE_FILE")) +// storePassword = localProperties.getProperty("RELEASE_STORE_PASSWORD") +// keyAlias = localProperties.getProperty("RELEASE_KEY_ALIAS") +// keyPassword = localProperties.getProperty("RELEASE_KEY_PASSWORD") +// } } buildTypes { @@ -83,21 +83,21 @@ android { ) } - val release by getting { - signingConfig = signingConfigs.getByName("release") - isDebuggable = false - isMinifyEnabled = true - proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") - - ndk { - isDebuggable = false - isMinifyEnabled = true - } - - firebaseCrashlytics { - nativeSymbolUploadEnabled = true - } - } +// val release by getting { +// signingConfig = signingConfigs.getByName("release") +// isDebuggable = false +// isMinifyEnabled = true +// proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") +// +// ndk { +// isDebuggable = false +// isMinifyEnabled = true +// } +// +// firebaseCrashlytics { +// nativeSymbolUploadEnabled = true +// } +// } } diff --git a/gruntsoftware-build-logic b/gruntsoftware-build-logic deleted file mode 160000 index 2b00192e..00000000 --- a/gruntsoftware-build-logic +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2b00192e99ee10540a49782c7d02dfc3e79c8afe diff --git a/modules/private-general-purpose b/modules/private-general-purpose index 8c366827..5d8e9f99 160000 --- a/modules/private-general-purpose +++ b/modules/private-general-purpose @@ -1 +1 @@ -Subproject commit 8c366827c82519e30841517eb0e314f3468e707b +Subproject commit 5d8e9f9967ffc396082f84dc6b5c6749a81c7e41 diff --git a/settings.gradle.kts b/settings.gradle.kts index 25b6aadb..bbbebf96 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,5 @@ pluginManagement { - includeBuild("gruntsoftware-build-logic") + includeBuild("android-build-logic") repositories { google { content { @@ -21,7 +21,7 @@ dependencyResolutionManagement { } versionCatalogs { create("grunt") { - from(files("gruntsoftware-build-logic/gradle/libs.versions.toml")) + from(files("android-build-logic/gradle/libs.versions.toml")) } } } From 573825456fb95c7dec23cebd139fccd88df2c937 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Thu, 9 Apr 2026 23:22:41 +0100 Subject: [PATCH 085/116] Added auto translate (#178) * Add auto-translate workflow for strings.xml This workflow automatically translates missing strings in strings.xml files when changes are pushed to specific branches or manually triggered. It checks for changes, creates a new branch for translations, commits the updates, and opens a pull request if there are any changes. * Added auto translate files per push * Polished files * fixed typo * nit --- .github/workflows/SETUP_GUIDE.md | 174 +++++++++++++++++++++ .github/workflows/auto-translate.yml | 74 +++++++++ scripts/translate_strings.py | 217 +++++++++++++++++++++++++++ 3 files changed, 465 insertions(+) create mode 100644 .github/workflows/SETUP_GUIDE.md create mode 100644 .github/workflows/auto-translate.yml create mode 100755 scripts/translate_strings.py diff --git a/.github/workflows/SETUP_GUIDE.md b/.github/workflows/SETUP_GUIDE.md new file mode 100644 index 00000000..e6fa8e41 --- /dev/null +++ b/.github/workflows/SETUP_GUIDE.md @@ -0,0 +1,174 @@ +# 🌍 Brainwallet Android — Auto-Translation Setup Guide + +## What this does + +Every time code is pushed to `main`/`master` that touches +`app/src/main/res/values/strings.xml`, a GitHub Actions workflow: + +1. Finds every locale `strings.xml` under `app/src/main/res/values-*/` +2. Detects strings that are missing or empty in each locale file +3. Calls the Claude API to translate the missing strings +4. Creates a new branch `translations/auto-YYYYMMDD-HHMMSS` +5. Commits the updated locale files +6. Opens a Pull Request with a table summarising what was translated + +--- + +## Files to add to your repository + +``` +your-android-repo/ +├── .github/ +│ └── workflows/ +│ └── auto-translate.yml ← copy from this package +└── scripts/ + └── translate_strings.py ← copy from this package +``` + +--- + +## Step 1 — Create a GitHub Personal Access Token (PAT) + +The workflow needs permission to create branches and open PRs. + +1. Go to **https://github.com/settings/tokens?type=beta** + *(Fine-grained tokens — more secure than classic tokens)* + +2. Click **"Generate new token"** + +3. Fill in: + | Field | Value | + |---|---| + | **Token name** | `brainwallet-translations` | + | **Expiration** | 1 year (or "No expiration") | + | **Repository access** | Only select repositories → `gruntsoftware/android` | + +4. Under **Repository permissions**, set: + | Permission | Access | + |---|---| + | **Contents** | Read and write | + | **Pull requests** | Read and write | + | **Workflows** | Read and write | + | **Metadata** | Read-only *(auto-selected)* | + +5. Click **"Generate token"** and **copy it immediately** — you won't see it again. + +--- + +## Step 2 — Add secrets to the repository + +Go to: +**https://github.com/gruntsoftware/android/settings/secrets/actions** + +Add two secrets: + +| Secret name | Value | +|---|---| +| `TRANSLATION_PAT` | The PAT you just created in Step 1 | +| `ANTHROPIC_API_KEY` | Your Anthropic API key from https://console.anthropic.com/settings/keys | + +--- + +## Step 3 — Add the files to your repository + +### Option A — via GitHub web UI + +1. In your repo, navigate to `.github/workflows/` + (create the folder if it doesn't exist) +2. Click **"Add file" → "Create new file"** +3. Name it `auto-translate.yml` and paste in the content +4. Repeat for `scripts/translate_strings.py` + +### Option B — via Git (recommended) + +```bash +# Clone the repo +git clone https://github.com/gruntsoftware/android.git +cd android + +# Create the folders +mkdir -p .github/workflows scripts + +# Copy the two files from this package, then: +git add .github/workflows/auto-translate.yml scripts/translate_strings.py +git commit -m "chore: add auto-translation GitHub Action" +git push origin main +``` + +--- + +## Step 4 — Create locale resource directories + +The script writes to `app/src/main/res/values-{locale}/strings.xml`. +These directories are created automatically if they don't exist, but +you can create them manually too: + +``` +app/src/main/res/ +├── values/ ← source English (already exists) +├── values-ar/ ← Arabic +├── values-zh-rTW/ ← Traditional Chinese +├── values-zh-rCN/ ← Simplified Chinese +├── values-fr/ ← French +├── values-de/ ← German +├── values-fa/ ← Farsi +├── values-pa/ ← Punjabi +├── values-pl/ ← Polish +├── values-in/ ← Indonesian +├── values-es/ ← Spanish +├── values-sv/ ← Swedish +├── values-uk/ ← Ukrainian +├── values-ru/ ← Russian +├── values-tr/ ← Turkish +├── values-ja/ ← Japanese +├── values-ko/ ← Korean +├── values-hi/ ← Hindi +├── values-it/ ← Italian +└── values-pt-rBR/ ← Brazilian Portuguese +``` + +--- + +## Step 5 — Test it + +Either push a change to `values/strings.xml`, or trigger manually: + +1. Go to **https://github.com/gruntsoftware/android/actions** +2. Select **"Auto-Translate strings.xml"** +3. Click **"Run workflow"** → **"Run workflow"** + +After ~2–5 minutes a PR will appear at: +**https://github.com/gruntsoftware/android/pulls** + +--- + +## Triggering behaviour + +| Trigger | When | +|---|---| +| **Automatic** | Any push to `main`/`master` that changes `**/values/strings.xml` | +| **Manual** | Via Actions tab → "Run workflow" | + +Pushes that don't touch `strings.xml` are **ignored** — no unnecessary API calls. + +--- + +## Costs + +- The script batches strings in groups of 40 per API call. +- Your `strings.xml` has ~273 translatable strings across 19 languages + = roughly **130–140 API calls** on a full first run. +- Subsequent runs only translate **new/changed strings**, so costs drop + significantly after the first pass. + +--- + +## Troubleshooting + +| Problem | Fix | +|---|---| +| `ERROR: ANTHROPIC_API_KEY not set` | Check the secret name is exactly `ANTHROPIC_API_KEY` | +| PR not created | Check `TRANSLATION_PAT` has `pull-requests: write` permission | +| "Resource not accessible by integration" | PAT needs `workflows: write` and `contents: write` | +| Empty translations | Check Actions logs for API errors; may be a rate limit | +| Branch already exists | Workflow uses timestamp — only happens if triggered twice in one second | diff --git a/.github/workflows/auto-translate.yml b/.github/workflows/auto-translate.yml new file mode 100644 index 00000000..139d613d --- /dev/null +++ b/.github/workflows/auto-translate.yml @@ -0,0 +1,74 @@ +name: Auto-Translate strings.xml + +on: + push: + branches: + - main + - develop + - bento + paths: + - '**/values/strings.xml' + workflow_dispatch: # allow manual trigger from GitHub UI + +permissions: + contents: write + pull-requests: write + +jobs: + translate: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.TRANSLATION_PAT_GHA_CLAUDE_JUL082026 }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: pip install anthropic lxml requests + + - name: Run translation script + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_GH_API_KEY }} + run: python scripts/translate_strings.py + + - name: Check for changes + id: changes + run: | + git diff --quiet && echo "changed=false" >> $GITHUB_OUTPUT || echo "changed=true" >> $GITHUB_OUTPUT + + - name: Create branch and commit + if: steps.changes.outputs.changed == 'true' + run: | + BRANCH="translations/auto-$(date +%Y%m%d-%H%M%S)" + echo "BRANCH=$BRANCH" >> $GITHUB_ENV + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b "$BRANCH" + git add app/src/main/res/values-*/strings.xml + git commit -m "chore(i18n): auto-translate missing strings [skip ci] + + Languages updated: ar, zh-rTW, zh-rCN, fr, de, fa, pa, pl, in, es, sv, uk, ru, tr, ja, ko, hi, it, pt-rBR + Triggered by: ${{ github.sha }} + " + git push origin "$BRANCH" + + - name: Open Pull Request + if: steps.changes.outputs.changed == 'true' + env: + GH_TOKEN: ${{ secrets.TRANSLATION_PAT_GHA_CLAUDE_JUL082026 }} + run: | + gh pr create \ + --title "🌍 Auto-translations: missing strings updated" \ + --body "$(cat /tmp/pr_body.md)" \ + --base main \ + --head "$BRANCH" \ + --label "translations" \ + --reviewer "${{ github.actor }}" diff --git a/scripts/translate_strings.py b/scripts/translate_strings.py new file mode 100755 index 00000000..0044640d --- /dev/null +++ b/scripts/translate_strings.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python3 +""" +translate_strings.py +Finds all Android locale strings.xml files under app/src/main/res/, +compares them to the source (values/strings.xml), translates any missing +strings via the Anthropic API, and writes the updated files back to disk. +Also writes /tmp/pr_body.md summarising what was changed for the PR. +""" + +import os +import re +import sys +import json +import textwrap +import anthropic +from pathlib import Path +from lxml import etree + +# ── Configuration ───────────────────────────────────────────────────────────── + +SOURCE_DIR = "app/src/main/res/values" +RES_BASE_DIR = "app/src/main/res" +PR_BODY_PATH = "/tmp/pr_body.md" + +# Map Android locale folder suffix → human language name for the prompt +LOCALE_MAP = { + "values-ar": "Arabic", + "values-zh-rTW": "Traditional Chinese (Taiwan)", + "values-zh-rCN": "Simplified Chinese (Mainland China)", + "values-fr": "French", + "values-de": "German", + "values-fa": "Farsi (Persian)", + "values-pa": "Punjabi", + "values-pl": "Polish", + "values-in": "Indonesian", + "values-es": "Spanish", + "values-sv": "Swedish", + "values-uk": "Ukrainian", + "values-ru": "Russian", + "values-tr": "Turkish", + "values-ja": "Japanese", + "values-ko": "Korean", + "values-hi": "Hindi", + "values-it": "Italian", + "values-pt-rBR": "Brazilian Portuguese", +} + +# RTL languages that need android:textDirection="rtl" awareness (informational) +RTL_LOCALES = {"values-ar", "values-fa", "values-pa"} + +BATCH_SIZE = 40 # strings per API call – keeps prompts manageable + +# ── Helpers ─────────────────────────────────────────────────────────────────── + +def parse_strings(path: Path) -> dict[str, str]: + """Return {name: text} for every translatable in the file.""" + if not path.exists(): + return {} + tree = etree.parse(str(path)) + result = {} + for el in tree.getroot().findall("string"): + name = el.get("name") + translatable = el.get("translatable", "true") + if name and translatable.lower() != "false": + # Preserve inner XML (handles , , %1$s etc.) + inner = (el.text or "") + "".join( + etree.tostring(child, encoding="unicode") for child in el + ) + result[name] = inner.strip() + return result + + +def load_or_create_tree(path: Path): + """Parse existing file or return a fresh tree.""" + if path.exists(): + return etree.parse(str(path)) + root = etree.Element("resources") + root.addprevious(etree.Comment(" Auto-generated by translate_strings.py ")) + return etree.ElementTree(root) + + +def write_tree(tree, path: Path): + path.parent.mkdir(parents=True, exist_ok=True) + tree.write( + str(path), + encoding="utf-8", + xml_declaration=True, + pretty_print=True, + ) + +def set_translated(tree, name: str, translated_text: str): + """Insert or update a element in the tree.""" + root = tree.getroot() + existing = root.find(f'string[@name="{name}"]') + if existing is not None: + existing.text = translated_text + return + el = etree.SubElement(root, "string") + el.set("name", name) + el.text = translated_text + + +# ── Translation via Anthropic ───────────────────────────────────────────────── + +def translate_batch( + client: anthropic.Anthropic, + language: str, + batch: dict[str, str], +) -> dict[str, str]: + """ + Send a batch of {name: english_text} to Claude and get back + {name: translated_text}. + Returns an empty dict on failure (strings will be skipped this run). + """ + items_json = json.dumps(batch, ensure_ascii=False, indent=2) + + prompt = textwrap.dedent(f""" + You are a professional mobile-app localisation expert. + + Translate the following Android string resource values from English into + **{language}**. + + Rules: + - Preserve ALL placeholder tokens exactly as-is: %1$s %2$s %d %f etc. + - Preserve HTML tags exactly:
etc. + - Preserve ampersand escapes: & < > \' etc. + - Do NOT translate the JSON keys (string resource names). + - Do NOT add explanations or markdown — return ONLY valid JSON. + - The app is a Litecoin cryptocurrency wallet called "Brainwallet". + Keep "Brainwallet", "Litecoin", "LTC", "PIN", "QR" untranslated. + - Use natural, friendly language suitable for a mobile finance app. + + Input JSON (keys are resource names, values are English strings): + {items_json} + + Return a JSON object with the same keys and translated values. + """).strip() + + try: + message = client.messages.create( + model="claude-opus-4-5", + max_tokens=4096, + messages=[{"role": "user", "content": prompt}], + ) + raw = message.content[0].text.strip() + # Strip possible ```json fences + raw = re.sub(r"^```(?:json)?\s*", "", raw) + raw = re.sub(r"\s*```$", "", raw) + return json.loads(raw) + except Exception as exc: + print(f" ⚠️ API/parse error for {language}: {exc}", file=sys.stderr) + return {} + + +# ── Main ────────────────────────────────────────────────────────────────────── + +def main(): + api_key = os.environ.get("ANTHROPIC_GH_API_KEY") + if not api_key: + sys.exit("ERROR: ANTHROPIC_GH_API_KEY environment variable not set.") + + client = anthropic.Anthropic(api_key=api_key) + + source_path = Path(SOURCE_DIR) / "strings.xml" + if not source_path.exists(): + sys.exit(f"ERROR: Source file not found: {source_path}") + + source_strings = parse_strings(source_path) + print(f"✅ Source: {len(source_strings)} translatable strings loaded.") + + pr_lines = [ + "## 🌍 Auto-translation summary\n", + "| Language | New translations | File |", + "|---|---|---|", + ] + + for locale_dir, language in LOCALE_MAP.items(): + target_path = Path(RES_BASE_DIR) / locale_dir / "strings.xml" + existing = parse_strings(target_path) + missing = { + k: v for k, v in source_strings.items() + if k not in existing or not existing[k].strip() + } + + if not missing: + print(f" ✔ {language}: nothing to translate.") + pr_lines.append(f"| {language} | 0 (already complete) | `{target_path}` |") + continue + + print(f" 🔄 {language}: {len(missing)} strings to translate …") + tree = load_or_create_tree(target_path) + + translated_count = 0 + keys = list(missing.keys()) + for i in range(0, len(keys), BATCH_SIZE): + chunk_keys = keys[i : i + BATCH_SIZE] + batch = {k: missing[k] for k in chunk_keys} + result = translate_batch(client, language, batch) + + for name, text in result.items(): + if name in batch: # sanity-check key came from our batch + set_translated(tree, name, text) + translated_count += 1 + + write_tree(tree, target_path) + print(f" ✅ {language}: {translated_count} strings written → {target_path}") + pr_lines.append(f"| {language} | {translated_count} | `{target_path}` |") + + # Write PR body + pr_body = "\n".join(pr_lines) + "\n\n---\n*Generated automatically by translate_strings.py*\n" + Path(PR_BODY_PATH).write_text(pr_body, encoding="utf-8") + print(f"\n📄 PR body written to {PR_BODY_PATH}") + print("🎉 Translation run complete.") + + +if __name__ == "__main__": + main() From 25fcc5d34cbc6584b2c14c1d40b4dd260c6ffe17 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 12 Apr 2026 13:00:49 +0100 Subject: [PATCH 086/116] Add auto-translate workflow for strings.xml This workflow automates the translation of strings.xml files on push to specific branches and allows manual triggering. It checks for changes and creates a pull request if translations are updated. --- .github/workflows/develop-auto-translate.yml | 74 ++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 .github/workflows/develop-auto-translate.yml diff --git a/.github/workflows/develop-auto-translate.yml b/.github/workflows/develop-auto-translate.yml new file mode 100644 index 00000000..b693fdea --- /dev/null +++ b/.github/workflows/develop-auto-translate.yml @@ -0,0 +1,74 @@ +name: Auto-Translate strings.xml + +on: + push: + branches: + - main + - develop + - bento + paths: + - '**/values/strings.xml' + workflow_dispatch: # allow manual trigger from GitHub UI + +permissions: + contents: write + pull-requests: write + +jobs: + translate: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.TRANSLATION_PAT_GHA_CLAUDE_JUL082026 }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: pip install anthropic lxml requests + + - name: Run translation script + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_GH_API_KEY }} + run: python scripts/translate_strings.py + + - name: Check for changes + id: changes + run: | + git diff --quiet && echo "changed=false" >> $GITHUB_OUTPUT || echo "changed=true" >> $GITHUB_OUTPUT + + - name: Create branch and commit + if: steps.changes.outputs.changed == 'true' + run: | + BRANCH="translations/auto-$(date +%Y%m%d-%H%M%S)" + echo "BRANCH=$BRANCH" >> $GITHUB_ENV + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b "$BRANCH" + git add app/src/main/res/values-*/strings.xml + git commit -m "chore(i18n): auto-translate missing strings [skip ci] + + Languages updated: ar, zh-rTW, zh-rCN, fr, de, fa, pa, pl, in, es, sv, uk, ru, tr, ja, ko, hi, it, pt-rBR + Triggered by: ${{ github.sha }} + " + git push origin "$BRANCH" + + - name: Open Pull Request + if: steps.changes.outputs.changed == 'true' + env: + GH_TOKEN: ${{ secrets.TRANSLATION_PAT_GHA_CLAUDE_JUL082026 }} + run: | + gh pr create \ + --title "🌍 Auto-translations: missing strings updated" \ + --body "$(cat /tmp/pr_body.md)" \ + --base develop \ + --head "$BRANCH" \ + --label "translations" \ + --reviewer "${{ github.actor }}" From 34e6d6593cb9e0e7612c7f584cf6930d8cf3f013 Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Sun, 12 Apr 2026 23:37:10 +0100 Subject: [PATCH 087/116] Create PR summary workflow with GitHub Copilot Add GitHub Actions workflow for PR summary generation using Copilot --- .github/workflows/pr-summary-copilot.yml | 230 +++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 .github/workflows/pr-summary-copilot.yml diff --git a/.github/workflows/pr-summary-copilot.yml b/.github/workflows/pr-summary-copilot.yml new file mode 100644 index 00000000..f6cffa08 --- /dev/null +++ b/.github/workflows/pr-summary-copilot.yml @@ -0,0 +1,230 @@ +name: 🤖 Copilot PR Summary + +on: + pull_request: + types: [opened, synchronize, reopened] + branches: + - develop + - main + +permissions: + contents: read + pull-requests: write + +jobs: + summarize-pr: + name: Generate PR Summary + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get PR diff and changed files + id: pr_info + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Collect changed files with their status + gh pr view ${{ github.event.pull_request.number }} \ + --json files,title,body,additions,deletions,commits \ + > pr_meta.json + + # Get full diff (capped to avoid token limits) + git diff origin/${{ github.base_ref }}...HEAD \ + -- '*.kt' '*.java' '*.xml' '*.kts' '*.toml' \ + | head -c 32000 > pr_diff.txt + + # Summarise stats for the prompt + ADDITIONS=$(jq '.additions' pr_meta.json) + DELETIONS=$(jq '.deletions' pr_meta.json) + COMMITS=$(jq '.commits | length' pr_meta.json) + FILES=$(jq '.files | length' pr_meta.json) + FILE_LIST=$(jq -r '.files[].path' pr_meta.json | tr '\n' ', ') + + echo "additions=$ADDITIONS" >> $GITHUB_OUTPUT + echo "deletions=$DELETIONS" >> $GITHUB_OUTPUT + echo "commits=$COMMITS" >> $GITHUB_OUTPUT + echo "files=$FILES" >> $GITHUB_OUTPUT + echo "file_list=$FILE_LIST" >> $GITHUB_OUTPUT + + - name: Generate summary with GitHub Copilot + id: copilot_summary + uses: actions/github-script@v7 + env: + DIFF_CONTENT: ${{ steps.pr_info.outputs.diff }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + + const diff = fs.existsSync('pr_diff.txt') + ? fs.readFileSync('pr_diff.txt', 'utf8').slice(0, 28000) + : '(diff unavailable)'; + const prMeta = JSON.parse(fs.readFileSync('pr_meta.json', 'utf8')); + const title = prMeta.title || ''; + const files = (prMeta.files || []).map(f => f.path); + const additions = prMeta.additions ?? 0; + const deletions = prMeta.deletions ?? 0; + const commits = (prMeta.commits || []).length; + + // --- Classify change types from file paths --- + const isNewFeature = files.some(f => /Screen\.kt$|ViewModel\.kt$|Bento/.test(f)); + const isRefactor = files.some(f => /Repository|DataSource|Module\.kt$/.test(f)); + const isTest = files.some(f => /Test\.kt$|test\//.test(f)); + const isUI = files.some(f => /\.xml$|Theme|Color|strings/.test(f)); + const isConfig = files.some(f => /\.toml$|\.kts$|Constants/.test(f)); + const isPerfOrFix = files.some(f => /Fix|Bug|Perf/.test(f)); + + // --- Build Copilot prompt --- + const prompt = ` + You are a senior Android engineer reviewing a pull request for the Brainwallet Android app + (Kotlin, Jetpack Compose, MVI architecture, Koin DI, Coroutines/StateFlow). + + Repository layout: + - app/src/main/java/com/brainwallet/ → Kotlin/Java source (UI, ViewModels, repos, DI) + - app/src/main/res/ → XML resources (layouts, strings, drawables) + - app/src/main/jni/core/ → Native JNI wallet logic (C/C++) + - modules/private-general-purpose/ → :core, :games, :iap feature modules + - gradle/, android-build-logic/ → Build configuration + + PR title: ${title} + Files changed (${files.length}): ${files.join(', ')} + Additions: ${additions} Deletions: ${deletions} Commits: ${commits} + + Diff (truncated to 28 000 chars): + \`\`\`diff + ${diff} + \`\`\` + + Write a GitHub PR description using EXACTLY this markdown template. Fill every section + accurately from the diff. Do not add sections or change headings. + + --- + ## 📱 Description + <2–4 sentence plain-English summary of what this PR does and why> + + ## Platform + - [x] **Android** + + ## 🎯 Type of Change + - [${isPerfOrFix ? 'x' : ' '}] 🐛 Bug fix + - [${isNewFeature ? 'x' : ' '}] ✨ New feature + - [${isRefactor ? 'x' : ' '}] 🔧 Refactoring (code change that neither fixes a bug nor adds a feature) + - [ ] 📚 Documentation update + - [${isUI ? 'x' : ' '}] 🎨 UI/UX improvement + - [ ] ⚡ Performance improvement + - [${isTest ? 'x' : ' '}] 🧪 Test addition or improvement + + ## 📋 Changes + ### New Components Added + + + ### Modifications + + + ### Removals + + + ## 📊 Statistics + - **Additions:** ${additions} lines + - **Deletions:** ${deletions} lines + - **Files Changed:** ${files.length} + - **Commits:** ${commits} + + ## 🔗 Related Issues + - Fixes # + - Related to # + + ## 🧪 Tests Status + - [ ] Tests ran successfully locally? + - [ ] Added more tests? How many? + - [ ] Code coverage percentage of the codebase: __% + + ## 📸 Screenshots/Videos + | Before | After | + |--------|-------| + | _Add screenshot_ | _Add screenshot_ | + + ## 🎯 Reviewers + @kcw-grunt, @josikie + + --- + **Draft Status:** This PR is currently in draft mode and ready for review feedback. + --- + `; + + // --- Call Copilot / OpenAI-compatible endpoint via gh models --- + // GitHub Copilot in Actions is accessed through the GITHUB_TOKEN-scoped + // models API when the workflow has the `models: read` permission. + const response = await fetch( + 'https://models.inference.ai.azure.com/chat/completions', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`, + }, + body: JSON.stringify({ + model: 'gpt-4o', + messages: [{ role: 'user', content: prompt }], + max_tokens: 2048, + temperature: 0.3, + }), + } + ); + + if (!response.ok) { + const err = await response.text(); + core.setFailed(`Copilot API error ${response.status}: ${err}`); + return; + } + + const json = await response.json(); + const summary = json.choices?.[0]?.message?.content ?? '(no summary generated)'; + + core.setOutput('summary', summary); + fs.writeFileSync('pr_summary.md', summary); + console.log('Summary generated successfully.'); + + - name: Post summary as PR comment + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + const body = fs.readFileSync('pr_summary.md', 'utf8'); + + // Find and replace existing bot comment, or create a new one + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + + const botComment = comments.find(c => + c.user.type === 'Bot' && + c.body.includes('') + ); + + const fullBody = `\n> 🤖 _Auto-generated by GitHub Copilot — edit as needed before merging._\n\n${body}`; + + if (botComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body: fullBody, + }); + console.log('Updated existing summary comment.'); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: fullBody, + }); + console.log('Created new summary comment.'); + } From 914bcd341804bc834711736b9a6b2cbbf4bd0ab0 Mon Sep 17 00:00:00 2001 From: kcw-grunt Date: Mon, 13 Apr 2026 11:46:25 +0100 Subject: [PATCH 088/116] Changed the AI completions --- .github/workflows/pr-summary-copilot.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr-summary-copilot.yml b/.github/workflows/pr-summary-copilot.yml index f6cffa08..da03f2bb 100644 --- a/.github/workflows/pr-summary-copilot.yml +++ b/.github/workflows/pr-summary-copilot.yml @@ -156,16 +156,15 @@ jobs: --- `; - // --- Call Copilot / OpenAI-compatible endpoint via gh models --- - // GitHub Copilot in Actions is accessed through the GITHUB_TOKEN-scoped + // --- Call OpenAI-compatible endpoint via gh models --- // models API when the workflow has the `models: read` permission. const response = await fetch( - 'https://models.inference.ai.azure.com/chat/completions', + 'https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', - 'Authorization': `Bearer ${process.env.GITHUB_TOKEN}`, + 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`, }, body: JSON.stringify({ model: 'gpt-4o', From ca4fcd94dfb1ea5bbed405c4a4304a7153200290 Mon Sep 17 00:00:00 2001 From: kcw-grunt Date: Mon, 13 Apr 2026 12:17:59 +0100 Subject: [PATCH 089/116] Add more information of the README --- README.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f508e2aa..7d8dc45c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,66 @@ -## Easy and secure -Brainwallet is a easy and fun way to use your crypto (Litecoin) and memorize your seed words +# Brainwallet: Android +The open source code of Brainwallet Android -### Release notes +## CI/CD Status +**main**: [![CircleCI](https://dl.circleci.com/status-badge/img/gh/gruntsoftware/android/tree/main.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/gruntsoftware/android/tree/main) -- v4.5.4 - - Added new MP Buy UI +**develop**: [![CircleCI](https://dl.circleci.com/status-badge/img/gh/gruntsoftware/android/tree/develop.svg?style=svg)](https://dl.circleci.com/status-badge/redirect/gh/gruntsoftware/android/tree/develop) -### Dev notes -- Paired with @kcw-grunt, @josikie to verify the android build logic and private repo. +## Release Notes +### v4.8.3 +# 🚀 Brainwallet Android — Release Notes + +--- +## ✨ New UI — Favourites & Tutorials Bento Sections +**PR [#191](https://github.com/gruntsoftware/android/pull/191)** +The main screen now features two new purpose-built bento panels replacing the generic placeholder container. The **Favourites** panel displays a set of coloured circular indicators using the app's design theme colours (affirm, info, warn, error) with full dark/light mode support. The **Tutorials** panel shows a "Coming Soon" placeholder consistent with the broader bento design language. The old `HomeBentoContainer` has been removed. String resources for both sections have been translated across 19 locales including Arabic, Chinese (Traditional & Simplified), French, German, Farsi, Hindi, Indonesian, Italian, Japanese, Korean, Polish, Punjabi, Brazilian Portuguese, Russian, Spanish, Swedish, Turkish, and Ukrainian. +--- + +## 🔧 Send Screen Overhaul & Financial Precision +**PR [#182](https://github.com/gruntsoftware/android/pull/182)** +The send transaction flow has been fully redesigned as a multi-step paged screen (Pre-send → Confirm → Authenticate). All monetary values have been migrated from `Float` to `BigDecimal` with explicit rounding modes, eliminating floating-point precision issues in fiat/LTC conversions. Transaction fees are now calculated dynamically using `getFeePerKb()` rather than a static default. The pre-send composable has been broken into focused sub-components (`PreSendAddressRow`, `PreSendAmountRow`, `PreSendMemoRow`), and passcode UI components have been extracted into a dedicated package. QR code scanning is now wired into the send flow via an `EventBus` event. A `BWSender` class handles transaction preparation with proper error handling and activity context management. +--- + +## 🧪 Test Coverage Expanded to 309 Tests +**PR [#182](https://github.com/gruntsoftware/android/pull/182)** + +Unit test coverage has been significantly expanded alongside the send screen work, bringing the total suite to **309 tests**. New test classes include `AppModuleTest`, `SendStateTest`, and `BrainwalletAppTest`, covering the Koin DI module wiring, send state logic, and core app initialisation paths. + + + +### v3.9.0 - v3.9.1 Latest +Update README for improved description by @kcw-grunt in #78 +Beta Release [ 🚀 ] Merge Develop into Main by @kcw-grunt in #81 + +#### Fixes and Changes: +- Current fiat preference from Settings needs to be reset if set in the TickerBento +- Localizations are covered to 100% +- Mini game FALLINMOJI is present in the Welcome and Game Hub +- When setting the theme from the Settings and the Lock Screen and the Main screen is not consistently applied +- In general the fonts in the app are not consistent and need to be managed properly for consistency +- Mini game sounds set a nominal level +- Layout for iPhone 8 - iPhone 17 Pro Max is set for: Welcome Screen +- Support.brainwallet.co link is fixed + +### v3.6.0 Latest + +#### What's Changed +🚀[Release v3.5.0] Merge into Main by @kcw-grunt in #51 +Full Changelog: v3.4.2...v3.6.0\ + +#### Updates: +- using bundle exec fastlane single_unit_test_all +- downgrade firebase to 11.12.0 +- polsih ci config +- 🦾 Chore/migrate ready onboarding +- Fix/login view crash +- 🧰 fix: Removed the thread blocking seen in the lock screen trx. loading +- Epic/settings migration (#50) +- Chore/refactor firebase analytics +- Chore/activate test coverage + +### v3.3.1 +- Added locale filter +- Made improvements to UI +- Fixes From 12a3d835cd9c254f1047c038e3aa4d24e19e8677 Mon Sep 17 00:00:00 2001 From: kcw-grunt Date: Mon, 13 Apr 2026 12:19:47 +0100 Subject: [PATCH 090/116] nit fix --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 7d8dc45c..1d01cf45 100644 --- a/README.md +++ b/README.md @@ -11,16 +11,13 @@ The open source code of Brainwallet Android ### v4.8.3 # 🚀 Brainwallet Android — Release Notes ---- ## ✨ New UI — Favourites & Tutorials Bento Sections **PR [#191](https://github.com/gruntsoftware/android/pull/191)** The main screen now features two new purpose-built bento panels replacing the generic placeholder container. The **Favourites** panel displays a set of coloured circular indicators using the app's design theme colours (affirm, info, warn, error) with full dark/light mode support. The **Tutorials** panel shows a "Coming Soon" placeholder consistent with the broader bento design language. The old `HomeBentoContainer` has been removed. String resources for both sections have been translated across 19 locales including Arabic, Chinese (Traditional & Simplified), French, German, Farsi, Hindi, Indonesian, Italian, Japanese, Korean, Polish, Punjabi, Brazilian Portuguese, Russian, Spanish, Swedish, Turkish, and Ukrainian. ---- ## 🔧 Send Screen Overhaul & Financial Precision **PR [#182](https://github.com/gruntsoftware/android/pull/182)** The send transaction flow has been fully redesigned as a multi-step paged screen (Pre-send → Confirm → Authenticate). All monetary values have been migrated from `Float` to `BigDecimal` with explicit rounding modes, eliminating floating-point precision issues in fiat/LTC conversions. Transaction fees are now calculated dynamically using `getFeePerKb()` rather than a static default. The pre-send composable has been broken into focused sub-components (`PreSendAddressRow`, `PreSendAmountRow`, `PreSendMemoRow`), and passcode UI components have been extracted into a dedicated package. QR code scanning is now wired into the send flow via an `EventBus` event. A `BWSender` class handles transaction preparation with proper error handling and activity context management. ---- ## 🧪 Test Coverage Expanded to 309 Tests **PR [#182](https://github.com/gruntsoftware/android/pull/182)** From 5d3a6c214490acd480fe7770ef19f8d17d4f7edc Mon Sep 17 00:00:00 2001 From: Kerry Washington Date: Tue, 14 Apr 2026 09:38:16 +0100 Subject: [PATCH 091/116] =?UTF-8?q?=F0=9F=A6=96=F0=9F=98=B1=20=20HUGE!!=20?= =?UTF-8?q?Bento=20Integration=20(#192)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update Bento with Latest Develop (#144) * create private gp submodule * Update settings.gradle.kts * chore: Migrate build logic to version catalog and update submodules This commit migrates the project's build logic to use a centralized version catalog (`grunt`) and updates submodule references. Specific changes include: * **Submodule Updates:** * Updated `gruntsoftware-build-logic` submodule pointer. * Updated `modules/private-general-purpose` submodule pointer. * **Build Configuration (`settings.gradle.kts`):** * Removed the conditional loading of the `games` version catalog. * Added a `grunt` version catalog loaded from `gruntsoftware-build-logic/gradle/libs.versions.toml`. * Changed the included module from `:modules:private-general-purpose:content` to `:modules:private-general-purpose:games`. * Removed conditional inclusion logic for `:modules:private-general-purpose:content`. * **Root `build.gradle.kts`:** * Updated plugin aliases from `libs.plugins.android.*` to `grunt.plugins.android.*`. * **App `build.gradle.kts`:** * Updated plugin alias for `com.android.application` from `libs` to `grunt`. * Updated the `games` module dependency to `implementation(project(":modules:private-general-purpose:games"))` and removed the conditional logic for `findProject(":modules:games:content")`. * Updated various dependencies to use the `grunt` version catalog (e.g., `grunt.androidx.core.ktx`, `grunt.androidx.compose.bom`, `grunt.bundles.androidx.compose`, `grunt.material`). * **Version Catalog (`gradle/libs.versions.toml`):** * Removed versions for `agp` and `androidx-core-ktx`. * Removed versions for `androidx-compose-bom`, `androidx-activity-compose`, and `androidx-fragment-compose`. * Removed `androidx-core` library alias. * Removed various `androidx-compose` library aliases and the `androidx-compose` bundle. * Removed `android-application` and `android-library` plugin aliases. * feat(deps): add kotlin-immutable dependency This commit adds the `kotlinx-collections-immutable` library, version 0.4.0, to the project's dependencies. * refactor(app): Relocate core module imports Updates the import paths for the core presentation module from `ltd.grunt.brainwallet.core.presentation` to `com.grunt.brainwallet.core.presentation`. This refactoring touches multiple UI components and initializers across the `app` module to align with the new package structure. Additionally, this commit corrects a typo in `SeedWordItem.kt`, changing the error color variable from `chilli` to `chili` to match the theme definition. Finally, the submodule pointer for `private-general-purpose` is updated. --------- Co-authored-by: Kerry Washington * feat(bento): Scaffold Bento module with main screen (#143) This commit introduces the new `bento` Android libs module. It scaffolds the main screen (`BentoMainScreen`) which features a bento-style grid layout, a top action bar, a bottom navigation bar, and a modal navigation drawer with a custom rail. Key additions include: - `BentoActivity` as the main entry point. - Composable components for the main screen, rail, and various widgets. - Initial Gradle setup with necessary dependencies. - Android Manifest, resources, and vector drawables for the UI. - Inclusion of the `:bento` module in `settings.gradle.kts`. * Moderately moved to the old file system (#162) * Task: Added Basic layout functionality (#163) * Adjusted the padding to show the status bar at the top Compiling and added MVVM Classes Adding ComponentActivity instead of AppCompat connecting the Tab Actions Debugging the modals for the tab bar Successfully wired in tab actions * version bump * Task/add gamehub bento section (#164) * Adjusted the padding to show the status bar at the top Compiling and added MVVM Classes Adding ComponentActivity instead of AppCompat connecting the Tab Actions Debugging the modals for the tab bar Successfully wired in tab actions * Added the background and text * WIP: Resetting the bento ratios and the GameHub bento layout * Added ibm plex sans Polished the bottom nav bar * WIP: Layout of the MainScreen is 75% is there but it doesnt work 100% Working in the alts * Further discovery of the Settings data * version bump * version bump Resetting the bento ratios and the GameHub bento layout Added ibm plex sans Polished the bottom nav bar Further discovery of the Settings data * Fix/show unlock after ready restore (#167) * Version bump * Updated the modules and fixed some warnings Set the sdks Updated the submodules prior to the android-build-modules remove old android build logic * Updated the BRKeystore with a new putMasterPubKey method * Added more bulletproofing of the store pubkey Reset the secp256k1 commit: b408c6a This version is entirely sensitive of the lib because the Bitcoin devs decided it was not necessary flag. We still use it * RC: Verified the NEW_WALLET PATH now works The Ready path works. Added a FB if failing * Minor polish to the InputWords layout * Removed the commented out BRKeyStoreTest * Clean issue in remove tests * Added working BRKeyStore tests * Removed example test(s) * version bump * Rename Test stage * Feat/ltc picker bento with working onboarding (#168) * Version bump * Updated the modules and fixed some warnings Set the sdks Updated the submodules prior to the android-build-modules remove old android build logic * Updated the BRKeystore with a new putMasterPubKey method * Added more bulletproofing of the store pubkey Reset the secp256k1 commit: b408c6a This version is entirely sensitive of the lib because the Bitcoin devs decided it was not necessary flag. We still use it * RC: Verified the NEW_WALLET PATH now works The Ready path works. Added a FB if failing * Minor polish to the InputWords layout * Removed the commented out BRKeyStoreTest * Clean issue in remove tests * Added working BRKeyStore tests * Removed example test(s) * version bump * Rename Test stage * Transferred theme elements * Changed to local DesignTheme from old BWTheme * Replaced thet private BrainwalletTheme to a local DesignTheme This is a WIP * Fixed the theme toggle button * WIP: Brought more update UI LTCPicker Wired in the latest date into the LTC Picker added new stringResource Building the LTC Picker Polished the layout of the LTCPicker Bento Added a state test Added a new class enum to match iso to country flags Added label version bump * Polished the unlock screen * Added new tests for the LTCPickerBento * WIP: Debugging the toolbar at the top for settings and theme buttons * Polished the ltc and nav bar * Added Test Coverage flags in the build gradle * ⚖️ Feature/add balance bento clean (#171) * Deleted old files some cruft some to support new design * Added new files for the effort to include Composables, strings and images * Updated resources for strings and images * Updated the Android Studio and Project files * Added more test files * Renamed the BRConstants file to BWConstants * Changed for the LTCPickerBentos from a previously merged PR * Reset the Routes and its naming Reset the Utils for constants Changing the layout Renamed a home to main * Renamed the nav layer Removed unused code Added id to TxItem for the Layout of items Added comments * Updated the design elements Added the new name of the activity * Added an update to the PeerManager Included the LTCStats using the new endpoint for the latest block height Changed the koinModules loading Added a removal of the connection listener Added far more functionality into the BrainwalletActivity against BreadActivity Updated and properly set the core to commit 28d7d31ae057bdde33b1d19e6b7af3ba07710c89 * Added tests to the Balance Bento ViewModel tests Adjusted the model to support DI * Added tests for the Event and State classes of BalanceBento * cleaned the mem settings adjusted gradle per CircleCI statement recommendation reorg the circleci config to expand the cache set the tests run polish memory in CircleCI * Fixing new wallet route Fixed my routing for the new wallet Tested and verified * 💰Feature/transaction detail bento (#173) * 💅🏼 Task/polish buy receive action (#174) * version bump * Added animation of the transactions bentos Added the basic transaction rows and detail added the viewModel and Event Included the bar icons and the switch Wired in the composables Added more string resources Set detail sizes Built in Transaction Detail Connected the isDark from Settings Polishing the Transaction Row and Detail added the QR code WIP: Added constant for the transaction view Added a empty No Transactions Row when there are not transactions WIP fixing the toggle Adding an empty transaction * Reused the BuyReceive Screen For when the user has no txns * Added the release candidate layout for the Balance Bento for syncing Also, polished the sync activity * Added some padding for the scrolling Added a blockage if the user has no transactions * Renamed the preferences Recalculated the values in the Transactions detail Added better layout of the filter toggle button Debugging the amounts and txItem values * added unit tests of Transaction view model * Reusing the BuyDialog within a Modal * Polished the layout of the modal Moved the Receive classes to the bento section Added tests for the RecieveDialogViewModelTests * Added more tests for ReceiveDialogState * 🎛️ Task/re attachment settings screen (#175) * Added animation of the transactions bentos Added the basic transaction rows and detail added the viewModel and Event Included the bar icons and the switch Wired in the composables Added more string resources Set detail sizes Built in Transaction Detail Connected the isDark from Settings Polishing the Transaction Row and Detail added the QR code WIP: Added constant for the transaction view Added a empty No Transactions Row when there are not transactions WIP fixing the toggle Adding an empty transaction * Reused the BuyReceive Screen For when the user has no txns * Added the release candidate layout for the Balance Bento for syncing Also, polished the sync activity * Added some padding for the scrolling Added a blockage if the user has no transactions * Renamed the preferences Recalculated the values in the Transactions detail Added better layout of the filter toggle button Debugging the amounts and txItem values * Reusing the BuyDialog within a Modal * Polished the layout of the modal Moved the Receive classes to the bento section Added tests for the RecieveDialogViewModelTests * Wired into the Most updated version of the SettingsComposable Set some constants Removed references to the legacy version Changed the location of the package * Added more tests of the BWConstants Combined the LTCPicker Tests * Renamed and reorged the file structure Deleted unused files * Debugged the AppModule issue Debugged the fiat / iso setting throughout the app Removal of the History classes Setup the transactionDetail action without route Removed the BRSharedPrefs callbacks Converted to Flow style with more popular and modern style * Migrated more appSetting to StateFlow Applied StateFlow in most placed for Settings Some AppSettings need to be migrated * Added a confirmation indicator * Pass LTC States Added a polish into the transaction per row Added the string localizations Migrated the data source as state flows Pass LTC Stats across many VMs * Refactor to update tests Removed old code * localized the tagline * 🛠️ Task/refactor code bugfixes (#177) * Added a special test for Insta and Linktree version bump WIP Debug the sync state * Renamed the BRWalletManager callback: onBalancedChanged * Refactor resources Removed or modified colors Removed or modified images Removed or modified strings * Added more composables Added more design elements:Gradients Dashed divider * small changes to the Transaction classes * Small update of the Balance Bento Moved the state to MainViewModel rather than a duplicate in BalanceViewModel * Refactors the navbar and updated that toml * Refactored of the MainScreen and related classes * Refactoring tests * version bump * Feat/send classes adding func modal (#181) * Added working Send group Polished the layout and UI for Send Renamed the send prep classes Added the Memo field in confirm * Refactoring the Send Rows Refactored the precision of the amounts for send and balances Updated all relevant types to BigDecimal Flowed some values to the ViewModel * Set formatting of the Confirmation widget Broke the PreSend Composable into smaller composables - PreSendAddressRow - PreSendAmountRow - PreSendMemoRow Polished the rows Added a debug for the memo row Refactored the amount * Added focus listener to recalculate the values prior to send * Added state variable brainwalletIsSyncing to the main WIP Debugging the send Readded then camera Passed the ltc address to the send class Wiring in the old Send Fragment and testing * Removed a legacy activity Adding the Passcode wrapper Wired in the passcode composable to be used in the send function Added a combined boolean to check for send disable fixed the send button enable disable Relaying out the spaces for the SendScreen refactor the send modal spacer Fixed the extra coinflip Successfully sent. need to cleanup calls * version bump * Added a clearance of value on edit version bump Added BigDecimal with rounding mode * Added gh workflow auto-translate * fix typo * Change translation PAT secret in workflow Updated GitHub Actions workflow to use new translation PAT secret. * Remove environment specification from translate job * moved script py * dupe of the script * changed the key * Update environment variable for translation script * Change environment variable from ANTHROPIC_API_KEY to ANTHROPIC_GH_API_KEY * add test workflow * Add workflow to test Anthropic API key * Change base branch for PR from main to bento * Changed the model for the translation * Added a number counter * remove the test workflow * 🥃 🥽🧪 Added tests to increase coverage (#182) * Added working Send group Polished the layout and UI for Send Renamed the send prep classes Added the Memo field in confirm * Refactoring the Send Rows Refactored the precision of the amounts for send and balances Updated all relevant types to BigDecimal Flowed some values to the ViewModel * Set formatting of the Confirmation widget Broke the PreSend Composable into smaller composables - PreSendAddressRow - PreSendAmountRow - PreSendMemoRow Polished the rows Added a debug for the memo row Refactored the amount * Added focus listener to recalculate the values prior to send * Added state variable brainwalletIsSyncing to the main WIP Debugging the send Readded then camera Passed the ltc address to the send class Wiring in the old Send Fragment and testing * Removed a legacy activity Adding the Passcode wrapper Wired in the passcode composable to be used in the send function Added a combined boolean to check for send disable fixed the send button enable disable Relaying out the spaces for the SendScreen refactor the send modal spacer Fixed the extra coinflip Successfully sent. need to cleanup calls * Added a clearance of value on edit version bump Added BigDecimal with rounding mode * Added Module Tests * Added gh workflow auto-translate * Added more Tests: BrainwalletAppTest * Feat/add fav bento design (#189) * Added design for Top Secret and the Tutorials bentos Added preview added strings files and localizations * Removed HomeBento placeholder code * fixed the config commenting * 🍱 Feat/add fav bento design (#191) * Added design for Top Secret and the Tutorials bentos Added preview added strings files and localizations * Removed HomeBento placeholder code * Fixed to unescaped aposthrphes chore(i18n): auto-translate missing strings [skip ci] Languages updated: ar, zh-rTW, zh-rCN, fr, de, fa, pa, pl, in, es, sv, uk, ru, tr, ja, ko, hi, it, pt-rBR Triggered by: 3d594e9c3360eae8d105bf81e7eeb36676d7c23c chore(i18n): auto-translate missing strings [skip ci] Languages updated: ar, zh-rTW, zh-rCN, fr, de, fa, pa, pl, in, es, sv, uk, ru, tr, ja, ko, hi, it, pt-rBR Triggered by: 2443fdef72e17658a481a091abb17ab145b1f495 Reformat the xmls Revert the notation --------- Co-authored-by: github-actions[bot] * 🎠 feat: Add Carousels (#193) * Add containers for carousels Midway adding the components of a carousel * Added the pager screen and the baseline * Added creatives Added the wiring to deploy screens and or actions * Revert "Merge branch 'bento' into feat/add-carousel-in-gamehub" This reverts commit 2b340eb2059708954bd1c851ea1dcd1f7f4dddec, reversing changes made to 6af30b1eae900aa09c6ecdcddece1ecd0c4ebb24. * chore(i18n): auto-translate missing strings [skip ci] Languages updated: ar, zh-rTW, zh-rCN, fr, de, fa, pa, pl, in, es, sv, uk, ru, tr, ja, ko, hi, it, pt-rBR Triggered by: 2b340eb2059708954bd1c851ea1dcd1f7f4dddec * Polished the LTC picker --------- Co-authored-by: github-actions[bot] * Version bump Ran test successfully * added pr summary workflow for GH Actions * Moved to the Claude for the PR Summary * fix typo * fixed the naming * Fixed name across script * add a log statement * add a log statement Moved to the Claude for the PR Summary fix typo fixed the naming Fixed name across script * fixed model typo --------- Co-authored-by: Joseph Sanjaya Co-authored-by: github-actions[bot] --- .circleci/config.yml | 6 +- .github/workflows/auto-translate.yml | 6 +- .github/workflows/bento-auto-translate.yml | 73 + .github/workflows/pr-summary-copilot.yml | 25 +- android/scripts/translate_strings.py | 218 +++ app/build.gradle.kts | 94 +- app/src/main/AndroidManifest.xml | 18 +- .../java/com/brainwallet/BrainwalletApp.kt | 60 +- .../com/brainwallet/constants/BWConstants.kt | 155 ++ .../com/brainwallet/constants/Constants.kt | 23 + .../brainwallet/data/model/GlobalCurrency.kt | 141 ++ .../com/brainwallet/data/model/LtcStats.kt | 23 + .../data/model/MoonpayCurrencyLimit.kt | 2 +- .../data/repository/ConnectivityRepository.kt | 46 + .../FirebaseRemoteConfigRepository.kt | 10 + .../FirebaseRemoteConfigSourceImpl.kt | 30 + .../repository/HubContentRepositoryImpl.kt | 45 + .../data/repository/LtcRepository.kt | 8 + .../data/repository/LtcRepositoryImpl.kt | 54 +- .../data/repository/SettingRepository.kt | 5 + .../data/repository/SettingRepositoryImpl.kt | 42 +- .../data/repository/TxRepository.kt | 10 + .../data/repository/TxRepositoryImpl.kt | 42 + .../data/source/PeerManagerSource.kt | 54 +- .../data/source/RemoteApiSource.kt | 4 + .../data/source/RemoteConfigSource.kt | 3 + .../main/java/com/brainwallet/di/AppModule.kt | 11 +- .../com/brainwallet/di/RemoteConfigModule.kt | 20 + .../brainwallet/initializer/AppInitializer.kt | 4 +- .../navigation/LegacyNavigation.kt | 40 +- .../{MainNav.kt => MainNavigationHost.kt} | 53 +- .../java/com/brainwallet/navigation/Route.kt | 21 +- .../com/brainwallet/navigation/UiEffect.kt | 4 + .../presenter/activities/BreadActivity.java | 48 +- .../activities/DisabledActivity.java | 2 +- .../presenter/activities/LoginActivity.java | 16 +- .../activities/ReEnterPinActivity.java | 176 ++ .../activities/UpdatePinActivity.java | 204 +++ .../activities/intro/RecoverActivity.kt | 2 +- .../activities/settings/AboutActivity.java | 14 +- .../settings/DisplayCurrencyActivity.java | 10 +- .../settings/SecurityCenterActivity.java | 2 +- .../settings/SpendLimitActivity.java | 2 +- .../settings/SyncBlockchainActivity.java | 14 +- .../presenter/activities/util/BRActivity.java | 21 +- .../presenter/entities/BRMenuItem.java | 20 - .../presenter/entities/BRMenuItem.kt | 9 + ....java => BWDatabaseTransactionEntity.java} | 4 +- .../presenter/entities/TxItem.java | 6 + .../presenter/fragments/BuyTabFragment.java | 41 - .../fragments/FragmentBalanceSeedReminder.kt | 5 +- .../presenter/fragments/FragmentMenu.java | 7 +- .../fragments/FragmentPhraseWord.java | 42 - .../presenter/fragments/FragmentPin.java | 208 --- .../presenter/fragments/FragmentReceive.java | 4 +- .../presenter/fragments/FragmentSend.kt | 10 +- .../fragments/FragmentTransactionItem.java | 10 +- .../presenter/history/HistoryFooter.kt | 6 +- .../presenter/history/HistoryFragment.kt | 15 +- .../interfaces/BRAuthCompletion.java | 6 - .../interfaces/BROnSignalCompletion.java | 3 + .../presenter/interfaces/BreadPayment.java | 5 - .../brainwallet/tools/adapter/CurAdapter.java | 81 - .../tools/adapter/TransactionListAdapter.java | 2 +- .../tools/animation/BRAnimator.java | 17 +- .../tools/listeners/SyncReceiver.java | 4 +- .../tools/manager/AnalyticsManager.java | 11 +- .../tools/manager/BRSharedPrefs.java | 271 ++- .../tools/manager/InternetManager.java | 3 + .../tools/manager/PromptManager.java | 3 +- .../brainwallet/tools/manager/TxManager.java | 4 + .../tools/manager/{ => sync}/SyncManager.java | 46 +- .../tools/manager/sync/SyncThreadManager.kt | 102 ++ .../tools/security/AuthManager.java | 4 - .../tools/security/BRKeyStore.java | 50 +- .../brainwallet/tools/security/BRSender.java | 100 +- .../tools/security/BitcoinUrlHandler.java | 22 +- .../brainwallet/tools/security/PostAuth.java | 30 +- .../tools/security/RootHelper.java | 39 - .../tools/sqlite/BRDataSourceInterface.java | 9 - .../tools/sqlite/BRDataSourceInterface.kt | 12 + .../tools/sqlite/CurrencyDataSource.java | 7 +- .../tools/sqlite/MerkleBlockDataSource.java | 4 +- .../tools/sqlite/PeerDataSource.java | 4 +- .../tools/sqlite/TransactionDataSource.java | 23 +- .../brainwallet/tools/threads/Examples.java | 57 - .../PaymentProtocolPostPaymentTask.java | 135 -- .../tools/threads/PaymentProtocolTask.java | 6 +- .../threads/PriorityThreadPoolExecutor.java | 50 - .../brainwallet/tools/util/BRConstants.java | 211 --- .../brainwallet/tools/util/BRCurrency.java | 21 +- .../brainwallet/tools/util/BRExchange.java | 31 +- .../com/brainwallet/tools/util/Extension.kt | 1 + .../brainwallet/tools/util/FileHelper.java | 53 - .../com/brainwallet/tools/util/Utils.java | 12 +- .../com/brainwallet/ui/BrainwalletActivity.kt | 423 +++-- .../brainwallet/ui/BrainwalletViewModel.kt | 20 +- .../balancebento/BalanceBentoEvent.kt | 6 + .../balancebento/BalanceBentoScreen.kt | 397 +++++ .../balancebento/BalanceBentoState.kt | 21 + .../balancebento/BalanceBentoViewModel.kt | 165 ++ .../balancebento/NoWifiBalanceAlertScreen.kt | 120 ++ .../balancebento/SyncStatusSubScreen.kt | 77 + .../buyreceivebento}/receive/ReceiveDialog.kt | 69 +- .../receive/ReceiveDialogEvent.kt | 2 +- .../receive/ReceiveDialogFragment.kt | 5 +- .../receive/ReceiveDialogState.kt | 2 +- .../receive/ReceiveDialogViewModel.kt | 8 +- .../favouritesbento/FavouritesBentoScreen.kt | 171 ++ .../gamehubbento/GameHubBentoEvent.kt | 4 + .../gamehubbento/GameHubBentoPagerScreen.kt | 86 + .../gamehubbento/GameHubBentoRiceScreen.kt | 101 ++ .../gamehubbento/GameHubBentoScreen.kt | 197 +++ .../gamehubbento/GameHubBentoState.kt | 7 + .../gamehubbento/GameHubBentoUnagiScreen.kt | 111 ++ .../gamehubbento/GameHubBentoViewModel.kt | 43 + .../ltcpickerbento/LTCPickerBentoEvent.kt | 9 + .../ltcpickerbento/LTCPickerBentoScreen.kt | 222 +++ .../ltcpickerbento/LTCPickerBentoState.kt | 23 + .../ltcpickerbento/LTCPickerBentoViewModel.kt | 115 ++ .../transactionbento/ConfirmationStatus.kt | 83 + .../bentosections/transactionbento/NoTxRow.kt | 110 ++ .../transactionbento/TransactionBentoEvent.kt | 7 + .../transactionbento/TransactionBentoState.kt | 10 + .../TransactionBentoViewModel.kt | 65 + .../transactionbento/TransactionDetail.kt | 328 ++++ .../transactionbento/TransactionFilter.kt | 5 + .../transactionbento/TransactionRow.kt | 243 +++ .../TransactionsBentoScreen.kt | 254 +++ .../tutorials/TutorialsBentoScreen.kt | 98 ++ .../brainwallet/ui/composable/ActionButton.kt | 36 + .../ui/composable/BentoBottomNavBar.kt | 213 +++ .../ui/composable/BrainWalletLogo.kt | 39 - .../com/brainwallet/ui/composable/Buttons.kt | 139 ++ .../brainwallet/ui/composable/CircleButton.kt | 6 +- .../ui/composable/DarkModeToggleButton.kt | 10 +- .../ui/composable/DashedDividers.kt | 38 + .../brainwallet/ui/composable/Foundation.kt | 22 +- .../brainwallet/ui/composable/LargeButton.kt | 63 - .../ui/composable/LoadingDialog.kt | 6 +- .../brainwallet/ui/composable/MediumButton.kt | 6 +- .../ui/composable/MoonpayBuyButton.kt | 8 +- .../brainwallet/ui/composable/SeedWordItem.kt | 14 +- .../brainwallet/ui/composable/WheelPicker.kt | 40 +- .../bottomsheet/FiatSelectorBottomSheet.kt | 14 +- .../LanguageSelectorBottomSheet.kt | 8 +- .../{ => passcode}/PasscodeIndicator.kt | 2 +- .../{ => passcode}/PasscodeKeypad.kt | 23 +- .../passcode/PasscodeKeypadEvent.kt | 5 + .../passcode/PasscodeKeypadWrapper.kt | 19 + .../composable/{ => passcode}/PinDotItem.kt | 8 +- .../screens/buylitecoin/BuyLitecoinEvent.kt | 11 - .../ui/screens/buyreceive/BuyReceiveEvent.kt | 11 + .../BuyReceiveScreen.kt} | 26 +- .../BuyReceiveState.kt} | 8 +- .../BuyReceiveViewModel.kt} | 33 +- .../ui/screens/gamehub/GameHubEvent.kt | 7 + .../ui/screens/gamehub/GameHubScreen.kt | 89 + .../ui/screens/gamehub/GameHubState.kt | 8 + .../ui/screens/gamehub/GameHubViewModel.kt | 25 + .../brainwallet/ui/screens/home/HomeScreen.kt | 87 - .../ui/screens/home/history/HistoryScreen.kt | 10 - .../ui/screens/inputwords/InputWordsEvent.kt | 21 - .../brainwallet/ui/screens/main/MainScreen.kt | 431 +++++ .../ui/screens/main/MainScreenEvent.kt | 15 + .../ui/screens/main/MainScreenState.kt | 51 + .../ui/screens/main/MainViewModel.kt | 367 ++++ .../ui/screens/main/SettingsButton.kt | 64 + .../ui/screens/main/ThemeButton.kt | 64 + .../ui/screens/restore/RestoreEvent.kt | 21 + .../RestoreScreen.kt} | 45 +- .../RestoreState.kt} | 10 +- .../RestoreViewModel.kt} | 55 +- .../ui/screens/send/BWSendResult.kt | 13 + .../brainwallet/ui/screens/send/BWSender.kt | 92 + .../ui/screens/send/ConfirmSend.kt | 190 +++ .../ui/screens/send/PasscodeConfirmWidget.kt | 99 ++ .../brainwallet/ui/screens/send/PreSend.kt | 49 + .../ui/screens/send/PreSendAddressRow.kt | 141 ++ .../ui/screens/send/PreSendAmountRow.kt | 200 +++ .../ui/screens/send/PreSendMemoRow.kt | 101 ++ .../ui/screens/send/SendDetailRow.kt | 79 + .../brainwallet/ui/screens/send/SendEvent.kt | 22 + .../brainwallet/ui/screens/send/SendScreen.kt | 270 +++ .../brainwallet/ui/screens/send/SendState.kt | 41 + .../ui/screens/send/SendViewModel.kt | 362 ++++ .../screens/setpasscode/SetPasscodeScreen.kt | 6 +- .../{home => settings}/SettingsEvent.kt | 2 +- .../{home => settings}/SettingsState.kt | 5 +- .../{home => settings}/SettingsViewModel.kt | 71 +- .../settingsrows/CurrencyDetail.kt | 55 +- .../settingsrows/GamesDetail.kt | 2 +- .../settingsrows}/HomeSettingDrawerSheet.kt | 30 +- .../settingsrows/LanguageDetail.kt | 43 +- .../settingsrows/LitecoinBlockchainDetail.kt | 8 +- .../settingsrows/LockSettingRowItem.kt | 6 +- .../settingsrows/SecurityDetail.kt | 4 +- .../settingsrows/SettingRowItem.kt | 25 +- .../settingsrows/ThemeSettingRowItem.kt | 2 +- .../ui/screens/topup/TopUpScreen.kt | 18 +- .../ui/screens/unlock/UnLockEvent.kt | 2 - .../ui/screens/unlock/UnLockScreen.kt | 2 +- .../ui/screens/unlock/UnLockViewModel.kt | 4 +- .../unlock/components/UnLockScreenBody.kt | 57 +- .../unlock/components/UnLockScreenFooter.kt | 30 +- .../unlock/components/UnLockScreenHeader.kt | 40 +- .../ui/screens/welcome/WelcomeScreen.kt | 52 +- .../yourseedproveit/YourSeedProveItScreen.kt | 6 +- .../YourSeedProveItViewModel.kt | 23 +- .../java/com/brainwallet/ui/theme/Colors.kt | 12 + .../com/brainwallet/ui/theme/DesignCore.kt | 146 ++ .../java/com/brainwallet/ui/theme/Fonts.kt | 22 + .../java/com/brainwallet/ui/theme/Gradient.kt | 157 ++ .../java/com/brainwallet/ui/theme/Theme.kt | 6 +- .../com/brainwallet/ui/theme/Typography.kt | 85 + .../java/com/brainwallet/util/EventBus.kt | 7 + .../brainwallet/util/VersionCodeProvider.kt | 6 + .../com/brainwallet/wallet/BRPeerManager.java | 43 +- .../brainwallet/wallet/BRWalletManager.java | 84 +- .../worker/CurrencyUpdateWorker.kt | 13 +- .../platform/kvstore/ReplicatedKVStore.java | 4 +- .../platform/sqlite/PlatformSqliteHelper.java | 4 +- .../com/platform/tools/KVStoreManager.java | 4 +- .../main/res/anim/anticipate_interpolator.xml | 4 - app/src/main/res/anim/enter_from_top.xml | 13 - app/src/main/res/anim/exit_to_top.xml | 12 - app/src/main/res/anim/fade_in.xml | 19 - app/src/main/res/anim/fade_out.xml | 18 - app/src/main/res/animator/from_left.xml | 10 - app/src/main/res/animator/from_top.xml | 12 - app/src/main/res/animator/to_right.xml | 10 - app/src/main/res/animator/to_top.xml | 12 - .../color/bottom_nav_icon_tint_selector.xml | 5 - .../res/color/fee_selector_text_selector.xml | 5 - .../res/color/fiat_option_text_selector.xml | 5 - .../transfer_fiat_option_text_selector.xml | 5 - .../main/res/drawable-hdpi/bubble_up.9.png | Bin 713 -> 0 bytes app/src/main/res/drawable-hdpi/bug.png | Bin 4176 -> 0 bytes app/src/main/res/drawable-hdpi/burger.png | Bin 446 -> 0 bytes .../drawable-hdpi/cameraguidebluesmall.png | Bin 447 -> 0 bytes .../main/res/drawable-hdpi/caret_right.png | Bin 374 -> 0 bytes app/src/main/res/drawable-hdpi/checkmark.png | Bin 461 -> 0 bytes app/src/main/res/drawable-hdpi/chevron.png | Bin 293 -> 0 bytes .../res/drawable-hdpi/clickable_layout.xml | 9 - app/src/main/res/drawable-hdpi/cross_icon.png | Bin 679 -> 0 bytes .../res/drawable-hdpi/faq_question_white.png | Bin 618 -> 0 bytes .../res/drawable-hdpi/fingerprint_icon.png | Bin 2491 -> 0 bytes app/src/main/res/drawable-hdpi/flash_off.png | Bin 1249 -> 0 bytes app/src/main/res/drawable-hdpi/flash_on.png | Bin 1269 -> 0 bytes app/src/main/res/drawable-hdpi/ic_nav_buy.png | Bin 1048 -> 0 bytes .../res/drawable-hdpi/ic_question_mark.png | Bin 757 -> 0 bytes .../drawable-hdpi/ic_share_vertical_blue.png | Bin 298 -> 0 bytes .../main/res/drawable-hdpi/ic_stat_name.png | Bin 549 -> 0 bytes .../res/drawable-hdpi/ic_wallet_locked.png | Bin 2131 -> 0 bytes .../drawable-hdpi/icon_delete_cirlce_grey.png | Bin 679 -> 0 bytes app/src/main/res/drawable-hdpi/locker.png | Bin 3245 -> 0 bytes .../main/res/drawable-hdpi/navigationback.png | Bin 753 -> 0 bytes app/src/main/res/drawable-hdpi/no_eye.png | Bin 6090 -> 0 bytes app/src/main/res/drawable-hdpi/no_key.png | Bin 2395 -> 0 bytes app/src/main/res/drawable-hdpi/settings.png | Bin 1000 -> 0 bytes app/src/main/res/drawable-hdpi/x.png | Bin 515 -> 0 bytes .../main/res/drawable-mdpi/caret_right.png | Bin 253 -> 0 bytes .../res/drawable-mdpi/faq_question_white.png | Bin 386 -> 0 bytes .../res/drawable-mdpi/fingerprint_icon.png | Bin 1368 -> 0 bytes app/src/main/res/drawable-mdpi/ic_nav_buy.png | Bin 711 -> 0 bytes .../res/drawable-mdpi/ic_question_mark.png | Bin 487 -> 0 bytes .../drawable-mdpi/ic_share_vertical_blue.png | Bin 220 -> 0 bytes .../main/res/drawable-mdpi/ic_stat_name.png | Bin 363 -> 0 bytes .../res/drawable-mdpi/ic_wallet_locked.png | Bin 1340 -> 0 bytes .../drawable-mdpi/icon_delete_cirlce_grey.png | Bin 449 -> 0 bytes .../drawable-xhdpi/cameraguide_blue_small.png | Bin 447 -> 0 bytes .../main/res/drawable-xhdpi/caret_right.png | Bin 491 -> 0 bytes .../res/drawable-xhdpi/faq_question_white.png | Bin 832 -> 0 bytes .../res/drawable-xhdpi/fingerprint_icon.png | Bin 3623 -> 0 bytes .../main/res/drawable-xhdpi/ic_nav_buy.png | Bin 1275 -> 0 bytes .../res/drawable-xhdpi/ic_question_mark.png | Bin 998 -> 0 bytes .../drawable-xhdpi/ic_share_vertical_blue.png | Bin 302 -> 0 bytes .../main/res/drawable-xhdpi/ic_stat_name.png | Bin 726 -> 0 bytes .../res/drawable-xhdpi/ic_wallet_locked.png | Bin 3075 -> 0 bytes .../icon_delete_cirlce_grey.png | Bin 920 -> 0 bytes .../res/drawable-xhdpi/right_arrow_white.png | Bin 1743 -> 0 bytes .../main/res/drawable-xxhdpi/caret_right.png | Bin 708 -> 0 bytes .../drawable-xxhdpi/faq_question_white.png | Bin 1359 -> 0 bytes .../res/drawable-xxhdpi/fingerprint_icon.png | Bin 5805 -> 0 bytes .../main/res/drawable-xxhdpi/ic_nav_buy.png | Bin 1823 -> 0 bytes .../res/drawable-xxhdpi/ic_question_mark.png | Bin 1478 -> 0 bytes .../ic_share_vertical_blue.png | Bin 390 -> 0 bytes .../main/res/drawable-xxhdpi/ic_stat_name.png | Bin 1195 -> 0 bytes .../res/drawable-xxhdpi/ic_wallet_locked.png | Bin 5228 -> 0 bytes .../icon_delete_cirlce_grey.png | Bin 1414 -> 0 bytes .../res/drawable-xxhdpi/received_label.9.png | Bin 258 -> 0 bytes .../main/res/drawable-xxhdpi/sent_label.9.png | Bin 264 -> 0 bytes .../drawable-xxhdpi/unconfirmed_label.9.png | Bin 210 -> 0 bytes .../main/res/drawable-xxxhdpi/caret_right.png | Bin 910 -> 0 bytes .../drawable-xxxhdpi/faq_question_white.png | Bin 1879 -> 0 bytes .../res/drawable-xxxhdpi/fingerprint_icon.png | Bin 8165 -> 0 bytes .../main/res/drawable-xxxhdpi/ic_nav_buy.png | Bin 2364 -> 0 bytes .../res/drawable-xxxhdpi/ic_qr_code_white.png | Bin 14543 -> 0 bytes .../res/drawable-xxxhdpi/ic_question_mark.png | Bin 1965 -> 0 bytes .../ic_share_vertical_blue.png | Bin 451 -> 0 bytes .../res/drawable-xxxhdpi/ic_stat_name.png | Bin 1727 -> 0 bytes .../res/drawable-xxxhdpi/ic_wallet_locked.png | Bin 7620 -> 0 bytes .../icon_delete_cirlce_grey.png | Bin 1826 -> 0 bytes app/src/main/res/drawable/b_blue.xml | 14 - app/src/main/res/drawable/b_blue_pressed.xml | 15 - app/src/main/res/drawable/b_blue_stroke.xml | 18 - .../res/drawable/b_blue_stroke_pressed.xml | 18 - app/src/main/res/drawable/b_gray_stroke.xml | 18 - .../res/drawable/b_gray_stroke_pressed.xml | 18 - .../main/res/drawable/b_half_left_white.xml | 12 - .../main/res/drawable/b_half_right_white.xml | 4 - app/src/main/res/drawable/black_ltc_coin.png | Bin 0 -> 62089 bytes app/src/main/res/drawable/border_shape.xml | 13 - .../res/drawable/border_shape_pressed.xml | 13 - .../res/drawable/bread_dialog_rounded.xml | 8 - app/src/main/res/drawable/bread_gradient.xml | 9 - .../main/res/drawable/button_intro_left.xml | 19 - .../main/res/drawable/button_intro_right.xml | 19 - .../res/drawable/button_no_thanks_emails.xml | 19 - .../main/res/drawable/buy_partner_shape.xml | 9 - app/src/main/res/drawable/bw_logo_white.png | Bin 46985 -> 0 bytes app/src/main/res/drawable/cancel_24dp.xml | 9 + .../main/res/drawable/check_circle_24dp.xml | 9 + .../main/res/drawable/circle_circle_24dp.xml | 9 + .../main/res/drawable/circle_indicator.xml | 9 - app/src/main/res/drawable/copy_button.xml | 8 - .../main/res/drawable/divider_white_shape.xml | 8 - .../main/res/drawable/donate_slider_thumb.xml | 13 - app/src/main/res/drawable/edit.png | Bin 5845 -> 0 bytes .../main/res/drawable/fee_selector_bg_end.xml | 17 - .../res/drawable/fee_selector_bg_middle.xml | 15 - .../res/drawable/fee_selector_bg_start.xml | 17 - .../res/drawable/fiat_option_bg_selector.xml | 10 - app/src/main/res/drawable/finger_gradient.xml | 10 - app/src/main/res/drawable/game_hub_bk.png | Bin 0 -> 115055 bytes app/src/main/res/drawable/home_24px.xml | 10 + app/src/main/res/drawable/ic_burger_menu.xml | 9 + app/src/main/res/drawable/ic_buy_receive.xml | 9 + .../res/drawable/ic_fingerprint_large.xml | 10 - app/src/main/res/drawable/ic_game_hub.xml | 9 + app/src/main/res/drawable/ic_history.xml | 16 + app/src/main/res/drawable/ic_import.xml | 19 - app/src/main/res/drawable/ic_moon_stars.xml | 9 + app/src/main/res/drawable/ic_no_wifi.xml | 9 + .../res/drawable/ic_search_black_24dp.xml | 9 - .../main/res/drawable/ic_search_gray_24dp.xml | 9 - app/src/main/res/drawable/ic_send.xml | 9 + app/src/main/res/drawable/ic_sunny.xml | 9 + app/src/main/res/drawable/import_gradient.xml | 10 - .../res/drawable/keyboard_trans_button.xml | 5 - .../res/drawable/lang_rounded_background.xml | 6 - .../res/drawable/load_wallet_progress.xml | 28 - .../res/drawable/loading_wallet_layout.xml | 17 - app/src/main/res/drawable/logo_circle.xml | 8 - .../main/res/drawable/paper_key_gradient.xml | 10 - app/src/main/res/drawable/phrase_field.xml | 6 - .../main/res/drawable/pin_round_corner.xml | 8 - .../res/drawable/powered_by_moonpay_blk.xml | 10 + .../res/drawable/powered_by_moonpay_wht.xml | 10 + app/src/main/res/drawable/progress_blue.xml | 20 - .../main/res/drawable/recover_gradient.xml | 10 - .../main/res/drawable/restore_gradient.xml | 10 - app/src/main/res/drawable/rice_partner_03.jpg | Bin 0 -> 106705 bytes .../res/drawable/rounded_16_jade_green.xml | 7 - .../res/drawable/rounded_16_lite_blue.xml | 7 - .../drawable/rounded_16_lite_blue_stroke.xml | 9 - app/src/main/res/drawable/rounded_dialog.xml | 7 - .../res/drawable/rounded_gradient_header.xml | 15 - .../main/res/drawable/rounded_phrase_word.xml | 7 - .../res/drawable/rounded_pop_up_intro.xml | 9 - .../main/res/drawable/search_background.xml | 6 - app/src/main/res/drawable/selector_blue.xml | 7 - .../res/drawable/selector_blue_stroke.xml | 7 - .../res/drawable/selector_gray_stroke.xml | 7 - app/src/main/res/drawable/shadow_back.xml | 17 - app/src/main/res/drawable/syncing_rounded.xml | 12 - .../drawable/transfer_amount_max_shape.xml | 11 - .../transfer_fiat_option_bg_selector.xml | 10 - .../res/drawable/transfer_fiat_options_bg.xml | 7 - .../res/drawable/transfer_up_down_circle.xml | 14 - app/src/main/res/drawable/unagi_social_01.jpg | Bin 0 -> 160320 bytes app/src/main/res/drawable/visibility_off.xml | 9 + app/src/main/res/drawable/visibility_svg.xml | 9 + app/src/main/res/drawable/white_ltc_coin.png | Bin 0 -> 62986 bytes app/src/main/res/font/bolden_van.ttf | Bin 0 -> 65124 bytes app/src/main/res/font/ibm_plex_sans_bold.ttf | Bin 0 -> 218212 bytes .../res/font/ibm_plex_sans_extra_light.ttf | Bin 0 -> 218948 bytes .../main/res/font/ibm_plex_sans_italic.ttf | Bin 0 -> 233508 bytes app/src/main/res/font/ibm_plex_sans_light.ttf | Bin 0 -> 218848 bytes .../main/res/font/ibm_plex_sans_medium.ttf | Bin 0 -> 218268 bytes .../main/res/font/ibm_plex_sans_regular.ttf | Bin 0 -> 218236 bytes .../main/res/font/ibm_plex_sans_semi_bold.ttf | Bin 0 -> 218248 bytes app/src/main/res/font/ibm_plex_sans_thin.ttf | Bin 0 -> 218724 bytes app/src/main/res/layout/activity_about.xml | 2 - app/src/main/res/layout/activity_advanced.xml | 1 - app/src/main/res/layout/activity_bread.xml | 9 +- app/src/main/res/layout/activity_camera.xml | 1 - app/src/main/res/layout/activity_disabled.xml | 1 - .../res/layout/activity_display_currency.xml | 1 - .../main/res/layout/activity_fingerprint.xml | 131 -- app/src/main/res/layout/activity_intro.xml | 100 -- .../res/layout/activity_intro_recover.xml | 4 - app/src/main/res/layout/activity_nodes.xml | 1 - .../main/res/layout/activity_notification.xml | 1 - .../main/res/layout/activity_paper_key.xml | 1 - .../res/layout/activity_paper_key_prove.xml | 1 - app/src/main/res/layout/activity_pin.xml | 1 - .../main/res/layout/activity_pin_template.xml | 119 ++ app/src/main/res/layout/activity_qr.xml | 1 - .../res/layout/activity_security_center.xml | 1 - app/src/main/res/layout/activity_settings.xml | 1 - .../main/res/layout/activity_share_data.xml | 1 - .../main/res/layout/activity_spend_limit.xml | 1 - .../res/layout/activity_sync_blockchain.xml | 1 - app/src/main/res/layout/activity_web_view.xml | 21 - .../main/res/layout/activity_write_down.xml | 2 - .../main/res/layout/bread_spinner_item.xml | 31 - app/src/main/res/layout/buy_partner_item.xml | 179 -- .../res/layout/fragment_authentication.xml | 5 - .../layout/fragment_balance_seed_reminder.xml | 5 - .../main/res/layout/fragment_bread_pin.xml | 93 - app/src/main/res/layout/fragment_manage.xml | 88 - app/src/main/res/layout/fragment_menu.xml | 1 - app/src/main/res/layout/fragment_receive.xml | 5 - app/src/main/res/layout/fragment_send.xml | 5 - .../main/res/layout/fragment_word_item.xml | 23 - app/src/main/res/layout/notification_bar.xml | 1 - .../main/res/layout/pop_up_language_intro.xml | 60 - app/src/main/res/layout/search_bar.xml | 146 -- app/src/main/res/layout/spinner_item.xml | 17 - .../res/layout/transaction_details_item.xml | 1 - .../res/layout/view_bip38password_dialog.xml | 1 - app/src/main/res/menu/bottom_nav_menu.xml | 2 +- .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 - .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 3732 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 2416 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 5300 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 8124 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 11330 -> 0 bytes app/src/main/res/values-ar/strings.xml | 260 +-- app/src/main/res/values-de/strings.xml | 488 +----- app/src/main/res/values-es/strings.xml | 411 +---- app/src/main/res/values-fa/strings.xml | 1486 +++++++--------- app/src/main/res/values-fr/strings.xml | 261 +-- app/src/main/res/values-h700dp/dimens.xml | 4 +- app/src/main/res/values-h700dp/strings.xml | 26 + app/src/main/res/values-hi/strings.xml | 258 +-- app/src/main/res/values-in/strings.xml | 262 +-- app/src/main/res/values-it/strings.xml | 259 +-- app/src/main/res/values-ja/strings.xml | 259 +-- app/src/main/res/values-ko/strings.xml | 259 +-- app/src/main/res/values-land/dimens.xml | 4 +- app/src/main/res/values-land/strings.xml | 26 + app/src/main/res/values-night/colors.xml | 2 - app/src/main/res/values-night/strings.xml | 26 + app/src/main/res/values-pa/strings.xml | 1491 +++++++---------- app/src/main/res/values-pl/strings.xml | 1481 +++++++--------- app/src/main/res/values-pt-rBR/strings.xml | 282 ++++ app/src/main/res/values-pt/strings.xml | 239 +-- app/src/main/res/values-ru/strings.xml | 259 +-- app/src/main/res/values-sv/strings.xml | 258 +-- app/src/main/res/values-tr/strings.xml | 261 +-- app/src/main/res/values-uk/strings.xml | 246 +-- app/src/main/res/values-w1240dp/dimens.xml | 4 +- app/src/main/res/values-w1240dp/strings.xml | 26 + app/src/main/res/values-w600dp/dimens.xml | 4 +- app/src/main/res/values-w600dp/strings.xml | 26 + app/src/main/res/values-zh-rCN/strings.xml | 259 +-- app/src/main/res/values-zh-rTW/strings.xml | 259 +-- app/src/main/res/values/colors.xml | 2 - app/src/main/res/values/dimens.xml | 11 - app/src/main/res/values/font_certs.xml | 17 +- .../res/values/ic_launcher_background.xml | 4 +- app/src/main/res/values/ids.xml | 1 - app/src/main/res/values/integer.xml | 4 - app/src/main/res/values/strings.xml | 479 +----- app/src/main/res/values/styles.xml | 63 - .../brainwallet/BrainwalletScreengrabApp.kt | 2 +- .../flow/RecoverWalletScreenGrabsTest.kt | 0 .../currency/BackupRateFetchTests.kt | 4 +- .../java/com/brainwallet/data/BaseURLTests.kt | 2 +- .../data/repository/PeerManagerSourceTest.kt | 91 +- .../com/brainwallet/example/ExampleTest.kt | 123 -- .../tools/database/DatabaseTests.kt | 76 +- .../tools/security/BRKeyStoreTest.kt | 1046 ------------ .../tools/security/NewKeyStoreTests.kt | 179 -- .../brainwallet/tools/util/BRConstantsTest.kt | 143 -- .../tools/util/ProdAPIManagerTests.kt | 4 +- .../ui/screens/unlock/UnLockViewModelTest.kt | 42 +- .../brainwallet/wallet/BRWalleManagerTest.kt | 114 ++ .../com/brainwallet/BrainwalletAppTest.kt | 174 ++ .../brainwallet/consants/BWConstantsTest.kt | 338 ++++ .../com/brainwallet/di/AppModuleTests.kt | 117 ++ .../tools/constants/BWConstantTests.kt | 208 +++ .../tools/security/BWAIKeyStoreTests.kt | 706 ++++++++ .../balancebento/BalanceBentoEventTest.kt | 55 + .../balancebento/BalanceBentoStateTest.kt | 107 ++ .../balancebento/BalanceBentoViewModelTest.kt | 350 ++++ .../buyreceive/ReceiveDialogStateTest.kt | 164 ++ .../buyreceive/ReceiveDialogViewModelTest.kt | 200 +++ .../LTCPickerBentoStateTests.kt | 121 ++ .../LTCPickerBentoViewModelTests.kt | 118 ++ .../TransactionBentoViewModelTest.kt | 96 ++ .../ui/screens/send/SendStateTest.kt | 142 ++ .../ui/screens/settings/SettingsStateTests.kt | 35 + build.gradle.kts | 1 - config/detekt-app-baseline.xml | 109 +- gradle.properties | 73 +- gradle/libs.versions.toml | 15 +- scripts/test_anthropic_flow.py | 31 + scripts/translate_strings.py | 12 +- translate_strings.py | 218 +++ 512 files changed, 16677 insertions(+), 12764 deletions(-) create mode 100644 .github/workflows/bento-auto-translate.yml create mode 100755 android/scripts/translate_strings.py create mode 100644 app/src/main/java/com/brainwallet/constants/BWConstants.kt create mode 100644 app/src/main/java/com/brainwallet/constants/Constants.kt create mode 100644 app/src/main/java/com/brainwallet/data/model/GlobalCurrency.kt create mode 100644 app/src/main/java/com/brainwallet/data/model/LtcStats.kt create mode 100644 app/src/main/java/com/brainwallet/data/repository/ConnectivityRepository.kt create mode 100644 app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigSourceImpl.kt create mode 100644 app/src/main/java/com/brainwallet/data/repository/HubContentRepositoryImpl.kt create mode 100644 app/src/main/java/com/brainwallet/data/repository/TxRepository.kt create mode 100644 app/src/main/java/com/brainwallet/data/repository/TxRepositoryImpl.kt create mode 100644 app/src/main/java/com/brainwallet/di/RemoteConfigModule.kt rename app/src/main/java/com/brainwallet/navigation/{MainNav.kt => MainNavigationHost.kt} (69%) create mode 100644 app/src/main/java/com/brainwallet/presenter/activities/ReEnterPinActivity.java create mode 100644 app/src/main/java/com/brainwallet/presenter/activities/UpdatePinActivity.java delete mode 100644 app/src/main/java/com/brainwallet/presenter/entities/BRMenuItem.java create mode 100644 app/src/main/java/com/brainwallet/presenter/entities/BRMenuItem.kt rename app/src/main/java/com/brainwallet/presenter/entities/{BRTransactionEntity.java => BWDatabaseTransactionEntity.java} (84%) delete mode 100644 app/src/main/java/com/brainwallet/presenter/fragments/BuyTabFragment.java delete mode 100644 app/src/main/java/com/brainwallet/presenter/fragments/FragmentPhraseWord.java delete mode 100644 app/src/main/java/com/brainwallet/presenter/fragments/FragmentPin.java delete mode 100644 app/src/main/java/com/brainwallet/presenter/interfaces/BRAuthCompletion.java delete mode 100644 app/src/main/java/com/brainwallet/presenter/interfaces/BreadPayment.java delete mode 100644 app/src/main/java/com/brainwallet/tools/adapter/CurAdapter.java rename app/src/main/java/com/brainwallet/tools/manager/{ => sync}/SyncManager.java (67%) create mode 100644 app/src/main/java/com/brainwallet/tools/manager/sync/SyncThreadManager.kt delete mode 100644 app/src/main/java/com/brainwallet/tools/security/RootHelper.java delete mode 100644 app/src/main/java/com/brainwallet/tools/sqlite/BRDataSourceInterface.java create mode 100644 app/src/main/java/com/brainwallet/tools/sqlite/BRDataSourceInterface.kt delete mode 100644 app/src/main/java/com/brainwallet/tools/threads/Examples.java delete mode 100644 app/src/main/java/com/brainwallet/tools/threads/PaymentProtocolPostPaymentTask.java delete mode 100644 app/src/main/java/com/brainwallet/tools/threads/PriorityThreadPoolExecutor.java delete mode 100644 app/src/main/java/com/brainwallet/tools/util/BRConstants.java delete mode 100644 app/src/main/java/com/brainwallet/tools/util/FileHelper.java create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoViewModel.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/balancebento/NoWifiBalanceAlertScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/balancebento/SyncStatusSubScreen.kt rename app/src/main/java/com/brainwallet/ui/{screens/home => bentosections/buyreceivebento}/receive/ReceiveDialog.kt (88%) rename app/src/main/java/com/brainwallet/ui/{screens/home => bentosections/buyreceivebento}/receive/ReceiveDialogEvent.kt (92%) rename app/src/main/java/com/brainwallet/ui/{screens/home => bentosections/buyreceivebento}/receive/ReceiveDialogFragment.kt (93%) rename app/src/main/java/com/brainwallet/ui/{screens/home => bentosections/buyreceivebento}/receive/ReceiveDialogState.kt (97%) rename app/src/main/java/com/brainwallet/ui/{screens/home => bentosections/buyreceivebento}/receive/ReceiveDialogViewModel.kt (95%) create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/favouritesbento/FavouritesBentoScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoPagerScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoRiceScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoUnagiScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoViewModel.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoViewModel.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/ConfirmationStatus.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/NoTxRow.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoViewModel.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionDetail.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionFilter.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionRow.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionsBentoScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/bentosections/tutorials/TutorialsBentoScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/ActionButton.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/BentoBottomNavBar.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/Buttons.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/DashedDividers.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt rename app/src/main/java/com/brainwallet/ui/composable/{ => passcode}/PasscodeIndicator.kt (91%) rename app/src/main/java/com/brainwallet/ui/composable/{ => passcode}/PasscodeKeypad.kt (83%) create mode 100644 app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypadEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypadWrapper.kt rename app/src/main/java/com/brainwallet/ui/composable/{ => passcode}/PinDotItem.kt (69%) delete mode 100644 app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveEvent.kt rename app/src/main/java/com/brainwallet/ui/screens/{buylitecoin/BuyLitecoinScreen.kt => buyreceive/BuyReceiveScreen.kt} (86%) rename app/src/main/java/com/brainwallet/ui/screens/{buylitecoin/BuyLitecoinState.kt => buyreceive/BuyReceiveState.kt} (68%) rename app/src/main/java/com/brainwallet/ui/screens/{buylitecoin/BuyLitecoinViewModel.kt => buyreceive/BuyReceiveViewModel.kt} (78%) create mode 100644 app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubViewModel.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/screens/home/HomeScreen.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/screens/home/history/HistoryScreen.kt delete mode 100644 app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/main/MainScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/main/MainScreenEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/main/MainScreenState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/main/MainViewModel.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/main/SettingsButton.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/main/ThemeButton.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/restore/RestoreEvent.kt rename app/src/main/java/com/brainwallet/ui/screens/{inputwords/InputWordsScreen.kt => restore/RestoreScreen.kt} (87%) rename app/src/main/java/com/brainwallet/ui/screens/{inputwords/InputWordsState.kt => restore/RestoreState.kt} (59%) rename app/src/main/java/com/brainwallet/ui/screens/{inputwords/InputWordsViewModel.kt => restore/RestoreViewModel.kt} (66%) create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/BWSendResult.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/BWSender.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/ConfirmSend.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/PasscodeConfirmWidget.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/PreSend.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/PreSendAddressRow.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/PreSendAmountRow.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/PreSendMemoRow.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/SendDetailRow.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/SendEvent.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/SendScreen.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/SendState.kt create mode 100644 app/src/main/java/com/brainwallet/ui/screens/send/SendViewModel.kt rename app/src/main/java/com/brainwallet/ui/screens/{home => settings}/SettingsEvent.kt (96%) rename app/src/main/java/com/brainwallet/ui/screens/{home => settings}/SettingsState.kt (87%) rename app/src/main/java/com/brainwallet/ui/screens/{home => settings}/SettingsViewModel.kt (74%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings}/settingsrows/CurrencyDetail.kt (68%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings}/settingsrows/GamesDetail.kt (97%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings/settingsrows}/HomeSettingDrawerSheet.kt (87%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings}/settingsrows/LanguageDetail.kt (68%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings}/settingsrows/LitecoinBlockchainDetail.kt (94%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings}/settingsrows/LockSettingRowItem.kt (69%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings}/settingsrows/SecurityDetail.kt (96%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings}/settingsrows/SettingRowItem.kt (84%) rename app/src/main/java/com/brainwallet/ui/screens/{home/composable => settings}/settingsrows/ThemeSettingRowItem.kt (93%) create mode 100644 app/src/main/java/com/brainwallet/ui/theme/Colors.kt create mode 100644 app/src/main/java/com/brainwallet/ui/theme/DesignCore.kt create mode 100644 app/src/main/java/com/brainwallet/ui/theme/Fonts.kt create mode 100644 app/src/main/java/com/brainwallet/ui/theme/Gradient.kt create mode 100644 app/src/main/java/com/brainwallet/ui/theme/Typography.kt delete mode 100644 app/src/main/res/anim/anticipate_interpolator.xml delete mode 100644 app/src/main/res/anim/enter_from_top.xml delete mode 100644 app/src/main/res/anim/exit_to_top.xml delete mode 100644 app/src/main/res/anim/fade_in.xml delete mode 100644 app/src/main/res/anim/fade_out.xml delete mode 100644 app/src/main/res/animator/from_left.xml delete mode 100644 app/src/main/res/animator/from_top.xml delete mode 100644 app/src/main/res/animator/to_right.xml delete mode 100644 app/src/main/res/animator/to_top.xml delete mode 100644 app/src/main/res/color/bottom_nav_icon_tint_selector.xml delete mode 100644 app/src/main/res/color/fee_selector_text_selector.xml delete mode 100644 app/src/main/res/color/fiat_option_text_selector.xml delete mode 100644 app/src/main/res/color/transfer_fiat_option_text_selector.xml delete mode 100644 app/src/main/res/drawable-hdpi/bubble_up.9.png delete mode 100644 app/src/main/res/drawable-hdpi/bug.png delete mode 100644 app/src/main/res/drawable-hdpi/burger.png delete mode 100644 app/src/main/res/drawable-hdpi/cameraguidebluesmall.png delete mode 100644 app/src/main/res/drawable-hdpi/caret_right.png delete mode 100644 app/src/main/res/drawable-hdpi/checkmark.png delete mode 100644 app/src/main/res/drawable-hdpi/chevron.png delete mode 100644 app/src/main/res/drawable-hdpi/clickable_layout.xml delete mode 100644 app/src/main/res/drawable-hdpi/cross_icon.png delete mode 100644 app/src/main/res/drawable-hdpi/faq_question_white.png delete mode 100644 app/src/main/res/drawable-hdpi/fingerprint_icon.png delete mode 100644 app/src/main/res/drawable-hdpi/flash_off.png delete mode 100644 app/src/main/res/drawable-hdpi/flash_on.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_nav_buy.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_question_mark.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_share_vertical_blue.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_stat_name.png delete mode 100644 app/src/main/res/drawable-hdpi/ic_wallet_locked.png delete mode 100644 app/src/main/res/drawable-hdpi/icon_delete_cirlce_grey.png delete mode 100644 app/src/main/res/drawable-hdpi/locker.png delete mode 100644 app/src/main/res/drawable-hdpi/navigationback.png delete mode 100644 app/src/main/res/drawable-hdpi/no_eye.png delete mode 100644 app/src/main/res/drawable-hdpi/no_key.png delete mode 100644 app/src/main/res/drawable-hdpi/settings.png delete mode 100644 app/src/main/res/drawable-hdpi/x.png delete mode 100644 app/src/main/res/drawable-mdpi/caret_right.png delete mode 100644 app/src/main/res/drawable-mdpi/faq_question_white.png delete mode 100644 app/src/main/res/drawable-mdpi/fingerprint_icon.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_nav_buy.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_question_mark.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_share_vertical_blue.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_stat_name.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_wallet_locked.png delete mode 100644 app/src/main/res/drawable-mdpi/icon_delete_cirlce_grey.png delete mode 100644 app/src/main/res/drawable-xhdpi/cameraguide_blue_small.png delete mode 100644 app/src/main/res/drawable-xhdpi/caret_right.png delete mode 100644 app/src/main/res/drawable-xhdpi/faq_question_white.png delete mode 100644 app/src/main/res/drawable-xhdpi/fingerprint_icon.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_nav_buy.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_question_mark.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_share_vertical_blue.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_stat_name.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_wallet_locked.png delete mode 100644 app/src/main/res/drawable-xhdpi/icon_delete_cirlce_grey.png delete mode 100644 app/src/main/res/drawable-xhdpi/right_arrow_white.png delete mode 100644 app/src/main/res/drawable-xxhdpi/caret_right.png delete mode 100644 app/src/main/res/drawable-xxhdpi/faq_question_white.png delete mode 100644 app/src/main/res/drawable-xxhdpi/fingerprint_icon.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_nav_buy.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_question_mark.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_share_vertical_blue.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_stat_name.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_wallet_locked.png delete mode 100644 app/src/main/res/drawable-xxhdpi/icon_delete_cirlce_grey.png delete mode 100644 app/src/main/res/drawable-xxhdpi/received_label.9.png delete mode 100644 app/src/main/res/drawable-xxhdpi/sent_label.9.png delete mode 100644 app/src/main/res/drawable-xxhdpi/unconfirmed_label.9.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/caret_right.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/faq_question_white.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/fingerprint_icon.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_nav_buy.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_qr_code_white.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_question_mark.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_share_vertical_blue.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_stat_name.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_wallet_locked.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/icon_delete_cirlce_grey.png delete mode 100644 app/src/main/res/drawable/b_blue.xml delete mode 100644 app/src/main/res/drawable/b_blue_pressed.xml delete mode 100644 app/src/main/res/drawable/b_blue_stroke.xml delete mode 100644 app/src/main/res/drawable/b_blue_stroke_pressed.xml delete mode 100644 app/src/main/res/drawable/b_gray_stroke.xml delete mode 100644 app/src/main/res/drawable/b_gray_stroke_pressed.xml delete mode 100644 app/src/main/res/drawable/b_half_left_white.xml delete mode 100644 app/src/main/res/drawable/b_half_right_white.xml create mode 100644 app/src/main/res/drawable/black_ltc_coin.png delete mode 100644 app/src/main/res/drawable/border_shape.xml delete mode 100644 app/src/main/res/drawable/border_shape_pressed.xml delete mode 100644 app/src/main/res/drawable/bread_dialog_rounded.xml delete mode 100644 app/src/main/res/drawable/bread_gradient.xml delete mode 100644 app/src/main/res/drawable/button_intro_left.xml delete mode 100644 app/src/main/res/drawable/button_intro_right.xml delete mode 100644 app/src/main/res/drawable/button_no_thanks_emails.xml delete mode 100644 app/src/main/res/drawable/buy_partner_shape.xml delete mode 100644 app/src/main/res/drawable/bw_logo_white.png create mode 100644 app/src/main/res/drawable/cancel_24dp.xml create mode 100644 app/src/main/res/drawable/check_circle_24dp.xml create mode 100644 app/src/main/res/drawable/circle_circle_24dp.xml delete mode 100644 app/src/main/res/drawable/circle_indicator.xml delete mode 100644 app/src/main/res/drawable/copy_button.xml delete mode 100644 app/src/main/res/drawable/divider_white_shape.xml delete mode 100644 app/src/main/res/drawable/donate_slider_thumb.xml delete mode 100644 app/src/main/res/drawable/edit.png delete mode 100644 app/src/main/res/drawable/fee_selector_bg_end.xml delete mode 100644 app/src/main/res/drawable/fee_selector_bg_middle.xml delete mode 100644 app/src/main/res/drawable/fee_selector_bg_start.xml delete mode 100644 app/src/main/res/drawable/fiat_option_bg_selector.xml delete mode 100644 app/src/main/res/drawable/finger_gradient.xml create mode 100644 app/src/main/res/drawable/game_hub_bk.png create mode 100644 app/src/main/res/drawable/home_24px.xml create mode 100644 app/src/main/res/drawable/ic_burger_menu.xml create mode 100644 app/src/main/res/drawable/ic_buy_receive.xml delete mode 100644 app/src/main/res/drawable/ic_fingerprint_large.xml create mode 100644 app/src/main/res/drawable/ic_game_hub.xml create mode 100644 app/src/main/res/drawable/ic_history.xml delete mode 100644 app/src/main/res/drawable/ic_import.xml create mode 100644 app/src/main/res/drawable/ic_moon_stars.xml create mode 100644 app/src/main/res/drawable/ic_no_wifi.xml delete mode 100644 app/src/main/res/drawable/ic_search_black_24dp.xml delete mode 100644 app/src/main/res/drawable/ic_search_gray_24dp.xml create mode 100644 app/src/main/res/drawable/ic_send.xml create mode 100644 app/src/main/res/drawable/ic_sunny.xml delete mode 100644 app/src/main/res/drawable/import_gradient.xml delete mode 100644 app/src/main/res/drawable/keyboard_trans_button.xml delete mode 100644 app/src/main/res/drawable/lang_rounded_background.xml delete mode 100644 app/src/main/res/drawable/load_wallet_progress.xml delete mode 100644 app/src/main/res/drawable/loading_wallet_layout.xml delete mode 100644 app/src/main/res/drawable/logo_circle.xml delete mode 100644 app/src/main/res/drawable/paper_key_gradient.xml delete mode 100644 app/src/main/res/drawable/phrase_field.xml delete mode 100644 app/src/main/res/drawable/pin_round_corner.xml create mode 100644 app/src/main/res/drawable/powered_by_moonpay_blk.xml create mode 100644 app/src/main/res/drawable/powered_by_moonpay_wht.xml delete mode 100644 app/src/main/res/drawable/progress_blue.xml delete mode 100644 app/src/main/res/drawable/recover_gradient.xml delete mode 100644 app/src/main/res/drawable/restore_gradient.xml create mode 100644 app/src/main/res/drawable/rice_partner_03.jpg delete mode 100644 app/src/main/res/drawable/rounded_16_jade_green.xml delete mode 100644 app/src/main/res/drawable/rounded_16_lite_blue.xml delete mode 100644 app/src/main/res/drawable/rounded_16_lite_blue_stroke.xml delete mode 100644 app/src/main/res/drawable/rounded_dialog.xml delete mode 100644 app/src/main/res/drawable/rounded_gradient_header.xml delete mode 100644 app/src/main/res/drawable/rounded_phrase_word.xml delete mode 100644 app/src/main/res/drawable/rounded_pop_up_intro.xml delete mode 100644 app/src/main/res/drawable/search_background.xml delete mode 100644 app/src/main/res/drawable/selector_blue.xml delete mode 100644 app/src/main/res/drawable/selector_blue_stroke.xml delete mode 100644 app/src/main/res/drawable/selector_gray_stroke.xml delete mode 100644 app/src/main/res/drawable/shadow_back.xml delete mode 100644 app/src/main/res/drawable/syncing_rounded.xml delete mode 100644 app/src/main/res/drawable/transfer_amount_max_shape.xml delete mode 100644 app/src/main/res/drawable/transfer_fiat_option_bg_selector.xml delete mode 100644 app/src/main/res/drawable/transfer_fiat_options_bg.xml delete mode 100644 app/src/main/res/drawable/transfer_up_down_circle.xml create mode 100644 app/src/main/res/drawable/unagi_social_01.jpg create mode 100644 app/src/main/res/drawable/visibility_off.xml create mode 100644 app/src/main/res/drawable/visibility_svg.xml create mode 100644 app/src/main/res/drawable/white_ltc_coin.png create mode 100755 app/src/main/res/font/bolden_van.ttf create mode 100644 app/src/main/res/font/ibm_plex_sans_bold.ttf create mode 100644 app/src/main/res/font/ibm_plex_sans_extra_light.ttf create mode 100644 app/src/main/res/font/ibm_plex_sans_italic.ttf create mode 100644 app/src/main/res/font/ibm_plex_sans_light.ttf create mode 100644 app/src/main/res/font/ibm_plex_sans_medium.ttf create mode 100644 app/src/main/res/font/ibm_plex_sans_regular.ttf create mode 100644 app/src/main/res/font/ibm_plex_sans_semi_bold.ttf create mode 100644 app/src/main/res/font/ibm_plex_sans_thin.ttf delete mode 100644 app/src/main/res/layout/activity_fingerprint.xml delete mode 100644 app/src/main/res/layout/activity_intro.xml create mode 100644 app/src/main/res/layout/activity_pin_template.xml delete mode 100644 app/src/main/res/layout/activity_web_view.xml delete mode 100644 app/src/main/res/layout/bread_spinner_item.xml delete mode 100644 app/src/main/res/layout/buy_partner_item.xml delete mode 100644 app/src/main/res/layout/fragment_authentication.xml delete mode 100644 app/src/main/res/layout/fragment_bread_pin.xml delete mode 100644 app/src/main/res/layout/fragment_manage.xml delete mode 100644 app/src/main/res/layout/fragment_word_item.xml delete mode 100644 app/src/main/res/layout/pop_up_language_intro.xml delete mode 100644 app/src/main/res/layout/search_bar.xml delete mode 100644 app/src/main/res/layout/spinner_item.xml delete mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml delete mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp delete mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values-h700dp/strings.xml create mode 100644 app/src/main/res/values-land/strings.xml create mode 100644 app/src/main/res/values-night/strings.xml create mode 100644 app/src/main/res/values-pt-rBR/strings.xml create mode 100644 app/src/main/res/values-w1240dp/strings.xml create mode 100644 app/src/main/res/values-w600dp/strings.xml rename app/src/{androidTest => screengrabTests}/kotlin/flow/RecoverWalletScreenGrabsTest.kt (100%) delete mode 100644 app/src/test/java/com/brainwallet/example/ExampleTest.kt delete mode 100644 app/src/test/java/com/brainwallet/tools/security/BRKeyStoreTest.kt delete mode 100644 app/src/test/java/com/brainwallet/tools/security/NewKeyStoreTests.kt delete mode 100644 app/src/test/java/com/brainwallet/tools/util/BRConstantsTest.kt create mode 100644 app/src/test/java/com/brainwallet/wallet/BRWalleManagerTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/BrainwalletAppTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/consants/BWConstantsTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/di/AppModuleTests.kt create mode 100644 app/src/test/kotlin/com/brainwallet/tools/constants/BWConstantTests.kt create mode 100644 app/src/test/kotlin/com/brainwallet/tools/security/BWAIKeyStoreTests.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/bentosections/balancebento/BalanceBentoEventTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/bentosections/balancebento/BalanceBentoStateTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/bentosections/balancebento/BalanceBentoViewModelTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/bentosections/buyreceive/ReceiveDialogStateTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/bentosections/buyreceive/ReceiveDialogViewModelTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoStateTests.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoViewModelTests.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoViewModelTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/screens/send/SendStateTest.kt create mode 100644 app/src/test/kotlin/com/brainwallet/ui/screens/settings/SettingsStateTests.kt create mode 100644 scripts/test_anthropic_flow.py create mode 100755 translate_strings.py diff --git a/.circleci/config.yml b/.circleci/config.yml index a639a553..6d4ff714 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,6 +12,7 @@ commands: description: "Sets up the basic environment for all jobs (checkout, credentials, submodules)" steps: - checkout + - android/restore_gradle_cache - run: name: "Setup environment..." command: "echo Setting up environment for brainwallet-android!" @@ -59,7 +60,6 @@ commands: sed -i "s#https://github.com/#https://${GH_TOKEN}@github.com/#g" .gitmodules git submodule sync --recursive git submodule update --init --recursive - - android/restore_gradle_cache # Define a job to be invoked later in a workflow. # See: https://circleci.com/docs/2.0/configuration-reference/#jobs @@ -72,8 +72,8 @@ jobs: steps: - setup_environment - run: - name: "Execute Unit Test" - command: ./gradlew testBrainwalletDebugUnitTest + name: "Execute Unit Tests" + command: ./gradlew testBrainwalletDebugUnitTest --no-daemon --max-workers=2 -Dorg.gradle.jvmargs="-Xmx8g" -Dkotlin.compiler.execution.strategy=in-process - android/save_gradle_cache - run: name: Save test results diff --git a/.github/workflows/auto-translate.yml b/.github/workflows/auto-translate.yml index 139d613d..8ffaf880 100644 --- a/.github/workflows/auto-translate.yml +++ b/.github/workflows/auto-translate.yml @@ -3,9 +3,8 @@ name: Auto-Translate strings.xml on: push: branches: - - main - - develop - bento + - develop paths: - '**/values/strings.xml' workflow_dispatch: # allow manual trigger from GitHub UI @@ -18,7 +17,6 @@ jobs: translate: runs-on: ubuntu-latest timeout-minutes: 30 - steps: - name: Checkout repository uses: actions/checkout@v4 @@ -36,7 +34,7 @@ jobs: - name: Run translation script env: - ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_GH_API_KEY }} + ANTHROPIC_GH_API_KEY: ${{ secrets.ANTHROPIC_GH_API_KEY }} run: python scripts/translate_strings.py - name: Check for changes diff --git a/.github/workflows/bento-auto-translate.yml b/.github/workflows/bento-auto-translate.yml new file mode 100644 index 00000000..83e43947 --- /dev/null +++ b/.github/workflows/bento-auto-translate.yml @@ -0,0 +1,73 @@ +name: Auto-Translate strings.xml + +on: + push: + branches: + - main + - bento + paths: + - '**/values/strings.xml' + workflow_dispatch: # allow manual trigger from GitHub UI + +permissions: + contents: write + pull-requests: write + +jobs: + translate: + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.TRANSLATION_PAT_GHA_CLAUDE_JUL082026 }} + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install dependencies + run: pip install anthropic lxml requests + + - name: Run translation script + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_GH_API_KEY }} + run: python scripts/translate_strings.py + + - name: Check for changes + id: changes + run: | + git diff --quiet && echo "changed=false" >> $GITHUB_OUTPUT || echo "changed=true" >> $GITHUB_OUTPUT + + - name: Create branch and commit + if: steps.changes.outputs.changed == 'true' + run: | + BRANCH="translations/auto-$(date +%Y%m%d-%H%M%S)" + echo "BRANCH=$BRANCH" >> $GITHUB_ENV + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git checkout -b "$BRANCH" + git add app/src/main/res/values-*/strings.xml + git commit -m "chore(i18n): auto-translate missing strings [skip ci] + + Languages updated: ar, zh-rTW, zh-rCN, fr, de, fa, pa, pl, in, es, sv, uk, ru, tr, ja, ko, hi, it, pt-rBR + Triggered by: ${{ github.sha }} + " + git push origin "$BRANCH" + + - name: Open Pull Request + if: steps.changes.outputs.changed == 'true' + env: + GH_TOKEN: ${{ secrets.TRANSLATION_PAT_GHA_CLAUDE_JUL082026 }} + run: | + gh pr create \ + --title "🌍 Auto-translations: missing strings updated" \ + --body "$(cat /tmp/pr_body.md)" \ + --base bento \ + --head "$BRANCH" \ + --label "translations" \ + --reviewer "${{ github.actor }}" diff --git a/.github/workflows/pr-summary-copilot.yml b/.github/workflows/pr-summary-copilot.yml index da03f2bb..bb4892fa 100644 --- a/.github/workflows/pr-summary-copilot.yml +++ b/.github/workflows/pr-summary-copilot.yml @@ -55,6 +55,7 @@ jobs: uses: actions/github-script@v7 env: DIFF_CONTENT: ${{ steps.pr_info.outputs.diff }} + ANTHROPIC_GH_API_KEY: ${{ secrets.ANTHROPIC_GH_API_KEY }} with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | @@ -156,33 +157,33 @@ jobs: --- `; - // --- Call OpenAI-compatible endpoint via gh models --- + // --- Call Claude-compatible endpoint via gh models --- // models API when the workflow has the `models: read` permission. const response = await fetch( - 'https://api.openai.com/v1/chat/completions', + 'https://api.anthropic.com/v1/messages', { method: 'POST', headers: { 'Content-Type': 'application/json', - 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`, + 'x-api-key': process.env.ANTHROPIC_GH_API_KEY, + 'anthropic-version': '2023-06-01', }, body: JSON.stringify({ - model: 'gpt-4o', + model: 'claude-haiku-4-5-20251001', messages: [{ role: 'user', content: prompt }], max_tokens: 2048, - temperature: 0.3, }), } ); - - if (!response.ok) { - const err = await response.text(); - core.setFailed(`Copilot API error ${response.status}: ${err}`); + const data = await response.json(); + // Check Data + if (!response.ok || !data.content) { + console.log('API response status:', response.status); + console.log('API response body:', JSON.stringify(data, null, 2)); + core.setFailed(`Anthropic API error: ${JSON.stringify(data)}`); return; } - - const json = await response.json(); - const summary = json.choices?.[0]?.message?.content ?? '(no summary generated)'; + const summary = data.content[0].text; core.setOutput('summary', summary); fs.writeFileSync('pr_summary.md', summary); diff --git a/android/scripts/translate_strings.py b/android/scripts/translate_strings.py new file mode 100755 index 00000000..65872a16 --- /dev/null +++ b/android/scripts/translate_strings.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python3 +""" +translate_strings.py +Finds all Android locale strings.xml files under app/src/main/res/, +compares them to the source (values/strings.xml), translates any missing +strings via the Anthropic API, and writes the updated files back to disk. +Also writes /tmp/pr_body.md summarising what was changed for the PR. +""" + +import os +import re +import sys +import json +import textwrap +import anthropic +from pathlib import Path +from lxml import etree + +# ── Configuration ───────────────────────────────────────────────────────────── + +SOURCE_DIR = "app/src/main/res/values" +RES_BASE_DIR = "app/src/main/res" +PR_BODY_PATH = "/tmp/pr_body.md" + +# Map Android locale folder suffix → human language name for the prompt +LOCALE_MAP = { + "values-ar": "Arabic", + "values-zh-rTW": "Traditional Chinese (Taiwan)", + "values-zh-rCN": "Simplified Chinese (Mainland China)", + "values-fr": "French", + "values-de": "German", + "values-fa": "Farsi (Persian)", + "values-pa": "Punjabi", + "values-pl": "Polish", + "values-in": "Indonesian", + "values-es": "Spanish", + "values-sv": "Swedish", + "values-uk": "Ukrainian", + "values-ru": "Russian", + "values-tr": "Turkish", + "values-ja": "Japanese", + "values-ko": "Korean", + "values-hi": "Hindi", + "values-it": "Italian", + "values-pt-rBR": "Brazilian Portuguese", +} + +# RTL languages that need android:textDirection="rtl" awareness (informational) +RTL_LOCALES = {"values-ar", "values-fa", "values-pa"} + +BATCH_SIZE = 40 # strings per API call – keeps prompts manageable + +# ── Helpers ─────────────────────────────────────────────────────────────────── + +def parse_strings(path: Path) -> dict[str, str]: + """Return {name: text} for every translatable in the file.""" + if not path.exists(): + return {} + tree = etree.parse(str(path)) + result = {} + for el in tree.getroot().findall("string"): + name = el.get("name") + translatable = el.get("translatable", "true") + if name and translatable.lower() != "false": + # Preserve inner XML (handles , , %1$s etc.) + inner = (el.text or "") + "".join( + etree.tostring(child, encoding="unicode") for child in el + ) + result[name] = inner.strip() + return result + + +def load_or_create_tree(path: Path): + """Parse existing file or return a fresh tree.""" + if path.exists(): + return etree.parse(str(path)) + root = etree.Element("resources") + root.addprevious(etree.Comment(" Auto-generated by translate_strings.py ")) + return etree.ElementTree(root) + + +def write_tree(tree, path: Path): + path.parent.mkdir(parents=True, exist_ok=True) + tree.write( + str(path), + encoding="utf-8", + xml_declaration=True, + pretty_print=True, + ) + + +def set_translated(tree, name: str, translated_text: str): + """Insert or update a element in the tree.""" + root = tree.getroot() + existing = root.find(f'string[@name="{name}"]') + if existing is not None: + existing.text = translated_text + return + el = etree.SubElement(root, "string") + el.set("name", name) + el.text = translated_text + + +# ── Translation via Anthropic ───────────────────────────────────────────────── + +def translate_batch( + client: anthropic.Anthropic, + language: str, + batch: dict[str, str], +) -> dict[str, str]: + """ + Send a batch of {name: english_text} to Claude and get back + {name: translated_text}. + Returns an empty dict on failure (strings will be skipped this run). + """ + items_json = json.dumps(batch, ensure_ascii=False, indent=2) + + prompt = textwrap.dedent(f""" + You are a professional mobile-app localisation expert. + + Translate the following Android string resource values from English into + **{language}**. + + Rules: + - Preserve ALL placeholder tokens exactly as-is: %1$s %2$s %d %f etc. + - Preserve HTML tags exactly:
etc. + - Preserve ampersand escapes: & < > \' etc. + - Do NOT translate the JSON keys (string resource names). + - Do NOT add explanations or markdown — return ONLY valid JSON. + - The app is a Litecoin cryptocurrency wallet called "Brainwallet". + Keep "Brainwallet", "Litecoin", "LTC", "PIN", "QR" untranslated. + - Use natural, friendly language suitable for a mobile finance app. + + Input JSON (keys are resource names, values are English strings): + {items_json} + + Return a JSON object with the same keys and translated values. + """).strip() + + try: + message = client.messages.create( + model="claude-opus-4-5", + max_tokens=4096, + messages=[{"role": "user", "content": prompt}], + ) + raw = message.content[0].text.strip() + # Strip possible ```json fences + raw = re.sub(r"^```(?:json)?\s*", "", raw) + raw = re.sub(r"\s*```$", "", raw) + return json.loads(raw) + except Exception as exc: + print(f" ⚠️ API/parse error for {language}: {exc}", file=sys.stderr) + return {} + + +# ── Main ────────────────────────────────────────────────────────────────────── + +def main(): + api_key = os.environ.get("ANTHROPIC_GH_API_KEY") + if not api_key: + sys.exit("ERROR: ANTHROPIC_GH_API_KEY environment variable not set.") + + client = anthropic.Anthropic(api_key=api_key) + + source_path = Path(SOURCE_DIR) / "strings.xml" + if not source_path.exists(): + sys.exit(f"ERROR: Source file not found: {source_path}") + + source_strings = parse_strings(source_path) + print(f"✅ Source: {len(source_strings)} translatable strings loaded.") + + pr_lines = [ + "## 🌍 Auto-translation summary\n", + "| Language | New translations | File |", + "|---|---|---|", + ] + + for locale_dir, language in LOCALE_MAP.items(): + target_path = Path(RES_BASE_DIR) / locale_dir / "strings.xml" + existing = parse_strings(target_path) + missing = { + k: v for k, v in source_strings.items() + if k not in existing or not existing[k].strip() + } + + if not missing: + print(f" ✔ {language}: nothing to translate.") + pr_lines.append(f"| {language} | 0 (already complete) | `{target_path}` |") + continue + + print(f" 🔄 {language}: {len(missing)} strings to translate …") + tree = load_or_create_tree(target_path) + + translated_count = 0 + keys = list(missing.keys()) + for i in range(0, len(keys), BATCH_SIZE): + chunk_keys = keys[i : i + BATCH_SIZE] + batch = {k: missing[k] for k in chunk_keys} + result = translate_batch(client, language, batch) + + for name, text in result.items(): + if name in batch: # sanity-check key came from our batch + set_translated(tree, name, text) + translated_count += 1 + + write_tree(tree, target_path) + print(f" ✅ {language}: {translated_count} strings written → {target_path}") + pr_lines.append(f"| {language} | {translated_count} | `{target_path}` |") + + # Write PR body + pr_body = "\n".join(pr_lines) + "\n\n---\n*Generated automatically by translate_strings.py*\n" + Path(PR_BODY_PATH).write_text(pr_body, encoding="utf-8") + print(f"\n📄 PR body written to {PR_BODY_PATH}") + print("🎉 Translation run complete.") + + +if __name__ == "__main__": + main() diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9bbab904..6ca27551 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -5,7 +5,6 @@ plugins { alias(grunt.plugins.android.application) alias(grunt.plugins.jetbrains.kotlin.android) alias(grunt.plugins.jetbrains.kotlin.compose) - alias(libs.plugins.jetbrains.kotlin.kapt) alias(grunt.plugins.jetbrains.kotlin.serialization) alias(libs.plugins.google.services) alias(libs.plugins.firebase.crashlytics) @@ -18,18 +17,27 @@ val localProperties = gradleLocalProperties(rootDir, providers) android { namespace = "com.brainwallet" - compileSdk = 36 + compileSdk = 35 + + firebaseCrashlytics { + nativeSymbolUploadEnabled = true + } + + /// For screengrab testing + val screengrabPaperKey = localProperties + .getProperty("SCREENGRAB_PAPERKEY", "") + .split(" ") + .filter { it.isNotBlank() } + .joinToString(separator = ", ") { "\"$it\"" } defaultConfig { applicationId = "ltd.grunt.brainwallet" minSdk = 29 - targetSdk = 36 - versionCode = 202506301 - versionName = "v4.8.0" - + targetSdk = 35 + versionCode = 202506314 + versionName = "v4.8.4" multiDexEnabled = true base.archivesName.set("${defaultConfig.versionName}(${defaultConfig.versionCode})") - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" ndk { @@ -42,6 +50,12 @@ android { arguments("-DANDROID_TOOLCHAIN=clang") } } + + buildConfigField( + "String[]", + "SCREENGRAB_PAPERKEY", + "new String[] {$screengrabPaperKey}" + ) } assetPacks.addAll(setOf(":install_time_asset_pack")) @@ -53,52 +67,37 @@ android { keyAlias = localProperties.getProperty("DEBUG_KEY_ALIAS") keyPassword = localProperties.getProperty("DEBUG_KEY_PASSWORD") } -// val release by creating { -// storeFile = file(localProperties.getProperty("RELEASE_STORE_FILE")) -// storePassword = localProperties.getProperty("RELEASE_STORE_PASSWORD") -// keyAlias = localProperties.getProperty("RELEASE_KEY_ALIAS") -// keyPassword = localProperties.getProperty("RELEASE_KEY_PASSWORD") -// } + val release by creating { + storeFile = file(localProperties.getProperty("RELEASE_STORE_FILE")) + storePassword = localProperties.getProperty("RELEASE_STORE_PASSWORD") + keyAlias = localProperties.getProperty("RELEASE_KEY_ALIAS") + keyPassword = localProperties.getProperty("RELEASE_KEY_PASSWORD") + } } buildTypes { val debug by getting { isDebuggable = true isMinifyEnabled = false - + enableUnitTestCoverage = true + enableAndroidTestCoverage = true ndk { isDebuggable = true isMinifyEnabled = false } - - firebaseCrashlytics { - nativeSymbolUploadEnabled = true - } - buildConfigField("String[]", "SCREENGRAB_PAPERKEY", - "new String[] {${ - localProperties.getProperty("SCREENGRAB_PAPERKEY", "") - .split(" ") - .joinToString { "\"$it\"" } - }}" - ) } -// val release by getting { -// signingConfig = signingConfigs.getByName("release") -// isDebuggable = false -// isMinifyEnabled = true -// proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") -// -// ndk { -// isDebuggable = false -// isMinifyEnabled = true -// } -// -// firebaseCrashlytics { -// nativeSymbolUploadEnabled = true -// } -// } + val release by getting { + signingConfig = signingConfigs.getByName("release") + isDebuggable = false + isMinifyEnabled = true + proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro") + ndk { + isDebuggable = false + isMinifyEnabled = true + } + } } externalNativeBuild { @@ -224,8 +223,13 @@ dependencies { implementation(grunt.bundles.koin) implementation(platform(grunt.koin.annotation.bom)) implementation(grunt.koin.annotation) + implementation("androidx.compose.material:material-icons-extended:1.7.8") + implementation(libs.androidx.junit.ktx) + implementation(libs.androidx.espresso.core) + implementation(libs.androidx.runtime) + implementation(libs.androidx.foundation) + implementation(libs.androidx.animation) ksp(grunt.koin.annotation.compiler) - implementation(platform(libs.squareup.okhttp.bom)) implementation(libs.bundles.squareup.okhttp) implementation(libs.bundles.squareup.retrofit) @@ -239,14 +243,18 @@ dependencies { implementation(libs.razir.progressbutton) implementation(libs.appsflyer) implementation(libs.android.installreferrer) - + implementation("androidx.compose.animation:animation:1.5.0") + implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7") testImplementation(libs.junit) testImplementation(libs.mockk) testImplementation(libs.turbine) testImplementation(libs.slf4j.android) testImplementation(libs.kotlinx.coroutines.tests) - + testImplementation("io.mockk:mockk:1.13.5") + testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.7.3") + testImplementation("app.cash.turbine:turbine:1.0.0") androidTestImplementation(platform(grunt.androidx.compose.bom)) + androidTestImplementation("androidx.test:core-ktx:1.5.0") androidTestImplementation(grunt.bundles.androidx.compose.ui.test) androidTestImplementation(libs.bundles.android.test) androidTestImplementation(libs.fastlane.screengrab) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7f7fd339..e929fb90 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -58,10 +58,21 @@ android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> - - - + + + + + + + + - () { - // @Override - // public void onSuccess(String s) { - // Timber.d("timber: fcm getToken= %s", s); - // } - // }) - // .addOnFailureListener(new OnFailureListener() { - // @Override - // public void onFailure(@NonNull Exception e) { - // Timber.d(e, "timber: fcm getToken failure"); - // } - // }); - if (BuildConfig.DEBUG) Timber.plant(DebugTree()) + // DEV: uncomment for debugging FirebaseMessaging +// FirebaseMessaging.getInstance() +// .getToken() +// .addOnSuccessListener(new OnSuccessListener() { +// @Override +// public void onSuccess(String s) { +// Timber.d("timber: fcm getToken= %s", s); +// } +// }) +// .addOnFailureListener(new OnFailureListener() { +// @Override +// public void onFailure(@NonNull Exception e) { +// Timber.d(e, "timber: fcm getToken failure"); +// } +// }); DISPLAY_HEIGHT_PX = Resources.getSystem().displayMetrics.heightPixels - val afID = Utils.fetchServiceItem(this, ServiceItems.AFDEVID) - val appsFlyerLib = AppsFlyerLib.getInstance() - appsFlyerLib.init(afID, null, this) - appsFlyerLib.setDebugLog(BuildConfig.DEBUG) - appsFlyerLib.setCollectAndroidID(true) - appsFlyerLib.start(this) + if (!BuildConfig.DEBUG) { + val afID = Utils.fetchServiceItem(this, ServiceItems.AFDEVID) + val appsFlyerLib = AppsFlyerLib.getInstance() + appsFlyerLib.init(afID, null, this) + appsFlyerLib.setCollectAndroidID(true) + appsFlyerLib.start(this) + } } -// override fun attachBaseContext(base: Context) { -// init(base) -// super.attachBaseContext(instance.setLocale(base)) -// } - interface OnAppBackgrounded { fun onBackgrounded() } diff --git a/app/src/main/java/com/brainwallet/constants/BWConstants.kt b/app/src/main/java/com/brainwallet/constants/BWConstants.kt new file mode 100644 index 00000000..c6e68745 --- /dev/null +++ b/app/src/main/java/com/brainwallet/constants/BWConstants.kt @@ -0,0 +1,155 @@ +package com.brainwallet.constants + +import com.brainwallet.BuildConfig +import java.math.RoundingMode +import java.util.Locale + +object BWConstants { + + const val MIN_MASTERPUBKEY_LENGTH = 33 + + /** + * App Version and Version Code + */ + @JvmField + val APP_VERSION_NAME_CODE: String = String.format( + Locale.US, + "%1\$s (%2\$s)", + BuildConfig.VERSION_NAME, + BuildConfig.VERSION_CODE + ) + + /** + * Native library name + */ + const val NATIVE_LIB_NAME: String = "core-lib" + + const val _BW_MAIN_OPEN: String = "bw_main_open" + + /** + * Permissions + */ + const val CAMERA_REQUEST_ID: Int = 34 + + /** + * Animation values + */ + const val FADE_IN_DURATION: Int = 400 + const val FADE_OUT_DURATION: Int = 400 + const val SHRINK_DURATION: Int = 700 + const val EXPAND_DURATION: Int = 700 + + /** + * Request codes for auth + */ + const val SHOW_PHRASE_REQUEST_CODE: Int = 111 + const val PAY_REQUEST_CODE: Int = 112 + const val CANARY_REQUEST_CODE: Int = 113 + const val PUT_PHRASE_NEW_WALLET_REQUEST_CODE: Int = 114 + const val PUT_PHRASE_RECOVERY_WALLET_REQUEST_CODE: Int = 115 + const val PROVE_PHRASE_REQUEST: Int = 119 + + /** + * Request codes for taking pictures + */ + const val SCANNER_REQUEST: Int = 201 + const val CANARY_STRING: String = "canary" + const val FIRST_ADDRESS: String = "firstAddress" + const val SECURE_TIME_PREFS: String = "secureTime" + + const val ONE_BITCOIN: Int = 100000000 + + /** + * BRSharedPrefs + */ + const val PREFS_NAME: String = "MyPrefsFile" + const val RECEIVE_ADDRESS: String = "receive_address" + const val START_HEIGHT: String = "startHeight" + const val LAST_BLOCK_HEIGHT: String = "lastBlockHeight" + const val LTC_STATS_BLOCK_HEIGHT: String = "ltcStatsBlockHeight" + const val LTC_STATS_MEMPOOL_TRANSACTIONS: String = "ltcStatsMempoolTransactions" + const val LTC_STATS_MEMPOOL_SIZE: String = "ltcStatsMempoolSize" + const val LTC_STATS_TRANSACTIONS_OVER_24H: String = "ltcStatsTransactionsOver24H" + const val CURRENT_UNIT: String = "currencyUnit" + const val POSITION: String = "position" + const val PHRASE_WRITTEN: String = "phraseWritten" + const val ALLOW_SPEND: String = "allowSpend" + const val USER_ID: String = "userId" + const val GEO_PERMISSIONS_REQUESTED: String = "geoPermissionsRequested" + + /** + * Currency units + */ + const val CURRENT_UNIT_PHOTONS: Int = 0 // formerly CURRENT_UNIT_BITS + const val CURRENT_UNIT_LITES: Int = 1 // formerly CURRENT_UNIT_MBITS + const val CURRENT_UNIT_LITECOINS: Int = 2 + const val litecoinLowercase: String = "\u0142" + const val litecoinUppercase: String = "\u0141" + + @JvmField + val ROUNDING_MODE: RoundingMode = RoundingMode.HALF_EVEN + const val WAL: Boolean = true + + const val loopBug: String = "android-loop-bug" + + /** + * brainwallet pin/passcode length + */ + const val BW_PIN_LENGTH: Int = 4 + + /** + * App External URLs + */ + const val TWITTER_LINK: String = "https://twitter.com/Brainwallet_App" + const val INSTAGRAM_LINK: String = "https://www.instagram.com/brainwalletapp" + const val WEB_LINK: String = "https://brainwallet.co" + const val SUPPORT_WEB_LINK: String = "https://www.brainwallet.co/support" + const val TOS_LINK: String = "https://www.brainwallet.co/privacypolicy" + const val LINKTREE_URL: String = "https://linktr.ee/brainwallet" + + /** + * API Hosts + */ + const val BW_API_PROD_HOST: String = "https://api.grunt.ltd" + + const val BLOCKCHAIR_EXPLORER_BASE_URL: String = "https://blockchair.com/litecoin/transaction/" + const val BLOCKCYPHER_EXPLORER_BASE_URL: String = "https://live.blockcypher.com/ltc/" + + const val _20191105_AL: String = "app_launched" + const val _20191105_VSC: String = "visit_send_controller" + const val _20202116_VRC: String = "visit_receive_controller" + const val _20191105_DSL: String = "did_send_ltc" + const val _20191105_DTBT: String = "did_tap_buy_tab" + const val _20200111_FNI: String = "feeperkb_not_initialized" + const val _20200111_TNI: String = "transaction_not_initialized" + const val _20200111_WNI: String = "wallet_not_initialized" + const val _20200112_ERR: String = "brainwallet_android_error" + const val _20200112_DSR: String = "did_start_resync" + const val _20201118_DTGS: String = "did_tap_get_support" + const val _20200217_DUWB: String = "did_unlock_with_biometrics" + + const val _20250303_DSTU: String = "did_skip_top_up" + const val _20250517_WCINFO: String = "wallet_callback_info" + const val _20241006_DRR: String = "did_request_rating" + const val _20241006_UCR: String = "user_completed_rating" + const val _HOME_OPEN: String = "home_open" + + /** + * Analytics keys + */ + const val START_TIME: String = "start_time" + const val SUCCESS_TIME: String = "success_time" + const val FAILURE_TIME: String = "failure_time" + const val ERROR: String = "error" + + /** + * False Positive rate keys + */ + const val FALSE_POS_RATE_LOW_PRIVACY: Float = 0.00005f + const val FALSE_POS_RATE_SEMI_PRIVACY: Float = 0.00008f + const val FALSE_POS_RATE_ANONYMOUS: Float = 0.0005f + + @Retention(AnnotationRetention.SOURCE) + annotation class Event + const val ON_QR_CODE_RESULT: String = "on_qr_code_result" +} diff --git a/app/src/main/java/com/brainwallet/constants/Constants.kt b/app/src/main/java/com/brainwallet/constants/Constants.kt new file mode 100644 index 00000000..9f44dab5 --- /dev/null +++ b/app/src/main/java/com/brainwallet/constants/Constants.kt @@ -0,0 +1,23 @@ +package com.brainwallet.constants + +import androidx.compose.ui.unit.dp +val balanceGameBentoHt = 125.dp +val gameHubHt = 120.dp +val transactionRowHt = 70.dp + +val transactionRowDetailHt = 140.dp + +val transactionQRSize = 120.dp + +const val transactionHtPercent = 0.9f +val statusBarPadding = 44.dp +val bentoBottomNavBarHt = 60.dp + +val iconBorderSize = 40.dp +val iconSize = 26.dp + +val topNavButtonSize = 48.dp + +val topNavStartEndPadding = 12.dp + +val favouriteSize = 30.dp diff --git a/app/src/main/java/com/brainwallet/data/model/GlobalCurrency.kt b/app/src/main/java/com/brainwallet/data/model/GlobalCurrency.kt new file mode 100644 index 00000000..95cc4eba --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/model/GlobalCurrency.kt @@ -0,0 +1,141 @@ +package com.brainwallet.data.model + +import java.util.Currency +import java.util.Locale + +object CurrencyUtils { + /** + * Finds the currency symbol for a given ISO 4217 currency code. + * This mimics the Swift implementation by searching through available locales. + */ + fun getSymbolForCurrencyCode(code: String): String? { + return try { + val currency = Currency.getInstance(code) + // In Android/Java, Currency.getSymbol() returns the symbol for the default locale. + // If you specifically want to find a locale that matches the currency like the Swift code: + Locale.getAvailableLocales().firstOrNull { locale -> + try { + Currency.getInstance(locale).currencyCode == code + } catch (e: Exception) { + false + } + }?.let { currency.getSymbol(it) } ?: currency.symbol + } catch (e: Exception) { + null + } + } +} + +enum class GlobalCurrency( + val id: Int, + val code: String, + val fullCurrencyName: String, + val symbol: String, + val countryFlag: String +) { + USD(0, "USD", "US Dollar", "$", "🇺🇸"), + EUR(1, "EUR", "Euro", "€", "🇪🇺"), + AED(2, "AED", "UAE Dirham", "د.إ", "🇦🇪"), + AFN(3, "AFN", "Afghan Afghani", "؋", "🇦🇫"), + ALL(4, "ALL", "Albanian Lek", "L", "🇦🇱"), + AMD(5, "AMD", "Armenian Dram", "֏", "🇦🇲"), + ARS(6, "ARS", "Argentine Peso", "$", "🇦🇷"), + AUD(7, "AUD", "Australian Dollar", "A$", "🇦🇺"), + AZN(8, "AZN", "Azerbaijani Manat", "₼", "🇦🇿"), + BAM(9, "BAM", "Bosnia and Herzegovina Convertible Mark", "КМ", "🇧🇦"), + BBD(10, "BBD", "Barbadian Dollar", "Bds$", "🇧🇧"), + BDT(11, "BDT", "Bangladeshi Taka", "৳", "🇧🇩"), + BGN(12, "BGN", "Bulgarian Lev", "лв", "🇧🇬"), + BHD(13, "BHD", "Bahraini Dinar", ".د.ب", "🇧🇭"), + BND(14, "BND", "Brunei Dollar", "B$", "🇧🇳"), + BOB(15, "BOB", "Bolivian Boliviano", "Bs.", "🇧🇴"), + BRL(16, "BRL", "Brazilian Real", "R$", "🇧🇷"), + BTN(17, "BTN", "Bhutanese Ngultrum", "Nu.", "🇧🇹"), + BYN(18, "BYN", "Belarusian Ruble", "Br", "🇧🇾"), + CAD(19, "CAD", "Canadian Dollar", "C$", "🇨🇦"), + CHF(20, "CHF", "Swiss Franc", "CHF", "🇨🇭"), + CLP(21, "CLP", "Chilean Peso", "$", "🇨🇱"), + CNY(22, "CNY", "Chinese Yuan", "¥", "🇨🇳"), + COP(23, "COP", "Colombian Peso", "$", "🇨🇴"), + CRC(24, "CRC", "Costa Rican Colón", "₡", "🇨🇷"), + CZK(25, "CZK", "Czech Koruna", "Kč", "🇨🇿"), + DKK(26, "DKK", "Danish Krone", "kr", "🇩🇰"), + DOP(27, "DOP", "Dominican Peso", "RD$", "🇩🇴"), + DZD(28, "DZD", "Algerian Dinar", "د.ج", "🇩🇿"), + EGP(29, "EGP", "Egyptian Pound", "£", "🇪🇬"), + FJD(30, "FJD", "Fijian Dollar", "FJ$", "🇫🇯"), + GBP(31, "GBP", "British Pound Sterling", "£", "🇬🇧"), + GEL(32, "GEL", "Georgian Lari", "₾", "🇬🇪"), + GHS(33, "GHS", "Ghanaian Cedi", "₵", "🇬🇭"), + GTQ(34, "GTQ", "Guatemalan Quetzal", "Q", "🇬🇹"), + HKD(35, "HKD", "Hong Kong Dollar", "HK$", "🇭🇰"), + HNL(36, "HNL", "Honduran Lempira", "L", "🇭🇳"), + HRK(37, "HRK", "Croatian Kuna", "kn", "🇭🇷"), + HUF(38, "HUF", "Hungarian Forint", "Ft", "🇭🇺"), + IDR(39, "IDR", "Indonesian Rupiah", "Rp", "🇮🇩"), + ILS(40, "ILS", "Israeli Shekel", "₪", "🇮🇱"), + INR(41, "INR", "Indian Rupee", "₹", "🇮🇳"), + ISK(42, "ISK", "Icelandic Krona", "kr", "🇮🇸"), + JMD(43, "JMD", "Jamaican Dollar", "J$", "🇯🇲"), + JOD(44, "JOD", "Jordanian Dinar", "د.ا", "🇯🇴"), + JPY(45, "JPY", "Japanese Yen", "¥", "🇯🇵"), + KES(46, "KES", "Kenyan Shilling", "Sh", "🇰🇪"), + KGS(47, "KGS", "Kyrgyzstani Som", "лв", "🇰🇬"), + KHR(48, "KHR", "Cambodian Riel", "៛", "🇰🇭"), + KRW(49, "KRW", "South Korean Won", "₩", "🇰🇷"), + KWD(50, "KWD", "Kuwaiti Dinar", "د.ك", "🇰🇼"), + KZT(51, "KZT", "Kazakhstani Tenge", "₸", "🇰🇿"), + LAK(52, "LAK", "Lao Kip", "₭", "🇱🇦"), + LKR(53, "LKR", "Sri Lankan Rupee", "Rs", "🇱🇰"), + MAD(54, "MAD", "Moroccan Dirham", "د.م.", "🇲🇦"), + MDL(55, "MDL", "Moldovan Leu", "L", "🇲🇩"), + MKD(56, "MKD", "Macedonian Denar", "ден", "🇲🇰"), + MMK(57, "MMK", "Myanmar Kyat", "Ks", "🇲🇲"), + MNT(58, "MNT", "Mongolian Tugrik", "₮", "🇲🇳"), + MXN(59, "MXN", "Mexican Peso", "$", "🇲🇽"), + MYR(60, "MYR", "Malaysian Ringgit", "RM", "🇲🇾"), + NGN(61, "NGN", "Nigerian Naira", "₦", "🇳🇬"), + NIO(62, "NIO", "Nicaraguan Córdoba", "C$", "🇳🇮"), + NOK(63, "NOK", "Norwegian Krone", "kr", "🇳🇴"), + NPR(64, "NPR", "Nepalese Rupee", "Rs", "🇳🇵"), + NZD(65, "NZD", "New Zealand Dollar", "NZ$", "🇳🇿"), + OMR(66, "OMR", "Omani Rial", "﷼", "🇴🇲"), + PAB(67, "PAB", "Panamanian Balboa", "B/.", "🇵🇦"), + PEN(68, "PEN", "Peruvian Sol", "S/", "🇵🇪"), + PGK(69, "PGK", "Papua New Guinea Kina", "K", "🇵🇬"), + PHP(70, "PHP", "Philippine Peso", "₱", "🇵🇭"), + PKR(71, "PKR", "Pakistani Rupee", "₨", "🇵🇰"), + PLN(72, "PLN", "Polish Zloty", "zł", "🇵🇱"), + PYG(73, "PYG", "Paraguayan Guarani", "₲", "🇵🇾"), + QAR(74, "QAR", "Qatari Riyal", "﷼", "🇶🇦"), + RON(75, "RON", "Romanian Leu", "lei", "🇷🇴"), + RSD(76, "RSD", "Serbian Dinar", "дин", "🇷🇸"), + RUB(77, "RUB", "Russian Ruble", "₽", "🇷🇺"), + SAR(78, "SAR", "Saudi Riyal", "﷼", "🇸🇦"), + SBD(79, "SBD", "Solomon Islands Dollar", "SI$", "🇸🇧"), + SEK(80, "SEK", "Swedish Krona", "kr", "🇸🇪"), + SGD(81, "SGD", "Singapore Dollar", "S$", "🇸🇬"), + THB(82, "THB", "Thai Baht", "฿", "🇹🇭"), + TJS(83, "TJS", "Tajikistani Somoni", "ЅМ", "🇹🇯"), + TMT(84, "TMT", "Turkmenistani Manat", "m", "🇹🇲"), + TND(85, "TND", "Tunisian Dinar", "د.ت", "🇹🇳"), + TOP(86, "TOP", "Tongan Pa'anga", "T$", "🇹🇴"), + TRY(87, "TRY", "Turkish Lira", "₺", "🇹🇷"), + TTD(88, "TTD", "Trinidad and Tobago Dollar", "TT$", "🇹🇹"), + TWD(89, "TWD", "Taiwan Dollar", "NT$", "🇹🇼"), + UAH(90, "UAH", "Ukrainian Hryvnia", "₴", "🇺🇦"), + UYU(91, "UYU", "Uruguayan Peso", "$", "🇺🇾"), + UZS(92, "UZS", "Uzbekistani Som", "лв", "🇺🇿"), + VES(93, "VES", "Venezuelan Bolívar", "Bs.S", "🇻🇪"), + VND(94, "VND", "Vietnamese Dong", "₫", "🇻🇳"), + VUV(95, "VUV", "Vanuatu Vatu", "Vt", "🇻🇺"), + WST(96, "WST", "Samoan Tala", "WS$", "🇼🇸"), + XCD(97, "XCD", "East Caribbean Dollar", "$", "🇦🇬"), + ZAR(98, "ZAR", "South African Rand", "R", "🇿🇦"); + + companion object { + fun from(code: String): GlobalCurrency? { + return entries.find { it.code == code } + } + } +} diff --git a/app/src/main/java/com/brainwallet/data/model/LtcStats.kt b/app/src/main/java/com/brainwallet/data/model/LtcStats.kt new file mode 100644 index 00000000..3cf3db39 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/model/LtcStats.kt @@ -0,0 +1,23 @@ +package com.brainwallet.data.model + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class LtcStats( + @JvmField + @SerialName("blocks") + var currentBlockHeight: Int, + @JvmField + @SerialName("mempool_transactions") + var mempoolTransactions: Int, + @JvmField + @SerialName("mempool_size") + var mempoolSize: Int, + @JvmField + @SerialName("transactions_24h") + var transactionsOver24H: Int +) { + companion object { + } +} diff --git a/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt b/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt index 06387ec9..d4b792e2 100644 --- a/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt +++ b/app/src/main/java/com/brainwallet/data/model/MoonpayCurrencyLimit.kt @@ -18,7 +18,7 @@ data class MoonpayCurrencyLimit( @Serializable data class CurrencyLimit( val code: String = "usd", - @SerialName("minBuyAmount") val min: Float = 21f, + @SerialName("minBuyAmount") var min: Float = 21f, @SerialName("maxBuyAmount") val max: Float = 29849f ) } diff --git a/app/src/main/java/com/brainwallet/data/repository/ConnectivityRepository.kt b/app/src/main/java/com/brainwallet/data/repository/ConnectivityRepository.kt new file mode 100644 index 00000000..1fc72436 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/ConnectivityRepository.kt @@ -0,0 +1,46 @@ +package com.brainwallet.data.repository + +import android.app.Application +import android.content.Context +import android.net.ConnectivityManager +import android.net.Network +import android.net.NetworkCapabilities +import android.net.NetworkRequest +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.SharingStarted +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.stateIn +import org.koin.core.annotation.Single + +@Single +class ConnectivityRepository(private val app: Application) { + + val isConnected: StateFlow = callbackFlow { + val manager = app.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + val callback = object : ConnectivityManager.NetworkCallback() { + override fun onAvailable(network: Network) { trySend(true) } + override fun onLost(network: Network) { trySend(false) } + } + + val request = NetworkRequest.Builder() + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .build() + + manager.registerNetworkCallback(request, callback) + trySend(manager.activeNetwork != null) + + awaitClose { manager.unregisterNetworkCallback(callback) } + } + .distinctUntilChanged() + .stateIn( + CoroutineScope(Dispatchers.IO + SupervisorJob()), + SharingStarted.Eagerly, + false + ) +} diff --git a/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt b/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt index e932ae6d..7ab636a0 100644 --- a/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigRepository.kt @@ -8,8 +8,11 @@ import com.google.firebase.remoteconfig.ConfigUpdateListener import com.google.firebase.remoteconfig.FirebaseRemoteConfig import com.google.firebase.remoteconfig.FirebaseRemoteConfigException import com.google.firebase.remoteconfig.remoteConfigSettings +import kotlinx.coroutines.suspendCancellableCoroutine import org.koin.core.annotation.Single import timber.log.Timber +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException @Single(binds = [RemoteConfigSource::class]) class FirebaseRemoteConfigRepository( @@ -48,6 +51,13 @@ class FirebaseRemoteConfigRepository( }) } + override suspend fun fetchAndActivate(): Boolean = + suspendCancellableCoroutine { continuation -> + remoteConfig.fetchAndActivate() + .addOnSuccessListener { activated -> continuation.resume(activated) } + .addOnFailureListener { e -> continuation.resumeWithException(e) } + } + override fun getString(key: String): String { return remoteConfig.getString(key) } diff --git a/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigSourceImpl.kt b/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigSourceImpl.kt new file mode 100644 index 00000000..2b17919e --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/FirebaseRemoteConfigSourceImpl.kt @@ -0,0 +1,30 @@ +package com.brainwallet.data.repository + +import com.brainwallet.data.source.RemoteConfigSource +import com.google.firebase.remoteconfig.FirebaseRemoteConfig +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException + +class FirebaseRemoteConfigRepositoryImpl( + private val firebaseRemoteConfig: FirebaseRemoteConfig, +) : RemoteConfigSource { + + override suspend fun fetchAndActivate(): Boolean = + suspendCancellableCoroutine { continuation -> + firebaseRemoteConfig.fetchAndActivate() + .addOnSuccessListener { activated -> continuation.resume(activated) } + .addOnFailureListener { e -> continuation.resumeWithException(e) } + } + + override fun initialize() {} + + override fun getString(key: String): String = + firebaseRemoteConfig.getString(key) + + override fun getNumber(key: String): Double = + firebaseRemoteConfig.getDouble(key) + + override fun getBoolean(key: String): Boolean = + firebaseRemoteConfig.getBoolean(key) +} diff --git a/app/src/main/java/com/brainwallet/data/repository/HubContentRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/HubContentRepositoryImpl.kt new file mode 100644 index 00000000..cfd4e94a --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/HubContentRepositoryImpl.kt @@ -0,0 +1,45 @@ +package com.brainwallet.data.repository +import com.brainwallet.data.source.RemoteConfigSource +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.serialization.SerialName +import kotlinx.serialization.json.Json +import timber.log.Timber + +data class HubContent( + @SerialName("content_name") val contentName: String, + @SerialName("asset_url") val assetUrl: String, + @SerialName("title") val title: String, + @SerialName("subtitle") val subtitle: String, + @SerialName("id") val id: Long, +) + +interface HubContentRepository { + val hubContent: StateFlow> + suspend fun refresh() +} + +class HubContentRepositoryImpl( + private val remoteConfigSource: RemoteConfigSource, + private val json: Json, +) : HubContentRepository { + + private val _hubContent = MutableStateFlow>(emptyList()) + override val hubContent: StateFlow> = _hubContent.asStateFlow() + + override suspend fun refresh() { + runCatching { remoteConfigSource.fetchAndActivate() } + .onFailure { Timber.e(it, "RemoteConfig fetch failed") } + + val rawJson = remoteConfigSource.getString(RemoteConfigSource.KEY_FEATURE_GAMEHUB_CONTENT) + runCatching { + val wrapper = json.decodeFromString(rawJson) + _hubContent.value = wrapper.hubContent + }.onFailure { Timber.e(it, "RemoteConfig parse failed") } + } + + private data class HubContentWrapper( + @SerialName("hubcontent") val hubContent: List = emptyList() + ) +} diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt index d4912a53..5d17e732 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepository.kt @@ -2,14 +2,22 @@ package com.brainwallet.data.repository import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Fee +import com.brainwallet.data.model.LtcStats import com.brainwallet.data.model.MoonpayCurrencyLimit import com.brainwallet.data.source.response.GetMoonpayBuyQuoteResponse +import kotlinx.coroutines.flow.StateFlow interface LtcRepository { + + val rates: StateFlow> + val ltcStats: StateFlow + suspend fun fetchRates(): List suspend fun fetchFeePerKb(): Fee + suspend fun fetchLtcStats(): LtcStats + suspend fun fetchLimits(baseCurrencyCode: String): MoonpayCurrencyLimit suspend fun fetchBuyQuote(params: Map): GetMoonpayBuyQuoteResponse diff --git a/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt index e5f975d1..0f315d0f 100644 --- a/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt +++ b/app/src/main/java/com/brainwallet/data/repository/LtcRepositoryImpl.kt @@ -6,6 +6,7 @@ import androidx.core.net.toUri import com.brainwallet.BuildConfig import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Fee +import com.brainwallet.data.model.LtcStats import com.brainwallet.data.model.MoonpayCurrencyLimit import com.brainwallet.data.repository.LtcRepository.Companion.PREF_KEY_BUY_LIMITS_PREFIX import com.brainwallet.data.repository.LtcRepository.Companion.PREF_KEY_BUY_LIMITS_PREFIX_CACHED_AT @@ -16,6 +17,9 @@ import com.brainwallet.tools.manager.BRSharedPrefs import com.brainwallet.tools.manager.FeeManager import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.tools.util.Utils +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import org.koin.core.annotation.Single @Single(binds = [LtcRepository::class]) @@ -26,12 +30,22 @@ class LtcRepositoryImpl( private val sharedPreferences: SharedPreferences, ) : LtcRepository { - // todo: make it offline first here later, currently just using CurrencyDataSource.getAllCurrencies + private val _rates = MutableStateFlow>(emptyList()) + override val rates: StateFlow> = _rates.asStateFlow() + private val _ltcStats = MutableStateFlow( + LtcStats( + 0, + 0, + 0, + 0 + ) + ) + override val ltcStats: StateFlow = _ltcStats.asStateFlow() + override suspend fun fetchRates(): List { return runCatching { val rates = remoteApiSource.getRates() - // legacy logic FeeManager.updateFeePerKb(context) val selectedISO = BRSharedPrefs.getIsoSymbol(context) rates.forEachIndexed { index, currencyEntity -> @@ -41,19 +55,35 @@ class LtcRepositoryImpl( } } - // save to local + val liveLtcStats = remoteApiSource.getLtcStats() + _ltcStats.value = liveLtcStats currencyDataSource.putCurrencies(rates) - return rates - }.getOrElse { currencyDataSource.getAllCurrencies(true) } + rates + }.getOrElse { + currencyDataSource.getAllCurrencies(true) + }.also { result -> + _rates.value = result + } + } + + override suspend fun fetchFeePerKb(): Fee { + return runCatching { + val feesPerKb = remoteApiSource.getFeePerKb() + Fee( + feesPerKb.economy, + feesPerKb.regular, + feesPerKb.luxury, + System.currentTimeMillis() + ) + }.getOrElse { + Fee.Default + } } - /** - * for now we just using [Fee.Default] - * will move to [RemoteApiSource.getFeePerKb] after fix the calculation when we do send - * - * maybe need updaete core if we need to use dynamic fee? - */ - override suspend fun fetchFeePerKb(): Fee = Fee.Default // using static fee + override suspend fun fetchLtcStats(): LtcStats { + return remoteApiSource.getLtcStats() + .also { _ltcStats.value = it } + } override suspend fun fetchLimits(baseCurrencyCode: String): MoonpayCurrencyLimit { return sharedPreferences.fetchWithCache( diff --git a/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt b/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt index 577781d2..db997479 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SettingRepository.kt @@ -3,10 +3,12 @@ package com.brainwallet.data.repository import com.brainwallet.data.model.AppSetting import com.brainwallet.data.model.Language import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.StateFlow interface SettingRepository { val settings: Flow + val currentSettings: StateFlow suspend fun save(setting: AppSetting) @@ -37,5 +39,8 @@ interface SettingRepository { const val KEY_LANGUAGE_CODE = "language_code" const val KEY_FIAT_CURRENCY_CODE = "fiat_currency_code" const val KEY_SELECTED_FEE_TYPE = "selected_fee_type" + const val KEY_FIAT_CURRENCY_NAME = "selected_currency_name" + const val KEY_FIAT_CURRENCY_RATE = "selected_currency_rate" + const val KEY_FIAT_CURRENCY_SYMBOL = "selected_currency_symbol" } } diff --git a/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt index 71d8befb..3e93da94 100644 --- a/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt +++ b/app/src/main/java/com/brainwallet/data/repository/SettingRepositoryImpl.kt @@ -6,11 +6,13 @@ import com.brainwallet.data.model.AppSetting import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Language import com.brainwallet.data.repository.SettingRepository.Companion.KEY_FIAT_CURRENCY_CODE +import com.brainwallet.data.repository.SettingRepository.Companion.KEY_FIAT_CURRENCY_NAME +import com.brainwallet.data.repository.SettingRepository.Companion.KEY_FIAT_CURRENCY_RATE +import com.brainwallet.data.repository.SettingRepository.Companion.KEY_FIAT_CURRENCY_SYMBOL import com.brainwallet.data.repository.SettingRepository.Companion.KEY_IS_DARK_MODE import com.brainwallet.data.repository.SettingRepository.Companion.KEY_LANGUAGE_CODE import com.brainwallet.data.repository.SettingRepository.Companion.KEY_SELECTED_FEE_TYPE import com.brainwallet.tools.manager.FeeManager -import com.brainwallet.tools.sqlite.CurrencyDataSource import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -21,7 +23,6 @@ import org.koin.core.annotation.Single @Single(binds = [SettingRepository::class]) class SettingRepositoryImpl( private val sharedPreferences: SharedPreferences, - private val currencyDataSource: CurrencyDataSource ) : SettingRepository { private val _state = MutableStateFlow(load()) @@ -30,11 +31,30 @@ class SettingRepositoryImpl( override val settings: Flow get() = state + override val currentSettings: StateFlow = _state.asStateFlow() + + private fun load(): AppSetting { + return AppSetting( + isDarkMode = sharedPreferences.getBoolean(KEY_IS_DARK_MODE, true), + languageCode = sharedPreferences.getString(KEY_LANGUAGE_CODE, Language.ENGLISH.code) + ?: Language.ENGLISH.code, + currency = CurrencyEntity( + code = sharedPreferences.getString(KEY_FIAT_CURRENCY_CODE, "USD") ?: "USD", + name = sharedPreferences.getString(KEY_FIAT_CURRENCY_NAME, "US Dollar") ?: "US Dollar", + rate = sharedPreferences.getFloat(KEY_FIAT_CURRENCY_RATE, -1f), + symbol = sharedPreferences.getString(KEY_FIAT_CURRENCY_SYMBOL, "$") ?: "$" + ) + + ) + } override suspend fun save(setting: AppSetting) { sharedPreferences.edit { putBoolean(KEY_IS_DARK_MODE, setting.isDarkMode) putString(KEY_LANGUAGE_CODE, setting.languageCode) putString(KEY_FIAT_CURRENCY_CODE, setting.currency.code) + putString(KEY_FIAT_CURRENCY_NAME, setting.currency.name) + putFloat(KEY_FIAT_CURRENCY_RATE, setting.currency.rate) + putString(KEY_FIAT_CURRENCY_SYMBOL, setting.currency.symbol) } _state.update { setting } } @@ -69,22 +89,4 @@ class SettingRepositoryImpl( override fun getSelectedFeeType(): String = sharedPreferences.getString(KEY_SELECTED_FEE_TYPE, FeeManager.REGULAR) ?: FeeManager.REGULAR - - private fun load(): AppSetting { - return AppSetting( - isDarkMode = sharedPreferences.getBoolean(KEY_IS_DARK_MODE, true), - languageCode = sharedPreferences.getString(KEY_LANGUAGE_CODE, Language.ENGLISH.code) - ?: Language.ENGLISH.code, - currency = sharedPreferences.getString(KEY_FIAT_CURRENCY_CODE, "USD").let { - currencyDataSource.getCurrencyByIso(it) - ?: return@let CurrencyEntity( - "USD", - "US Dollar", - -1f, - "$" - ) - } - - ) - } } diff --git a/app/src/main/java/com/brainwallet/data/repository/TxRepository.kt b/app/src/main/java/com/brainwallet/data/repository/TxRepository.kt new file mode 100644 index 00000000..49258e30 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/TxRepository.kt @@ -0,0 +1,10 @@ +package com.brainwallet.data.repository + +import com.brainwallet.presenter.entities.TxItem +import kotlinx.collections.immutable.ImmutableList +import kotlinx.coroutines.flow.StateFlow + +interface TxRepository { + val transactionItems: StateFlow> + suspend fun refresh() +} diff --git a/app/src/main/java/com/brainwallet/data/repository/TxRepositoryImpl.kt b/app/src/main/java/com/brainwallet/data/repository/TxRepositoryImpl.kt new file mode 100644 index 00000000..06b2bf67 --- /dev/null +++ b/app/src/main/java/com/brainwallet/data/repository/TxRepositoryImpl.kt @@ -0,0 +1,42 @@ +package com.brainwallet.data.repository + +import android.app.Application +import com.brainwallet.presenter.entities.TxItem +import com.brainwallet.wallet.BRWalletManager +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.withContext +import org.koin.core.annotation.Single +import timber.log.Timber + +@Single(binds = [TxRepository::class]) +class TxRepositoryImpl( + private val app: Application +) : TxRepository { + + private val _transactionItems = MutableStateFlow>(persistentListOf()) + override val transactionItems: StateFlow> = _transactionItems.asStateFlow() + + override suspend fun refresh() = withContext(Dispatchers.IO) { + val items = BRWalletManager.getInstance().getTransactions() + ?.toImmutableList() ?: persistentListOf() + Timber.d("TxRepositoryImpl refresh: count=${items.size}") + _transactionItems.update { items } + } + + suspend fun allReceiveTransactions(): ImmutableList { + val receivedItems = _transactionItems.value.filter { it.received > 0 } + return receivedItems.toImmutableList() + } + + suspend fun allSentTransactions(): ImmutableList { + val sentItems = _transactionItems.value.filter { it.sent > 0 } + return sentItems.toImmutableList() + } +} diff --git a/app/src/main/java/com/brainwallet/data/source/PeerManagerSource.kt b/app/src/main/java/com/brainwallet/data/source/PeerManagerSource.kt index 10eaf13b..c2f4313b 100644 --- a/app/src/main/java/com/brainwallet/data/source/PeerManagerSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/PeerManagerSource.kt @@ -1,17 +1,65 @@ package com.brainwallet.data.source +import android.app.Application +import com.brainwallet.tools.manager.BRSharedPrefs import com.brainwallet.wallet.BRPeerManager +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch import org.koin.core.annotation.Single interface BRPeerManagerProxy { fun getCurrentBlockHeight(): Int fun getLastBlockTimestamp(): Long + fun getSyncProgress(): Double } -@Single -class PeerManagerSource( +interface PeerManagerSource : BRPeerManagerProxy { + val blockInfo: StateFlow +} + +data class BlockInfo( + val blockHeight: Int, + val timestamp: Long, + val syncProgress: Float +) + +@Single(binds = [PeerManagerSource::class]) +class PeerManagerSourceImpl( + private val app: Application, private val proxy: BRPeerManagerProxy = object : BRPeerManagerProxy { override fun getCurrentBlockHeight(): Int = BRPeerManager.getCurrentBlockHeight() override fun getLastBlockTimestamp(): Long = BRPeerManager.getInstance().lastBlockTimestamp + override fun getSyncProgress(): Double = BRPeerManager.syncProgress(BRSharedPrefs.getStartHeight(app)) } -) : BRPeerManagerProxy by proxy +) : PeerManagerSource, BRPeerManagerProxy by proxy { + + private val _blockInfo = MutableStateFlow( + BlockInfo( + blockHeight = proxy.getCurrentBlockHeight(), + timestamp = proxy.getLastBlockTimestamp(), + syncProgress = proxy.getSyncProgress().toFloat() + ) + ) + override val blockInfo: StateFlow = _blockInfo.asStateFlow() + + init { + CoroutineScope(Dispatchers.IO).launch { + while (true) { + delay(300L) + _blockInfo.update { + BlockInfo( + blockHeight = proxy.getCurrentBlockHeight(), + timestamp = proxy.getLastBlockTimestamp(), + syncProgress = proxy.getSyncProgress().toFloat() + ) + } + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt index ce5a3bb0..2b7b5fb2 100644 --- a/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/RemoteApiSource.kt @@ -2,6 +2,7 @@ package com.brainwallet.data.source import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Fee +import com.brainwallet.data.model.LtcStats import com.brainwallet.data.model.MoonpayCurrencyLimit import com.brainwallet.data.source.response.GetMoonpayBuyQuoteResponse import com.brainwallet.data.source.response.GetMoonpaySignUrlResponse @@ -15,6 +16,9 @@ interface RemoteApiSource { @GET("v1/rates") suspend fun getRates(): List + @GET("v1/ltc-stats") + suspend fun getLtcStats(): LtcStats + @GET("v1/fee-per-kb") suspend fun getFeePerKb(): Fee diff --git a/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt b/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt index 0de62915..11085d27 100644 --- a/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt +++ b/app/src/main/java/com/brainwallet/data/source/RemoteConfigSource.kt @@ -2,9 +2,12 @@ package com.brainwallet.data.source interface RemoteConfigSource { + suspend fun fetchAndActivate(): Boolean + companion object { const val KEY_FEATURE_MENU_HIDDEN_EXAMPLE = "feature_menu_hidden_example" const val KEY_FEATURE_SELECTED_PEERS_ENABLED = "feature_selected_peers_enabled" + const val KEY_FEATURE_GAMEHUB_CONTENT = "feature_gamehub_content" } fun initialize() diff --git a/app/src/main/java/com/brainwallet/di/AppModule.kt b/app/src/main/java/com/brainwallet/di/AppModule.kt index 07e6b8d4..b06bf48c 100644 --- a/app/src/main/java/com/brainwallet/di/AppModule.kt +++ b/app/src/main/java/com/brainwallet/di/AppModule.kt @@ -3,9 +3,12 @@ package com.brainwallet.di import android.content.Context import android.content.SharedPreferences import com.brainwallet.BuildConfig +import com.brainwallet.data.repository.TxRepository import com.brainwallet.data.source.RemoteApiSource import com.brainwallet.tools.sqlite.CurrencyDataSource -import com.brainwallet.tools.util.BRConstants +import com.brainwallet.constants.BWConstants +import com.brainwallet.data.repository.TxRepositoryImpl +import com.brainwallet.tools.manager.sync.SyncThreadManager import com.google.firebase.Firebase import com.google.firebase.remoteconfig.remoteConfig import kotlinx.serialization.json.Json @@ -36,10 +39,12 @@ object AppModule { single { Firebase.remoteConfig } single { json } factory { provideOkHttpClient() } - single { provideRetrofit(get(), get(), BRConstants.BW_API_PROD_HOST) } + single { provideRetrofit(get(), get(), BWConstants.BW_API_PROD_HOST) } single { provideApi(get()) } single { CurrencyDataSource.getInstance(get()) } single { provideSharedPreferences(context = androidApplication()) } + single { TxRepositoryImpl(get()) } + single { SyncThreadManager(get(), get()) } } private fun provideSharedPreferences( @@ -74,7 +79,7 @@ object AppModule { internal fun provideRetrofit( json: Json, okHttpClient: OkHttpClient, - baseUrl: String = BRConstants.BW_API_PROD_HOST, + baseUrl: String = BWConstants.BW_API_PROD_HOST, ): Retrofit = Retrofit.Builder() .baseUrl(baseUrl) .client(okHttpClient) diff --git a/app/src/main/java/com/brainwallet/di/RemoteConfigModule.kt b/app/src/main/java/com/brainwallet/di/RemoteConfigModule.kt new file mode 100644 index 00000000..be82670d --- /dev/null +++ b/app/src/main/java/com/brainwallet/di/RemoteConfigModule.kt @@ -0,0 +1,20 @@ +package com.brainwallet.di + +import com.brainwallet.data.repository.FirebaseRemoteConfigRepositoryImpl +import com.brainwallet.data.repository.HubContentRepository +import com.brainwallet.data.repository.HubContentRepositoryImpl +import com.brainwallet.data.source.RemoteConfigSource +import com.google.firebase.remoteconfig.FirebaseRemoteConfig +import org.koin.dsl.module + +val remoteConfigModule = module { + single { + FirebaseRemoteConfig.getInstance().apply { + setDefaultsAsync( + mapOf(RemoteConfigSource.KEY_FEATURE_GAMEHUB_CONTENT to "[]") + ) + } + } + single { FirebaseRemoteConfigRepositoryImpl(get()) } + single { HubContentRepositoryImpl(get(), get()) } +} diff --git a/app/src/main/java/com/brainwallet/initializer/AppInitializer.kt b/app/src/main/java/com/brainwallet/initializer/AppInitializer.kt index 9095b8d0..9b6d8f01 100644 --- a/app/src/main/java/com/brainwallet/initializer/AppInitializer.kt +++ b/app/src/main/java/com/brainwallet/initializer/AppInitializer.kt @@ -4,6 +4,7 @@ import android.content.Context import androidx.startup.Initializer import com.brainwallet.data.source.RemoteConfigSource import com.brainwallet.di.AppModule +import com.brainwallet.di.remoteConfigModule import com.brainwallet.domain.MessagingTopicUseCase import com.grunt.brainwallet.core.presentation.KoinInitializer import org.koin.core.component.KoinComponent @@ -20,7 +21,8 @@ class AppInitializer( loadKoinModules( listOf( AppModule.dataModule, - AppModule.module + AppModule.module, + remoteConfigModule ) ) } diff --git a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt index 1897844f..b519558d 100644 --- a/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt +++ b/app/src/main/java/com/brainwallet/navigation/LegacyNavigation.kt @@ -4,51 +4,51 @@ import android.app.Activity import android.content.Context import android.content.Intent import com.brainwallet.R -import com.brainwallet.presenter.activities.BreadActivity import com.brainwallet.ui.BrainwalletActivity import timber.log.Timber - -// provide old navigation using intent activity object LegacyNavigation { - // todo - /** - * wrapper for old `startBreadActivity` - * at [com.brainwallet.tools.animation.BRAnimator.startBreadActivity] + * Wrapper for old `startBreadActivity` + * Previously routed to BentoActivity via BentoNavigation — now routes directly + * to BrainwalletActivity with Route.Main (auth=false) or Route.UnLock (auth=true). */ @JvmStatic - fun startBreadActivity( + fun startBrainwalletActivity( from: Activity, auth: Boolean ) { - Timber.i("timber: startBreadActivity: %s", from.javaClass.name) + Timber.i("timber: startBrainwalletActivity: %s", from.javaClass.name) - val intent = if (auth) { - BrainwalletActivity.createIntent(from, Route.UnLock()) - } else { - Intent(from, BreadActivity::class.java) + val destination = if (auth) Route.UnLock() else Route.Main + BrainwalletActivity.createIntent(from, destination).apply { + addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) + }.also { + from.startActivity(it) } - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) - from.startActivity(intent) + from.overridePendingTransition(R.anim.fade_up, R.anim.fade_down) if (!from.isDestroyed) { from.finish() } } + /** + * Restarts the main wallet activity, clearing the back stack. + * Previously pointed at the legacy BreadActivity. + */ @JvmStatic - fun restartBreadActivity( - context: Context - ) { - Intent(context, BreadActivity::class.java).apply { + fun restartBreadActivity(context: Context) { + BrainwalletActivity.createIntent(context, Route.Main).apply { addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) }.also { context.startActivity(it) } } - // open compose from old activity + /** + * Opens a specific Compose screen from a legacy (non-Compose) context. + */ @JvmStatic @JvmOverloads fun openComposeScreen( diff --git a/app/src/main/java/com/brainwallet/navigation/MainNav.kt b/app/src/main/java/com/brainwallet/navigation/MainNavigationHost.kt similarity index 69% rename from app/src/main/java/com/brainwallet/navigation/MainNav.kt rename to app/src/main/java/com/brainwallet/navigation/MainNavigationHost.kt index 0fe70d70..6331403f 100644 --- a/app/src/main/java/com/brainwallet/navigation/MainNav.kt +++ b/app/src/main/java/com/brainwallet/navigation/MainNavigationHost.kt @@ -7,9 +7,13 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.toRoute -import com.brainwallet.ui.screens.buylitecoin.BuyLitecoinScreen -import com.brainwallet.ui.screens.inputwords.InputWordsScreen +import com.brainwallet.ui.screens.buyreceive.BuyReceiveScreen +import com.brainwallet.ui.screens.gamehub.GameHubScreen +import com.brainwallet.ui.screens.home.MainScreen +import com.brainwallet.ui.bentosections.buyreceivebento.receive.ReceiveDialog +import com.brainwallet.ui.screens.restore.RestoreScreen import com.brainwallet.ui.screens.ready.ReadyScreen +import com.brainwallet.ui.screens.send.SendScreen import com.brainwallet.ui.screens.setpasscode.SetPasscodeScreen import com.brainwallet.ui.screens.topup.TopUpScreen import com.brainwallet.ui.screens.unlock.UnLockScreen @@ -25,10 +29,11 @@ import com.brainwallet.ui.screens.yourseedwords.YourSeedWordsScreen * maybe we have back stack activity from the old * */ +// / Route.Welcome, @Composable -fun MainNavHost( - startDestination: Any = Route.Welcome, +fun MainNavigationHost( onFinish: () -> Unit, + startDestination: Any = Route.Welcome, navController: NavHostController = rememberNavController(), ) { NavHost( @@ -48,6 +53,9 @@ fun MainNavHost( } navController.navigate(route = it.destinationRoute!!) { + if (it.forcePopBackStack) { + popUpTo(navController.graph.id) { inclusive = true } + } it.navOptionsBuilder?.invoke(this) } } @@ -67,12 +75,10 @@ fun NavGraphBuilder.mainNavGraph( composable { ReadyScreen(onNavigate = onNavigate) } - composable { navBackStackEntry -> val route: Route.TopUp = navBackStackEntry.toRoute() TopUpScreen(onNavigate = onNavigate) } - composable { navBackStackEntry -> val route: Route.SetPasscode = navBackStackEntry.toRoute() SetPasscodeScreen( @@ -80,9 +86,9 @@ fun NavGraphBuilder.mainNavGraph( passcode = route.passcode, ) } - composable { navBackStackEntry -> - val route: Route.InputWords = navBackStackEntry.toRoute() - InputWordsScreen( + composable { navBackStackEntry -> + val route: Route.Restore = navBackStackEntry.toRoute() + RestoreScreen( onNavigate = onNavigate, source = route.source, ) @@ -102,21 +108,32 @@ fun NavGraphBuilder.mainNavGraph( ) } - /** - * for now, still using old activity & fragment [com.brainwallet.presenter.activities.BreadActivity] - */ -// composable { -// HomeScreen(onNavigate = onNavigate) -// } + composable { navBackStackEntry -> + val route: Route.Main = navBackStackEntry.toRoute() + MainScreen(onNavigate = onNavigate) + } composable { navBackStackEntry -> val route: Route.UnLock = navBackStackEntry.toRoute() UnLockScreen(onNavigate = onNavigate, isUpdatePin = route.isUpdatePin) } - composable { navBackStackEntry -> - BuyLitecoinScreen(onNavigate = onNavigate) + composable { navBackStackEntry -> + val route: Route.BuyReceive = navBackStackEntry.toRoute() + ReceiveDialog(onDismissRequest = {}) } - // todo add more composable screens + composable { navBackStackEntry -> + val route: Route.Send = navBackStackEntry.toRoute() + SendScreen(onNavigate = onNavigate) + } + + composable { navBackStackEntry -> + val route: Route.GameHub = navBackStackEntry.toRoute() + GameHubScreen(onNavigate = onNavigate) + } + composable { navBackStackEntry -> + val route: Route.GameHub = navBackStackEntry.toRoute() + BuyReceiveScreen(onNavigate = onNavigate) + } } diff --git a/app/src/main/java/com/brainwallet/navigation/Route.kt b/app/src/main/java/com/brainwallet/navigation/Route.kt index 005a11b3..06726ae1 100644 --- a/app/src/main/java/com/brainwallet/navigation/Route.kt +++ b/app/src/main/java/com/brainwallet/navigation/Route.kt @@ -24,7 +24,7 @@ sealed class Route : JavaSerializable { ) : Route() @Serializable - data class InputWords(val source: Source? = null) : Route() { + data class Restore(val source: Source? = null) : Route() { enum class Source { RESET_PIN, SETTING_WIPE @@ -37,13 +37,24 @@ sealed class Route : JavaSerializable { @Serializable data class YourSeedProveIt(val seedWords: List) : Route() -// for now, still using old activity & fragment -// @Serializable -// object Home : Route() + @Serializable + object Main : Route() @Serializable data class UnLock(val isUpdatePin: Boolean = false) : Route() @Serializable - object BuyLitecoin : Route() + object BuyReceive : Route() + + @Serializable + object History : Route() + + @Serializable + object Send : Route() + + @Serializable + object GameHub : Route() + + @Serializable + object MoonPayWeb : Route() } diff --git a/app/src/main/java/com/brainwallet/navigation/UiEffect.kt b/app/src/main/java/com/brainwallet/navigation/UiEffect.kt index ee7cdf7b..3d48fd1f 100644 --- a/app/src/main/java/com/brainwallet/navigation/UiEffect.kt +++ b/app/src/main/java/com/brainwallet/navigation/UiEffect.kt @@ -21,6 +21,10 @@ sealed class UiEffect { data class ShowDialog(val name: String) : UiEffect() data object ShowMoonPayDialog : UiEffect() + object OpenQRScanner : UiEffect() + + object OnEnterAuthPasscode : UiEffect() + data class ShowMessage( val message: String, val type: Type = Type.Success, diff --git a/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java index 7a82beeb..79c86137 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/BreadActivity.java @@ -12,7 +12,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.telephony.TelephonyManager; import android.view.ViewTreeObserver; import android.view.animation.AnimationUtils; import android.widget.Button; @@ -25,7 +24,6 @@ import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; -import androidx.browser.customtabs.CustomTabsIntent; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintSet; import androidx.core.app.ActivityCompat; @@ -41,29 +39,26 @@ import com.brainwallet.presenter.activities.settings.SyncBlockchainActivity; import com.brainwallet.presenter.activities.util.BRActivity; import com.brainwallet.presenter.customviews.BRNotificationBar; -import com.brainwallet.presenter.fragments.BuyTabFragment; -import com.brainwallet.presenter.fragments.FragmentMoonpay; import com.brainwallet.presenter.history.HistoryFragment; import com.brainwallet.tools.animation.BRAnimator; import com.brainwallet.tools.animation.TextSizeTransition; import com.brainwallet.tools.manager.AnalyticsManager; import com.brainwallet.tools.manager.BRSharedPrefs; import com.brainwallet.tools.manager.InternetManager; -import com.brainwallet.tools.manager.SyncManager; +import com.brainwallet.tools.manager.sync.SyncManager; import com.brainwallet.tools.security.BitcoinUrlHandler; import com.brainwallet.tools.security.PostAuth; import com.brainwallet.tools.sqlite.TransactionDataSource; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.BRCurrency; import com.brainwallet.tools.util.BRExchange; import com.brainwallet.tools.util.ExtensionKt; import com.brainwallet.tools.util.Utils; import com.brainwallet.ui.BrainwalletActivity; -import com.brainwallet.ui.screens.home.SettingsViewModel; -import com.brainwallet.ui.screens.home.composable.HomeSettingDrawerComposeView; -import com.brainwallet.ui.screens.home.receive.ReceiveDialogFragment; -import com.brainwallet.ui.screens.home.receive.ReceiveDialogKt; +import com.brainwallet.ui.screens.settings.SettingsViewModel; +import com.brainwallet.ui.screens.settings.settingsrows.HomeSettingDrawerComposeView; +import com.brainwallet.ui.bentosections.buyreceivebento.receive.ReceiveDialogFragment; import com.brainwallet.util.PermissionUtil; import com.brainwallet.wallet.BRPeerManager; import com.brainwallet.wallet.BRWalletManager; @@ -78,7 +73,7 @@ import timber.log.Timber; -public class BreadActivity extends BRActivity implements BRWalletManager.OnBalanceChanged, BRSharedPrefs.OnIsoChangedListener, +public class BreadActivity extends BRActivity implements BRWalletManager.OnBalanceChanged, TransactionDataSource.OnTxAddedListener, InternetManager.ConnectionReceiverListener { public static final Point screenParametersPoint = new Point(); @@ -121,13 +116,13 @@ public static BreadActivity getApp() { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_bread); - AnalyticsManager.logCustomEvent(BRConstants._HOME_OPEN); + AnalyticsManager.logCustomEvent(BWConstants._HOME_OPEN); app = this; getWindowManager().getDefaultDisplay().getSize(screenParametersPoint); initializeViews(); - setPriceTags(BRSharedPrefs.getPreferredLTC(BreadActivity.this), false); + setPriceTags(BRSharedPrefs.getLTCViewingPreference(BreadActivity.this), false); setListeners(); setUpBarFlipper(); checkTransactionDatabase(); @@ -179,7 +174,7 @@ private void showInAppReviewDialogIfNeeded() { ReviewManager manager = ReviewManagerFactory.create(this); Task request = manager.requestReviewFlow(); request.addOnCompleteListener(task -> { - AnalyticsManager.logCustomEvent(BRConstants._20241006_DRR); + AnalyticsManager.logCustomEvent(BWConstants._20241006_DRR); if (task.isSuccessful()) { ReviewInfo reviewInfo = task.getResult(); Task flow = manager.launchReviewFlow(BreadActivity.this, reviewInfo); @@ -190,7 +185,7 @@ private void showInAppReviewDialogIfNeeded() { Timber.i("timber: In-app LaunchReviewFlow completed successful (%s)", task1.isSuccessful()); if (task1.isSuccessful()) { BRSharedPrefs.inAppReviewDone(BreadActivity.this); - AnalyticsManager.logCustomEvent(BRConstants._20241006_UCR); + AnalyticsManager.logCustomEvent(BWConstants._20241006_UCR); } }); } else { @@ -202,12 +197,10 @@ private void showInAppReviewDialogIfNeeded() { private void addObservers() { BRWalletManager.getInstance().addBalanceChangedListener(this); - BRSharedPrefs.addIsoChangedListener(this); } private void removeObservers() { BRWalletManager.getInstance().removeListener(this); - BRSharedPrefs.removeListener(this); } private void setUrlHandler(Intent intent) { @@ -274,10 +267,9 @@ public boolean handleNavigationItemSelected(int menuItemId) { private void swap() { if (!BRAnimator.isClickAllowed()) return; - boolean b = !BRSharedPrefs.getPreferredLTC(this); + boolean b = !BRSharedPrefs.getLTCViewingPreference(this); setPriceTags(b, true); - BRSharedPrefs.putPreferredLTC(this, b); - BRSharedPrefs.notifyIsoChanged(""); + BRSharedPrefs.putLTCViewingPreference(this, b); } private void setPriceTags(boolean ltcPreferred, boolean animate) { @@ -393,11 +385,10 @@ private void initializeViews() { navigationDrawer = findViewById(R.id.navigationDrawer); drawerLayout = findViewById(R.id.drawerLayout); - homeSettingDrawerComposeView = findViewById(R.id.homeDrawerComposeView); homeSettingDrawerComposeView.observeBus(message -> { drawerLayout.close(); if (SettingsViewModel.LEGACY_EFFECT_ON_LOCK.equals(message.getMessage())) { - LegacyNavigation.startBreadActivity(this, true); + LegacyNavigation.startBrainwalletActivity(this, true); } else if (SettingsViewModel.LEGACY_EFFECT_ON_TOGGLE_DARK_MODE.equals(message.getMessage())) { LegacyNavigation.restartBreadActivity(this); } else if (SettingsViewModel.LEGACY_EFFECT_ON_SEC_UPDATE_PIN.equals(message.getMessage())) { @@ -438,7 +429,7 @@ public void onGlobalLayout() { } if (uiIsDone) return; uiIsDone = true; - setPriceTags(BRSharedPrefs.getPreferredLTC(BreadActivity.this), false); + setPriceTags(BRSharedPrefs.getLTCViewingPreference(BreadActivity.this), false); } }); @@ -457,7 +448,7 @@ public void updateUI() { String iso = BRSharedPrefs.getIsoSymbol(BreadActivity.this); //current amount in litoshis - final BigDecimal amount = new BigDecimal(BRSharedPrefs.getCatchedBalance(BreadActivity.this)); + final BigDecimal amount = new BigDecimal(BRSharedPrefs.getCachedBalance(BreadActivity.this)); //amount in LTC units BigDecimal btcAmount = BRExchange.getLitecoinForLitoshis(BreadActivity.this, amount); @@ -472,11 +463,6 @@ public void updateUI() { }); } - @Override - public void onIsoChanged(String iso) { - updateUI(); - } - @Override public void onTxAdded() { BRWalletManager.getInstance().refreshBalance(BreadActivity.this); @@ -487,11 +473,11 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { - case BRConstants.CAMERA_REQUEST_ID: { + case BWConstants.CAMERA_REQUEST_ID: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - BRAnimator.openScanner(this, BRConstants.SCANNER_REQUEST); + BRAnimator.openScanner(this, BWConstants.SCANNER_REQUEST); // permission was granted, yay! Do the // contacts-related task you need to do. } else { diff --git a/app/src/main/java/com/brainwallet/presenter/activities/DisabledActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/DisabledActivity.java index 18c9d923..f13c01e2 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/DisabledActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/DisabledActivity.java @@ -56,7 +56,7 @@ public void onClick(View v) { //to navigate into compose screen LegacyNavigation.openComposeScreen( DisabledActivity.this, - new Route.InputWords(Route.InputWords.Source.RESET_PIN) + new Route.Restore(Route.Restore.Source.RESET_PIN) ); overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left); } diff --git a/app/src/main/java/com/brainwallet/presenter/activities/LoginActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/LoginActivity.java index f429ea5b..450c1321 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/LoginActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/LoginActivity.java @@ -28,7 +28,7 @@ import com.brainwallet.tools.security.BRKeyStore; import com.brainwallet.tools.sqlite.CurrencyDataSource; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.BRCurrency; import com.brainwallet.ui.BrainwalletActivity; import com.brainwallet.wallet.BRWalletManager; @@ -106,7 +106,7 @@ protected void onCreate(Bundle savedInstanceState) { keyboard.setCustomButtonBackgroundColor(10, getColor(android.R.color.transparent)); keyboard.setDeleteImage(getDrawable(R.drawable.ic_delete_white)); - versionText.setText(BRConstants.APP_VERSION_NAME_CODE); + versionText.setText(BWConstants.APP_VERSION_NAME_CODE); // DEV: Keeping for reference when REFACTORING // findViewById(R.id.scanQRCodeImgBut).setOnClickListener(v -> { @@ -123,7 +123,7 @@ protected void onCreate(Bundle savedInstanceState) { // } else { // ActivityCompat.requestPermissions(app, // new String[]{Manifest.permission.CAMERA}, -// BRConstants.CAMERA_REQUEST_ID); +// BWConstants.CAMERA_REQUEST_ID); // } // } else { // Intent intent = new Intent(app, ScanQRActivity.class); @@ -145,7 +145,7 @@ private void setCurrentLtcPrice() { CurrencyEntity currency = CurrencyDataSource.getInstance(this).getCurrencyByIso(iso); if (currency != null) { final BigDecimal roundedPriceAmount = new BigDecimal(currency.rate).multiply(new BigDecimal(100)) - .divide(new BigDecimal(100), 2, BRConstants.ROUNDING_MODE); + .divide(new BigDecimal(100), 2, BWConstants.ROUNDING_MODE); formattedCurrency = BRCurrency.getFormattedCurrencyString(this, iso, roundedPriceAmount); } else { Timber.w("The currency related to %s is NULL", iso); @@ -257,11 +257,9 @@ private void updateDots() { if (AuthManager.getInstance().checkAuth(pin.toString(), LoginActivity.this)) { AuthManager.getInstance().authSuccess(LoginActivity.this); unlockWallet(); - AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB); - AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB); + AnalyticsManager.logCustomEvent(BWConstants._20200217_DUWB); } else { - AuthManager.getInstance().authFail(LoginActivity.this); showFailedToUnlock(); } }); @@ -272,11 +270,11 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { - case BRConstants.CAMERA_REQUEST_ID: { + case BWConstants.CAMERA_REQUEST_ID: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - BRAnimator.openScanner(this, BRConstants.SCANNER_REQUEST); + BRAnimator.openScanner(this, BWConstants.SCANNER_REQUEST); // permission was granted, yay! Do the // contacts-related task you need to do. } else { diff --git a/app/src/main/java/com/brainwallet/presenter/activities/ReEnterPinActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/ReEnterPinActivity.java new file mode 100644 index 00000000..f5dc8eec --- /dev/null +++ b/app/src/main/java/com/brainwallet/presenter/activities/ReEnterPinActivity.java @@ -0,0 +1,176 @@ +package com.brainwallet.presenter.activities; + +import android.os.Bundle; +import android.os.Handler; +import android.view.View; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.brainwallet.R; +import com.brainwallet.presenter.activities.util.BRActivity; +import com.brainwallet.presenter.customviews.BRKeyboard; +import com.brainwallet.presenter.interfaces.BROnSignalCompletion; +import com.brainwallet.tools.animation.BRAnimator; +import com.brainwallet.tools.animation.SpringAnimator; +import com.brainwallet.tools.security.AuthManager; +import com.brainwallet.tools.security.PostAuth; +import com.brainwallet.tools.util.Utils; + +import timber.log.Timber; + +public class ReEnterPinActivity extends BRActivity { + private BRKeyboard keyboard; + public static ReEnterPinActivity reEnterPinActivity; + private View dot1; + private View dot2; + private View dot3; + private View dot4; + private StringBuilder pin = new StringBuilder(); + private TextView title; + private int pinLimit = 4; + private String firstPIN; + private boolean isPressAllowed = true; + private LinearLayout pinLayout; + public static boolean appVisible = false; + private static ReEnterPinActivity app; + + public static ReEnterPinActivity getApp() { + return app; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_pin_template); + + keyboard = (BRKeyboard) findViewById(R.id.brkeyboard); + pinLayout = (LinearLayout) findViewById(R.id.pinLayout); + + ImageButton faq = (ImageButton) findViewById(R.id.faq_button); + //TODO: all views are using the layout of this button. Views should be refactored without it + // Hiding until layouts are built. + + title = (TextView) findViewById(R.id.title); + title.setText(getString(R.string.UpdatePin_createTitleConfirm)); + firstPIN = getIntent().getExtras().getString("pin"); + if (Utils.isNullOrEmpty(firstPIN)) { + throw new RuntimeException("first PIN is required"); + } + reEnterPinActivity = this; + + dot1 = findViewById(R.id.dot1); + dot2 = findViewById(R.id.dot2); + dot3 = findViewById(R.id.dot3); + dot4 = findViewById(R.id.dot4); + + keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() { + @Override + public void onClick(String key) { + handleClick(key); + } + }); + keyboard.setShowDot(false); + } + + @Override + protected void onResume() { + super.onResume(); + updateDots(); + appVisible = true; + app = this; + isPressAllowed = true; + } + + @Override + protected void onPause() { + super.onPause(); + appVisible = false; + } + + private void handleClick(String key) { + if (!isPressAllowed) return; + if (key == null) { + Timber.d("timber: handleClick: key is null! "); + return; + } + + if (key.isEmpty()) { + handleDeleteClick(); + } else if (Character.isDigit(key.charAt(0))) { + handleDigitClick(Integer.parseInt(key.substring(0, 1))); + } else { + Timber.d("timber: handleClick: oops: %s", key); + } + } + + + private void handleDigitClick(Integer dig) { + if (pin.length() < pinLimit) + pin.append(dig); + updateDots(); + } + + private void handleDeleteClick() { + if (pin.length() > 0) + pin.deleteCharAt(pin.length() - 1); + updateDots(); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right); + } + + private void updateDots() { + int selectedDots = pin.length(); + + dot1.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); + selectedDots--; + dot2.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); + selectedDots--; + dot3.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); + selectedDots--; + dot4.setBackground(getDrawable(selectedDots <= 0 ? R.drawable.ic_pin_dot_gray : R.drawable.ic_pin_dot_black)); + selectedDots--; + + if (pin.length() == 4) { + verifyPin(); + } + } + + private void verifyPin() { + if (firstPIN.equalsIgnoreCase(pin.toString())) { + AuthManager.getInstance().authSuccess(this); + isPressAllowed = false; + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + pin = new StringBuilder(); + updateDots(); + } + }, 200); + AuthManager.getInstance().setPinCode(pin.toString(), this); + if (getIntent().getBooleanExtra("noPin", false)) { + BRAnimator.startBreadActivity(this, false); + } else { + BRAnimator.showBreadSignal(this, getString(R.string.Alerts_pinSet), getString(R.string.UpdatePin_createInstruction), R.drawable.ic_check_mark_white, new BROnSignalCompletion() { + @Override + public void onComplete() { + PostAuth.getInstance().onCreateWalletAuth(ReEnterPinActivity.this, false); + } + }); + } + } else { + Timber.d("timber: verifyPin: FAIL: firs: %s, reEnter: %s ", firstPIN, pin); + SpringAnimator.failShakeAnimation(this, pinLayout); + pin = new StringBuilder(); + } + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + } +} diff --git a/app/src/main/java/com/brainwallet/presenter/activities/UpdatePinActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/UpdatePinActivity.java new file mode 100644 index 00000000..4233e92c --- /dev/null +++ b/app/src/main/java/com/brainwallet/presenter/activities/UpdatePinActivity.java @@ -0,0 +1,204 @@ +package com.brainwallet.presenter.activities; + +import static com.brainwallet.constants.BWConstants.BW_PIN_LENGTH; + +import android.os.Bundle; +import android.os.Handler; +import android.view.View; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.brainwallet.R; +import com.brainwallet.presenter.activities.util.BRActivity; +import com.brainwallet.presenter.customviews.BRKeyboard; +import com.brainwallet.presenter.interfaces.BROnSignalCompletion; +import com.brainwallet.tools.animation.BRAnimator; +import com.brainwallet.tools.animation.SpringAnimator; +import com.brainwallet.tools.security.AuthManager; +import com.brainwallet.tools.security.BRKeyStore; + +import timber.log.Timber; + +public class UpdatePinActivity extends BRActivity { + private BRKeyboard keyboard; + private View dot1; + private View dot2; + private View dot3; + private View dot4; + private StringBuilder pin = new StringBuilder(); + private int pinLimit = 4; + // private boolean allowInserting = true; + private TextView title; + private TextView description; + int mode = ENTER_PIN; + public static final int ENTER_PIN = 1; + public static final int ENTER_NEW_PIN = 2; + public static final int RE_ENTER_NEW_PIN = 3; + + private ImageButton faq; + private LinearLayout pinLayout; + private String curNewPin = ""; + public static boolean appVisible = false; + private static UpdatePinActivity app; + + public static UpdatePinActivity getApp() { + return app; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_pin_template); + + keyboard = (BRKeyboard) findViewById(R.id.brkeyboard); + title = (TextView) findViewById(R.id.title); + description = (TextView) findViewById(R.id.description); + pinLayout = (LinearLayout) findViewById(R.id.pinLayout); + if (BRKeyStore.getPinCode(this).length() == BW_PIN_LENGTH) pinLimit = BW_PIN_LENGTH; + setMode(ENTER_PIN); + title.setText(getString(R.string.UpdatePin_updateTitle)); + dot1 = findViewById(R.id.dot1); + dot2 = findViewById(R.id.dot2); + dot3 = findViewById(R.id.dot3); + dot4 = findViewById(R.id.dot4); + + //TODO: all views are using the layout of this button. Views should be refactored without it + // Hiding until layouts are built. + faq = (ImageButton) findViewById(R.id.faq_button); + + keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() { + @Override + public void onClick(String key) { + handleClick(key); + } + }); + keyboard.setShowDot(false); + + } + + @Override + protected void onResume() { + super.onResume(); + updateDots(); + appVisible = true; + app = this; + } + + @Override + protected void onPause() { + super.onPause(); + appVisible = false; + } + + private void handleClick(String key) { + if (key == null) { + Timber.d("timber: handleClick: key is null! "); + return; + } + + if (key.isEmpty()) { + handleDeleteClick(); + } else if (Character.isDigit(key.charAt(0))) { + handleDigitClick(Integer.parseInt(key.substring(0, 1))); + } else { + Timber.d("timber: handleClick: oops: %s", key); + } + } + + + private void handleDigitClick(Integer dig) { + if (pin.length() < pinLimit) + pin.append(dig); + updateDots(); + } + + private void handleDeleteClick() { + if (pin.length() > 0) + pin.deleteCharAt(pin.length() - 1); + updateDots(); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + overridePendingTransition(R.anim.enter_from_left, R.anim.exit_to_right); + } + + private void updateDots() { + + AuthManager.getInstance().updateDots(this, pinLimit, pin.toString(), dot1, dot2, dot3, dot4, R.drawable.ic_pin_dot_gray, new AuthManager.OnPinSuccess() { + @Override + public void onSuccess() { + new Handler().postDelayed(new Runnable() { + @Override + public void run() { + goNext(); + } + }, 100); + } + }); + } + + private void goNext() { + switch (mode) { + case ENTER_PIN: + if (AuthManager.getInstance().checkAuth(pin.toString(), this)) { + setMode(ENTER_NEW_PIN); + pinLimit = 4; + } else { + SpringAnimator.failShakeAnimation(this, pinLayout); + } + pin = new StringBuilder(); + updateDots(); + break; + case ENTER_NEW_PIN: + setMode(RE_ENTER_NEW_PIN); + curNewPin = pin.toString(); + pin = new StringBuilder(); + updateDots(); + break; + + case RE_ENTER_NEW_PIN: + if (curNewPin.equalsIgnoreCase(pin.toString())) { + AuthManager.getInstance().setPinCode(pin.toString(), this); + BRAnimator.showBreadSignal(this, getString(R.string.Alerts_pinSet), getString(R.string.UpdatePin_caption), R.drawable.ic_check_mark_white, new BROnSignalCompletion() { + @Override + public void onComplete() { + BRAnimator.startBreadActivity(UpdatePinActivity.this, false); + } + }); + } else { + SpringAnimator.failShakeAnimation(this, pinLayout); + setMode(ENTER_NEW_PIN); + pinLimit = BRKeyStore.getPinCode(this).length(); + } + pin = new StringBuilder(); + updateDots(); + break; + } + } + + private void setMode(int mode) { + String text = ""; + this.mode = mode; + switch (mode) { + case ENTER_PIN: + text = getString(R.string.UpdatePin_enterCurrent); + break; + case ENTER_NEW_PIN: + text = getString(R.string.UpdatePin_enterNew); + break; + case RE_ENTER_NEW_PIN: + text = getString(R.string.UpdatePin_reEnterNew); + break; + } + description.setText(text); + SpringAnimator.springView(description); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + } +} diff --git a/app/src/main/java/com/brainwallet/presenter/activities/intro/RecoverActivity.kt b/app/src/main/java/com/brainwallet/presenter/activities/intro/RecoverActivity.kt index 906229c9..2006b779 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/intro/RecoverActivity.kt +++ b/app/src/main/java/com/brainwallet/presenter/activities/intro/RecoverActivity.kt @@ -25,7 +25,7 @@ class RecoverActivity : BRActivity() { if (!BRAnimator.isClickAllowed()) return@OnClickListener LegacyNavigation.openComposeScreen( context = this@RecoverActivity, - destination = Route.InputWords() + destination = Route.Restore() ) } ) diff --git a/app/src/main/java/com/brainwallet/presenter/activities/settings/AboutActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/settings/AboutActivity.java index c38b27e1..ccdbc1c2 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/settings/AboutActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/settings/AboutActivity.java @@ -12,7 +12,7 @@ import com.brainwallet.presenter.activities.util.ActivityUTILS; import com.brainwallet.presenter.activities.util.BRActivity; import com.brainwallet.tools.animation.BRAnimator; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; public class AboutActivity extends BRActivity { private static final String TAG = AboutActivity.class.getName(); @@ -47,14 +47,14 @@ protected void onCreate(Bundle savedInstanceState) { instagramShare = (ImageView) findViewById(R.id.instagram_share_button); twitterShare = (ImageView) findViewById(R.id.twitter_share_button); blogShare = (ImageView) findViewById(R.id.blog_share_button); - versionText.setText(BRConstants.APP_VERSION_NAME_CODE); + versionText.setText(BWConstants.APP_VERSION_NAME_CODE); - versionText.setText(BRConstants.APP_VERSION_NAME_CODE); + versionText.setText(BWConstants.APP_VERSION_NAME_CODE); instagramShare.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BRConstants.INSTAGRAM_LINK)); + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BWConstants.INSTAGRAM_LINK)); startActivity(browserIntent); app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300); } @@ -63,7 +63,7 @@ public void onClick(View v) { twitterShare.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BRConstants.TWITTER_LINK)); + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BWConstants.TWITTER_LINK)); startActivity(browserIntent); app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300); } @@ -71,7 +71,7 @@ public void onClick(View v) { blogShare.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BRConstants.WEB_LINK)); + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BWConstants.WEB_LINK)); startActivity(browserIntent); app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300); } @@ -79,7 +79,7 @@ public void onClick(View v) { policyText.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BRConstants.TOS_LINK)); + Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(BWConstants.TOS_LINK)); startActivity(browserIntent); app.overridePendingTransition(R.anim.enter_from_bottom, R.anim.empty_300); } diff --git a/app/src/main/java/com/brainwallet/presenter/activities/settings/DisplayCurrencyActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/settings/DisplayCurrencyActivity.java index 95bf127b..fb09f353 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/settings/DisplayCurrencyActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/settings/DisplayCurrencyActivity.java @@ -21,7 +21,7 @@ import com.brainwallet.data.model.CurrencyEntity; import com.brainwallet.tools.manager.BRSharedPrefs; import com.brainwallet.tools.sqlite.CurrencyDataSource; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.BRCurrency; import java.math.BigDecimal; @@ -83,7 +83,7 @@ public void onClick(View v) { }); int unit = BRSharedPrefs.getCurrencyUnit(this); - if (unit == BRConstants.CURRENT_UNIT_LITES) { + if (unit == BWConstants.CURRENT_UNIT_LITES) { setButton(true); } else { setButton(false); @@ -121,7 +121,7 @@ private void updateExchangeRate() { CurrencyEntity entity = CurrencyDataSource.getInstance(this).getCurrencyByIso(iso); if (entity != null) { String finalExchangeRate = BRCurrency.getFormattedCurrencyString(DisplayCurrencyActivity.this, BRSharedPrefs.getIsoSymbol(this), new BigDecimal(entity.rate)); - boolean bits = BRSharedPrefs.getCurrencyUnit(this) == BRConstants.CURRENT_UNIT_LITES; + boolean bits = BRSharedPrefs.getCurrencyUnit(this) == BWConstants.CURRENT_UNIT_LITES; exchangeText.setText(BRCurrency.getFormattedCurrencyString(this, "LTC", new BigDecimal(bits ? 1000 : 1)) + " = " + finalExchangeRate); } adapter.notifyDataSetChanged(); @@ -129,13 +129,13 @@ private void updateExchangeRate() { private void setButton(boolean left) { if (left) { - BRSharedPrefs.putCurrencyUnit(this, BRConstants.CURRENT_UNIT_LITES); + BRSharedPrefs.putCurrencyUnit(this, BWConstants.CURRENT_UNIT_LITES); leftButton.setTextColor(getColor(R.color.grape)); leftButton.setBackground(getDrawable(R.drawable.b_half_left_blue)); rightButton.setTextColor(getColor(R.color.cheddar)); rightButton.setBackground(getDrawable(R.drawable.b_half_right_blue_stroke)); } else { - BRSharedPrefs.putCurrencyUnit(this, BRConstants.CURRENT_UNIT_LITECOINS); + BRSharedPrefs.putCurrencyUnit(this, BWConstants.CURRENT_UNIT_LITECOINS); leftButton.setTextColor(getColor(R.color.cheddar)); leftButton.setBackground(getDrawable(R.drawable.b_half_left_blue_stroke)); rightButton.setTextColor(getColor(R.color.grape)); diff --git a/app/src/main/java/com/brainwallet/presenter/activities/settings/SecurityCenterActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/settings/SecurityCenterActivity.java index 8d7fa3d1..80de11af 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/settings/SecurityCenterActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/settings/SecurityCenterActivity.java @@ -1,6 +1,6 @@ package com.brainwallet.presenter.activities.settings; -import static com.brainwallet.tools.util.BRConstants.BW_PIN_LENGTH; +import static com.brainwallet.constants.BWConstants.BW_PIN_LENGTH; import android.app.Activity; import android.content.Context; diff --git a/app/src/main/java/com/brainwallet/presenter/activities/settings/SpendLimitActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/settings/SpendLimitActivity.java index 8d5bb60e..6a85a967 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/settings/SpendLimitActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/settings/SpendLimitActivity.java @@ -1,6 +1,6 @@ package com.brainwallet.presenter.activities.settings; -import static com.brainwallet.tools.util.BRConstants.ONE_BITCOIN; +import static com.brainwallet.constants.BWConstants.ONE_BITCOIN; import android.app.Activity; import android.content.Context; diff --git a/app/src/main/java/com/brainwallet/presenter/activities/settings/SyncBlockchainActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/settings/SyncBlockchainActivity.java index 8ec82627..aa2a79ff 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/settings/SyncBlockchainActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/settings/SyncBlockchainActivity.java @@ -16,7 +16,7 @@ import com.brainwallet.tools.manager.AnalyticsManager; import com.brainwallet.tools.manager.BRSharedPrefs; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.wallet.BRPeerManager; @@ -51,10 +51,10 @@ private void updateSyncPreference() { String rateAsString = String.format("%1.5f",fprate); syncPreferenceTextView.setText(getString(R.string.sync_preferences, rateAsString)); - if (fprate == BRConstants.FALSE_POS_RATE_LOW_PRIVACY) { + if (fprate == BWConstants.FALSE_POS_RATE_LOW_PRIVACY) { syncRadioGroup.check(R.id.radio_low_privacy); } - else if (fprate == BRConstants.FALSE_POS_RATE_SEMI_PRIVACY) { + else if (fprate == BWConstants.FALSE_POS_RATE_SEMI_PRIVACY) { syncRadioGroup.check(R.id.radio_semi_private); }else { ///Assumed the Anon option is preferred @@ -85,7 +85,7 @@ protected void onCreate(Bundle savedInstanceState) { lowPrivacyButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BRConstants.FALSE_POS_RATE_LOW_PRIVACY); + BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BWConstants.FALSE_POS_RATE_LOW_PRIVACY); updateSyncPreference(); } }); @@ -93,14 +93,14 @@ public void onClick(View v) { semiPrivateButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BRConstants.FALSE_POS_RATE_SEMI_PRIVACY); + BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BWConstants.FALSE_POS_RATE_SEMI_PRIVACY); updateSyncPreference(); } }); anonymousButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BRConstants.FALSE_POS_RATE_ANONYMOUS); + BRSharedPrefs.putFalsePositivesRate(SyncBlockchainActivity.this, BWConstants.FALSE_POS_RATE_ANONYMOUS); updateSyncPreference(); } }); @@ -123,7 +123,7 @@ public void run() { BRSharedPrefs.putAllowSpend(SyncBlockchainActivity.this, false); BRPeerManager.getInstance().rescan(); BRAnimator.startBreadActivity(SyncBlockchainActivity.this, false); - AnalyticsManager.logCustomEvent(BRConstants._20200112_DSR); + AnalyticsManager.logCustomEvent(BWConstants._20200112_DSR); } }); } diff --git a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java index df68dc39..6644a386 100644 --- a/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java +++ b/app/src/main/java/com/brainwallet/presenter/activities/util/BRActivity.java @@ -22,7 +22,7 @@ import com.brainwallet.tools.security.BitcoinUrlHandler; import com.brainwallet.tools.security.PostAuth; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.wallet.BRWalletManager; import com.brainwallet.worker.CurrencyUpdateWorker; @@ -32,10 +32,13 @@ import timber.log.Timber; +/// Need to update to ComponentActivity +/// This will help migrate fully to Jetpack Compose +/// TBD public class BRActivity extends AppCompatActivity { static { - System.loadLibrary(BRConstants.NATIVE_LIB_NAME); + System.loadLibrary(BWConstants.NATIVE_LIB_NAME); } private SettingRepository settingRepository = (SettingRepository) KoinJavaComponent.inject(SettingRepository.class).getValue(); @@ -69,7 +72,7 @@ protected void onResume() { protected void onActivityResult(int requestCode, int resultCode, final Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { - case BRConstants.PAY_REQUEST_CODE: + case BWConstants.PAY_REQUEST_CODE: if (resultCode == RESULT_OK) { BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { @Override @@ -80,7 +83,7 @@ public void run() { } break; - case BRConstants.CANARY_REQUEST_CODE: + case BWConstants.CANARY_REQUEST_CODE: if (resultCode == RESULT_OK) { PostAuth.getInstance().onCanaryCheck(this, true); } else { @@ -88,17 +91,17 @@ public void run() { } break; - case BRConstants.SHOW_PHRASE_REQUEST_CODE: + case BWConstants.SHOW_PHRASE_REQUEST_CODE: if (resultCode == RESULT_OK) { PostAuth.getInstance().onPhraseCheckAuth(this, true); } break; - case BRConstants.PROVE_PHRASE_REQUEST: + case BWConstants.PROVE_PHRASE_REQUEST: if (resultCode == RESULT_OK) { PostAuth.getInstance().onPhraseProveAuth(this, true); } break; - case BRConstants.PUT_PHRASE_RECOVERY_WALLET_REQUEST_CODE: + case BWConstants.PUT_PHRASE_RECOVERY_WALLET_REQUEST_CODE: if (resultCode == RESULT_OK) { PostAuth.getInstance().onRecoverWalletAuth(this, true); } else { @@ -106,7 +109,7 @@ public void run() { } break; - case BRConstants.SCANNER_REQUEST: + case BWConstants.SCANNER_REQUEST: if (resultCode == Activity.RESULT_OK) { new Handler().postDelayed(new Runnable() { @Override @@ -122,7 +125,7 @@ public void run() { } break; - case BRConstants.PUT_PHRASE_NEW_WALLET_REQUEST_CODE: + case BWConstants.PUT_PHRASE_NEW_WALLET_REQUEST_CODE: if (resultCode == RESULT_OK) { PostAuth.getInstance().onCreateWalletAuth(this, true); } else { diff --git a/app/src/main/java/com/brainwallet/presenter/entities/BRMenuItem.java b/app/src/main/java/com/brainwallet/presenter/entities/BRMenuItem.java deleted file mode 100644 index cbfcfbbe..00000000 --- a/app/src/main/java/com/brainwallet/presenter/entities/BRMenuItem.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.brainwallet.presenter.entities; - -import android.content.DialogInterface; -import android.os.Parcel; -import android.os.Parcelable; -import android.view.View; - -public class BRMenuItem { - - public String text; - public int resId; - public View.OnClickListener listener; - - public BRMenuItem(String text, int resId, View.OnClickListener listener) { - this.text = text; - this.resId = resId; - this.listener = listener; - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/presenter/entities/BRMenuItem.kt b/app/src/main/java/com/brainwallet/presenter/entities/BRMenuItem.kt new file mode 100644 index 00000000..0b5d2c17 --- /dev/null +++ b/app/src/main/java/com/brainwallet/presenter/entities/BRMenuItem.kt @@ -0,0 +1,9 @@ +package com.brainwallet.presenter.entities + +import android.view.View + +class BRMenuItem( + @JvmField var text: String?, + @JvmField var resId: Int, + @JvmField var listener: View.OnClickListener? +) diff --git a/app/src/main/java/com/brainwallet/presenter/entities/BRTransactionEntity.java b/app/src/main/java/com/brainwallet/presenter/entities/BWDatabaseTransactionEntity.java similarity index 84% rename from app/src/main/java/com/brainwallet/presenter/entities/BRTransactionEntity.java rename to app/src/main/java/com/brainwallet/presenter/entities/BWDatabaseTransactionEntity.java index d808ddc4..18178552 100644 --- a/app/src/main/java/com/brainwallet/presenter/entities/BRTransactionEntity.java +++ b/app/src/main/java/com/brainwallet/presenter/entities/BWDatabaseTransactionEntity.java @@ -1,6 +1,6 @@ package com.brainwallet.presenter.entities; -public class BRTransactionEntity { +public class BWDatabaseTransactionEntity { private byte[] buff; private int blockheight; private long timestamp; @@ -30,7 +30,7 @@ public void setTxHash(String txHash) { this.txHash = txHash; } - public BRTransactionEntity(byte[] txBuff, int blockheight, long timestamp, String txHash) { + public BWDatabaseTransactionEntity(byte[] txBuff, int blockheight, long timestamp, String txHash) { this.blockheight = blockheight; this.timestamp = timestamp; this.buff = txBuff; diff --git a/app/src/main/java/com/brainwallet/presenter/entities/TxItem.java b/app/src/main/java/com/brainwallet/presenter/entities/TxItem.java index bd4c749c..acb0836b 100644 --- a/app/src/main/java/com/brainwallet/presenter/entities/TxItem.java +++ b/app/src/main/java/com/brainwallet/presenter/entities/TxItem.java @@ -3,7 +3,12 @@ import com.platform.entities.TxMetaData; +import org.jetbrains.annotations.NotNull; + import java.io.Serializable; +import java.util.UUID; + +import kotlin.Unit; public class TxItem implements Serializable { public static final String TAG = TxItem.class.getName(); @@ -22,6 +27,7 @@ public class TxItem implements Serializable { private int txSize; public TxMetaData metaData; + public UUID id = UUID.randomUUID(); private TxItem() { } diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/BuyTabFragment.java b/app/src/main/java/com/brainwallet/presenter/fragments/BuyTabFragment.java deleted file mode 100644 index feeabfd3..00000000 --- a/app/src/main/java/com/brainwallet/presenter/fragments/BuyTabFragment.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.brainwallet.presenter.fragments; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.brainwallet.R; -import com.brainwallet.tools.manager.AnalyticsManager; -import com.brainwallet.tools.util.BRConstants; - -public class BuyTabFragment extends Fragment { - - private RecyclerView mRecyclerView; - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return null; - } - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - mRecyclerView = view.findViewById(R.id.recycler_view); - mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); - DividerItemDecoration itemDecor = new DividerItemDecoration(mRecyclerView.getContext(), DividerItemDecoration.VERTICAL); - itemDecor.setDrawable(ContextCompat.getDrawable(mRecyclerView.getContext(), R.drawable.divider_white_shape)); - mRecyclerView.addItemDecoration(itemDecor); - AnalyticsManager.logCustomEvent(BRConstants._20191105_DTBT); - } -} diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentBalanceSeedReminder.kt b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentBalanceSeedReminder.kt index dfd7ed25..ec3e9157 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentBalanceSeedReminder.kt +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentBalanceSeedReminder.kt @@ -11,9 +11,8 @@ import com.brainwallet.R import com.brainwallet.tools.animation.BRAnimator import com.brainwallet.tools.manager.AnalyticsManager import com.brainwallet.tools.security.BRKeyStore -import com.brainwallet.tools.util.BRConstants +import com.brainwallet.constants.BWConstants import timber.log.Timber -import java.util.* class FragmentBalanceSeedReminder : Fragment() { private lateinit var backgroundLayout: ScrollView @@ -72,7 +71,7 @@ class FragmentBalanceSeedReminder : Fragment() { Timber.d("Fragment Balance Seed: RegisterError : %s", errorString) val params = Bundle() params.putString("lwa_error_message", errorString) - AnalyticsManager.logCustomEventWithParams(BRConstants._20200112_ERR, params) + AnalyticsManager.logCustomEventWithParams(BWConstants._20200112_ERR, params) } fun fetchSeedPhrase() { seedPhraseTextView.text = "NO_PHRASE" diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentMenu.java b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentMenu.java index 44935669..31143495 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentMenu.java +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentMenu.java @@ -24,7 +24,6 @@ import androidx.browser.customtabs.CustomTabsIntent; import androidx.constraintlayout.widget.ConstraintLayout; -import com.brainwallet.BrainwalletApp; import com.brainwallet.R; import com.brainwallet.presenter.activities.settings.SecurityCenterActivity; import com.brainwallet.presenter.activities.settings.SettingsActivity; @@ -32,7 +31,7 @@ import com.brainwallet.tools.animation.BRAnimator; import com.brainwallet.tools.animation.SlideDetector; import com.brainwallet.tools.manager.AnalyticsManager; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.data.source.RemoteConfigSource; import org.json.JSONObject; @@ -75,8 +74,8 @@ public View onCreateView(LayoutInflater inflater, itemList.add(new BRMenuItem(getString(R.string.MenuButton_support), R.drawable.faq_question_black, v -> { CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); CustomTabsIntent customTabsIntent = builder.build(); - customTabsIntent.launchUrl(getContext(), Uri.parse(BRConstants.WEB_LINK)); - AnalyticsManager.logCustomEvent(BRConstants._20201118_DTGS); + customTabsIntent.launchUrl(getContext(), Uri.parse(BWConstants.WEB_LINK)); + AnalyticsManager.logCustomEvent(BWConstants._20201118_DTGS); })); /* Settings */ diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentPhraseWord.java b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentPhraseWord.java deleted file mode 100644 index f4b4bd63..00000000 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentPhraseWord.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.brainwallet.presenter.fragments; - -import android.app.Fragment; -import android.content.Intent; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import com.brainwallet.R; - -public class FragmentPhraseWord extends Fragment { - private static final String TAG = FragmentPhraseWord.class.getName(); - - @Override - public View onCreateView(LayoutInflater inflater, - ViewGroup container, Bundle savedInstanceState) { - - - View rootView = inflater.inflate(R.layout.fragment_word_item, container, false); - TextView b = (TextView) rootView.findViewById(R.id.word_button); - b.setText(getArguments().getString("text")); - - return rootView; - } - - public static FragmentPhraseWord newInstance(String text) { - - FragmentPhraseWord f = new FragmentPhraseWord(); - Bundle b = new Bundle(); - b.putString("text", text); - - f.setArguments(b); - - return f; - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentPin.java b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentPin.java deleted file mode 100644 index 1d8831b6..00000000 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentPin.java +++ /dev/null @@ -1,208 +0,0 @@ -package com.brainwallet.presenter.fragments; - -import static com.brainwallet.tools.util.BRConstants.BW_PIN_LENGTH; - -import android.app.Activity; -import android.os.Bundle; -import android.os.Handler; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.animation.OvershootInterpolator; -import android.widget.LinearLayout; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import androidx.annotation.Nullable; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.fragment.app.Fragment; - -import com.brainwallet.R; -import com.brainwallet.presenter.activities.BreadActivity; -import com.brainwallet.presenter.customviews.BRKeyboard; -import com.brainwallet.presenter.interfaces.BRAuthCompletion; -import com.brainwallet.tools.animation.DecelerateOvershootInterpolator; -import com.brainwallet.tools.animation.SpringAnimator; -import com.brainwallet.tools.security.AuthManager; -import com.brainwallet.tools.security.BRKeyStore; -import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.Utils; - -import timber.log.Timber; - -public class FragmentPin extends Fragment { - private BRAuthCompletion completion; - - private BRKeyboard keyboard; - private LinearLayout pinLayout; - private View dot1; - private View dot2; - private View dot3; - private View dot4; - private StringBuilder pin = new StringBuilder(); - private int pinLimit = 4; - private TextView title; - private TextView message; - private RelativeLayout dialogLayout; - ConstraintLayout mainLayout; - private boolean authSucceeded; - private String customTitle; - private String customMessage; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_bread_pin, container, false); - keyboard = (BRKeyboard) rootView.findViewById(R.id.brkeyboard); - pinLayout = (LinearLayout) rootView.findViewById(R.id.pinLayout); - - if (BRKeyStore.getPinCode(getContext()).length() == BW_PIN_LENGTH) pinLimit = BW_PIN_LENGTH; - - title = (TextView) rootView.findViewById(R.id.title); - message = (TextView) rootView.findViewById(R.id.message); - dialogLayout = (RelativeLayout) rootView.findViewById(R.id.pin_dialog); - mainLayout = (ConstraintLayout) rootView.findViewById(R.id.activity_pin); - - mainLayout.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - requireActivity().getSupportFragmentManager().beginTransaction().remove(FragmentPin.this).commit(); - } - }); - - dot1 = rootView.findViewById(R.id.dot1); - dot2 = rootView.findViewById(R.id.dot2); - dot3 = rootView.findViewById(R.id.dot3); - dot4 = rootView.findViewById(R.id.dot4); - - keyboard.addOnInsertListener(new BRKeyboard.OnInsertListener() { - @Override - public void onClick(String key) { - handleClick(key); - } - }); - keyboard.setShowDot(false); - - return rootView; - } - - @Override - public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - float keyboardTrY = keyboard.getTranslationY(); - Bundle bundle = getArguments(); - String titleString = bundle.getString("title"); - String messageString = bundle.getString("message"); - if (!Utils.isNullOrEmpty(titleString)) { - customTitle = titleString; - title.setText(customTitle); - } - if (!Utils.isNullOrEmpty(messageString)) { - customMessage = messageString; - message.setText(customMessage); - } - keyboard.setTranslationY(keyboardTrY + BreadActivity.screenParametersPoint.y / 3); - keyboard.animate() - .translationY(keyboardTrY) - .setDuration(400) - .setInterpolator(new DecelerateOvershootInterpolator(2.0f, 1f)) - .withLayer(); - float dialogScaleX = dialogLayout.getScaleX(); - float dialogScaleY = dialogLayout.getScaleY(); - dialogLayout.setScaleX(dialogScaleX / 2); - dialogLayout.setScaleY(dialogScaleY / 2); - dialogLayout.animate() - .scaleY(dialogScaleY) - .scaleX(dialogScaleX) - .setInterpolator(new OvershootInterpolator(2f)); - - } - - @Override - public void onResume() { - super.onResume(); - updateDots(); - authSucceeded = false; - } - - - private void handleClick(String key) { - if (key == null) { - Timber.d("timber: handleClick: key is null! "); - return; - } - - if (key.isEmpty()) { - handleDeleteClick(); - } else if (Character.isDigit(key.charAt(0))) { - handleDigitClick(Integer.parseInt(key.substring(0, 1))); - } else { - Timber.d("timber: handleClick: oops: %s", key); - } - } - - private void handleDigitClick(Integer dig) { - if (pin.length() < pinLimit) - pin.append(dig); - updateDots(); - } - - private void handleDeleteClick() { - if (pin.length() > 0) - pin.deleteCharAt(pin.length() - 1); - updateDots(); - } - - private void updateDots() { - if (dot1 == null) return; - AuthManager.getInstance().updateDots(getActivity(), pinLimit, pin.toString(), dot1, dot2, dot3, dot4, R.drawable.ic_pin_dot_gray, new AuthManager.OnPinSuccess() { - @Override - public void onSuccess() { - if (AuthManager.getInstance().checkAuth(pin.toString(), getContext())) { - handleSuccess(); - } else { - handleFail(); - } - pin = new StringBuilder(); - } - }); - } - - private void handleSuccess() { - BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(100); - } catch (InterruptedException e) { - Timber.e(e); - } - authSucceeded = true; - completion.onComplete(); - Activity app = getActivity(); - AuthManager.getInstance().authSuccess(app); - if (app != null) - app.getFragmentManager().popBackStack(); - } - }); - } - - private void handleFail() { - SpringAnimator.failShakeAnimation(getActivity(), pinLayout); - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - updateDots(); - } - }, 500); - AuthManager.getInstance().authFail(getActivity()); - } - - @Override - public void onStop() { - super.onStop(); - } - - public void setCompletion(BRAuthCompletion completion) { - this.completion = completion; - } -} diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentReceive.java b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentReceive.java index 4d4176fd..c9a184cc 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentReceive.java +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentReceive.java @@ -32,7 +32,7 @@ import com.brainwallet.tools.manager.BRSharedPrefs; import com.brainwallet.tools.qrcode.QRUtils; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.Utils; import com.brainwallet.wallet.BRWalletManager; @@ -94,7 +94,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa signalLayout.removeView(copiedLayout); signalLayout.setLayoutTransition(BRAnimator.getDefaultTransition()); signalLayout.setOnTouchListener(new SlideDetector(signalLayout, this::animateClose)); - AnalyticsManager.logCustomEvent(BRConstants._20202116_VRC); + AnalyticsManager.logCustomEvent(BWConstants._20202116_VRC); return rootView; } diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt index 1e550bca..8a98028a 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentSend.kt @@ -38,10 +38,10 @@ import com.brainwallet.tools.manager.FeeManager import com.brainwallet.tools.security.BRSender import com.brainwallet.tools.security.BitcoinUrlHandler import com.brainwallet.tools.threads.BRExecutor -import com.brainwallet.tools.util.BRConstants import com.brainwallet.tools.util.BRCurrency import com.brainwallet.tools.util.BRExchange import com.brainwallet.tools.util.Utils +import com.brainwallet.constants.BWConstants import com.brainwallet.wallet.BRWalletManager import timber.log.Timber import java.math.BigDecimal @@ -104,7 +104,7 @@ class FragmentSend : Fragment() { // warningText = rootView.findViewById(R.id.warning_text) as TextView closeButton = rootView.findViewById(R.id.close_button) as ImageButton selectedIsoCurrencySymbol = - if (BRSharedPrefs.getPreferredLTC(context)) { + if (BRSharedPrefs.getLTCViewingPreference(context)) { "LTC" } else { BRSharedPrefs.getIsoSymbol( @@ -124,7 +124,7 @@ class FragmentSend : Fragment() { feeText.text = "" signalLayout.setOnTouchListener(SlideDetector(signalLayout) { animateClose() }) - AnalyticsManager.logCustomEvent(BRConstants._20191105_VSC) + AnalyticsManager.logCustomEvent(BWConstants._20191105_VSC) // setupFeesSelector(rootView) // showFeeSelectionButtons(feeButtonsShown) // edit.setOnClickListener { @@ -378,7 +378,7 @@ class FragmentSend : Fragment() { View.OnClickListener { if (!BRAnimator.isClickAllowed()) return@OnClickListener saveMetaData() - BRAnimator.openScanner(activity, BRConstants.SCANNER_REQUEST) + BRAnimator.openScanner(activity, BWConstants.SCANNER_REQUEST) }, ) @@ -422,7 +422,7 @@ class FragmentSend : Fragment() { comment ), ) - AnalyticsManager.logCustomEvent(BRConstants._20191105_DSL) + AnalyticsManager.logCustomEvent(BWConstants._20191105_DSL) BRSharedPrefs.incrementSendTransactionCount(context) } }, diff --git a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentTransactionItem.java b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentTransactionItem.java index 178e6fab..8602f1e6 100644 --- a/app/src/main/java/com/brainwallet/presenter/fragments/FragmentTransactionItem.java +++ b/app/src/main/java/com/brainwallet/presenter/fragments/FragmentTransactionItem.java @@ -1,8 +1,6 @@ package com.brainwallet.presenter.fragments; -import static androidx.core.content.ContextCompat.getSystemService; - import android.content.ClipData; import android.content.ClipboardManager; import android.content.Context; @@ -19,7 +17,6 @@ import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -29,13 +26,12 @@ import com.brainwallet.R; import com.brainwallet.presenter.entities.ServiceItems; import com.brainwallet.presenter.entities.TxItem; -import com.brainwallet.presenter.fragments.FragmentTransactionDetails; import com.brainwallet.tools.animation.BRAnimator; import com.brainwallet.tools.animation.SlideDetector; import com.brainwallet.tools.manager.BRSharedPrefs; import com.brainwallet.tools.manager.TxManager; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.BRCurrency; import com.brainwallet.tools.util.BRExchange; import com.brainwallet.tools.util.Utils; @@ -129,7 +125,7 @@ private void fillTexts() { } //get the current iso - String iso = BRSharedPrefs.getPreferredLTC(getActivity()) ? "LTC" : BRSharedPrefs.getIsoSymbol(getContext()); + String iso = BRSharedPrefs.getLTCViewingPreference(getActivity()) ? "LTC" : BRSharedPrefs.getIsoSymbol(getContext()); long opsAmount = getOpsAmount(); @@ -187,7 +183,7 @@ public void onClick(View v) { mTxHashLink.setOnClickListener(view -> { close(); - String txUrl = BRConstants.BLOCK_EXPLORER_BASE_URL + item.getTxHashHexReversed(); + String txUrl = BWConstants.BLOCKCHAIR_EXPLORER_BASE_URL + item.getTxHashHexReversed(); Timber.d("timber: txUrl = %s", txUrl); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(txUrl)); startActivity(browserIntent); diff --git a/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt b/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt index f097c88f..e6984c05 100644 --- a/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt +++ b/app/src/main/java/com/brainwallet/presenter/history/HistoryFooter.kt @@ -24,7 +24,7 @@ import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.theme.BrainwalletAppTheme import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import com.grunt.brainwallet.core.presentation.util.BaseViewModel import com.grunt.brainwallet.iap.presentation.model.ExportedTransaction import com.grunt.brainwallet.iap.presentation.screen.ExportTrxSheet @@ -86,8 +86,8 @@ fun HistoryFooter( if (showSheet) { ModalBottomSheet( sheetState = sheetState, - containerColor = BrainwalletTheme.colors.surface, - contentColor = BrainwalletTheme.colors.content, + containerColor = DesignTheme.colors.surface, + contentColor = DesignTheme.colors.content, onDismissRequest = onClick ) { ExportTrxSheet( diff --git a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt index 48dfe14d..7f056f09 100644 --- a/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt +++ b/app/src/main/java/com/brainwallet/presenter/history/HistoryFragment.kt @@ -9,12 +9,10 @@ import com.brainwallet.databinding.FragmentHistoryBinding import com.brainwallet.presenter.activities.BreadActivity import com.brainwallet.presenter.base.BaseFragment import com.brainwallet.tools.manager.AnalyticsManager -import com.brainwallet.tools.manager.BRSharedPrefs -import com.brainwallet.tools.manager.BRSharedPrefs.OnIsoChangedListener import com.brainwallet.tools.manager.TxManager import com.brainwallet.tools.sqlite.TransactionDataSource.OnTxAddedListener import com.brainwallet.tools.threads.BRExecutor -import com.brainwallet.tools.util.BRConstants +import com.brainwallet.constants.BWConstants import com.brainwallet.ui.theme.setContentWithTheme import com.brainwallet.wallet.BRPeerManager import com.brainwallet.wallet.BRPeerManager.OnTxStatusUpdate @@ -28,7 +26,6 @@ class HistoryFragment : BaseFragment(), OnBalanceChanged, OnTxStatusUpdate, - OnIsoChangedListener, OnTxAddedListener, HistoryView { lateinit var binding: FragmentHistoryBinding @@ -55,19 +52,17 @@ class HistoryFragment : private fun addObservers() { BRWalletManager.getInstance().addBalanceChangedListener(this) BRPeerManager.getInstance().addStatusUpdateListener(this) - BRSharedPrefs.addIsoChangedListener(this) } private fun removeObservers() { BRWalletManager.getInstance().removeListener(this) BRPeerManager.getInstance().removeListener(this) - BRSharedPrefs.removeListener(this) } private fun registerAnalyticsError(errorString: String) { val params = Bundle() params.putString("lwa_error_message", errorString) - AnalyticsManager.logCustomEventWithParams(BRConstants._20200112_ERR, params) + AnalyticsManager.logCustomEventWithParams(BWConstants._20200112_ERR, params) Timber.d("History Fragment: RegisterError : %s", errorString) } @@ -91,7 +86,7 @@ class HistoryFragment : updateUI() } - override fun onStatusUpdate() { + override fun onStatusPeerManagerUpdate() { BRExecutor.getInstance().forBackgroundTasks().execute { if (this.activity == null) { registerAnalyticsError("null_in_history_fragment_on_status_update") @@ -103,10 +98,6 @@ class HistoryFragment : } } - override fun onIsoChanged(iso: String) { - updateUI() - } - override fun onTxAdded() { BRExecutor.getInstance().forBackgroundTasks().execute { if (this.activity == null) { diff --git a/app/src/main/java/com/brainwallet/presenter/interfaces/BRAuthCompletion.java b/app/src/main/java/com/brainwallet/presenter/interfaces/BRAuthCompletion.java deleted file mode 100644 index c485a67c..00000000 --- a/app/src/main/java/com/brainwallet/presenter/interfaces/BRAuthCompletion.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.brainwallet.presenter.interfaces; - -public interface BRAuthCompletion { - void onComplete(); - void onCancel(); -} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/presenter/interfaces/BROnSignalCompletion.java b/app/src/main/java/com/brainwallet/presenter/interfaces/BROnSignalCompletion.java index 4222606b..3879db4e 100644 --- a/app/src/main/java/com/brainwallet/presenter/interfaces/BROnSignalCompletion.java +++ b/app/src/main/java/com/brainwallet/presenter/interfaces/BROnSignalCompletion.java @@ -1,5 +1,8 @@ package com.brainwallet.presenter.interfaces; +/// To be converted to kotlin +/// cannot currently due to type mismatch +/// kcw-grunt 21 MAR 2026 public interface BROnSignalCompletion { void onComplete(); } diff --git a/app/src/main/java/com/brainwallet/presenter/interfaces/BreadPayment.java b/app/src/main/java/com/brainwallet/presenter/interfaces/BreadPayment.java deleted file mode 100644 index 325bf1ca..00000000 --- a/app/src/main/java/com/brainwallet/presenter/interfaces/BreadPayment.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.brainwallet.presenter.interfaces; - -public interface BreadPayment { - -} diff --git a/app/src/main/java/com/brainwallet/tools/adapter/CurAdapter.java b/app/src/main/java/com/brainwallet/tools/adapter/CurAdapter.java deleted file mode 100644 index 56c08a52..00000000 --- a/app/src/main/java/com/brainwallet/tools/adapter/CurAdapter.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.brainwallet.tools.adapter; - -import static android.widget.Adapter.IGNORE_ITEM_VIEW_TYPE; - -import android.app.Activity; -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.recyclerview.widget.RecyclerView; - -import com.brainwallet.tools.util.BRCurrency; -import com.brainwallet.R; -import com.brainwallet.presenter.customviews.BRButton; - -import java.util.ArrayList; -import java.util.List; - -public class CurAdapter extends RecyclerView.Adapter { - public static final String TAG = CurAdapter.class.getName(); - - private final Context mContext; - private final int layoutResourceId; - private List itemFeed; - - public CurAdapter(Context mContext, List items) { - itemFeed = items; - if (itemFeed == null) itemFeed = new ArrayList<>(); - this.layoutResourceId = R.layout.spinner_item; - this.mContext = mContext; - } - - public String getItemAtPos(int pos) { - return itemFeed.get(pos); - } - - public List getItems() { - return itemFeed; - } - - @Override - public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - // inflate the layout - LayoutInflater inflater = ((Activity) mContext).getLayoutInflater(); - View convertView = inflater.inflate(layoutResourceId, parent, false); - return new CustomViewHolder(convertView); - } - - @Override - public void onBindViewHolder(CustomViewHolder holder, int position) { - setTexts(holder, position); - } - - @Override - public int getItemViewType(int position) { - return IGNORE_ITEM_VIEW_TYPE; - } - - @Override - public int getItemCount() { - return itemFeed.size(); - } - - private void setTexts(CustomViewHolder convertView, int position) { - - String item = itemFeed.get(position); - convertView.button.setText(String.format("%s(%s)", item, BRCurrency.getSymbolByIso(mContext, item))); - - } - - class CustomViewHolder extends RecyclerView.ViewHolder { - public BRButton button; - - public CustomViewHolder(View view) { - super(view); - button = (BRButton) view.findViewById(R.id.watch_list_layout); - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/tools/adapter/TransactionListAdapter.java b/app/src/main/java/com/brainwallet/tools/adapter/TransactionListAdapter.java index bcf7567e..902b25ac 100644 --- a/app/src/main/java/com/brainwallet/tools/adapter/TransactionListAdapter.java +++ b/app/src/main/java/com/brainwallet/tools/adapter/TransactionListAdapter.java @@ -287,7 +287,7 @@ else if (confirms == 3) } long sentLitoshisAmount = received ? item.getReceived() : (item.getSent() - item.getReceived() - opsAmount); - boolean isBTCPreferred = BRSharedPrefs.getPreferredLTC(mContext); + boolean isBTCPreferred = BRSharedPrefs.getLTCViewingPreference(mContext); String iso = isBTCPreferred ? "LTC" : BRSharedPrefs.getIsoSymbol(mContext); convertView.amount.setText(BRCurrency.getFormattedCurrencyString(mContext, iso, BRExchange.getAmountFromLitoshis(mContext, iso, new BigDecimal(sentLitoshisAmount)))); diff --git a/app/src/main/java/com/brainwallet/tools/animation/BRAnimator.java b/app/src/main/java/com/brainwallet/tools/animation/BRAnimator.java index cfddf17b..14cd1ca2 100644 --- a/app/src/main/java/com/brainwallet/tools/animation/BRAnimator.java +++ b/app/src/main/java/com/brainwallet/tools/animation/BRAnimator.java @@ -11,7 +11,6 @@ import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.app.Activity; -import android.app.FragmentTransaction; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; @@ -22,7 +21,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.compose.ui.platform.ComposeView; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.fragment.app.FragmentActivity; @@ -32,14 +30,13 @@ import com.brainwallet.presenter.fragments.FragmentMoonpay; import com.brainwallet.tools.manager.AnalyticsManager; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.R; import com.brainwallet.presenter.activities.BreadActivity; import com.brainwallet.presenter.activities.camera.ScanQRActivity; import com.brainwallet.presenter.customviews.BRDialogView; import com.brainwallet.presenter.entities.TxItem; import com.brainwallet.presenter.fragments.FragmentBalanceSeedReminder; -import com.brainwallet.presenter.fragments.FragmentMenu; import com.brainwallet.presenter.fragments.FragmentReceive; import com.brainwallet.presenter.fragments.FragmentSend; import com.brainwallet.presenter.fragments.FragmentSignal; @@ -86,7 +83,7 @@ public static void showBreadSignal(@NonNull FragmentActivity activity, transaction.commit(); } catch (IllegalStateException e) { transaction.commitAllowingStateLoss(); - AnalyticsManager.logCustomEvent(BRConstants._20200112_ERR); + AnalyticsManager.logCustomEvent(BWConstants._20200112_ERR); } } @@ -174,7 +171,11 @@ public static void openScanner(Activity app, int requestID) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(app, Manifest.permission.CAMERA)) { - BRDialog.showCustomDialog(app, app.getString(R.string.Send_cameraUnavailabeTitle_android), app.getString(R.string.Send_cameraUnavailabeMessage_android), app.getString(R.string.AccessibilityLabels_close), null, new BRDialogView.BROnClickListener() { + BRDialog.showCustomDialog(app, + app.getString(R.string.Send_cameraUnavailabeTitle_android), + app.getString(R.string.Send_cameraUnavailabeMessage_android), + app.getString(R.string.AccessibilityLabels_close), + null, new BRDialogView.BROnClickListener() { @Override public void onClick(BRDialogView brDialogView) { brDialogView.dismiss(); @@ -184,7 +185,7 @@ public void onClick(BRDialogView brDialogView) { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(app, new String[]{Manifest.permission.CAMERA}, - BRConstants.CAMERA_REQUEST_ID); + BWConstants.CAMERA_REQUEST_ID); } } else { // Permission is granted, open camera @@ -293,7 +294,7 @@ public static void startBreadIfNotStarted(Activity app) { * wrap using [com.brainwallet.navigation.LegacyNavigation.startBreadActivity] */ public static void startBreadActivity(Activity from, boolean auth) { - LegacyNavigation.startBreadActivity(from, auth); + LegacyNavigation.startBrainwalletActivity(from, auth); } public static void animateSignalSlide(ViewGroup signalLayout, final boolean reverse, @Nullable final OnSlideAnimationEnd listener) { diff --git a/app/src/main/java/com/brainwallet/tools/listeners/SyncReceiver.java b/app/src/main/java/com/brainwallet/tools/listeners/SyncReceiver.java index 61b67c2e..92383e93 100644 --- a/app/src/main/java/com/brainwallet/tools/listeners/SyncReceiver.java +++ b/app/src/main/java/com/brainwallet/tools/listeners/SyncReceiver.java @@ -4,7 +4,7 @@ import android.content.Context; import android.content.Intent; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.wallet.BRWalletManager; public class SyncReceiver extends IntentService { @@ -14,7 +14,7 @@ public class SyncReceiver extends IntentService { // private Calendar c = Calendar.getInstance(); static { - System.loadLibrary(BRConstants.NATIVE_LIB_NAME); + System.loadLibrary(BWConstants.NATIVE_LIB_NAME); } public SyncReceiver() { diff --git a/app/src/main/java/com/brainwallet/tools/manager/AnalyticsManager.java b/app/src/main/java/com/brainwallet/tools/manager/AnalyticsManager.java index 60bd5138..9b05afc0 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/AnalyticsManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/AnalyticsManager.java @@ -3,7 +3,7 @@ import android.content.Context; import android.os.Bundle; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.google.firebase.analytics.FirebaseAnalytics; public final class AnalyticsManager { @@ -18,12 +18,17 @@ public static void init(Context context) { instance = FirebaseAnalytics.getInstance(context); } - public static Object logCustomEvent(@BRConstants.Event String customEvent) { + public static Object logCustomEvent(@BWConstants.Event String customEvent) { instance.logEvent(customEvent, null); return null; } - public static void logCustomEventWithParams(@BRConstants.Event String customEvent, Bundle params) { + public static Object logQuickEvent(String quickEvent, Bundle params) { + instance.logEvent(quickEvent, params); + return null; + } + + public static void logCustomEventWithParams(@BWConstants.Event String customEvent, Bundle params) { instance.logEvent(customEvent, params); } } diff --git a/app/src/main/java/com/brainwallet/tools/manager/BRSharedPrefs.java b/app/src/main/java/com/brainwallet/tools/manager/BRSharedPrefs.java index 6fd054b9..e918e132 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/BRSharedPrefs.java +++ b/app/src/main/java/com/brainwallet/tools/manager/BRSharedPrefs.java @@ -3,11 +3,11 @@ import android.content.Context; import android.content.SharedPreferences; -import android.util.Log; - +import com.brainwallet.data.model.LtcStats; import com.brainwallet.data.repository.SettingRepository; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; +import org.koin.core.annotation.Single; import org.koin.java.KoinJavaComponent; import java.text.SimpleDateFormat; @@ -18,26 +18,12 @@ import java.util.Locale; import timber.log.Timber; - +@Single public class BRSharedPrefs { - - private static final List isoChangedListeners = new ArrayList<>(); public static final String SEND_TRANSACTION_COUNT = "send_transaction_count"; public static final String IN_APP_REVIEW_DONE = "in_app_review_done"; public static final String PREFERRED_FPRATE = "preferredFalsePositiveRate"; - public interface OnIsoChangedListener { - void onIsoChanged(String iso); - } - - public static void addIsoChangedListener(OnIsoChangedListener listener) { - if (isoChangedListeners.contains(listener)) return; - isoChangedListeners.add(listener); - } - - public static void removeListener(OnIsoChangedListener listener) { - isoChangedListeners.remove(listener); - } public static String getIsoSymbol(Context context) { SharedPreferences settingsToGet = KoinJavaComponent.get(SharedPreferences.class); @@ -64,345 +50,344 @@ public static void putIso(Context context, String code) { SharedPreferences.Editor editor = settings.edit(); editor.putString(SettingRepository.KEY_FIAT_CURRENCY_CODE, code); //using new shared prefs used by setting repository editor.apply(); - - notifyIsoChanged(code); } - public static void notifyIsoChanged(String iso) { - for (OnIsoChangedListener listener : isoChangedListeners) { - if (listener != null) listener.onIsoChanged(iso); - } - } /// /////////////////////////////////////////////////////////////////////////// /// ///////////////// Active Shared Preferences /////////////////////////////// - public static void putStartSyncTimestamp(Context context, long time) { - if (context == null) { - Log.e("BRSharedPrefs", "Context is null in putStartSyncTimestamp!"); - return; - } - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - editor.putLong("startSyncTime", time); - editor.apply(); + ////// Start Sync Timestamp /////////// + public static void putStartSyncTimestamp(long time) { + SharedPreferences prefs = KoinJavaComponent.get(SharedPreferences.class); + prefs.edit().putLong("startSyncTime", time).apply(); } - - public static long getStartSyncTimestamp(Context context) { - if (context == null) { - Log.e("BRSharedPrefs", "Context is null in getStartSyncTimestamp!"); - } - SharedPreferences startSyncTime = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return startSyncTime.getLong("startSyncTime", System.currentTimeMillis()); + public static long getStartSyncTimestamp() { + SharedPreferences prefs = KoinJavaComponent.get(SharedPreferences.class); + return prefs.getLong("startSyncTime", System.currentTimeMillis()); } - public static void putEndSyncTimestamp(Context context, long time) { - - if (context == null) { - Log.e("BRSharedPrefs", "Context is null in putEndSyncTimestamp!"); - return; - } - - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - editor.putLong("endSyncTime", time); - editor.apply(); + ////// End Sync Timestamp /////////// + public static void putEndSyncTimestamp(long time) { + SharedPreferences prefs = KoinJavaComponent.get(SharedPreferences.class); + prefs.edit().putLong("endSyncTime", time).apply(); } - - public static String getSyncMetadata(Context context) { - SharedPreferences syncMetadata = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return syncMetadata.getString("syncMetadata", " No Sync Duration metadata"); + public static long getEndSyncTimestamp() { + SharedPreferences prefs = KoinJavaComponent.get(SharedPreferences.class); + return prefs.getLong("endSyncTime", System.currentTimeMillis()); } - public static void putSyncMetadata(Context activity, long startSyncTime, long endSyncTime) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, 0); - SharedPreferences.Editor editor = prefs.edit(); - + ////// Sync Metadata /////////// + public static void putSyncMetadata(long startSyncTime, long endSyncTime) { + SharedPreferences prefs = KoinJavaComponent.get(SharedPreferences.class); double syncDuration = (double) (endSyncTime - startSyncTime) / 1_000.0 / 60.0; - SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm"); + SimpleDateFormat sdf = new SimpleDateFormat("MMM dd HH:mm", + Locale.getDefault()); Date startDate = new Date(startSyncTime); Date endDate = new Date(endSyncTime); - - String formattedMetadata = String.format("Duration: %3.2f mins\nStarted: %d (%s)\nEnded: %d (%s)", syncDuration, startSyncTime, sdf.format(startDate), endSyncTime, sdf.format(endDate)); - editor.putString("syncMetadata", formattedMetadata); - editor.apply(); + String formattedMetadata = String.format(Locale.getDefault(), + "Duration: %3.2f mins\nStarted: %d (%s)\nEnded: %d (%s)", + syncDuration, + startSyncTime, sdf.format(startDate), + endSyncTime, sdf.format(endDate)); + prefs.edit().putString("syncMetadata", formattedMetadata).apply(); } - - public static long getEndSyncTimestamp(Context context) { - SharedPreferences endSyncTime = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return endSyncTime.getLong("endSyncTime", System.currentTimeMillis()); + public static String getSyncMetadata(Context context) { + SharedPreferences syncMetadata = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); + return syncMetadata.getString("syncMetadata", " No Sync Duration metadata"); } + public static boolean getPhraseWroteDown(Context context) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return prefs.getBoolean(BRConstants.PHRASE_WRITTEN, false); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getBoolean(BWConstants.PHRASE_WRITTEN, false); } public static void putPhraseWroteDown(Context context, boolean check) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(BRConstants.PHRASE_WRITTEN, check); + editor.putBoolean(BWConstants.PHRASE_WRITTEN, check); editor.apply(); } public static int getCurrencyListPosition(Context context) { - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); - return settings.getInt(BRConstants.POSITION, 0); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); + return settings.getInt(BWConstants.POSITION, 0); } public static void putCurrencyListPosition(Context context, int lastItemsPosition) { - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); - editor.putInt(BRConstants.POSITION, lastItemsPosition); + editor.putInt(BWConstants.POSITION, lastItemsPosition); editor.apply(); } public static String getReceiveAddress(Context context) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return prefs.getString(BRConstants.RECEIVE_ADDRESS, ""); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getString(BWConstants.RECEIVE_ADDRESS, ""); } public static void putReceiveAddress(Context ctx, String tmpAddr) { - SharedPreferences.Editor editor = ctx.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE).edit(); - editor.putString(BRConstants.RECEIVE_ADDRESS, tmpAddr); + SharedPreferences.Editor editor = ctx.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE).edit(); + editor.putString(BWConstants.RECEIVE_ADDRESS, tmpAddr); editor.apply(); } public static String getFirstAddress(Context context) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return prefs.getString(BRConstants.FIRST_ADDRESS, ""); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getString(BWConstants.FIRST_ADDRESS, ""); } public static void putFirstAddress(Context context, String firstAddress) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); - editor.putString(BRConstants.FIRST_ADDRESS, firstAddress); + editor.putString(BWConstants.FIRST_ADDRESS, firstAddress); editor.apply(); } - public static long getCatchedBalance(Context context) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + public static long getCachedBalance(Context context) { + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); return prefs.getLong("balance", 0); } - public static void putCatchedBalance(Context context, long fee) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + public static void putCachedBalance(Context context, long amount) { + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); - editor.putLong("balance", fee); + editor.putLong("balance", amount); editor.apply(); } public static long getSecureTime(Context activity) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return prefs.getLong(BRConstants.SECURE_TIME_PREFS, System.currentTimeMillis() / 1000); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getLong(BWConstants.SECURE_TIME_PREFS, System.currentTimeMillis() / 1000); } //secure time from the server public static void putSecureTime(Context activity, long date) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); - editor.putLong(BRConstants.SECURE_TIME_PREFS, date); + editor.putLong(BWConstants.SECURE_TIME_PREFS, date); editor.apply(); } public static long getFeeTime(Context activity) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); return prefs.getLong("feeTime", 0); } public static void putFeeTime(Context activity, long feeTime) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putLong("feeTime", feeTime); editor.apply(); } public static boolean getAllowSpend(Context activity) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); - return prefs.getBoolean(BRConstants.ALLOW_SPEND, true); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); + return prefs.getBoolean(BWConstants.ALLOW_SPEND, true); } public static void putAllowSpend(Context activity, boolean allow) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(BRConstants.ALLOW_SPEND, allow); + editor.putBoolean(BWConstants.ALLOW_SPEND, allow); editor.apply(); } - //if the user prefers all in litecoin units, not other currencies - public static boolean getPreferredLTC(Context activity) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + //if the user prefers all in litecoin units, versus the preferred fiat currency + public static boolean getLTCViewingPreference(Context activity) { + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); return prefs.getBoolean("priceSetToLitecoin", true); } - //if the user prefers all in litecoin units, not other currencies - public static void putPreferredLTC(Context activity, boolean b) { + //if the user prefers all in litecoin units, versus the preferred fiat currency + public static void putLTCViewingPreference(Context activity, boolean b) { Timber.d("timber: putPreferredLTC: %s", b); - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean("priceSetToLitecoin", b); editor.apply(); } - //if the user prefers all in litecoin units, not other currencies + //if the user prefers to authenticate with biometrics public static boolean getUseFingerprint(Context activity) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); return prefs.getBoolean("useFingerprint", false); } - //if the user prefers all in litecoin units, not other currencies + //if the user prefers to authenticate with biometrics public static void putUseFingerprint(Context activity, boolean use) { - SharedPreferences prefs = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean("useFingerprint", use); editor.apply(); } public static int getStartHeight(Context context) { - SharedPreferences settingsToGet = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); - return settingsToGet.getInt(BRConstants.START_HEIGHT, 0); + SharedPreferences settingsToGet = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); + return settingsToGet.getInt(BWConstants.START_HEIGHT, 0); } public static void putStartHeight(Context context, int startHeight) { if (context == null) return; - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); - editor.putInt(BRConstants.START_HEIGHT, startHeight); + editor.putInt(BWConstants.START_HEIGHT, startHeight); editor.apply(); } - public static int getLastBlockHeight(Context context) { - SharedPreferences settingsToGet = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); - return settingsToGet.getInt(BRConstants.LAST_BLOCK_HEIGHT, 0); + SharedPreferences settingsToGet = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); + return settingsToGet.getInt(BWConstants.LAST_BLOCK_HEIGHT, 0); + } + public static void putLiveLtcStats(Context context, + int ltcBlockHeight, + int mempoolTransactions, + int mempoolSize, + int transactionsOver24H) { + SharedPreferences.Editor editor = context + .getSharedPreferences(BWConstants.PREFS_NAME, 0) + .edit(); + editor.putInt(BWConstants.LTC_STATS_BLOCK_HEIGHT, ltcBlockHeight); + editor.putInt(BWConstants.LTC_STATS_MEMPOOL_TRANSACTIONS, mempoolTransactions); + editor.putInt(BWConstants.LTC_STATS_MEMPOOL_SIZE, mempoolSize); + editor.putInt(BWConstants.LTC_STATS_TRANSACTIONS_OVER_24H, transactionsOver24H); + editor.apply(); + } + public static LtcStats getLiveLtcStats(Context context) { + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); + return new LtcStats( + prefs.getInt(BWConstants.LTC_STATS_BLOCK_HEIGHT, 0), + prefs.getInt(BWConstants.LTC_STATS_MEMPOOL_TRANSACTIONS, 0), + prefs.getInt(BWConstants.LTC_STATS_MEMPOOL_SIZE, 0), + prefs.getInt(BWConstants.LTC_STATS_TRANSACTIONS_OVER_24H, 0) + ); } - public static void putLastBlockHeight(Context context, int lastHeight) { if (context == null) return; - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); - editor.putInt(BRConstants.LAST_BLOCK_HEIGHT, lastHeight); + editor.putInt(BWConstants.LAST_BLOCK_HEIGHT, lastHeight); editor.apply(); } public static boolean getScanRecommended(Context context) { - SharedPreferences settingsToGet = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); + SharedPreferences settingsToGet = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); return settingsToGet.getBoolean("scanRecommended", false); } public static void putScanRecommended(Context context, boolean recommended) { if (context == null) return; - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("scanRecommended", recommended); editor.apply(); } public static int getCurrencyUnit(Context context) { - SharedPreferences settingsToGet = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); - return settingsToGet.getInt(BRConstants.CURRENT_UNIT, BRConstants.CURRENT_UNIT_LITECOINS); + SharedPreferences settingsToGet = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); + return settingsToGet.getInt(BWConstants.CURRENT_UNIT, BWConstants.CURRENT_UNIT_LITECOINS); } public static void putCurrencyUnit(Context context, int unit) { if (context == null) return; - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); - editor.putInt(BRConstants.CURRENT_UNIT, unit); + editor.putInt(BWConstants.CURRENT_UNIT, unit); editor.apply(); } private static void setDeviceId(Context context, String uuid) { if (context == null) return; - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, 0); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, 0); SharedPreferences.Editor editor = settings.edit(); - editor.putString(BRConstants.USER_ID, uuid); + editor.putString(BWConstants.USER_ID, uuid); editor.apply(); } public static void clearAllPrefs(Context activity) { - SharedPreferences.Editor editor = activity.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE).edit(); + SharedPreferences.Editor editor = activity.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE).edit(); editor.clear(); editor.apply(); } public static boolean getShowNotification(Context context) { - SharedPreferences settingsToGet = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences settingsToGet = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); return settingsToGet.getBoolean("showNotification", false); } public static void putShowNotification(Context context, boolean show) { if (context == null) return; - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("showNotification", show); editor.apply(); } public static boolean getShareData(Context context) { - SharedPreferences settingsToGet = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences settingsToGet = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); return settingsToGet.getBoolean("shareData", false); } public static void putShareData(Context context, boolean show) { if (context == null) return; - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("shareData", show); editor.apply(); } public static boolean getShareDataDismissed(Context context) { - SharedPreferences settingsToGet = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences settingsToGet = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); return settingsToGet.getBoolean("shareDataDismissed", false); } public static void putShareDataDismissed(Context context, boolean dismissed) { if (context == null) return; - SharedPreferences settings = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences settings = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = settings.edit(); editor.putBoolean("shareDataDismissed", dismissed); editor.apply(); } public static String getTrustNode(Context context) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); return prefs.getString("trustNode", ""); } public static void putTrustNode(Context context, String trustNode) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putString("trustNode", trustNode); editor.apply(); } public static void incrementSendTransactionCount(Context context) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); int currentTransactions = prefs.getInt(SEND_TRANSACTION_COUNT, 0); prefs.edit().putInt(SEND_TRANSACTION_COUNT, currentTransactions + 1).apply(); } public static int getSendTransactionCount(Context context) { - return context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE) + return context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE) .getInt(SEND_TRANSACTION_COUNT, 0); } public static boolean isInAppReviewDone(Context context) { - return context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE) + return context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE) .getBoolean(IN_APP_REVIEW_DONE, false); } public static void inAppReviewDone(Context context) { - context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE) + context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE) .edit().putBoolean(IN_APP_REVIEW_DONE, true).apply(); } public static float getFalsePositivesRate(Context context) { - return context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE).getFloat(PREFERRED_FPRATE, BRConstants.FALSE_POS_RATE_LOW_PRIVACY); + return context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE).getFloat(PREFERRED_FPRATE, BWConstants.FALSE_POS_RATE_LOW_PRIVACY); } public static void putFalsePositivesRate(Context context, float preferredRate) { - SharedPreferences prefs = context.getSharedPreferences(BRConstants.PREFS_NAME, Context.MODE_PRIVATE); + SharedPreferences prefs = context.getSharedPreferences(BWConstants.PREFS_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = prefs.edit(); editor.putFloat(PREFERRED_FPRATE, preferredRate); editor.apply(); diff --git a/app/src/main/java/com/brainwallet/tools/manager/InternetManager.java b/app/src/main/java/com/brainwallet/tools/manager/InternetManager.java index da74ff0b..582e9b2a 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/InternetManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/InternetManager.java @@ -34,6 +34,9 @@ public static void addConnectionListener(ConnectionReceiverListener listener) { if (!connectionReceiverListeners.contains(listener)) connectionReceiverListeners.add(listener); } + public static void removeConnectionListener(ConnectionReceiverListener listener) { + connectionReceiverListeners.remove(listener); + } @Override public void onReceive(final Context context, final Intent intent) { boolean connected = false; diff --git a/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java b/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java index 6eed34f7..3f73359e 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/PromptManager.java @@ -2,14 +2,13 @@ import static com.brainwallet.tools.manager.PromptManager.PromptItem.RECOMMEND_RESCAN; import static com.brainwallet.tools.manager.PromptManager.PromptItem.UPGRADE_PIN; -import static com.brainwallet.tools.util.BRConstants.BW_PIN_LENGTH; +import static com.brainwallet.constants.BWConstants.BW_PIN_LENGTH; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.view.View; -import com.brainwallet.presenter.activities.settings.SyncBlockchainActivity; import com.brainwallet.tools.security.BRKeyStore; import com.brainwallet.tools.threads.BRExecutor; import com.brainwallet.R; diff --git a/app/src/main/java/com/brainwallet/tools/manager/TxManager.java b/app/src/main/java/com/brainwallet/tools/manager/TxManager.java index e54395d3..c8739878 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/TxManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/TxManager.java @@ -44,6 +44,10 @@ public static TxManager getInstance() { return instance; } + public void init(final BreadActivity app) { + init(app, null); + } + public void init(final BreadActivity app, RecyclerView recyclerView) { txList = recyclerView; txList.setLayoutManager(new CustomLinearLayoutManager(app)); diff --git a/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java b/app/src/main/java/com/brainwallet/tools/manager/sync/SyncManager.java similarity index 67% rename from app/src/main/java/com/brainwallet/tools/manager/SyncManager.java rename to app/src/main/java/com/brainwallet/tools/manager/sync/SyncManager.java index c33fc2c5..ec2f6243 100644 --- a/app/src/main/java/com/brainwallet/tools/manager/SyncManager.java +++ b/app/src/main/java/com/brainwallet/tools/manager/sync/SyncManager.java @@ -1,6 +1,5 @@ -package com.brainwallet.tools.manager; +package com.brainwallet.tools.manager.sync; -import static com.brainwallet.data.source.RemoteConfigSource.KEY_FEATURE_SELECTED_PEERS_ENABLED; import static com.brainwallet.tools.manager.BRSharedPrefs.putSyncMetadata; import android.app.AlarmManager; @@ -8,12 +7,12 @@ import android.content.Context; import android.content.Intent; import android.os.Build; -import android.os.Bundle; import com.brainwallet.data.repository.SyncAnalyticsRepository; -import com.brainwallet.data.source.RemoteConfigSource; import com.brainwallet.tools.listeners.SyncReceiver; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.tools.manager.BRSharedPrefs; +import com.brainwallet.tools.manager.PromptManager; +import com.brainwallet.tools.manager.TxManager; import com.brainwallet.tools.util.Utils; import com.brainwallet.R; import com.brainwallet.presenter.activities.BreadActivity; @@ -123,7 +122,7 @@ public void run() { long runTimeStamp = System.currentTimeMillis(); Timber.d("timber: run: starting: %s date: %d", progressStatus, runTimeStamp); ///Set StartSync - BRSharedPrefs.putStartSyncTimestamp(app, runTimeStamp); + BRSharedPrefs.putStartSyncTimestamp(runTimeStamp); if (app != null) { final long lastBlockTimeStamp = BRPeerManager.getInstance().getLastBlockTimestamp() * 1000; @@ -142,37 +141,9 @@ public void run() { while (running) { if (app != null) { - int startHeight = BRSharedPrefs.getStartHeight(app); - progressStatus = BRPeerManager.syncProgress(startHeight); - if (progressStatus == 1) { - running = false; - /// Record sync time - long startTimeStamp = BRSharedPrefs.getStartSyncTimestamp(app); - long endSyncTimeStamp = System.currentTimeMillis(); - BRSharedPrefs.putEndSyncTimestamp(app, endSyncTimeStamp); - - double syncDuration = (double) (endSyncTimeStamp - startTimeStamp) / 1_000.0 / 60.0; - /// only update if the sync duration is longer than 2 mins - if (syncDuration > 2.0) { - putSyncMetadata(app, startTimeStamp, endSyncTimeStamp); - } - continue; - } - final long lastBlockTimeStamp = BRPeerManager.getInstance().getLastBlockTimestamp() * 1000; - final int currentBlockHeight = BRPeerManager.getCurrentBlockHeight(); app.runOnUiThread(new Runnable() { @Override public void run() { - if (TxManager.getInstance().currentPrompt != PromptManager.PromptItem.SYNCING) { - Timber.d("timber: run: currentPrompt != SYNCING, showPrompt(SYNCING) ...."); - TxManager.getInstance().showPrompt(app, PromptManager.PromptItem.SYNCING); - } - if (TxManager.getInstance().syncingProgressViewHolder != null) { - TxManager.getInstance().syncingProgressViewHolder.progress.setProgress((int) (progressStatus * 100)); - TxManager.getInstance().syncingProgressViewHolder.date.setText(Utils.formatTimeStamp(lastBlockTimeStamp, "MMM. dd, yyyy ha")); - String progressString = String.format("%3.2f%%", progressStatus * 100); - TxManager.getInstance().syncingProgressViewHolder.label.setText(String.format("%s %s - %d",BreadActivity.getApp().getString(R.string.SyncingView_header),progressString, currentBlockHeight)); - } } }); @@ -180,11 +151,6 @@ public void run() { app = BreadActivity.getApp(); } - ///DEV: kcw-grunt 26-10-24 - /// DUMB sleep was slowing sync dramatically - /// Why is this here? - /// Reduced it from 500msec to 100msec until refactor - /// Poor control flow, loop should continue for the next task try { Thread.sleep(100); } catch (InterruptedException e) { @@ -199,7 +165,7 @@ public void run() { app.runOnUiThread(new Runnable() { @Override public void run() { - TxManager.getInstance().hidePrompt(app, PromptManager.PromptItem.SYNCING); + //Old Message: TxManager.getInstance().hidePrompt(app, PromptManager.PromptItem.SYNCING); } }); } diff --git a/app/src/main/java/com/brainwallet/tools/manager/sync/SyncThreadManager.kt b/app/src/main/java/com/brainwallet/tools/manager/sync/SyncThreadManager.kt new file mode 100644 index 00000000..aa8abfbd --- /dev/null +++ b/app/src/main/java/com/brainwallet/tools/manager/sync/SyncThreadManager.kt @@ -0,0 +1,102 @@ +package com.brainwallet.tools.manager.sync + +import com.brainwallet.data.repository.SyncAnalyticsRepository +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.manager.BRSharedPrefs.putEndSyncTimestamp +import com.brainwallet.tools.manager.BRSharedPrefs.putStartSyncTimestamp +import com.brainwallet.tools.manager.BRSharedPrefs.putSyncMetadata +import com.brainwallet.wallet.BRPeerManager +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import org.koin.core.annotation.Single +import org.koin.java.KoinJavaComponent +import timber.log.Timber +import kotlin.coroutines.cancellation.CancellationException + +@Single +class SyncThreadManager( + private val syncAnalyticsRepository: SyncAnalyticsRepository, + private val sharedPrefs: BRSharedPrefs, +) { + private val _syncState = MutableStateFlow(SyncState.Idle) + val syncState: StateFlow = _syncState.asStateFlow() + + private var syncJob: Job? = null + private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) + + sealed class SyncState { + data object Idle : SyncState() + data class Syncing( + val progress: Float, + val lastBlockTimestamp: Long, + val currentBlockHeight: Int, + ) : SyncState() + data object Complete : SyncState() + } + + fun startSyncing(startHeight: Int) { + if (syncJob?.isActive == true) return + + syncJob = scope.launch(Dispatchers.IO) { + val runTimestamp = System.currentTimeMillis() + putStartSyncTimestamp(runTimestamp) + syncAnalyticsRepository.startSync() + + try { + while (isActive) { + val progress = BRPeerManager.syncProgress(startHeight).toFloat() + val lastBlockTimestamp = BRPeerManager.getInstance().getLastBlockTimestamp() * 1000L + val currentBlockHeight = BRPeerManager.getCurrentBlockHeight() + + if (progress >= 1f) { + val endTimestamp = System.currentTimeMillis() + putEndSyncTimestamp(endTimestamp) + + val durationMinutes = (endTimestamp - runTimestamp) / 1_000.0 / 60.0 + if (durationMinutes > 2.0) { + putSyncMetadata(runTimestamp, endTimestamp) + } + _syncState.value = SyncState.Complete + syncAnalyticsRepository.completeSync() + break + } + + _syncState.value = SyncState.Syncing( + progress = progress, + lastBlockTimestamp = lastBlockTimestamp, + currentBlockHeight = currentBlockHeight, + ) + + delay(100) + } + } catch (e: CancellationException) { + Timber.d("SyncManager: job cancelled") + throw e + } finally { + if (_syncState.value !is SyncState.Complete) { + syncAnalyticsRepository.stopSync() + _syncState.value = SyncState.Idle + } + } + } + } + + fun stopSyncing() { + syncJob?.cancel() + syncJob = null + } + + companion object { + @JvmStatic + fun getInstance(): SyncThreadManager = KoinJavaComponent + .get(SyncThreadManager::class.java) + } +} diff --git a/app/src/main/java/com/brainwallet/tools/security/AuthManager.java b/app/src/main/java/com/brainwallet/tools/security/AuthManager.java index 1eda80a4..e23e5b46 100644 --- a/app/src/main/java/com/brainwallet/tools/security/AuthManager.java +++ b/app/src/main/java/com/brainwallet/tools/security/AuthManager.java @@ -68,10 +68,6 @@ public void run() { BRKeyStore.putLastPinUsedTime(System.currentTimeMillis(), app); } - public void authFail(Context app) { - //TODO: Check if this cruft from the BRD implementation - } - public boolean isWalletDisabled(Activity app) { int failCount = BRKeyStore.getFailCount(app); return failCount >= 3 && disabledUntil(app) > BRSharedPrefs.getSecureTime(app); diff --git a/app/src/main/java/com/brainwallet/tools/security/BRKeyStore.java b/app/src/main/java/com/brainwallet/tools/security/BRKeyStore.java index c76bb892..10f76aa9 100644 --- a/app/src/main/java/com/brainwallet/tools/security/BRKeyStore.java +++ b/app/src/main/java/com/brainwallet/tools/security/BRKeyStore.java @@ -49,6 +49,7 @@ import java.security.NoSuchProviderException; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; @@ -67,7 +68,7 @@ import timber.log.Timber; //TODO: [yuana] please migrate the caller using [KeyStoreManager] -@Deprecated + public class BRKeyStore { public static final String KEY_STORE_PREFS_NAME = "keyStorePrefs"; @@ -297,17 +298,58 @@ public synchronized static String getCanary(final Context context, int requestCo } return result; } - public synchronized static boolean putMasterPublicKey(byte[] masterPubKey, Context context) { + if (masterPubKey == null || masterPubKey.length == 0) { + Timber.e("putMasterPublicKey: called with null or empty key"); + return false; + } AliasObject obj = aliasObjectMap.get(PUB_KEY_ALIAS); try { - return masterPubKey != null && masterPubKey.length != 0 && _setData(context, masterPubKey, obj.alias, obj.datafileName, obj.ivFileName, 0, false); + boolean wrote = _setData(context, masterPubKey, obj.alias, obj.datafileName, obj.ivFileName, 0, false); + if (!wrote) { + Timber.e("putMasterPublicKey: _setData returned false"); + FirebaseCrashlytics.getInstance().recordException( + new RuntimeException("putMasterPublicKey: _setData returned false") + ); + return false; + } + // verify the write + byte[] readBack = _getData(context, obj.alias, obj.datafileName, obj.ivFileName, 0); + if (!Arrays.equals(masterPubKey, readBack)) { + Timber.e("putMasterPublicKey: read-back verification failed"); + FirebaseCrashlytics.getInstance().recordException( + new RuntimeException("putMasterPublicKey: read-back mismatch") + ); + return false; + } + Timber.d("putMasterPublicKey: verified write OK (%d bytes)", masterPubKey.length); + return true; } catch (UserNotAuthenticatedException e) { - Timber.e(e); + Timber.e(e, "putMasterPublicKey: unexpected auth exception"); + return false; + } + } + + public synchronized static boolean putMasterPublicKeyWithRetry(byte[] masterPubKey, Context context) { + final int MAX_ATTEMPTS = 3; + for (int attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) { + boolean success = putMasterPublicKey(masterPubKey, context); + if (success) { + Timber.d("putMasterPublicKey: succeeded on attempt %d", attempt); + return true; + } + Timber.w("putMasterPublicKey: attempt %d failed, retrying...", attempt); + try { Thread.sleep(80L * attempt); } catch (InterruptedException ignored) {} } + Timber.e("putMasterPublicKey: all %d attempts failed", MAX_ATTEMPTS); + FirebaseCrashlytics.getInstance().recordException( + new RuntimeException("putMasterPublicKey: failed after " + MAX_ATTEMPTS + " attempts") + ); return false; } + + public synchronized static byte[] getMasterPublicKey(final Context context) { AliasObject obj = aliasObjectMap.get(PUB_KEY_ALIAS); try { diff --git a/app/src/main/java/com/brainwallet/tools/security/BRSender.java b/app/src/main/java/com/brainwallet/tools/security/BRSender.java index 78984db5..b9246d34 100644 --- a/app/src/main/java/com/brainwallet/tools/security/BRSender.java +++ b/app/src/main/java/com/brainwallet/tools/security/BRSender.java @@ -2,16 +2,15 @@ import android.app.Activity; import android.content.Context; - +import android.content.ContextWrapper; import androidx.fragment.app.FragmentActivity; - import com.brainwallet.tools.animation.BRAnimator; import com.brainwallet.tools.animation.BRDialog; import com.brainwallet.tools.manager.AnalyticsManager; import com.brainwallet.tools.manager.BRSharedPrefs; import com.brainwallet.tools.manager.FeeManager; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.BRCurrency; import com.brainwallet.tools.util.BRExchange; import com.brainwallet.tools.util.Utils; @@ -71,7 +70,7 @@ public void run() { if (time <= 0 || now - time >= FEE_EXPIRATION_MILLIS) { Timber.d("timber: sendTransaction: fee out of date even after fetching..."); - AnalyticsManager.logCustomEvent(BRConstants._20200111_FNI); + AnalyticsManager.logCustomEvent(BWConstants._20200111_FNI); throw new FeeOutOfDate(time, now); } @@ -87,13 +86,18 @@ public void run() { long minAmount = BRWalletManager.getInstance().getMinOutputAmountRequested(); errTitle[0] = app.getString(R.string.Alerts_sendFailure); errMessage[0] = String.format(Locale.getDefault(), app.getString(R.string.PaymentProtocol_Errors_smallPayment), - BRConstants.litecoinLowercase + new BigDecimal(minAmount).divide(new BigDecimal(100), BRConstants.ROUNDING_MODE)); + BWConstants.litecoinLowercase + new BigDecimal(minAmount).divide(new BigDecimal(100), BWConstants.ROUNDING_MODE)); } catch (SpendingNotAllowed spendingNotAllowed) { - showSpendNotAllowed(app); + Activity activity = convertToActivity(app); + if (activity != null) { + showSpendNotAllowed(activity); + } else { + Timber.e("sendTransaction: could not resolve Activity for showAdjustFee"); + } return; } catch (FeeNeedsAdjust feeNeedsAdjust) { //offer to change amount, so it would be enough for fee - showAdjustFee((Activity) app, transactionItem); + showAdjustFee((Activity) convertToActivity(app), transactionItem); return; } catch (FeeOutOfDate ex) { //Fee is out of date, show not connected error @@ -120,7 +124,10 @@ public void onClick(BRDialogView brDialogView) { BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() { @Override public void run() { - BRDialog.showCustomDialog(app, errTitle[0], errMessage[0], app.getString(R.string.Button_ok), null, new BRDialogView.BROnClickListener() { + Activity activity = convertToActivity(app); + BRDialog.showCustomDialog(activity, errTitle[0], + errMessage[0], activity.getString(R.string.Button_ok), + null, new BRDialogView.BROnClickListener() { @Override public void onClick(BRDialogView brDialogView) { brDialogView.dismiss(); @@ -132,6 +139,13 @@ public void onClick(BRDialogView brDialogView) { }); } + private static Activity convertToActivity(Context context) { + while (context instanceof ContextWrapper) { + if (context instanceof Activity) return (Activity) context; + context = ((ContextWrapper) context).getBaseContext(); + } + return null; + } //Try transaction and throw appropriate exceptions if something was wrong private void tryPay(final Context app, final TransactionItem transactionItem) throws InsufficientFundsException, AmountSmallerThanMinException, SpendingNotAllowed, FeeNeedsAdjust { @@ -150,7 +164,7 @@ private void tryPay(final Context app, final TransactionItem transactionItem) th final long maxOutputAmount = BRWalletManager.getInstance().getMaxOutputAmount(); // check if spending is allowed - if (!BRSharedPrefs.getAllowSpend(app)) { + if (!BRSharedPrefs.getAllowSpend(convertToActivity(app))) { throw new SpendingNotAllowed(); } @@ -177,7 +191,8 @@ private void tryPay(final Context app, final TransactionItem transactionItem) th throw new InsufficientFundsException(sendAmount, balance); } - long feeForTx = m.feeForTransaction(transactionItem.sendAddress, transactionItem.sendAmount + transactionItem.opsFee); + long feeForTx = m.feeForTransaction(transactionItem.sendAddress, + transactionItem.sendAmount + transactionItem.opsFee); throw new FeeNeedsAdjust(sendAmount, balance, feeForTx); } // payment successful @@ -190,7 +205,7 @@ public void run() { transactionItem.opsFee); if (tmpTx == null) { //something went wrong, failed to create tx - ((Activity) app).runOnUiThread(new Runnable() { + ((Activity) convertToActivity(app)).runOnUiThread(new Runnable() { @Override public void run() { BRDialog.showCustomDialog(app, "", app.getString(R.string.Alerts_sendFailure), app.getString(R.string.AccessibilityLabels_close), null, new BRDialogView.BROnClickListener() { @@ -219,14 +234,20 @@ private void showAdjustFee(final Activity app, TransactionItem item) { return; } if (maxAmountDouble == 0) { - BRDialog.showCustomDialog(app, app.getString(R.string.Alerts_sendFailure), "Insufficient amount for transaction fee", app.getString(R.string.Button_ok), null, new BRDialogView.BROnClickListener() { + BRDialog.showCustomDialog(app, app.getString(R.string.Alerts_sendFailure), + "Insufficient amount for transaction fee", + app.getString(R.string.Button_ok), null, + new BRDialogView.BROnClickListener() { @Override public void onClick(BRDialogView brDialogView) { brDialogView.dismissWithAnimation(); } }, null, null, 0); } else { - BRDialog.showCustomDialog(app, app.getString(R.string.Alerts_sendFailure), "Insufficient amount for transaction fee", app.getString(R.string.Button_ok), null, new BRDialogView.BROnClickListener() { + BRDialog.showCustomDialog(app, app.getString(R.string.Alerts_sendFailure), + "Insufficient amount for transaction fee", + app.getString(R.string.Button_ok), null, + new BRDialogView.BROnClickListener() { @Override public void onClick(BRDialogView brDialogView) { brDialogView.dismissWithAnimation(); @@ -253,13 +274,18 @@ private void confirmPay(final Context ctx, final TransactionItem transactionItem //amount can't be less than the min if (transactionItem.sendAmount < minOutput) { - final String bitcoinMinMessage = String.format(Locale.getDefault(), ctx.getString(R.string.PaymentProtocol_Errors_smallTransaction), - BRConstants.litecoinLowercase + new BigDecimal(minOutput).divide(new BigDecimal("100"))); + final String bitcoinMinMessage = String.format(Locale.getDefault(), + ctx.getString(R.string.PaymentProtocol_Errors_smallTransaction), + BWConstants.litecoinLowercase + + new BigDecimal(minOutput).divide(new BigDecimal("100"), + 8, BWConstants.ROUNDING_MODE)); ((Activity) ctx).runOnUiThread(new Runnable() { @Override public void run() { - BRDialog.showCustomDialog(ctx, ctx.getString(R.string.Alerts_sendFailure), bitcoinMinMessage, ctx.getString(R.string.AccessibilityLabels_close), null, new BRDialogView.BROnClickListener() { + BRDialog.showCustomDialog(ctx, ctx.getString(R.string.Alerts_sendFailure), + bitcoinMinMessage, ctx.getString(R.string.AccessibilityLabels_close), + null, new BRDialogView.BROnClickListener() { @Override public void onClick(BRDialogView brDialogView) { brDialogView.dismiss(); @@ -271,10 +297,8 @@ public void onClick(BRDialogView brDialogView) { } boolean forcePin = false; - Timber.d("timber: confirmPay: totalSent: %s, request.amount: %s, total limit: %s, limit: %s", BRWalletManager.getInstance().getTotalSent(),transactionItem.sendAmount, AuthManager.getInstance().getTotalLimit(ctx), BRKeyStore.getSpendLimit(ctx)); - - - if (BRWalletManager.getInstance().getTotalSent() + transactionItem.sendAmount > AuthManager.getInstance().getTotalLimit(ctx)) { + if (BRWalletManager.getInstance().getTotalSent() + + transactionItem.sendAmount > AuthManager.getInstance().getTotalLimit(ctx)) { forcePin = true; } @@ -310,7 +334,10 @@ private String createConfirmation(Context ctx, TransactionItem transactionItem) throw ex; } if (maxAmount == 0) { - BRDialog.showCustomDialog(ctx, "", ctx.getString(R.string.Alerts_sendFailure), ctx.getString(R.string.AccessibilityLabels_close), null, new BRDialogView.BROnClickListener() { + BRDialog.showCustomDialog(ctx, "", + ctx.getString(R.string.Alerts_sendFailure), + ctx.getString(R.string.AccessibilityLabels_close), + null, new BRDialogView.BROnClickListener() { @Override public void onClick(BRDialogView brDialogView) { brDialogView.dismiss(); @@ -324,13 +351,22 @@ public void onClick(BRDialogView brDialogView) { feesForTx += opsFee; } final long total = transactionItem.sendAmount + feesForTx + opsFee; - String formattedAmountLTC = BRCurrency.getFormattedCurrencyString(ctx, "LTC", BRExchange.getLitecoinForLitoshis(ctx, new BigDecimal(transactionItem.sendAmount))); - String formattedFeesLTC = BRCurrency.getFormattedCurrencyString(ctx, "LTC", BRExchange.getLitecoinForLitoshis(ctx, new BigDecimal(feesForTx))); - String formattedTotalLTC = BRCurrency.getFormattedCurrencyString(ctx, "LTC", BRExchange.getLitecoinForLitoshis(ctx, new BigDecimal(total))); - - String formattedAmount = BRCurrency.getFormattedCurrencyString(ctx, iso, BRExchange.getAmountFromLitoshis(ctx, iso, new BigDecimal(transactionItem.sendAmount))); - String formattedFees = BRCurrency.getFormattedCurrencyString(ctx, iso, BRExchange.getAmountFromLitoshis(ctx, iso, new BigDecimal(feesForTx))); - String formattedTotal = BRCurrency.getFormattedCurrencyString(ctx, iso, BRExchange.getAmountFromLitoshis(ctx, iso, new BigDecimal(total))); + String formattedAmountLTC = BRCurrency.getFormattedCurrencyString(ctx, + "LTC", BRExchange.getLitecoinForLitoshis(ctx, + new BigDecimal(transactionItem.sendAmount))); + String formattedFeesLTC = BRCurrency.getFormattedCurrencyString(ctx, + "LTC", BRExchange.getLitecoinForLitoshis(ctx, + new BigDecimal(feesForTx))); + String formattedTotalLTC = BRCurrency.getFormattedCurrencyString(ctx, + "LTC", BRExchange.getLitecoinForLitoshis(ctx, new BigDecimal(total))); + + String formattedAmount = BRCurrency.getFormattedCurrencyString(ctx, + iso, BRExchange.getAmountFromLitoshis(ctx, + iso, new BigDecimal(transactionItem.sendAmount))); + String formattedFees = BRCurrency.getFormattedCurrencyString(ctx, + iso, BRExchange.getAmountFromLitoshis(ctx, iso, new BigDecimal(feesForTx))); + String formattedTotal = BRCurrency.getFormattedCurrencyString(ctx, + iso, BRExchange.getAmountFromLitoshis(ctx, iso, new BigDecimal(total))); //formatted text return receiver + "\n\n" @@ -350,7 +386,8 @@ private boolean isSmallerThanMin(TransactionItem transactionItem) { } private boolean isLargerThanBalance(Context app, TransactionItem transactionItem) { - return transactionItem.sendAmount > 0 && transactionItem.sendAmount > BRWalletManager.getInstance().getBalance(app); + return transactionItem.sendAmount > 0 && + transactionItem.sendAmount > BRWalletManager.getInstance().getBalance(app); } private boolean notEnoughForFee(TransactionItem transactionItem) { @@ -367,7 +404,10 @@ private static void showSpendNotAllowed(final Context app) { ((Activity) app).runOnUiThread(new Runnable() { @Override public void run() { - BRDialog.showCustomDialog(app, app.getString(R.string.Alert_error), app.getString(R.string.Send_isRescanning), app.getString(R.string.Button_ok), null, new BRDialogView.BROnClickListener() { + BRDialog.showCustomDialog(app, app.getString(R.string.Alert_error), + app.getString(R.string.Send_isRescanning), + app.getString(R.string.Button_ok), + null, new BRDialogView.BROnClickListener() { @Override public void onClick(BRDialogView brDialogView) { brDialogView.dismissWithAnimation(); diff --git a/app/src/main/java/com/brainwallet/tools/security/BitcoinUrlHandler.java b/app/src/main/java/com/brainwallet/tools/security/BitcoinUrlHandler.java index 9207e385..15923bf5 100644 --- a/app/src/main/java/com/brainwallet/tools/security/BitcoinUrlHandler.java +++ b/app/src/main/java/com/brainwallet/tools/security/BitcoinUrlHandler.java @@ -1,7 +1,10 @@ package com.brainwallet.tools.security; +import android.media.metrics.Event; + import androidx.fragment.app.FragmentActivity; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.animation.BRAnimator; import com.brainwallet.tools.animation.BRDialog; import com.brainwallet.tools.threads.PaymentProtocolTask; @@ -12,6 +15,7 @@ import com.brainwallet.presenter.entities.PaymentRequestWrapper; import com.brainwallet.presenter.entities.RequestObject; import com.brainwallet.presenter.entities.TransactionItem; +import com.brainwallet.util.EventBus; import com.brainwallet.wallet.BRWalletManager; import java.io.UnsupportedEncodingException; @@ -154,26 +158,10 @@ private static boolean tryLitecoinURL(final String url, final FragmentActivity a app.runOnUiThread(new Runnable() { @Override public void run() { - BRAnimator.showSendFragment(app, url); + EventBus.INSTANCE.postQRCodeScanned(requestObject.address); } }); - } else { - if (app != null) { - BRAnimator.killAllFragments(app); - BRSender.getInstance() - .sendTransaction(app, - new TransactionItem(requestObject.address, - Utils.fetchServiceItem(app, ServiceItems.WALLETOPS), - null, - new BigDecimal(amount).longValue(), - Utils.tieredOpsFee(app, new BigDecimal(amount).longValue()), - null, - true)); - } else { - Timber.e(new NullPointerException("tryLitecoinURL, app is null!")); - } } - return true; } diff --git a/app/src/main/java/com/brainwallet/tools/security/PostAuth.java b/app/src/main/java/com/brainwallet/tools/security/PostAuth.java index 89127dd2..7a778d2b 100644 --- a/app/src/main/java/com/brainwallet/tools/security/PostAuth.java +++ b/app/src/main/java/com/brainwallet/tools/security/PostAuth.java @@ -15,8 +15,9 @@ import com.brainwallet.presenter.activities.util.ActivityUTILS; import com.brainwallet.presenter.entities.PaymentRequestWrapper; import com.brainwallet.presenter.entities.TransactionItem; +import com.brainwallet.tools.animation.BRDialog; import com.brainwallet.tools.manager.BRSharedPrefs; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.TypesConverter; import com.brainwallet.tools.util.Utils; import com.brainwallet.ui.BrainwalletActivity; @@ -31,11 +32,8 @@ public class PostAuth { private String phraseForKeyStore; public TransactionItem transactionItem; - private PaymentRequestWrapper paymentRequest; public static boolean isStuckWithAuthLoop; - private static PostAuth instance; - private PostAuth() { } @@ -65,7 +63,7 @@ public void onCreateWalletAuth(Activity app, boolean authAsked) { public void onPhraseCheckAuth(Activity app, boolean authAsked) { String cleanPhrase; try { - byte[] raw = BRKeyStore.getPhrase(app, BRConstants.SHOW_PHRASE_REQUEST_CODE); + byte[] raw = BRKeyStore.getPhrase(app, BWConstants.SHOW_PHRASE_REQUEST_CODE); if (raw == null) { NullPointerException ex = new NullPointerException("onPhraseCheckAuth: getPhrase = null"); Timber.e(ex); @@ -92,7 +90,7 @@ public void onPhraseCheckAuth(Activity app, boolean authAsked) { public void onPhraseProveAuth(Activity app, boolean authAsked) { String cleanPhrase; try { - cleanPhrase = new String(BRKeyStore.getPhrase(app, BRConstants.PROVE_PHRASE_REQUEST)); + cleanPhrase = new String(BRKeyStore.getPhrase(app, BWConstants.PROVE_PHRASE_REQUEST)); } catch (UserNotAuthenticatedException e) { if (authAsked) { Timber.d("timber: %s: WARNING!!!! LOOP", new Object() { @@ -120,7 +118,7 @@ public void onRecoverWalletAuth(FragmentActivity app, boolean authAsked) { boolean success; try { success = BRKeyStore.putPhrase(phraseForKeyStore.getBytes(), - app, BRConstants.PUT_PHRASE_RECOVERY_WALLET_REQUEST_CODE); + app, BWConstants.PUT_PHRASE_RECOVERY_WALLET_REQUEST_CODE); } catch (UserNotAuthenticatedException e) { if (authAsked) { Timber.e("timber:%s: WARNING!!!! LOOP", new Object() { @@ -145,7 +143,6 @@ public void onRecoverWalletAuth(FragmentActivity app, boolean authAsked) { byte[] pubKey = BRWalletManager.getInstance().getMasterPubKey(bytePhrase); BRKeyStore.putMasterPublicKey(pubKey, app); app.overridePendingTransition(R.anim.enter_from_right, R.anim.exit_to_left); - //using setpasscode from Intent intent = BrainwalletActivity.createIntent( app, new Route.SetPasscode() @@ -172,7 +169,7 @@ public void onPublishTxAuth(final Context app, boolean authAsked) { final BRWalletManager walletManager = BRWalletManager.getInstance(); byte[] rawSeed; try { - rawSeed = BRKeyStore.getPhrase(app, BRConstants.PAY_REQUEST_CODE); + rawSeed = BRKeyStore.getPhrase(app, BWConstants.PAY_REQUEST_CODE); } catch (UserNotAuthenticatedException e) { if (authAsked) { Timber.d("timber: %s: WARNING!!!! LOOP", new Object() { @@ -207,23 +204,16 @@ public void onPublishTxAuth(final Context app, boolean authAsked) { Arrays.fill(seed, (byte) 0); } } - public void setPhraseForKeyStore(String phraseForKeyStore) { this.phraseForKeyStore = phraseForKeyStore; } - public void setTransactionItem(TransactionItem item) { this.transactionItem = item; } - - public void setTmpPaymentRequest(PaymentRequestWrapper paymentRequest) { - this.paymentRequest = paymentRequest; - } - public void onCanaryCheck(final Activity app, boolean authAsked) { String canary; try { - canary = BRKeyStore.getCanary(app, BRConstants.CANARY_REQUEST_CODE); + canary = BRKeyStore.getCanary(app, BWConstants.CANARY_REQUEST_CODE); } catch (UserNotAuthenticatedException e) { if (authAsked) { Timber.d("timber: %s: WARNING!!!! LOOP", new Object() { @@ -232,10 +222,10 @@ public void onCanaryCheck(final Activity app, boolean authAsked) { } return; } - if (canary == null || !canary.equalsIgnoreCase(BRConstants.CANARY_STRING)) { + if (canary == null || !canary.equalsIgnoreCase(BWConstants.CANARY_STRING)) { byte[] phrase; try { - phrase = BRKeyStore.getPhrase(app, BRConstants.CANARY_REQUEST_CODE); + phrase = BRKeyStore.getPhrase(app, BWConstants.CANARY_REQUEST_CODE); } catch (UserNotAuthenticatedException e) { if (authAsked) { Timber.d("timber: %s: WARNING!!!! LOOP", new Object() { @@ -253,7 +243,7 @@ public void onCanaryCheck(final Activity app, boolean authAsked) { } else { Timber.d("timber: onCanaryCheck: Canary wasn't there, but the phrase persists, adding canary to keystore."); try { - BRKeyStore.putCanary(BRConstants.CANARY_STRING, app, 0); + BRKeyStore.putCanary(BWConstants.CANARY_STRING, app, 0); } catch (UserNotAuthenticatedException e) { if (authAsked) { Timber.d("timber: %s: WARNING!!!! LOOP", new Object() { diff --git a/app/src/main/java/com/brainwallet/tools/security/RootHelper.java b/app/src/main/java/com/brainwallet/tools/security/RootHelper.java deleted file mode 100644 index 547af1f8..00000000 --- a/app/src/main/java/com/brainwallet/tools/security/RootHelper.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.brainwallet.tools.security; - -import java.io.BufferedReader; -import java.io.File; -import java.io.InputStreamReader; - -public class RootHelper { - public static boolean isDeviceRooted() { - return checkRootA() || checkRootB() || checkRootC(); - } - - private static boolean checkRootA() { - String buildTags = android.os.Build.TAGS; - return buildTags != null && buildTags.contains("test-keys"); - } - - private static boolean checkRootB() { - String[] paths = {"/sbin/su", "/data/local/xbin/su", "/system/bin/su", "/system/xbin/su", - "/data/local/bin/su", "/system/app/Superuser.apk", "/system/sd/xbin/su", - "/system/bin/failsafe/su", "/data/local/su"}; - for (String path : paths) { - if (new File(path).exists()) return true; - } - return false; - } - - private static boolean checkRootC() { - Process p = null; - try { - p = Runtime.getRuntime().exec(new String[]{"/system/xbin/which", "su"}); - BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); - return in.readLine() != null; - } catch (Exception e) { - return false; - } finally { - if (p != null) p.destroy(); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/tools/sqlite/BRDataSourceInterface.java b/app/src/main/java/com/brainwallet/tools/sqlite/BRDataSourceInterface.java deleted file mode 100644 index 919e92af..00000000 --- a/app/src/main/java/com/brainwallet/tools/sqlite/BRDataSourceInterface.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.brainwallet.tools.sqlite; -import android.database.sqlite.SQLiteDatabase; - -public interface BRDataSourceInterface { - public static final String TAG = BRDataSourceInterface.class.getName(); - - SQLiteDatabase openDatabase(); - void closeDatabase(); -} diff --git a/app/src/main/java/com/brainwallet/tools/sqlite/BRDataSourceInterface.kt b/app/src/main/java/com/brainwallet/tools/sqlite/BRDataSourceInterface.kt new file mode 100644 index 00000000..9dce0eb5 --- /dev/null +++ b/app/src/main/java/com/brainwallet/tools/sqlite/BRDataSourceInterface.kt @@ -0,0 +1,12 @@ +package com.brainwallet.tools.sqlite + +import android.database.sqlite.SQLiteDatabase + +interface BRDataSourceInterface { + fun openDatabase(): SQLiteDatabase? + fun closeDatabase() + + companion object { + val TAG: String = BRDataSourceInterface::class.java.getName() + } +} diff --git a/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java b/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java index 6640916f..536f398e 100644 --- a/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java +++ b/app/src/main/java/com/brainwallet/tools/sqlite/CurrencyDataSource.java @@ -1,19 +1,16 @@ package com.brainwallet.tools.sqlite; -import static kotlinx.coroutines.flow.FlowKt.collect; - import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import com.brainwallet.data.model.CurrencyEntity; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Objects; @@ -189,7 +186,7 @@ private CurrencyEntity cursorToCurrency(Cursor cursor) { public SQLiteDatabase openDatabase() { if (database == null || !database.isOpen()) database = dbHelper.getWritableDatabase(); - dbHelper.setWriteAheadLoggingEnabled(BRConstants.WAL); + dbHelper.setWriteAheadLoggingEnabled(BWConstants.WAL); return database; } diff --git a/app/src/main/java/com/brainwallet/tools/sqlite/MerkleBlockDataSource.java b/app/src/main/java/com/brainwallet/tools/sqlite/MerkleBlockDataSource.java index 81b725e3..9ae1e6f5 100644 --- a/app/src/main/java/com/brainwallet/tools/sqlite/MerkleBlockDataSource.java +++ b/app/src/main/java/com/brainwallet/tools/sqlite/MerkleBlockDataSource.java @@ -6,7 +6,7 @@ import android.database.sqlite.SQLiteDatabase; import android.os.NetworkOnMainThreadException; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.presenter.activities.util.ActivityUTILS; import com.brainwallet.presenter.entities.BRMerkleBlockEntity; import com.brainwallet.presenter.entities.BlockEntity; @@ -120,7 +120,7 @@ public SQLiteDatabase openDatabase() { if (ActivityUTILS.isMainThread()) throw new NetworkOnMainThreadException(); if (database == null || !database.isOpen()) database = dbHelper.getWritableDatabase(); - dbHelper.setWriteAheadLoggingEnabled(BRConstants.WAL); + dbHelper.setWriteAheadLoggingEnabled(BWConstants.WAL); // } return database; } diff --git a/app/src/main/java/com/brainwallet/tools/sqlite/PeerDataSource.java b/app/src/main/java/com/brainwallet/tools/sqlite/PeerDataSource.java index 84eb39c3..7c8d7094 100644 --- a/app/src/main/java/com/brainwallet/tools/sqlite/PeerDataSource.java +++ b/app/src/main/java/com/brainwallet/tools/sqlite/PeerDataSource.java @@ -6,7 +6,7 @@ import android.database.sqlite.SQLiteDatabase; import android.os.NetworkOnMainThreadException; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.presenter.activities.util.ActivityUTILS; import com.brainwallet.presenter.entities.BRPeerEntity; import com.brainwallet.presenter.entities.PeerEntity; @@ -128,7 +128,7 @@ public SQLiteDatabase openDatabase() { if (ActivityUTILS.isMainThread()) throw new NetworkOnMainThreadException(); if (database == null || !database.isOpen()) database = dbHelper.getWritableDatabase(); - dbHelper.setWriteAheadLoggingEnabled(BRConstants.WAL); + dbHelper.setWriteAheadLoggingEnabled(BWConstants.WAL); // } return database; } diff --git a/app/src/main/java/com/brainwallet/tools/sqlite/TransactionDataSource.java b/app/src/main/java/com/brainwallet/tools/sqlite/TransactionDataSource.java index 5508a653..b8455347 100644 --- a/app/src/main/java/com/brainwallet/tools/sqlite/TransactionDataSource.java +++ b/app/src/main/java/com/brainwallet/tools/sqlite/TransactionDataSource.java @@ -6,9 +6,9 @@ import android.database.sqlite.SQLiteDatabase; import android.os.NetworkOnMainThreadException; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.presenter.activities.util.ActivityUTILS; -import com.brainwallet.presenter.entities.BRTransactionEntity; +import com.brainwallet.presenter.entities.BWDatabaseTransactionEntity; import java.util.ArrayList; import java.util.List; @@ -60,7 +60,7 @@ private TransactionDataSource(Context context) { dbHelper = BRSQLiteHelper.getInstance(context); } - public BRTransactionEntity putTransaction(BRTransactionEntity transactionEntity) { + public BWDatabaseTransactionEntity putTransaction(BWDatabaseTransactionEntity transactionEntity) { Cursor cursor = null; try { database = openDatabase(); @@ -75,7 +75,7 @@ public BRTransactionEntity putTransaction(BRTransactionEntity transactionEntity) cursor = database.query(BRSQLiteHelper.TX_TABLE_NAME, allColumns, null, null, null, null, null); cursor.moveToFirst(); - BRTransactionEntity transactionEntity1 = cursorToTransaction(cursor); + BWDatabaseTransactionEntity transactionEntity1 = cursorToTransaction(cursor); database.setTransactionSuccessful(); for (OnTxAddedListener listener : listeners) { @@ -101,8 +101,8 @@ public void deleteAllTransactions() { } } - public List getAllTransactions() { - List transactions = new ArrayList<>(); + public List getAllTransactions() { + List transactions = new ArrayList<>(); Cursor cursor = null; try { database = openDatabase(); @@ -112,7 +112,7 @@ public List getAllTransactions() { cursor.moveToFirst(); while (!cursor.isAfterLast()) { - BRTransactionEntity transactionEntity = cursorToTransaction(cursor); + BWDatabaseTransactionEntity transactionEntity = cursorToTransaction(cursor); transactions.add(transactionEntity); cursor.moveToNext(); } @@ -124,8 +124,11 @@ public List getAllTransactions() { return transactions; } - private BRTransactionEntity cursorToTransaction(Cursor cursor) { - return new BRTransactionEntity(cursor.getBlob(1), cursor.getInt(2), cursor.getLong(3), cursor.getString(0)); + private BWDatabaseTransactionEntity cursorToTransaction(Cursor cursor) { + return new BWDatabaseTransactionEntity(cursor.getBlob(1), + cursor.getInt(2), + cursor.getLong(3), + cursor.getString(0)); } public void updateTxBlockHeight(String hash, int blockHeight, int timeStamp) { @@ -160,7 +163,7 @@ public SQLiteDatabase openDatabase() { // Opening new database if (database == null || !database.isOpen()) database = dbHelper.getWritableDatabase(); - dbHelper.setWriteAheadLoggingEnabled(BRConstants.WAL); + dbHelper.setWriteAheadLoggingEnabled(BWConstants.WAL); return database; } diff --git a/app/src/main/java/com/brainwallet/tools/threads/Examples.java b/app/src/main/java/com/brainwallet/tools/threads/Examples.java deleted file mode 100644 index a9649242..00000000 --- a/app/src/main/java/com/brainwallet/tools/threads/Examples.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.brainwallet.tools.threads; - -public class Examples { - - - /* - * Using it for Background Tasks - */ - public void doSomeBackgroundWork() { - BRExecutor.getInstance().forBackgroundTasks() - .execute(new Runnable() { - @Override - public void run() { - // do some background work here. - } - }); - } - - /* - * Using it for Light-Weight Background Tasks - */ - public void doSomeLightWeightBackgroundWork() { - BRExecutor.getInstance().forLightWeightBackgroundTasks() - .execute(new Runnable() { - @Override - public void run() { - // do some light-weight background work here. - } - }); - } - - /* - * Using it for MainThread Tasks - */ - public void doSomeMainThreadWork() { - BRExecutor.getInstance().forMainThreadTasks() - .execute(new Runnable() { - @Override - public void run() { - // do some Main Thread work here. - } - }); - } - - /* -* do some task at high priority -*/ - public void doSomeTaskAtHighPriority(){ - BRExecutor.getInstance().forBackgroundTasks() - .submit(new PriorityRunnable(Priority.HIGH) { - @Override - public void run() { - // do some background work here at high priority. - } - }); - } -} diff --git a/app/src/main/java/com/brainwallet/tools/threads/PaymentProtocolPostPaymentTask.java b/app/src/main/java/com/brainwallet/tools/threads/PaymentProtocolPostPaymentTask.java deleted file mode 100644 index 5ee0ea19..00000000 --- a/app/src/main/java/com/brainwallet/tools/threads/PaymentProtocolPostPaymentTask.java +++ /dev/null @@ -1,135 +0,0 @@ -package com.brainwallet.tools.threads; - -import android.content.Context; -import android.os.AsyncTask; -import android.widget.Toast; - -import com.brainwallet.BrainwalletApp; -import com.brainwallet.tools.security.BitcoinUrlHandler; -import com.brainwallet.tools.util.BytesUtil; -import com.brainwallet.R; -import com.brainwallet.presenter.activities.BreadActivity; -import com.brainwallet.presenter.customviews.BRToast; -import com.brainwallet.presenter.entities.PaymentRequestWrapper; - -import java.io.DataOutputStream; -import java.io.InputStream; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.HashMap; -import java.util.Map; - -import timber.log.Timber; - -public class PaymentProtocolPostPaymentTask extends AsyncTask { - - public static final String TITLE = "title"; - public static final String MESSAGE = "message"; - - public HttpURLConnection urlConnection; - public PaymentRequestWrapper paymentRequest = null; - public static String message; - - public static boolean waiting = true; - public static boolean sent = false; - public static Map pendingErrorMessages = new HashMap<>(); - - public PaymentProtocolPostPaymentTask(PaymentRequestWrapper paymentRequest) { - this.paymentRequest = paymentRequest; - } - - @Override - protected String doInBackground(String... uri) { - InputStream in; - try { - waiting = true; - sent = false; - URL url = new URL(paymentRequest.paymentURL); - urlConnection = (HttpURLConnection) url.openConnection(); - urlConnection.setRequestProperty("Content-Type", "application/litecoin-payment"); - urlConnection.addRequestProperty("Accept", "application/litecoin-paymentack"); - urlConnection.setConnectTimeout(3000); - urlConnection.setReadTimeout(3000); - urlConnection.setRequestMethod("POST"); - urlConnection.setUseCaches(false); - urlConnection.setDoInput(true); - urlConnection.setDoOutput(true); - - DataOutputStream dStream = new DataOutputStream(urlConnection.getOutputStream()); - dStream.write(paymentRequest.payment); - - in = urlConnection.getInputStream(); - - if (in == null) { - Timber.i("timber: The inputStream is null!"); - return null; - } - byte[] serializedBytes = BytesUtil.readBytesFromStream(in); - if (serializedBytes == null || serializedBytes.length == 0) { - Timber.d("timber: serializedBytes are null!!!"); - return null; - } - - message = BitcoinUrlHandler.parsePaymentACK(serializedBytes); -// PostAuth.getInstance().setTmpPaymentRequest(paymentRequest); -// PostAuth.getInstance().onPaymentProtocolRequest(app,false); - } catch (Exception e) { - Context app = BrainwalletApp.getBreadContext(); - if (e instanceof java.net.UnknownHostException) { - if (app != null) { - pendingErrorMessages.put(TITLE, app.getString(R.string.Alert_error)); - pendingErrorMessages.put(MESSAGE, app.getString(R.string.Send_remoteRequestError)); - } - } -// else if (e instanceof FileNotFoundException) { -// if (app != null) { -// pendingErrorMessages.put(TITLE, app.getString(R.string.JailbreakWarnings_title)); -// pendingErrorMessages.put(MESSAGE, app.getString(R.string.bad_payment_request)); -// } -// } else if (e instanceof SocketTimeoutException) { -// if (app != null) { -// pendingErrorMessages.put(TITLE, app.getString(R.string.JailbreakWarnings_title)); -// pendingErrorMessages.put(MESSAGE, app.getString(R.string.connection_timed_out)); -// } -// } else { -// if (app != null) { -// pendingErrorMessages.put(TITLE, app.getString(R.string.JailbreakWarnings_title)); -// pendingErrorMessages.put(MESSAGE, app.getString(R.string.could_not_transmit_payment)); -//// if (!((BrainwalletApp) app.getApplication()).hasInternetAccess()) -//// BreadDialog. -//// showCustomDialog(app,app.getString(R.string.could_not_make_payment), app.getString(R.string.not_connected_network), app.getString(R.string.ok)); -// -// } -// -// } - Timber.e(e); - } finally { - if (urlConnection != null) urlConnection.disconnect(); - waiting = false; - } - return null; - } - - @Override - protected void onPostExecute(String result) { - super.onPostExecute(result); - handleMessage(); - } - - public static void handleMessage() { - Context app = BrainwalletApp.getBreadContext(); - if (app != null && message != null) { - if (!message.isEmpty()) { - BRToast. - showCustomToast(app, message, BreadActivity.screenParametersPoint.y / 2, Toast.LENGTH_LONG, R.drawable.toast_layout_black); - } else { - if (!waiting && !sent && pendingErrorMessages.get(MESSAGE) != null) { -// BreadDialog. -// showCustomDialog(app,pendingErrorMessages.get(TITLE), pendingErrorMessages.get(MESSAGE), app.getString(R.string.ok)); - pendingErrorMessages = null; - } - } - } - } - -} diff --git a/app/src/main/java/com/brainwallet/tools/threads/PaymentProtocolTask.java b/app/src/main/java/com/brainwallet/tools/threads/PaymentProtocolTask.java index 15c78a59..525515a2 100644 --- a/app/src/main/java/com/brainwallet/tools/threads/PaymentProtocolTask.java +++ b/app/src/main/java/com/brainwallet/tools/threads/PaymentProtocolTask.java @@ -7,7 +7,7 @@ import com.brainwallet.tools.manager.BRSharedPrefs; import com.brainwallet.tools.security.BitcoinUrlHandler; import com.brainwallet.tools.security.X509CertificateValidator; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.BRCurrency; import com.brainwallet.tools.util.BRExchange; import com.brainwallet.tools.util.BytesUtil; @@ -290,7 +290,7 @@ public void run() { double minOutput = BRWalletManager.getInstance().getMinOutputAmount(); if (paymentRequest.amount < minOutput) { final String bitcoinMinMessage = String.format(Locale.getDefault(), app.getString(R.string.PaymentProtocol_Errors_smallTransaction), - BRConstants.litecoinLowercase + new BigDecimal(minOutput).divide(new BigDecimal("100"))); + BWConstants.litecoinLowercase + new BigDecimal(minOutput).divide(new BigDecimal("100"), 8, BWConstants.ROUNDING_MODE)); app.runOnUiThread(new Runnable() { @Override public void run() { @@ -318,7 +318,7 @@ public void onClick(BRDialogView brDialogView) { @Override public void run() { /// DEV NOTES: Remove this call to auth Prompt - + } }); } diff --git a/app/src/main/java/com/brainwallet/tools/threads/PriorityThreadPoolExecutor.java b/app/src/main/java/com/brainwallet/tools/threads/PriorityThreadPoolExecutor.java deleted file mode 100644 index 39b5b17d..00000000 --- a/app/src/main/java/com/brainwallet/tools/threads/PriorityThreadPoolExecutor.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.brainwallet.tools.threads; - - -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; -import java.util.concurrent.PriorityBlockingQueue; -import java.util.concurrent.RejectedExecutionHandler; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -public class PriorityThreadPoolExecutor extends ThreadPoolExecutor { - - public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, - TimeUnit unit, ThreadFactory threadFactory, RejectedExecutionHandler handler) { - super(corePoolSize, maximumPoolSize, keepAliveTime, unit, new PriorityBlockingQueue(), threadFactory, handler); - } - - @Override - public Future submit(Runnable task) { - PriorityFutureTask futureTask = new PriorityFutureTask((PriorityRunnable) task); - execute(futureTask); - return futureTask; - } - - private static final class PriorityFutureTask extends FutureTask - implements Comparable { - private final PriorityRunnable priorityRunnable; - - public PriorityFutureTask(PriorityRunnable priorityRunnable) { - super(priorityRunnable, null); - this.priorityRunnable = priorityRunnable; - } - - /* - * compareTo() method is defined in interface java.lang.Comparable and it is used - * to implement natural sorting on java classes. natural sorting means the the sort - * order which naturally applies on object e.g. lexical order for String, numeric - * order for Integer or Sorting employee by there ID etc. most of the java core - * classes including String and Integer implements CompareTo() method and provide - * natural sorting. - */ - @Override - public int compareTo(PriorityFutureTask other) { - Priority p1 = priorityRunnable.getPriority(); - Priority p2 = other.priorityRunnable.getPriority(); - return p2.ordinal() - p1.ordinal(); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/brainwallet/tools/util/BRConstants.java b/app/src/main/java/com/brainwallet/tools/util/BRConstants.java deleted file mode 100644 index bd8f810b..00000000 --- a/app/src/main/java/com/brainwallet/tools/util/BRConstants.java +++ /dev/null @@ -1,211 +0,0 @@ -package com.brainwallet.tools.util; -import androidx.annotation.StringDef; - -import com.brainwallet.BuildConfig; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.math.RoundingMode; -import java.util.Locale; - -public class BRConstants { - - private BRConstants() { - } - - /** - * App Version and Version Code - */ - - public static final String APP_VERSION_NAME_CODE = String.format(Locale.US, "%1$s (%2$s)", - BuildConfig.VERSION_NAME, - BuildConfig.VERSION_CODE); - - /** - * Native library name - */ - public static final String NATIVE_LIB_NAME = "core-lib"; - - /** - * Permissions - */ - public static final int CAMERA_REQUEST_ID = 34; - public static final int GEO_REQUEST_ID = 35; - - /** - * Request codes for auth - */ - public static final int SHOW_PHRASE_REQUEST_CODE = 111; - public static final int PAY_REQUEST_CODE = 112; - public static final int CANARY_REQUEST_CODE = 113; - public static final int PUT_PHRASE_NEW_WALLET_REQUEST_CODE = 114; - public static final int PUT_PHRASE_RECOVERY_WALLET_REQUEST_CODE = 115; - public static final int PROVE_PHRASE_REQUEST = 119; - - /** - * Request codes for taking pictures - */ - public static final int SCANNER_REQUEST = 201; - - public static final String CANARY_STRING = "canary"; - public static final String FIRST_ADDRESS = "firstAddress"; - public static final String SECURE_TIME_PREFS = "secureTime"; - public static final String FEE_KB_PREFS = "feeKb"; - public static final String ECONOMY_FEE_KB_PREFS = "EconomyFeeKb"; - - public static final int ONE_BITCOIN = 100000000; - - /** - * BRSharedPrefs - */ - public static final String PREFS_NAME = "MyPrefsFile"; - public static final String RECEIVE_ADDRESS = "receive_address"; - public static final String START_HEIGHT = "startHeight"; - public static final String LAST_BLOCK_HEIGHT = "lastBlockHeight"; - public static final String CURRENT_UNIT = "currencyUnit"; - public static final String CURRENT_CURRENCY = "currentCurrency"; - public static final String POSITION = "position"; - public static final String PHRASE_WRITTEN = "phraseWritten"; - public static final String ALLOW_SPEND = "allowSpend"; - public static final String USER_ID = "userId"; - public static final String GEO_PERMISSIONS_REQUESTED = "geoPermissionsRequested"; - - /** - * Currency units - */ - public static final int CURRENT_UNIT_PHOTONS = 0; // formerly CURRENT_UNIT_BITS - public static final int CURRENT_UNIT_LITES = 1; // formerly CURRENT_UNIT_MBITS - public static final int CURRENT_UNIT_LITECOINS = 2; - - public static final String litecoinLowercase = "\u0142"; - public static final String litecoinUppercase = "\u0141"; - - public static boolean PLATFORM_ON = true; - public static final RoundingMode ROUNDING_MODE = RoundingMode.HALF_EVEN; - public static final boolean WAL = true; - - public static final String loopBug = "android-loop-bug"; - - /** - * brainwallet pin/passcode length - */ - public static final int BW_PIN_LENGTH = 4; - - /** - * App External URLs - */ - - public static final String TWITTER_LINK = "https://twitter.com/Brainwallet_App"; - public static final String INSTAGRAM_LINK = "https://www.instagram.com/brainwalletapp"; - public static final String WEB_LINK = "https://brainwallet.co"; - public static final String SUPPORT_WEB_LINK = "https://brainwallet.co/support.html"; - public static final String TOS_LINK = "https://brainwallet.co/privacy-policy.html"; - public static final String MOBILE_MP_LINK = "https://brainwallet.co/mobile-top-up.html"; - public static String BITREFILL_AFFILIATE_LINK = "https://www.bitrefill.com/"; - public static String LINKTREE_URL = "https://linktr.ee/brainwallet"; - - /** - * API Hosts - */ - public static final String BW_API_PROD_HOST = "https://api.grunt.ltd"; - public static final String LEGACY_BW_API_DEV_HOST = "https://dev.apigsltd.net"; - - public static final String BLOCK_EXPLORER_BASE_URL = "https://blockchair.com/litecoin/transaction/"; - - public static final String _20191105_AL = "app_launched"; - public static final String _20191105_VSC = "visit_send_controller"; - public static final String _20202116_VRC = "visit_receive_controller"; - public static final String _20191105_DSL = "did_send_ltc"; - public static final String _20191105_DTBT = "did_tap_buy_tab"; - public static final String _20200111_RNI = "rate_not_initialized"; - public static final String _20200111_FNI = "feeperkb_not_initialized"; - public static final String _20200111_TNI = "transaction_not_initialized"; - public static final String _20200111_WNI = "wallet_not_initialized"; - public static final String _20200111_PNI = "phrase_not_initialized"; - public static final String _20200111_UTST = "unable_to_sign_transaction"; - public static final String _20200112_ERR = "brainwallet_android_error"; - public static final String _20200112_DSR = "did_start_resync"; - public static final String _20200125_DSRR = "did_show_review_request"; - public static final String _20201118_DTGS = "did_tap_get_support"; - public static final String _20200217_DUWP = "did_unlock_with_pin"; - public static final String _20200217_DUWB = "did_unlock_with_biometrics"; - public static final String _20201121_SIL = "started_IFPS_lookup"; - public static final String _20201121_DRIA = "did_resolve_IPFS_address"; - public static final String _20201121_FRIA = "failed_resolve_IPFS_address"; - public static final String _20230113_BAC = "backup_apiserver_called"; - public static final String _20230407_DCS = "did_complete_sync"; - - public static final String _20250303_DSTU = "did_skip_top_up"; - public static final String _20250517_WCINFO = "wallet_callback_info"; - - ///Dev: These events not yet used - public static final String _20200207_DTHB = "did_tap_header_balance"; - public static final String _20210427_HCIEEH = "heartbeat_check_if_event_even_happens"; - public static final String _20220822_UTOU = "user_tapped_on_ud"; - public static final String _20230131_NENR = "no_error_nominal_response"; - public static final String _20240123_RAGI = "registered_android_general_interest"; - public static final String _20231225_UAP = "user_accepted_push"; - public static final String _20240101_US = "user_signup"; - public static final String _20241006_DRR = "did_request_rating"; - public static final String _20241006_UCR = "user_completed_rating"; - public static final String _HOME_OPEN = "home_open"; - public static final String _20250222_PAC = "prod_apiserver_called"; - - @Retention(RetentionPolicy.SOURCE) - @StringDef({ - _20191105_AL, - _20191105_VSC, - _20202116_VRC, - _20191105_DSL, - _20191105_DTBT, - _20200111_RNI, - _20200111_FNI, - _20200111_TNI, - _20200111_WNI, - _20200111_PNI, - _20200111_UTST, - _20200112_ERR, - _20200112_DSR, - _20200125_DSRR, - _20201118_DTGS, - _20200217_DUWP, - _20200217_DUWB, - _20201121_SIL, - _20201121_DRIA, - _20201121_FRIA, - _20230113_BAC, - _20200207_DTHB, - _20210427_HCIEEH, - _20220822_UTOU, - _20230131_NENR, - _20230407_DCS, - _20240123_RAGI, - _20231225_UAP, - _20240101_US, - _20241006_DRR, - _20241006_UCR, - _HOME_OPEN, - _20250222_PAC, - _20250303_DSTU, - _20250517_WCINFO - }) - public @interface Event { - } - - - /** - * Analytics keys - */ - - public static final String START_TIME = "start_time"; - public static final String SUCCESS_TIME = "success_time"; - public static final String FAILURE_TIME = "failure_time"; - public static final String ERROR = "error"; - - /** - * False Positive rate keys - */ - public static final float FALSE_POS_RATE_LOW_PRIVACY = 0.00005F; - public static final float FALSE_POS_RATE_SEMI_PRIVACY = 0.00008F; - public static final float FALSE_POS_RATE_ANONYMOUS = 0.0005F; -} diff --git a/app/src/main/java/com/brainwallet/tools/util/BRCurrency.java b/app/src/main/java/com/brainwallet/tools/util/BRCurrency.java index 1a178fff..62d81eb1 100644 --- a/app/src/main/java/com/brainwallet/tools/util/BRCurrency.java +++ b/app/src/main/java/com/brainwallet/tools/util/BRCurrency.java @@ -1,10 +1,11 @@ package com.brainwallet.tools.util; -import static com.brainwallet.tools.util.BRConstants.CURRENT_UNIT_PHOTONS; +import static com.brainwallet.constants.BWConstants.CURRENT_UNIT_PHOTONS; import android.content.Context; import com.brainwallet.tools.manager.BRSharedPrefs; +import com.brainwallet.constants.BWConstants; import java.math.BigDecimal; import java.text.DecimalFormat; @@ -38,7 +39,7 @@ public static String getFormattedCurrencyString(Context app, String isoCurrencyC } decimalFormatSymbols.setCurrencySymbol(symbol); currencyFormat.setGroupingUsed(true); - currencyFormat.setMaximumFractionDigits(BRSharedPrefs.getCurrencyUnit(app) == BRConstants.CURRENT_UNIT_LITECOINS ? 8 : 2); + currencyFormat.setMaximumFractionDigits(BRSharedPrefs.getCurrencyUnit(app) == BWConstants.CURRENT_UNIT_LITECOINS ? 8 : 2); currencyFormat.setDecimalFormatSymbols(decimalFormatSymbols); currencyFormat.setNegativePrefix(decimalFormatSymbols.getCurrencySymbol() + "-"); currencyFormat.setNegativeSuffix(""); @@ -48,18 +49,18 @@ public static String getFormattedCurrencyString(Context app, String isoCurrencyC public static String getSymbolByIso(Context app, String iso) { String symbol; if (Objects.equals(iso, "LTC")) { - String currencySymbolString = BRConstants.litecoinLowercase; + String currencySymbolString = BWConstants.litecoinLowercase; if (app != null) { int unit = BRSharedPrefs.getCurrencyUnit(app); switch (unit) { case CURRENT_UNIT_PHOTONS: - currencySymbolString = BRConstants.litecoinLowercase; + currencySymbolString = BWConstants.litecoinLowercase; break; - case BRConstants.CURRENT_UNIT_LITES: - currencySymbolString = "m" + BRConstants.litecoinUppercase; + case BWConstants.CURRENT_UNIT_LITES: + currencySymbolString = "m" + BWConstants.litecoinUppercase; break; - case BRConstants.CURRENT_UNIT_LITECOINS: - currencySymbolString = BRConstants.litecoinUppercase; + case BWConstants.CURRENT_UNIT_LITECOINS: + currencySymbolString = BWConstants.litecoinUppercase; break; } } @@ -84,9 +85,9 @@ public static String getCurrencyName(Context app, String iso) { switch (unit) { case CURRENT_UNIT_PHOTONS: return "Bits"; - case BRConstants.CURRENT_UNIT_LITES: + case BWConstants.CURRENT_UNIT_LITES: return "MBits"; - case BRConstants.CURRENT_UNIT_LITECOINS: + case BWConstants.CURRENT_UNIT_LITECOINS: return "LTC"; } } diff --git a/app/src/main/java/com/brainwallet/tools/util/BRExchange.java b/app/src/main/java/com/brainwallet/tools/util/BRExchange.java index c199b115..92ac199d 100644 --- a/app/src/main/java/com/brainwallet/tools/util/BRExchange.java +++ b/app/src/main/java/com/brainwallet/tools/util/BRExchange.java @@ -1,13 +1,14 @@ package com.brainwallet.tools.util; -import static com.brainwallet.tools.util.BRConstants.CURRENT_UNIT_PHOTONS; -import static com.brainwallet.tools.util.BRConstants.ROUNDING_MODE; +import static com.brainwallet.constants.BWConstants.CURRENT_UNIT_PHOTONS; +import static com.brainwallet.constants.BWConstants.ROUNDING_MODE; import android.content.Context; import com.brainwallet.tools.manager.BRSharedPrefs; import com.brainwallet.tools.sqlite.CurrencyDataSource; import com.brainwallet.data.model.CurrencyEntity; +import com.brainwallet.constants.BWConstants; import com.brainwallet.wallet.BRWalletManager; import java.math.BigDecimal; @@ -33,10 +34,10 @@ public static BigDecimal getLitecoinForLitoshis(Context app, BigDecimal amount) case CURRENT_UNIT_PHOTONS: result = new BigDecimal(String.valueOf(amount)).divide(new BigDecimal("100"), 2, ROUNDING_MODE); break; - case BRConstants.CURRENT_UNIT_LITES: + case BWConstants.CURRENT_UNIT_LITES: result = new BigDecimal(String.valueOf(amount)).divide(new BigDecimal("100000"), 5, ROUNDING_MODE); break; - case BRConstants.CURRENT_UNIT_LITECOINS: + case BWConstants.CURRENT_UNIT_LITECOINS: result = new BigDecimal(String.valueOf(amount)).divide(new BigDecimal("100000000"), 8, ROUNDING_MODE); break; } @@ -50,10 +51,10 @@ public static BigDecimal getLitoshisForLitecoin(Context app, BigDecimal amount) case CURRENT_UNIT_PHOTONS: result = new BigDecimal(String.valueOf(amount)).multiply(new BigDecimal("100")); break; - case BRConstants.CURRENT_UNIT_LITES: + case BWConstants.CURRENT_UNIT_LITES: result = new BigDecimal(String.valueOf(amount)).multiply(new BigDecimal("100000")); break; - case BRConstants.CURRENT_UNIT_LITECOINS: + case BWConstants.CURRENT_UNIT_LITECOINS: result = new BigDecimal(String.valueOf(amount)).multiply(new BigDecimal("100000000")); break; } @@ -71,24 +72,24 @@ public static BigDecimal getAmountFromLitoshis(Context app, String iso, BigDecim if (ent == null) return new BigDecimal(0); BigDecimal rate = new BigDecimal(ent.rate).multiply(new BigDecimal(100)); result = new BigDecimal(BRWalletManager.getInstance().localAmount(amount.longValue(), rate.doubleValue())) - .divide(new BigDecimal(100), 2, BRConstants.ROUNDING_MODE); + .divide(new BigDecimal(100), 2, BWConstants.ROUNDING_MODE); } return result; } public static String getLitecoinSymbol(Context app) { - String currencySymbolString = BRConstants.litecoinLowercase; + String currencySymbolString = BWConstants.litecoinLowercase; if (app != null) { int unit = BRSharedPrefs.getCurrencyUnit(app); switch (unit) { case CURRENT_UNIT_PHOTONS: - currencySymbolString = "m" + BRConstants.litecoinLowercase; + currencySymbolString = "m" + BWConstants.litecoinLowercase; break; - case BRConstants.CURRENT_UNIT_LITES: - currencySymbolString = BRConstants.litecoinLowercase; + case BWConstants.CURRENT_UNIT_LITES: + currencySymbolString = BWConstants.litecoinLowercase; break; - case BRConstants.CURRENT_UNIT_LITECOINS: - currencySymbolString = BRConstants.litecoinUppercase; + case BWConstants.CURRENT_UNIT_LITECOINS: + currencySymbolString = BWConstants.litecoinUppercase; break; } } @@ -108,11 +109,11 @@ public static BigDecimal getLitoshisFromAmount(Context app, String iso, BigDecim // Get the exchange rate BigDecimal rate = new BigDecimal(ent.rate); - result = amount.divide(rate, 8, BRConstants.ROUNDING_MODE) + result = amount.divide(rate, 8, BWConstants.ROUNDING_MODE) .multiply(new BigDecimal("100000000")); // Round to a whole number of litoshis - result = result.setScale(0, BRConstants.ROUNDING_MODE); + result = result.setScale(0, BWConstants.ROUNDING_MODE); } return result; } diff --git a/app/src/main/java/com/brainwallet/tools/util/Extension.kt b/app/src/main/java/com/brainwallet/tools/util/Extension.kt index 61389ac7..89a6dc58 100644 --- a/app/src/main/java/com/brainwallet/tools/util/Extension.kt +++ b/app/src/main/java/com/brainwallet/tools/util/Extension.kt @@ -185,3 +185,4 @@ fun Fragment.getString( result } } +fun String.capitalizeFirst(): String = replaceFirstChar { it.uppercase() } diff --git a/app/src/main/java/com/brainwallet/tools/util/FileHelper.java b/app/src/main/java/com/brainwallet/tools/util/FileHelper.java deleted file mode 100644 index eb43228b..00000000 --- a/app/src/main/java/com/brainwallet/tools/util/FileHelper.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.brainwallet.tools.util; - -import java.io.File; - -import timber.log.Timber; - -public class FileHelper { - - public static void printDirectoryTree(File folder) { - if (!folder.isDirectory()) { - throw new IllegalArgumentException("folder is not a Directory"); - } - Timber.d(folder.getAbsolutePath()); - int indent = 0; - StringBuilder sb = new StringBuilder(); - printDirectoryTree(folder, indent, sb); - Timber.d(sb.toString()); - } - - private static void printDirectoryTree(File folder, int indent, - StringBuilder sb) { - if (!folder.isDirectory()) { - throw new IllegalArgumentException("folder is not a Directory"); - } - sb.append(getIndentString(indent)); - sb.append("+--"); - sb.append(folder.getName()); - sb.append("/"); - sb.append("\n"); - for (File file : folder.listFiles()) { - if (file.isDirectory()) { - printDirectoryTree(file, indent + 1, sb); - } else { - printFile(file, indent + 1, sb); - } - } - } - - private static void printFile(File file, int indent, StringBuilder sb) { - sb.append(getIndentString(indent)); - sb.append("+--"); - sb.append(file.getName()); - sb.append("\n"); - } - - private static String getIndentString(int indent) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < indent; i++) { - sb.append("| "); - } - return sb.toString(); - } -} diff --git a/app/src/main/java/com/brainwallet/tools/util/Utils.java b/app/src/main/java/com/brainwallet/tools/util/Utils.java index 5a346596..0a1f180c 100644 --- a/app/src/main/java/com/brainwallet/tools/util/Utils.java +++ b/app/src/main/java/com/brainwallet/tools/util/Utils.java @@ -14,6 +14,7 @@ import com.brainwallet.tools.manager.AnalyticsManager; import com.brainwallet.presenter.entities.ServiceItems; +import com.brainwallet.constants.BWConstants; import java.security.InvalidKeyException; import java.security.KeyFactory; @@ -49,7 +50,6 @@ import java.util.UUID; import java.util.concurrent.ThreadLocalRandom; -import kotlin.uuid.Uuid; import timber.log.Timber; public class Utils { @@ -155,7 +155,9 @@ public static String createBitcoinUrl(String address, long satoshiAmount, String if (address != null && !address.isEmpty()) builder = builder.appendPath(address); if (satoshiAmount != 0) - builder = builder.appendQueryParameter("amount", new BigDecimal(satoshiAmount).divide(new BigDecimal(100000000), 8, BRConstants.ROUNDING_MODE).toPlainString()); + builder = builder.appendQueryParameter("amount", + new BigDecimal(satoshiAmount).divide(new BigDecimal(100000000), 8, BWConstants.ROUNDING_MODE) + .toPlainString()); if (label != null && !label.isEmpty()) builder = builder.appendQueryParameter("label", label); if (message != null && !message.isEmpty()) @@ -181,7 +183,7 @@ public static void hideKeyboard(Context app) { public static String getAgentString(Context app, String cfnetwork) { String deviceCode = Build.MANUFACTURER + "-|-" + Build.MODEL; - String appVersion = BRConstants.APP_VERSION_NAME_CODE; + String appVersion = BWConstants.APP_VERSION_NAME_CODE; return String.format(Locale.ENGLISH, "%s/%d %s Android/%s Device/%s", "Brainwallet", appVersion, cfnetwork, Build.VERSION.RELEASE, deviceCode); } @@ -190,7 +192,7 @@ public static String getEncryptedAgentString(Context app) { String deviceType = Build.DEVICE; String deviceModel = Build.MODEL; String udidString = String.valueOf(UUID.randomUUID()); - String appVersion = BRConstants.APP_VERSION_NAME_CODE; + String appVersion = BWConstants.APP_VERSION_NAME_CODE; String formattedAgentString = String.format(Locale.ENGLISH, "brainwallet-android,%s,%s-%s-%s,%s", appVersion, deviceCode,deviceType,deviceModel,udidString); @@ -355,7 +357,7 @@ else if (name == ServiceItems.CLIENTCODE) { } Bundle params = new Bundle(); params.putString("lwa_error_message: %s Key not found", name.getKey()); - AnalyticsManager.logCustomEventWithParams(BRConstants._20200112_ERR,params); + AnalyticsManager.logCustomEventWithParams(BWConstants._20200112_ERR,params); Timber.d("timber: fetchServiceItem lwa_error_message"); return ""; } diff --git a/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt b/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt index 2b76fefc..1d9b5c08 100644 --- a/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt +++ b/app/src/main/java/com/brainwallet/ui/BrainwalletActivity.kt @@ -1,41 +1,64 @@ package com.brainwallet.ui +import android.Manifest import android.content.Context import android.content.Intent +import android.content.IntentFilter +import android.net.ConnectivityManager +import android.os.Build import android.os.Bundle import android.widget.Toast import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.activity.result.contract.ActivityResultContracts +import androidx.annotation.RequiresApi +import androidx.appcompat.app.AlertDialog import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.lifecycle.lifecycleScope import com.brainwallet.BrainwalletApp import com.brainwallet.R +import com.brainwallet.constants.BWConstants +import com.brainwallet.constants.BWConstants.BW_PIN_LENGTH import com.brainwallet.data.model.AppSetting import com.brainwallet.data.repository.SettingRepository import com.brainwallet.navigation.LegacyNavigation -import com.brainwallet.navigation.MainNavHost +import com.brainwallet.navigation.LegacyNavigation.restartBreadActivity +import com.brainwallet.navigation.LegacyNavigation.startBrainwalletActivity +import com.brainwallet.navigation.MainNavigationHost import com.brainwallet.navigation.Route +import com.brainwallet.navigation.Route.UnLock +import com.brainwallet.presenter.activities.settings.SyncBlockchainActivity import com.brainwallet.presenter.activities.util.BRActivity import com.brainwallet.tools.animation.BRAnimator import com.brainwallet.tools.animation.BRDialog import com.brainwallet.tools.manager.AnalyticsManager import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.manager.InternetManager +import com.brainwallet.tools.manager.sync.SyncThreadManager import com.brainwallet.tools.security.AuthManager import com.brainwallet.tools.security.BRKeyStore import com.brainwallet.tools.security.PostAuth import com.brainwallet.tools.security.SmartValidator -import com.brainwallet.tools.util.BRConstants -import com.brainwallet.tools.util.BRConstants.BW_PIN_LENGTH +import com.brainwallet.tools.sqlite.TransactionDataSource +import com.brainwallet.tools.threads.BRExecutor import com.brainwallet.tools.util.Utils -import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.EFFECT_LEGACY_RECOVER_WALLET_AUTH -import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGACY_DIALOG_INVALID -import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGACY_DIALOG_WIPE_ALERT -import com.brainwallet.ui.screens.inputwords.InputWordsViewModel.Companion.LEGACY_EFFECT_RESET_PIN +import com.brainwallet.ui.screens.restore.RestoreViewModel.Companion.EFFECT_LEGACY_RECOVER_WALLET_AUTH +import com.brainwallet.ui.screens.restore.RestoreViewModel.Companion.LEGACY_DIALOG_INVALID +import com.brainwallet.ui.screens.restore.RestoreViewModel.Companion.LEGACY_DIALOG_WIPE_ALERT +import com.brainwallet.ui.screens.restore.RestoreViewModel.Companion.LEGACY_EFFECT_RESET_PIN +import com.brainwallet.ui.screens.settings.SettingsViewModel import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel.Companion.LEGACY_EFFECT_ON_PAPERKEY_PROVED -import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel.Companion.LEGACY_NAVIGATE_TO_HOME import com.brainwallet.ui.theme.BrainwalletAppTheme import com.brainwallet.util.EventBus +import com.brainwallet.util.PermissionUtil.hasPermission +import com.brainwallet.util.PermissionUtil.requestPermission +import com.brainwallet.wallet.BRPeerManager import com.brainwallet.wallet.BRWalletManager +import com.google.android.gms.tasks.OnCompleteListener +import com.google.android.gms.tasks.Task +import com.google.android.play.core.review.ReviewInfo +import com.google.android.play.core.review.ReviewManagerFactory import kotlinx.coroutines.delay import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -46,14 +69,39 @@ import timber.log.Timber /** * Compose entry point here */ -class BrainwalletActivity : BRActivity() { - +class BrainwalletActivity : + BRActivity(), + BRWalletManager.OnBalanceChanged, + BRPeerManager.OnTxStatusUpdate, + TransactionDataSource.OnTxAddedListener, + InternetManager.ConnectionReceiverListener { private val settingRepository by inject() + private var mConnectionReceiver: InternetManager? = null + var appVisible: Boolean = false + + private val requestNotificationPermissionLauncher = + registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> + if (isGranted) { + Toast.makeText( + this, + R.string.permission_notification_granted, + Toast.LENGTH_SHORT, + ).show() + + Timber.d("Notification permission granted") + } else { + Timber.d("Notification permission denied") + // Optionally show a message explaining reduced functionality + } + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - // /DEV: Test / Dev Composable Shortcut swap to launch - // / Ergo; Route.TopUp + AnalyticsManager.logCustomEvent(BWConstants._BW_MAIN_OPEN) + + onConnectionChanged(InternetManager.getInstance().isConnected(this)) + BRSharedPrefs.getLTCViewingPreference(application) + showInAppReviewDialogIfNeeded() val startDestination = intent.getSerializableExtra(EXTRA_START_DESTINATION) ?: Route.Welcome @@ -69,15 +117,14 @@ class BrainwalletActivity : BRActivity() { val appSetting by settingRepository.settings.collectAsState( AppSetting() ) - + enableEdgeToEdge() BrainwalletAppTheme(appSetting = appSetting) { - MainNavHost( + MainNavigationHost( startDestination = startDestination, onFinish = { finish() } ) } } - /** * Communication between compose and legacy logic using the following event bus * why we are using this event bus? @@ -88,89 +135,178 @@ class BrainwalletActivity : BRActivity() { .onEach { event -> delay(70) when (event) { - is EventBus.Event.Message -> { - when (event.message) { - EFFECT_LEGACY_RECOVER_WALLET_AUTH -> { - PostAuth.getInstance() - .onRecoverWalletAuth(this@BrainwalletActivity, false) - } + is EventBus.Event.Message -> handleLegacyMessage(event.message) + is EventBus.Event.LegacyPasscodeVerified -> onPasscodeVerified(event.passcode) + is EventBus.Event.LegacyUnLock -> onUnlock(event.passcode) + is EventBus.Event.QRCodeScanned -> Unit + } + } + .launchIn(lifecycleScope) + } + private fun handleLegacyMessage(message: String) { + when (message) { + SettingsViewModel.LEGACY_EFFECT_ON_LOCK -> { + startBrainwalletActivity(this, true) + } + SettingsViewModel.LEGACY_EFFECT_ON_TOGGLE_DARK_MODE -> { + restartBreadActivity(this) + } + SettingsViewModel.LEGACY_EFFECT_ON_SEC_UPDATE_PIN -> { + createIntent(this, UnLock(true)) + .apply { putExtra("noPin", true) } + .also { startActivity(it) } + } + SettingsViewModel.LEGACY_EFFECT_ON_SEED_PHRASE -> { + PostAuth.getInstance().onPhraseCheckAuth(this@BrainwalletActivity, true) + } + SettingsViewModel.LEGACY_EFFECT_ON_SHARE_ANALYTICS_DATA_TOGGLE -> { + val current = BRSharedPrefs.getShareData(this) + BRSharedPrefs.putShareData(this, !current) + } + SettingsViewModel.LEGACY_EFFECT_ON_SYNC -> { + startActivity(Intent(this, SyncBlockchainActivity::class.java)) + } + EFFECT_LEGACY_RECOVER_WALLET_AUTH -> { + PostAuth.getInstance().onRecoverWalletAuth(this@BrainwalletActivity, false) + } + LEGACY_EFFECT_RESET_PIN -> { + AuthManager.getInstance().setPinCode("", this) + createIntent( + context = this, + startDestination = Route.SetPasscode() + ).apply { + putExtra("noPin", true) + flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK + }.also { startActivity(it) } + } + LEGACY_EFFECT_ON_PAPERKEY_PROVED -> { + BRSharedPrefs.putPhraseWroteDown(this@BrainwalletActivity, true) + } + LEGACY_DIALOG_INVALID -> BRDialog.showCustomDialog( + BrainwalletApp.breadContext, + "", + getString(R.string.RecoverWallet_invalid), + getString(R.string.AccessibilityLabels_close), + null, + { brDialogView -> + brDialogView.dismissWithAnimation() + BRDialog.hideDialog() + }, + null, null, 0 + ) + LEGACY_DIALOG_WIPE_ALERT -> BRDialog.showCustomDialog( + this, + getString(R.string.WipeWallet_alertTitle), + getString(R.string.WipeWallet_alertMessage), + getString(R.string.WipeWallet_wipe), + getString(R.string.Button_cancel), + { brDialogView -> + brDialogView.dismissWithAnimation() + val m = BRWalletManager.getInstance() + m.wipeWalletButKeystore(this) + m.wipeKeyStore(this) + createIntent(this).apply { + flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK + }.also { startActivity(it) } + }, + { brDialogView -> brDialogView.dismissWithAnimation() }, + null, 0 + ) + else -> Unit + } + } - LEGACY_EFFECT_RESET_PIN -> { - /** - * when the wallet disabled after wrong passcode/pin - * we can enable by reset the pin - */ - AuthManager.getInstance().setPinCode("", this) - createIntent( - context = this, - startDestination = Route.SetPasscode() - ).apply { - putExtra("noPin", true) - flags = - Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK - }.also { - startActivity(it) - } - } + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + private fun setupNotificationPermission() { + if (hasPermission(this, Manifest.permission.POST_NOTIFICATIONS)) return - LEGACY_EFFECT_ON_PAPERKEY_PROVED -> { - BRSharedPrefs.putPhraseWroteDown(this@BrainwalletActivity, true) - } + if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) { + showNotificationRationaleDialog() + } else { + requestPermission(requestNotificationPermissionLauncher, Manifest.permission.POST_NOTIFICATIONS) + } + } - LEGACY_NAVIGATE_TO_HOME -> { - LegacyNavigation.startBreadActivity( - this@BrainwalletActivity, - false + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + private fun showNotificationRationaleDialog() { + AlertDialog.Builder(this) + .setTitle(R.string.permission_info) + .setMessage(R.string.please_grant_notification_permission) + .setNegativeButton(R.string.cancel) { dialog, _ -> dialog.dismiss() } + .setPositiveButton(R.string.ok) { _, _ -> + requestPermission(requestNotificationPermissionLauncher, Manifest.permission.POST_NOTIFICATIONS) + } + .show() + } + + private fun showInAppReviewDialogIfNeeded() { + if (!BRSharedPrefs.isInAppReviewDone(this) && BRSharedPrefs.getSendTransactionCount(this) > 2) { + val manager = ReviewManagerFactory.create(this) + val request = manager.requestReviewFlow() + request.addOnCompleteListener( + OnCompleteListener { task: Task? -> + AnalyticsManager.logCustomEvent(BWConstants._20241006_DRR) + if (task!!.isSuccessful()) { + val reviewInfo = task.getResult() + val flow = manager.launchReviewFlow(this@BrainwalletActivity, reviewInfo) + flow.addOnCompleteListener( + OnCompleteListener { task1: Task? -> + // The flow has finished. The API does not indicate whether the user + // reviewed or not, or even whether the review dialog was shown. Thus, no + // matter the result, we continue our app flow. + Timber.i( + "timber: In-app LaunchReviewFlow completed successful (%s)", + task1!!.isSuccessful() ) - finishAffinity() + if (task1.isSuccessful()) { + BRSharedPrefs.inAppReviewDone(this@BrainwalletActivity) + AnalyticsManager.logCustomEvent(BWConstants._20241006_UCR) + } } - - LEGACY_DIALOG_INVALID -> BRDialog.showCustomDialog( - BrainwalletApp.breadContext, - "", - getString(R.string.RecoverWallet_invalid), - getString(R.string.AccessibilityLabels_close), - null, - { brDialogView -> - brDialogView.dismissWithAnimation() - BRDialog.hideDialog() - }, - null, - null, - 0 - ) - - LEGACY_DIALOG_WIPE_ALERT -> BRDialog.showCustomDialog( - this, - getString(R.string.WipeWallet_alertTitle), - getString(R.string.WipeWallet_alertMessage), - getString(R.string.WipeWallet_wipe), - getString(R.string.Button_cancel), - { brDialogView -> - brDialogView.dismissWithAnimation() - val m = BRWalletManager.getInstance() - m.wipeWalletButKeystore(this@BrainwalletActivity) - m.wipeKeyStore(this@BrainwalletActivity) - - createIntent(this@BrainwalletActivity).apply { - flags = - Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK - }.also { startActivity(it) } - }, - { brDialogView -> brDialogView.dismissWithAnimation() }, - null, - 0 - ) - - else -> Unit - } + ) + } else { + Timber.e(task.getException(), "In-app request review flow failed") } - - is EventBus.Event.LegacyPasscodeVerified -> onPasscodeVerified(event.passcode) - is EventBus.Event.LegacyUnLock -> onUnlock(event.passcode) } + ) + } + } + + private fun setupNetworking() { + if (mConnectionReceiver == null) mConnectionReceiver = InternetManager.getInstance() + val mNetworkStateFilter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) + registerReceiver(mConnectionReceiver, mNetworkStateFilter) + InternetManager.addConnectionListener(this) + } + + private fun teardownNetworking() { + mConnectionReceiver?.let { + try { + unregisterReceiver(it) + } catch (e: IllegalArgumentException) { + Timber.w(e, "Connection receiver was not registered") } - .launchIn(lifecycleScope) + InternetManager.removeConnectionListener(this) + mConnectionReceiver = null + } + } + + override fun onConnectionChanged(isConnected: Boolean) { + val thisContext: Context = this@BrainwalletActivity + val ltcStats = BRSharedPrefs.getLiveLtcStats(thisContext) + val startHeight = ltcStats.currentBlockHeight + if (isConnected) { + BRExecutor.getInstance().forLightWeightBackgroundTasks().execute( + Runnable { + val progress = BRPeerManager.syncProgress(startHeight) + if (progress > 0 && progress < 1) { + SyncThreadManager.getInstance().startSyncing(startHeight) + } + } + ) + } else { + SyncThreadManager.getInstance().stopSyncing() + } } /** @@ -178,45 +314,69 @@ class BrainwalletActivity : BRActivity() { * then should go to setpasscode */ private fun onCheckPin() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + setupNotificationPermission() + } val pin = BRKeyStore.getPinCode(this) if (pin.isEmpty() && pin.length != BW_PIN_LENGTH) { lifecycleScope.launch { EventBus.emit( EventBus.Event.Message( - LEGACY_EFFECT_RESET_PIN + LEGACY_EFFECT_RESET_PIN, + address = null ) ) } } else if (BRSharedPrefs.getPhraseWroteDown(this).not()) { PostAuth.getInstance().onPhraseCheckAuth(this, false) + Timber.d("initWallet: post auth onPhraseCheckAuth") } } /** * provide old logic to use compose unlock screen instead of LoginActivity */ + + private fun onLegacyLogic() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + setupNotificationPermission() + } + if (Utils.isEmulatorOrDebug(this)) Utils.printPhoneSpecs() + + val masterPubKey = BRKeyStore.getMasterPublicKey(this) + var isFirstAddressCorrect = false + if (masterPubKey != null && masterPubKey.isNotEmpty()) { + Timber.d("timber: masterPubkey exists") + + isFirstAddressCorrect = SmartValidator.checkFirstAddress(this, masterPubKey) + } + if (!isFirstAddressCorrect) { + Timber.d("timber: Calling wipeWalletButKeyStore") + BRWalletManager.getInstance().wipeWalletButKeystore(this) + } + + /** + * inside the following it will handle navigate to old activity [com.brainwallet.presenter.activities.BreadActivity] + */ + PostAuth.getInstance().onCanaryCheck(this, false) + } private fun onUnlock(passcode: List) { if (AuthManager.getInstance().checkAuth(passcode.joinToString(""), this)) { AuthManager.getInstance().authSuccess(this) - AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) - AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) - LegacyNavigation.startBreadActivity(this, false) + AnalyticsManager.logCustomEvent(BWConstants._20200217_DUWB) + LegacyNavigation.startBrainwalletActivity(this, false) } else { - AuthManager.getInstance().authFail(this) - // for now just toast + // Auth fail toast Toast.makeText(this, R.string.incorrect_passcode, Toast.LENGTH_SHORT).show() } } - /** - * this is old logic - */ private fun onPasscodeVerified(passcode: List) { AuthManager.getInstance().authSuccess(this) AuthManager.getInstance().setPinCode(passcode.joinToString(separator = ""), this) if (intent.getBooleanExtra("noPin", false)) { - LegacyNavigation.startBreadActivity(this, false) + LegacyNavigation.startBrainwalletActivity(this, false) } else { BRAnimator.showBreadSignal( this, @@ -234,29 +394,54 @@ class BrainwalletActivity : BRActivity() { } } - /** - * describe [onLegacyLogic] - * this will be using the old logic from the IntroActivity (already gone) - */ - private fun onLegacyLogic() { - if (Utils.isEmulatorOrDebug(this)) Utils.printPhoneSpecs() + override fun onPause() { + super.onPause() + appVisible = false + removeObservers() + teardownNetworking() + } - val masterPubKey = BRKeyStore.getMasterPublicKey(this) - var isFirstAddressCorrect = false - if (masterPubKey != null && masterPubKey.isNotEmpty()) { - Timber.d("timber: masterPubkey exists") + override fun onDestroy() { + super.onDestroy() + } - isFirstAddressCorrect = SmartValidator.checkFirstAddress(this, masterPubKey) - } - if (!isFirstAddressCorrect) { - Timber.d("timber: Calling wipeWalletButKeyStore") - BRWalletManager.getInstance().wipeWalletButKeystore(this) + override fun onRestart() { + super.onRestart() + } + + private fun addObservers() { + BRWalletManager.getInstance().addBalanceChangedListener(this) + } + + private fun removeObservers() { + BRWalletManager.getInstance().removeListener(this) + } + + override fun onResume() { + super.onResume() + appVisible = true + addObservers() + setupNetworking() + + if (!BRWalletManager.getInstance().isCreated()) { + BRExecutor.getInstance().forBackgroundTasks().execute { + BRWalletManager.getInstance().initWallet(this) + } } + BRWalletManager.getInstance().refreshBalance(this) + } - /** - * inside the following it will handle navigate to old activity [com.brainwallet.presenter.activities.BreadActivity] - */ - PostAuth.getInstance().onCanaryCheck(this, false) + override fun onBalanceChanged(balance: Long) { + Timber.d("timber: BrainwalletActivity subscribed onBalanceChanged $balance") + } + + override fun onStatusPeerManagerUpdate() { + Timber.d("timber: BrainwalletActivity subscribed onStatusUpdate") + } + + override fun onTxAdded() { + BRWalletManager.getInstance().refreshBalance(this) + Timber.d("timber: BrainwalletActivity subscribed onTxAdded") } companion object { diff --git a/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt b/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt index 167d6688..e065136d 100644 --- a/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/BrainwalletViewModel.kt @@ -1,33 +1,31 @@ package com.brainwallet.ui import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import com.brainwallet.di.AppModule.json import com.brainwallet.navigation.UiEffect -import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.getAndUpdate -import kotlinx.coroutines.flow.receiveAsFlow -import kotlinx.coroutines.launch import kotlinx.serialization.json.JsonObject /** * describe [BrainwalletViewModel] here */ abstract class BrainwalletViewModel : ViewModel() { - - private val _uiEffect = Channel() - val uiEffect = _uiEffect.receiveAsFlow() - private val _loadingState = MutableStateFlow(LoadingState()) val loadingState: StateFlow = _loadingState.asStateFlow() + private val _uiEffect = MutableSharedFlow( + extraBufferCapacity = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST + ) + val uiEffect = _uiEffect.asSharedFlow() fun sendUiEffect(effect: UiEffect) { - viewModelScope.launch { - _uiEffect.send(effect) - } + _uiEffect.tryEmit(effect) } abstract fun onEvent(event: Event) diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoEvent.kt b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoEvent.kt new file mode 100644 index 00000000..cd968cd8 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoEvent.kt @@ -0,0 +1,6 @@ +package com.brainwallet.ui.bentosections.balancebento + +sealed class BalanceBentoEvent { + data object OnLoad : BalanceBentoEvent() + data object OnToggleBalanceVisibility : BalanceBentoEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoScreen.kt new file mode 100644 index 00000000..5c836a4a --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoScreen.kt @@ -0,0 +1,397 @@ +package com.brainwallet.ui.bentosections.balancebento + +import android.media.MediaPlayer +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.spring +import androidx.compose.animation.core.tween +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.LinearProgressIndicator +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.StrokeCap +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.compose.ui.zIndex +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.compose.LifecycleEventEffect +import androidx.lifecycle.viewmodel.compose.viewModel +import com.brainwallet.R +import com.brainwallet.presenter.entities.TxItem +import com.brainwallet.ui.screens.main.MainScreenEvent +import com.brainwallet.ui.screens.main.MainScreenState +import com.brainwallet.ui.screens.main.MainViewModel +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.balanceBackgroundGradient +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.blurWhen +import kotlinx.collections.immutable.ImmutableList +import org.koin.compose.viewmodel.koinViewModel +import java.math.BigDecimal + +@Composable +fun BalanceBentoScreen( + transactions: ImmutableList, + modifier: Modifier = Modifier, + viewModel: BalanceBentoViewModel = koinViewModel(), + mainViewModel: MainViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + val mainState by mainViewModel.state.collectAsState() + + LifecycleEventEffect(Lifecycle.Event.ON_RESUME) { + viewModel.onEvent(BalanceBentoEvent.OnLoad) + viewModel.onResume() + } + + LifecycleEventEffect(Lifecycle.Event.ON_PAUSE) { + viewModel.onPause() + } + + BalanceBentoScreen( + state = state, + transactions = transactions, + mainState = mainState, + onEvent = viewModel::onEvent, + onMainEvent = mainViewModel::onEvent, + modifier = modifier, + onDebugStatusUpdate = viewModel::debugTriggerStatusUpdate, + onDebugTxAdded = viewModel::debugTriggerTxAdded, + onDebugBalanceChanged = viewModel::debugTriggerBalanceChanged, + ) +} + +@Composable +fun BalanceBentoScreen( + state: BalanceBentoState, + transactions: ImmutableList, + mainState: MainScreenState, + onEvent: (BalanceBentoEvent) -> Unit, + onMainEvent: (MainScreenEvent) -> Unit, + modifier: Modifier = Modifier, + onDebugStatusUpdate: () -> Unit = {}, + onDebugTxAdded: () -> Unit = {}, + onDebugBalanceChanged: () -> Unit = {}, +) { + val context = LocalContext.current + val infiniteTransition = rememberInfiniteTransition() + var previousBalance by remember { mutableStateOf(BigDecimal.ZERO) } + + val throbOpacity by infiniteTransition.animateFloat( + initialValue = 0.5f, + targetValue = 1f, + animationSpec = infiniteRepeatable(tween(1000), RepeatMode.Reverse) + ) + + // ── swap animation ──────────────────────────────────────────────────── + var isSwapped by remember { mutableStateOf(false) } + val primaryOffset by animateDpAsState( + targetValue = if (isSwapped) 40.dp else 0.dp, + animationSpec = spring( + dampingRatio = 0.5f, + stiffness = Spring.StiffnessVeryLow, + ), + label = "primaryOffset", + ) + val secondaryOffset by animateDpAsState( + targetValue = if (isSwapped) 0.dp else 40.dp, + animationSpec = spring( + dampingRatio = 0.5f, + stiffness = Spring.StiffnessVeryLow, + ), + label = "secondaryOffset", + ) + + val progressLabel = "%.2f".format(state.syncProgress * 100) + "%" + val currentBlockLabel = stringResource(R.string.block_height_label) + + " ${state.currentBlockHeight}" + val currentTxsLabel = + stringResource(R.string.current_transaction_count) + " %d".format(transactions.size) + val iconImage: Painter + + if (state.balanceHidden) { + iconImage = painterResource(id = R.drawable.visibility_svg) + } else { + iconImage = painterResource(id = R.drawable.visibility_off) + } + val coinAudioPlayer = remember { MediaPlayer.create(context, R.raw.coinflip) } + val previousCount = remember { mutableIntStateOf(state.transactions.size) } + + // Listen for changes in number of transactions + LaunchedEffect(state.transactions) { + if (state.transactions.size > previousCount.intValue) { + coinAudioPlayer.start() + } + previousCount.intValue = state.transactions.size + } + + Box( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight() + .background( + brush = balanceBackgroundGradient, + shape = RoundedCornerShape(16.dp) + ) + .border( + width = 1.5.dp, + brush = if (state.darkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = RoundedCornerShape(16.dp) + ) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(start = 12.dp, end = 12.dp, top = 6.dp, bottom = 28.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Column( + modifier = Modifier + .fillMaxHeight() + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null + ) { isSwapped = !isSwapped } + ) { + // ──────── MY BALANCE LABEL ──────── + Text( + modifier = Modifier + .blurWhen(!mainState.isInternetReachable), + text = stringResource(R.string.my_balance), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = Color.White + ), + maxLines = 1 + ) + Box( + modifier = Modifier + .fillMaxHeight() + .fillMaxWidth(0.5f) + ) { + // ──────── TOP CURRENCY ──────── + Text( + text = if (state.balanceHidden) "" else "Ł${mainState.litoshiBalance}", + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = if (isSwapped) FontWeight.Light else FontWeight.SemiBold, + fontSize = if (isSwapped) 13.sp else 30.sp, + color = Color.White, + ), + maxLines = 1, + modifier = Modifier + .fillMaxWidth() + .blurWhen(!mainState.isInternetReachable) + .offset(y = primaryOffset) + .zIndex(if (isSwapped) 1f else 0f) + + ) + // ──────── BOTTOM CURRENCY ──────── + Text( + text = if (state.balanceHidden) { + "" + } else { + "${mainState.selectedCurrency.symbol}${mainState.fiatBalanceFormatted}" + }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = if (isSwapped) FontWeight.SemiBold else FontWeight.Light, + fontSize = if (isSwapped) 30.sp else 13.sp, + color = Color.White, + ), + maxLines = 1, + modifier = Modifier + .fillMaxWidth() + .blurWhen(!mainState.isInternetReachable) + .offset(y = secondaryOffset) + .zIndex(if (isSwapped) 0f else 1f) + ) + } + Spacer(modifier = Modifier.weight(1f)) + } + Spacer(modifier = Modifier.weight(1f)) + Column( + modifier = Modifier + .fillMaxHeight() + ) { + Icon( + modifier = Modifier.align(Alignment.End) + .padding(bottom = 5.dp) + .size(30.dp) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + ) { onEvent(BalanceBentoEvent.OnToggleBalanceVisibility) } + .blurWhen(!mainState.isInternetReachable), + painter = iconImage, + contentDescription = "Toggle Balance Show", + tint = Color.White + ) + // ──────── SYNC MESSAGE ──────── + Text( + modifier = Modifier.align(Alignment.End) + .alpha(if (state.brainwalletIsSyncing) 1f else 0f) + .blurWhen(!mainState.isInternetReachable), + text = state.topMessage, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = Color.White + ), + maxLines = 1 + ) + // ──────── CURRENT TXNS LABEL ──────── + Text( + modifier = Modifier.align(Alignment.End) + .alpha(if (state.brainwalletIsSyncing) 1f else 0f) + .blurWhen(!mainState.isInternetReachable), + text = currentTxsLabel, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = Color.White + ), + maxLines = 1 + ) + // ──────── TIMESTAMP LABEL ──────── + Text( + modifier = Modifier.align(Alignment.End) + .alpha(if (state.brainwalletIsSyncing) 1f else 0f) + .blurWhen(!mainState.isInternetReachable), + text = state.lastTimeStamp, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = Color.White + ) + ) + Spacer(modifier = Modifier.weight(1f)) + } + } + + Row( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight() + .padding(horizontal = 12.dp, vertical = 12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Column { + Spacer( + modifier = Modifier.weight(0.5f) + ) + Row( + modifier = Modifier + .fillMaxWidth() + .alpha(if (state.brainwalletIsSyncing) 1f else 0f), + verticalAlignment = Alignment.CenterVertically, + + ) { + Text( + modifier = Modifier + .width(70.dp) + .padding(bottom = 3.dp) + .blurWhen(!mainState.isInternetReachable) + .graphicsLayer { + alpha = throbOpacity + }, + text = progressLabel, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 12.sp, + color = Color.White + ), + maxLines = 1 + ) + + Text( + modifier = Modifier.padding(2.dp, bottom = 3.dp) + .blurWhen(!mainState.isInternetReachable), + text = if (state.currentBlockHeight > 1) currentBlockLabel else "", + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 13.sp, + color = Color.White + ), + maxLines = 1 + ) + + Spacer(modifier = Modifier.weight(1f)) + + SyncStatusSubScreen( + modifier = Modifier, + isInternetReachable = !mainState.isInternetReachable + ) + } + LinearProgressIndicator( + progress = { state.syncProgress }, + modifier = Modifier.fillMaxWidth() + .alpha(if (state.brainwalletIsSyncing) 1f else 0f) + .blurWhen(!mainState.isInternetReachable), + color = DesignTheme.colors.affirm, + trackColor = Color.White.copy(0.5f), + strokeCap = StrokeCap.Round, + gapSize = (-15).dp, + drawStopIndicator = {} + ) + } + } + NoWifiBalanceAlertScreen( + modifier = Modifier, + isInternetReachable = !mainState.isInternetReachable + ) +// Uncomment to trigger BRWalletManager Callbacks +// if (BuildConfig.DEBUG) { +// Row(modifier = Modifier.background(Color.Red)) { +// Button(onClick = onDebugStatusUpdate) { Text("Status Update") } +// Button(onClick = onDebugTxAdded) { Text("Tx Added") } +// Button(onClick = onDebugBalanceChanged) { Text("Balance Changed") } +// } +// } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoState.kt b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoState.kt new file mode 100644 index 00000000..51fc8b73 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoState.kt @@ -0,0 +1,21 @@ +package com.brainwallet.ui.bentosections.balancebento + +import com.brainwallet.data.model.LtcStats +import com.brainwallet.presenter.entities.TxItem +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf + +data class BalanceBentoState( + val darkMode: Boolean = true, + val fiatCode: String = "USD", + val symbol: String = "$", + val topMessage: String = "Syncing...", + val lastTimeStamp: String = "", + val syncProgress: Float = 0.5f, + val currentBlockHeight: Int = 0, + val balanceHidden: Boolean = true, + val brainwalletIsSyncing: Boolean = true, + val transactions: ImmutableList = persistentListOf(), + val isInternetReachable: Boolean = true, + val ltcStats: LtcStats? = null, +) diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoViewModel.kt b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoViewModel.kt new file mode 100644 index 00000000..17f2ee7f --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/BalanceBentoViewModel.kt @@ -0,0 +1,165 @@ +package com.brainwallet.ui.bentosections.balancebento +import android.app.Application +import androidx.lifecycle.viewModelScope +import com.brainwallet.BuildConfig +import com.brainwallet.data.repository.ConnectivityRepository +import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.data.repository.TxRepository +import com.brainwallet.data.source.PeerManagerSource +import com.brainwallet.tools.sqlite.TransactionDataSource +import com.brainwallet.ui.BrainwalletViewModel +import com.brainwallet.wallet.BRPeerManager +import com.brainwallet.wallet.BRWalletManager +import com.brainwallet.wallet.BRWalletManager.onBalanceChanged +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +import timber.log.Timber +import java.util.Date + +@KoinViewModel +class BalanceBentoViewModel( + private val app: Application, + private val txRepository: TxRepository, + private val ltcRepository: LtcRepository, + private val settingRepository: SettingRepository, + private val peerManagerSource: PeerManagerSource, + private val connectivityRepository: ConnectivityRepository, +) : BrainwalletViewModel(), + BRPeerManager.OnTxStatusUpdate, + TransactionDataSource.OnTxAddedListener { + private val _state = MutableStateFlow(BalanceBentoState()) + val state: StateFlow = _state.asStateFlow() + val formatter = java.text.SimpleDateFormat( + "MMM dd, yyyy hh:mm a", + java.util.Locale.getDefault() + ) + + init { + // ──────── Collecting PeerManager / Syncing Updates ──────── + viewModelScope.launch { + peerManagerSource.blockInfo.collect { blockInfo -> + Timber.d("timber: blockInfo Height: %d progress: %3.3f", blockInfo.blockHeight, blockInfo.syncProgress) + _state.update { + it.copy( + currentBlockHeight = blockInfo.blockHeight, + lastTimeStamp = formatter.format(Date(blockInfo.timestamp * 1000L)), + syncProgress = blockInfo.syncProgress, + brainwalletIsSyncing = blockInfo.syncProgress <= 0.99f, + ) + } + Timber.d("brainwalletIsSyncing Collecting PeerManager %s", state.value.brainwalletIsSyncing) + } + } + + // ──────── Collecting Mainnet LTC Chain Updates ──────── + viewModelScope.launch { + ltcRepository.ltcStats.collect { ltcStats -> + _state.update { + it.copy( + ltcStats = ltcStats, + ) + } + } + } + + // ──────── Collecting Reachability Updates ──────── + viewModelScope.launch { + connectivityRepository.isConnected.collect { isInternetReachable -> + _state.update { it.copy(isInternetReachable = isInternetReachable) } + } + } + } + + fun onResume( + isWalletCreated: () -> Boolean = { BRWalletManager.getInstance().isCreated() }, + ioDispatcher: CoroutineDispatcher = Dispatchers.IO + ) { + viewModelScope.launch(ioDispatcher) { + var attempts = 0 + + while (!isWalletCreated() && attempts < 20) { + delay(250) + attempts++ + } + if (isWalletCreated()) { + addObservers() + txRepository.refresh() + } else { + Timber.d("onResume: Wallet not ready") + } + } + } + + fun onPause() { + removeObservers() + } + + override fun onCleared() { + super.onCleared() + BRPeerManager.getInstance().removeListener(this) + TransactionDataSource.getInstance(app).removeListener(this) + } + private fun addObservers() { + BRPeerManager.getInstance().addStatusUpdateListener(this) + TransactionDataSource.getInstance(app).addTxAddedListener(this) + } + private fun removeObservers() { + BRPeerManager.getInstance().removeListener(this) + TransactionDataSource.getInstance(app).removeListener(this) + } + + override fun onStatusPeerManagerUpdate() { + Timber.d("BalanceBentoViewModel: onStatusPeerManagerUpdate fired") + } + + override fun onTxAdded() { + viewModelScope.launch(Dispatchers.IO) { + txRepository.refresh() + } + } + + override fun onEvent(event: BalanceBentoEvent) { + when (event) { + is BalanceBentoEvent.OnLoad -> { + val syncProgress = peerManagerSource.getSyncProgress().toFloat() + val currentSettings = settingRepository.currentSettings.value + _state.update { + it.copy( + lastTimeStamp = "", + fiatCode = currentSettings.currency.code, + symbol = currentSettings.currency.symbol, + syncProgress = syncProgress, + brainwalletIsSyncing = syncProgress <= 0.99f + ) + } + Timber.d("brainwalletIsSyncing BalanceBentoEvent.OnLoad %s", state.value.brainwalletIsSyncing) + } + is BalanceBentoEvent.OnToggleBalanceVisibility -> { + _state.update { it.copy(balanceHidden = !it.balanceHidden) } + } + } + } + + fun debugTriggerStatusUpdate() { + if (!BuildConfig.DEBUG) return + onStatusPeerManagerUpdate() + } + + fun debugTriggerTxAdded() { + if (!BuildConfig.DEBUG) return + onTxAdded() + } + + fun debugTriggerBalanceChanged(balance: Long = 1_000_000L) { + if (!BuildConfig.DEBUG) return + onBalanceChanged(balance) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/NoWifiBalanceAlertScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/NoWifiBalanceAlertScreen.kt new file mode 100644 index 00000000..9cd49db7 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/NoWifiBalanceAlertScreen.kt @@ -0,0 +1,120 @@ +package com.brainwallet.ui.bentosections.balancebento + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.constants.iconBorderSize +import com.brainwallet.constants.iconSize +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.grape + +class NoWifiBalanceAlertScreen + +@Composable +fun NoWifiBalanceAlertScreen( + modifier: Modifier = Modifier, + isInternetReachable: Boolean = true +) { + AnimatedVisibility( + visible = isInternetReachable, + enter = fadeIn(animationSpec = tween(700)), + exit = fadeOut(animationSpec = tween(700)) + ) { + Row( + modifier = Modifier + .fillMaxSize() + .border( + width = 1.dp, + color = Color.White.copy(alpha = 0.15f), + shape = RoundedCornerShape(16.dp) + ) + .background( + color = grape.copy(alpha = 0.45f), + shape = RoundedCornerShape(16.dp) + ) + ) { + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Spacer(modifier = Modifier.weight(1f)) + + Box( + contentAlignment = Alignment.Center, + modifier = Modifier + .size(iconBorderSize) + .background( + color = Color.White.copy(alpha = 0.15f), + shape = CircleShape + ) + ) { + Icon( + modifier = Modifier + .padding(start = 4.dp, end = 4.dp, bottom = 4.dp) + .height(iconSize) + .width(iconSize) + .offset(y = 2.dp), + painter = painterResource(R.drawable.ic_no_wifi), + contentDescription = "No Internet", + tint = Color.White, + ) + } + Text( + modifier = Modifier + .align(Alignment.CenterHorizontally) + .padding(top = 8.dp, bottom = 6.dp), + text = stringResource(R.string.no_internet_dialog_title), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 15.sp, + color = Color.White + ), + maxLines = 1 + ) + Text( + modifier = Modifier + .align(Alignment.CenterHorizontally) + .padding(top = 2.dp), + text = stringResource(R.string.no_internet_dialog_subtitle), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 13.sp, + color = Color.White + ), + maxLines = 1 + ) + Spacer(modifier = Modifier.weight(1f)) + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/SyncStatusSubScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/SyncStatusSubScreen.kt new file mode 100644 index 00000000..42c28e56 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/balancebento/SyncStatusSubScreen.kt @@ -0,0 +1,77 @@ +package com.brainwallet.ui.bentosections.balancebento + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.ui.theme.IBMPlexSans + +@Composable +fun SyncStatusSubScreen( + modifier: Modifier = Modifier, + isInternetReachable: Boolean = true +) { + Row( + modifier = Modifier + .alpha(if (isInternetReachable) 0f else 1f) + .fillMaxWidth() + .height(20.dp) + .padding(bottom = 4.dp) + ) { + Spacer(modifier = Modifier.weight(1f)) + Text( + modifier = Modifier.padding(end = 2.dp) + .align(Alignment.CenterVertically), + text = stringResource(R.string.Send_title), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Light, + fontSize = 11.sp, + color = Color.White + ), + maxLines = 1 + ) + Icon( + modifier = Modifier.padding(start = 4.dp, end = 4.dp) + .align(Alignment.CenterVertically), + painter = painterResource(R.drawable.cancel_24dp), + contentDescription = "Cancel", + tint = DesignTheme.colors.error + ) + Text( + modifier = Modifier.padding(start = 4.dp, end = 2.dp) + .align(Alignment.CenterVertically), + text = stringResource(R.string.Receive_title), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Light, + fontSize = 11.sp, + color = Color.White + ), + maxLines = 1 + ) + Icon( + modifier = Modifier.padding(start = 4.dp) + .align(Alignment.CenterVertically), + painter = painterResource(id = R.drawable.check_circle_24dp), + contentDescription = "Check circle send", + tint = DesignTheme.colors.affirm + ) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialog.kt similarity index 88% rename from app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt rename to app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialog.kt index 7d71701d..10252ec3 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialog.kt @@ -1,6 +1,6 @@ @file:OptIn(ExperimentalMaterial3Api::class, FlowPreview::class) -package com.brainwallet.ui.screens.home.receive +package com.brainwallet.ui.bentosections.buyreceivebento.receive import android.widget.Toast import androidx.compose.animation.AnimatedVisibility @@ -50,6 +50,7 @@ import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.KeyboardType @@ -66,11 +67,10 @@ import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.LoadingState import com.brainwallet.ui.composable.MoonpayBuyButton import com.brainwallet.ui.composable.VerticalWheelPicker -import com.brainwallet.ui.composable.WheelPickerFocusVertical import com.brainwallet.ui.composable.WheelPickerState import com.brainwallet.ui.composable.rememberWheelPickerState import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.delay import kotlinx.coroutines.flow.debounce @@ -78,6 +78,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import org.koin.compose.viewmodel.koinViewModel import timber.log.Timber +import com.brainwallet.ui.composable.WheelPickerFocusVertical @Composable fun ReceiveDialog( @@ -105,12 +106,12 @@ fun ReceiveDialog( } } } - + // Set the initial index to the selected fiat currency LaunchedEffect(Unit) { delay(500) wheelPickerFiatCurrencyState.scrollToIndex(state.getSelectedFiatCurrencyIndex()) } - + // Listen for changes in the selected fiat currency index LaunchedEffect(wheelPickerFiatCurrencyState) { snapshotFlow { wheelPickerFiatCurrencyState.currentIndex } .filter { it > -1 } @@ -153,13 +154,13 @@ private fun ReceiveDialog( Box( modifier = modifier .background( - BrainwalletTheme.colors.content, - shape = BrainwalletTheme.shapes.large + DesignTheme.colors.content, + shape = DesignTheme.shapes.large ) .border( width = 1.dp, - color = BrainwalletTheme.colors.surface, - shape = BrainwalletTheme.shapes.large + color = DesignTheme.colors.surface, + shape = DesignTheme.shapes.large ), ) { Column( @@ -171,14 +172,14 @@ private fun ReceiveDialog( ) { CenterAlignedTopAppBar( colors = TopAppBarDefaults.centerAlignedTopAppBarColors( - containerColor = BrainwalletTheme.colors.content // invert surface + containerColor = DesignTheme.colors.content // invert surface ), expandedHeight = 56.dp, title = { Text( text = stringResource(R.string.bottom_nav_item_buy_receive_title).uppercase(), - style = BrainwalletTheme.typography.titleSmall.copy( - color = BrainwalletTheme.colors.surface + style = DesignTheme.typography.titleSmall.copy( + color = DesignTheme.colors.surface ) ) }, @@ -202,7 +203,7 @@ private fun ReceiveDialog( Icon( Icons.Default.Close, contentDescription = stringResource(R.string.AccessibilityLabels_close), - tint = BrainwalletTheme.colors.surface + tint = DesignTheme.colors.surface ) } } @@ -232,7 +233,7 @@ private fun ReceiveDialog( .weight(1f), bitmap = imageBitmap, contentDescription = "address", - colorFilter = ColorFilter.tint(BrainwalletTheme.colors.surface) + colorFilter = ColorFilter.tint(DesignTheme.colors.surface) ) } ?: Box( modifier = Modifier @@ -248,9 +249,9 @@ private fun ReceiveDialog( ) { Text( text = state.address, - style = BrainwalletTheme.typography.bodyLarge.copy( + style = DesignTheme.typography.bodyLarge.copy( fontWeight = FontWeight.Bold, - color = BrainwalletTheme.colors.surface + color = DesignTheme.colors.surface ), maxLines = 4, overflow = TextOverflow.Ellipsis @@ -261,8 +262,8 @@ private fun ReceiveDialog( ) { Text( text = stringResource(R.string.new_address).uppercase(), - style = BrainwalletTheme.typography.bodySmall.copy( - color = BrainwalletTheme.colors.surface, + style = DesignTheme.typography.bodySmall.copy( + color = DesignTheme.colors.surface, ), modifier = Modifier.weight(1f) ) @@ -278,13 +279,13 @@ private fun ReceiveDialog( .show() }, colors = IconButtonDefaults.outlinedIconButtonColors( - containerColor = BrainwalletTheme.colors.content.copy(alpha = 0.5f) + containerColor = DesignTheme.colors.content.copy(alpha = 0.5f) ), ) { Icon( - painter = androidx.compose.ui.res.painterResource(id = R.drawable.ic_copy), + painter = painterResource(id = R.drawable.ic_copy), contentDescription = stringResource(R.string.URLHandling_copy), - tint = BrainwalletTheme.colors.surface + tint = DesignTheme.colors.surface ) } } @@ -302,7 +303,7 @@ private fun ReceiveDialog( modifier = Modifier.weight(1f), focus = { WheelPickerFocusVertical( - dividerColor = BrainwalletTheme.colors.surface.copy( + dividerColor = DesignTheme.colors.surface.copy( alpha = 0.5f ) ) @@ -314,7 +315,7 @@ private fun ReceiveDialog( Text( text = state.fiatCurrencies[index].code, fontWeight = FontWeight.Bold, - color = BrainwalletTheme.colors.surface + color = DesignTheme.colors.surface ) } @@ -324,15 +325,15 @@ private fun ReceiveDialog( ) { Text( text = state.getLtcAmountFormatted(loadingState.visible), - style = BrainwalletTheme.typography.titleLarge.copy( + style = DesignTheme.typography.titleLarge.copy( fontWeight = FontWeight.Bold, - color = BrainwalletTheme.colors.surface + color = DesignTheme.colors.surface ) ) Text( text = state.getRatesUpdatedAtFormatted(), - style = BrainwalletTheme.typography.bodySmall.copy( - color = BrainwalletTheme.colors.surface + style = DesignTheme.typography.bodySmall.copy( + color = DesignTheme.colors.surface ) ) } @@ -360,8 +361,8 @@ private fun ReceiveDialog( } else { quickFiatAmountOption.getFormattedText() }, - style = BrainwalletTheme.typography.bodyMedium.copy( - color = BrainwalletTheme.colors.surface + style = DesignTheme.typography.bodyMedium.copy( + color = DesignTheme.colors.surface ) ) }, @@ -380,8 +381,8 @@ private fun ReceiveDialog( prefix = { Text( text = state.selectedFiatCurrency.symbol, - style = BrainwalletTheme.typography.bodyMedium.copy( - color = BrainwalletTheme.colors.surface + style = DesignTheme.typography.bodyMedium.copy( + color = DesignTheme.colors.surface ) ) }, @@ -392,8 +393,8 @@ private fun ReceiveDialog( Icon(Icons.Default.Done, contentDescription = null) } }, - textStyle = BrainwalletTheme.typography.bodyMedium.copy( - color = BrainwalletTheme.colors.surface + textStyle = DesignTheme.typography.bodyMedium.copy( + color = DesignTheme.colors.surface ), value = "${if (state.fiatAmount < 1) "" else state.fiatAmount}", singleLine = true, @@ -402,7 +403,7 @@ private fun ReceiveDialog( val amount = input.toFloatOrNull() ?: 0f onEvent(ReceiveDialogEvent.OnFiatAmountChange(amount, false)) }, - shape = BrainwalletTheme.shapes.large, + shape = DesignTheme.shapes.large, isError = state.errorFiatAmountStringId != null, supportingText = { state.errorFiatAmountStringId?.let { diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogEvent.kt similarity index 92% rename from app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt rename to app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogEvent.kt index 7c090049..abf5d322 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogEvent.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.receive +package com.brainwallet.ui.bentosections.buyreceivebento.receive import android.content.Context import com.brainwallet.data.model.CurrencyEntity diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogFragment.kt similarity index 93% rename from app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt rename to app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogFragment.kt index c63a4d62..c13b1d48 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogFragment.kt +++ b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogFragment.kt @@ -1,5 +1,6 @@ -package com.brainwallet.ui.screens.home.receive +package com.brainwallet.ui.bentosections.buyreceivebento.receive +import android.R import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -52,7 +53,7 @@ class ReceiveDialogFragment : DialogFragment() { ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT ) - dialog?.window?.setBackgroundDrawableResource(android.R.color.transparent) + dialog?.window?.setBackgroundDrawableResource(R.color.transparent) isCancelable = false } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogState.kt similarity index 97% rename from app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt rename to app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogState.kt index 0cdb7854..8c12bf53 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogState.kt +++ b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogState.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.receive +package com.brainwallet.ui.bentosections.buyreceivebento.receive import android.graphics.Bitmap import com.brainwallet.data.model.CurrencyEntity diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogViewModel.kt similarity index 95% rename from app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt rename to app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogViewModel.kt index 0df5bd51..d58a2550 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/receive/ReceiveDialogViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/bentosections/buyreceivebento/receive/ReceiveDialogViewModel.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.receive +package com.brainwallet.ui.bentosections.buyreceivebento.receive import androidx.lifecycle.viewModelScope import com.brainwallet.R @@ -23,7 +23,6 @@ import kotlinx.coroutines.flow.updateAndGet import kotlinx.coroutines.launch import org.koin.android.annotation.KoinViewModel -// todo: wip @KoinViewModel class ReceiveDialogViewModel( private val settingRepository: SettingRepository, @@ -150,13 +149,14 @@ class ReceiveDialogViewModel( onLoading(true) val currentState = state.value + val currentSettings = settingRepository.currentSettings.value val signedUrl = ltcRepository.fetchMoonpaySignedUrl( mapOf( "baseCurrencyCode" to currentState.selectedFiatCurrency.code, "baseCurrencyAmount" to currentState.fiatAmount.toString(), - "language" to appSetting.value.languageCode, + "language" to currentSettings.languageCode, "walletAddress" to currentState.address, - "theme" to if (appSetting.value.isDarkMode) "dark" else "light" + "theme" to if (currentSettings.isDarkMode) "dark" else "light" ) ) diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/favouritesbento/FavouritesBentoScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/favouritesbento/FavouritesBentoScreen.kt new file mode 100644 index 00000000..f880eea2 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/favouritesbento/FavouritesBentoScreen.kt @@ -0,0 +1,171 @@ +package com.brainwallet.ui.bentosections.favouritesbento + +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.brainwallet.ui.screens.main.MainViewModel +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.R +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.airbnb.lottie.model.content.CircleShape +import com.brainwallet.constants.favouriteSize +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoDarkSurfaceGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.bentoLightSurfaceGradient +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun FavouritesBentoScreen( + modifier: Modifier = Modifier, + onClick: () -> Unit = {}, + viewModel: MainViewModel = koinViewModel() +) { + var resizedAsOfFontSize by remember { mutableStateOf(12.sp) } + val context = LocalContext.current + val appSetting by viewModel.appSetting.collectAsStateWithLifecycle() + val isDarkMode = appSetting.isDarkMode + val favouriteArray = intArrayOf(1, 2, 3, 4) + val opacityFactor = 0.3f + + Box( + modifier = Modifier + .fillMaxSize() + .background( + brush = if (isDarkMode) bentoDarkSurfaceGradient else bentoLightSurfaceGradient, + shape = RoundedCornerShape(16.dp) + ) + .border( + width = 1.5.dp, + brush = if (isDarkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = RoundedCornerShape(16.dp) + ) + ) { + Column( + modifier = Modifier + .padding(10.dp) + .fillMaxHeight(), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.Start + ) { + Text( + text = stringResource(com.brainwallet.R.string.favourites_label).uppercase(), + color = if (isDarkMode) Color.White else Color.Black, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 10.sp + ), + modifier = Modifier + .padding(start = 1.dp, end = 1.dp) + .background( + color = Color.White.copy(alpha = 0.2f), + shape = RoundedCornerShape(6.dp) + ) + .padding(horizontal = 6.dp, vertical = 2.dp) + ) + Row(modifier = Modifier.padding(top = 4.dp)) { + Box { + Column( + modifier = Modifier + .size(favouriteSize) + .offset(x = 0.dp) + .background( + color = DesignTheme.colors.affirm.copy(alpha = opacityFactor), + shape = CircleShape + ) + ) { + } + Column( + modifier = Modifier + .size(favouriteSize) + .offset(x = 25.dp) + .background( + color = DesignTheme.colors.info.copy(alpha = opacityFactor), + shape = CircleShape + ) + + ) { + } + Column( + modifier = Modifier + .size(favouriteSize) + .offset(x = 50.dp) + .background( + color = DesignTheme.colors.warn.copy(alpha = opacityFactor), + shape = CircleShape + ) + + ) { + } + Column( + modifier = Modifier + .size(favouriteSize) + .offset(x = 75.dp) + .background( + color = DesignTheme.colors.error.copy(opacityFactor), + shape = CircleShape + ), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + + ) { + Icon( + Icons.Default.Add, + contentDescription = "Plus", + tint = if (isDarkMode) { + Color.White.copy(0.1f) + } else { + Color.Black.copy(0.1f) + } + ) + } + } + Spacer(modifier = Modifier.weight(1f)) + } + } + } +} + +@PreviewLightDark +@Composable +private fun FavouritesBentoScreenPreview() { + Box( + modifier = Modifier + .fillMaxHeight(0.7f) + .padding(16.dp) + ) { + FavouritesBentoScreen() + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoEvent.kt b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoEvent.kt new file mode 100644 index 00000000..ffb3298e --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoEvent.kt @@ -0,0 +1,4 @@ +package com.brainwallet.ui.bentosections.gamehubbento +sealed class GameHubBentoEvent { + data object OnLoad : GameHubBentoEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoPagerScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoPagerScreen.kt new file mode 100644 index 00000000..f964f463 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoPagerScreen.kt @@ -0,0 +1,86 @@ +package com.brainwallet.ui.bentosections.gamehubbento + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.delay + +@Composable +fun GameHubBentoPagerScreen( + modifier: Modifier = Modifier, + onClick: (Int) -> Unit = {} +) { + val hubPageCount = 3 + val pagerState = rememberPagerState(pageCount = { hubPageCount }) + val context = LocalContext.current + + LaunchedEffect(pagerState.pageCount) { + var forward = true + while (true) { + delay(5_000) + if (!pagerState.isScrollInProgress) { + val nextPage = if (forward) { + (pagerState.currentPage + 1).also { + if (it >= pagerState.pageCount - 1) forward = false + } + } else { + (pagerState.currentPage - 1).also { + if (it <= 0) forward = true + } + } + pagerState.animateScrollToPage(nextPage) + } + } + } + + Box( + modifier = Modifier + .fillMaxWidth() + .background( + color = Color.Transparent, + shape = RoundedCornerShape(16.dp) + ) + .border( + width = 1.5.dp, + color = Color.Transparent, + shape = RoundedCornerShape(16.dp) + ), + ) { + HorizontalPager( + state = pagerState, + userScrollEnabled = true, + pageSpacing = 8.dp, + modifier = modifier.fillMaxSize() + ) { page -> + + when (page) { + 0 -> GameHubBentoScreen(onClick = { onClick(page) }) + 1 -> GameHubBentoRiceScreen(onClick = { onClick(page) }) + 2 -> GameHubBentoUnagiScreen(onClick = { onClick(page) }) + } + } + } +} + +@PreviewLightDark +@Composable +private fun GameHubBentoPagerScreenPreview() { + Box(modifier = Modifier.height(120.dp)) { + GameHubBentoPagerScreen() + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoRiceScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoRiceScreen.kt new file mode 100644 index 00000000..6af4a2ff --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoRiceScreen.kt @@ -0,0 +1,101 @@ +package com.brainwallet.ui.bentosections.gamehubbento +import androidx.compose.foundation.Image +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.gameTaglineGradient + +@Composable +fun GameHubBentoRiceScreen( + modifier: Modifier = Modifier, + onClick: () -> Unit = {} +) { + val hubPageCount = 3 + val pagerState = rememberPagerState(pageCount = { hubPageCount }) + var resizedTaglineFontSize by remember { mutableStateOf(16.sp) } + val riceBackground = R.drawable.rice_partner_03 + Card( + modifier = modifier.fillMaxSize(), + shape = RoundedCornerShape(16.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), + onClick = onClick + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .border( + width = 0.7.dp, + brush = bentoDarkBorderGradient, + shape = RoundedCornerShape(17.dp) + ) + ) { + Image( + painter = painterResource(riceBackground), + contentDescription = "game_hub_background", + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + Column( + modifier = Modifier.fillMaxWidth(0.5f) + .padding(start = 16.dp) + .fillMaxHeight(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.Start + ) { + Text( + text = stringResource(R.string.rice_partner_03_tagline), + onTextLayout = { textLayoutResult -> + if (textLayoutResult.hasVisualOverflow) { + resizedTaglineFontSize *= 0.95f + } + }, + style = TextStyle( + brush = gameTaglineGradient, + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = resizedTaglineFontSize + ), + maxLines = 2 + ) + } + } + } +} + +@PreviewLightDark +@Composable +private fun GameHubBentoRiceScreenPreview() { + Box(modifier = Modifier.height(120.dp)) { + GameHubBentoRiceScreen() + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoScreen.kt new file mode 100644 index 00000000..e6b7d378 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoScreen.kt @@ -0,0 +1,197 @@ +package com.brainwallet.ui.bentosections.gamehubbento + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shadow +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.ui.theme.BoldenVan +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.gameHubBackgroundGradient +import com.brainwallet.ui.theme.gameTaglineGradient +import com.brainwallet.ui.theme.gameTitleGradient + +@Composable +fun GameHubBentoScreen( + modifier: Modifier = Modifier, + onClick: () -> Unit = {} +) { + val gameHubBackground = R.drawable.game_hub_bk + var resizedTaglineFontSize by remember { mutableStateOf(14.sp) } + val hubPageCount = 3 + val pagerState = rememberPagerState(pageCount = { hubPageCount }) + + Card( + modifier = modifier.fillMaxWidth(), + shape = RoundedCornerShape(16.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), + onClick = onClick + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .background(brush = gameHubBackgroundGradient) + .border( + width = 0.7.dp, + brush = bentoDarkBorderGradient, + shape = RoundedCornerShape(16.dp) + ) + ) { + Image( + painter = painterResource(gameHubBackground), + contentDescription = "game_hub_background", + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + val textWidthRatio = 0.85f + Column( + modifier = Modifier + .padding(start = 16.dp) + .fillMaxHeight(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.Start + ) { + Box( + modifier = Modifier + .fillMaxWidth(textWidthRatio) + .height(44.dp) + ) { + Text( + text = "FALLINMOJI", + style = TextStyle( + fontFamily = BoldenVan, + fontWeight = FontWeight.Normal, + fontSize = 39.sp, + shadow = Shadow( + color = Color.Black.copy(alpha = 0.5f), + offset = Offset(x = 4f, y = 4f), + blurRadius = 4f + ) + ), + maxLines = 1, + modifier = Modifier.fillMaxWidth(textWidthRatio) + ) + + Text( + text = "FALLINMOJI", + style = TextStyle( + brush = gameTitleGradient, + fontFamily = BoldenVan, + fontWeight = FontWeight.Normal, + fontSize = 39.sp + ), + maxLines = 1, + modifier = Modifier.fillMaxWidth(textWidthRatio) + ) + } + Box( + modifier = Modifier + .fillMaxWidth(textWidthRatio) + .padding(top = 1.dp) + ) { + Text( + text = stringResource(R.string.game_hub_tagline), + onTextLayout = { textLayoutResult -> + if (textLayoutResult.hasVisualOverflow) { + resizedTaglineFontSize *= 0.95f + } + }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Medium, + fontSize = resizedTaglineFontSize, + shadow = Shadow( + color = Color.Black.copy(alpha = 0.5f), + offset = Offset(x = 4f, y = 4f), + blurRadius = 4f + ) + ), + maxLines = 1, + modifier = Modifier.fillMaxWidth(textWidthRatio) + ) + Text( + text = stringResource(R.string.game_hub_tagline), + onTextLayout = { textLayoutResult -> + if (textLayoutResult.hasVisualOverflow) { + resizedTaglineFontSize *= 0.95f + } + }, + style = TextStyle( + brush = gameTaglineGradient, + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Medium, + fontSize = resizedTaglineFontSize + ), + maxLines = 1, + modifier = Modifier.fillMaxWidth(textWidthRatio) + ) + } + } + + Column( + modifier = Modifier + .padding(10.dp) + .fillMaxHeight(), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.Start + ) { + Text( + text = stringResource(R.string.game_hub_title).uppercase(), + color = Color.White, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 10.sp + ), + modifier = Modifier + .padding(start = 1.dp, end = 1.dp) + .background( + color = Color.White.copy(alpha = 0.2f), + shape = RoundedCornerShape(6.dp) + ) + .padding(horizontal = 10.dp, vertical = 2.dp) + ) + } + } + } +} + +@PreviewLightDark +@Composable +private fun GameHubBentoScreenPreview() { + Box(modifier = Modifier.height(120.dp)) { + GameHubBentoScreen() + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoState.kt b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoState.kt new file mode 100644 index 00000000..8fa250fb --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoState.kt @@ -0,0 +1,7 @@ +package com.brainwallet.ui.bentosections.gamehubbento + +data class GameHubBentoState( + val darkMode: Boolean = true, + val hubPageCount: Int = 3, + val currentHubPageIndex: Int = 0 +) diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoUnagiScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoUnagiScreen.kt new file mode 100644 index 00000000..e8d30c25 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoUnagiScreen.kt @@ -0,0 +1,111 @@ +package com.brainwallet.ui.bentosections.gamehubbento +import androidx.compose.foundation.Image +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.gameTaglineGradient + +@Composable +fun GameHubBentoUnagiScreen( + modifier: Modifier = Modifier, + onClick: () -> Unit = {} +) { + val hubPageCount = 3 + val pagerState = rememberPagerState(pageCount = { hubPageCount }) + var resizedTaglineFontSize by remember { mutableStateOf(14.sp) } + val unagiBackground = R.drawable.unagi_social_01 + + Card( + modifier = modifier.fillMaxSize(), + shape = RoundedCornerShape(18.dp), + elevation = CardDefaults.cardElevation(defaultElevation = 0.dp), + onClick = { + when (unagiBackground) { + R.drawable.unagi_social_01 -> onClick() + else -> Unit + } + } + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .weight(1f) + .border( + width = 0.7.dp, + brush = bentoDarkBorderGradient, + shape = RoundedCornerShape(18.dp) + ) + ) { + Image( + painter = painterResource(unagiBackground), + contentDescription = "game_hub_background", + modifier = Modifier.fillMaxSize(), + contentScale = ContentScale.Crop + ) + Column( + modifier = Modifier.fillMaxSize(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text( + modifier = Modifier + .padding(6.dp) + .offset(y = (-10).dp), + text = stringResource(R.string.unagi_social_01_tagline), + + textAlign = TextAlign.Center, + onTextLayout = { textLayoutResult -> + if (textLayoutResult.hasVisualOverflow) { + resizedTaglineFontSize *= 0.95f + } + }, + style = TextStyle( + brush = gameTaglineGradient, + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = resizedTaglineFontSize + ), + maxLines = 2 + ) + } + } + } +} + +@PreviewLightDark +@Composable +private fun GameHubBentoUnagiScreenPreview() { + Box(modifier = Modifier.height(120.dp)) { + GameHubBentoUnagiScreen() + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoViewModel.kt b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoViewModel.kt new file mode 100644 index 00000000..d4a94002 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/gamehubbento/GameHubBentoViewModel.kt @@ -0,0 +1,43 @@ +package com.brainwallet.ui.bentosections.gamehubbento +import androidx.lifecycle.viewModelScope +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.data.source.RemoteConfigSource +import com.brainwallet.ui.BrainwalletViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +import org.koin.core.Koin +import org.koin.core.context.GlobalContext.getOrNull +import org.koin.core.parameter.parametersOf + +@KoinViewModel +class GameHubBentoViewModel( + private val settingRepository: SettingRepository, +) : BrainwalletViewModel() { + + private val _state = MutableStateFlow(GameHubBentoState()) + val state: StateFlow = _state.asStateFlow() + + init { + viewModelScope.launch { + } + } + + fun loadRemoteConfig(): String? { + val remoteConfigSource: Koin = getOrNull() ?: return null + return remoteConfigSource.getOrNull { parametersOf(RemoteConfigSource::class) } + // getOrNull(RemoteConfigSource.KEY_FEATURE_GAMEHUB_CONTENT) + } + override fun onEvent(event: GameHubBentoEvent) { + when (event) { + is GameHubBentoEvent.OnLoad -> { + _state.update { currentState -> + currentState.copy() + } + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoEvent.kt b/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoEvent.kt new file mode 100644 index 00000000..134452da --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoEvent.kt @@ -0,0 +1,9 @@ +package com.brainwallet.ui.bentosections.ltcpickerbento + +import com.brainwallet.data.model.GlobalCurrency + +sealed class LTCPickerBentoEvent { + data object OnLoad : LTCPickerBentoEvent() + data class OnGlobalCurrencyChange(val globalCurrency: GlobalCurrency) : LTCPickerBentoEvent() + data class OnLiveCurrencyUpdate(val globalCurrency: GlobalCurrency) : LTCPickerBentoEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoScreen.kt new file mode 100644 index 00000000..46f67ca9 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoScreen.kt @@ -0,0 +1,222 @@ +package com.brainwallet.ui.bentosections.ltcpickerbento + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.gestures.detectHorizontalDragGestures +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.Modifier +import androidx.compose.ui.R +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.data.model.GlobalCurrency +import com.brainwallet.ui.composable.VerticalWheelPicker +import com.brainwallet.ui.composable.WheelPickerFocusVertical +import com.brainwallet.ui.composable.rememberWheelPickerState +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoDarkSurfaceGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.bentoLightSurfaceGradient +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun LTCPickerBentoScreen( + modifier: Modifier = Modifier, + viewModel: LTCPickerBentoViewModel = koinViewModel(), +) { + val state by viewModel.state.collectAsState() + LTCPickerBentoScreen( + state = state, + modifier = modifier + ) +} + +@Composable +fun LTCPickerBentoScreen( + state: LTCPickerBentoState, + modifier: Modifier = Modifier, + viewModel: LTCPickerBentoViewModel = koinViewModel() +) { + val currenciesWithFlags = GlobalCurrency.entries.map { + " " + + it.countryFlag + " " + it.code + " / LTC" + } + + val wheelPickerState = rememberWheelPickerState(initialIndex = 0) + var resizedFiatFontSize by remember { mutableStateOf(16.sp) } + var resizedCurrencyNameFontSize by remember { mutableStateOf(18.sp) } + var resizedAsOfTimestampFontSize by remember { mutableStateOf(12.sp) } + val context = LocalContext.current + + // Set the initial index to the selected fiat currency + LaunchedEffect(Unit) { + delay(500) + wheelPickerState.scrollToIndex(state.getSelectedFiatRateIndex()) + } + + // Listen for changes in the selected fiat currency index + LaunchedEffect(wheelPickerState) { + snapshotFlow { wheelPickerState.currentIndex } + .filter { it > -1 } + .distinctUntilChanged() + .debounce(700) + .collect { + viewModel.onEvent(LTCPickerBentoEvent.OnGlobalCurrencyChange(state.globalCurrencies[it])) + } + } + + Box( + modifier = Modifier + .fillMaxSize() + .background( + brush = if (state.darkMode) bentoDarkSurfaceGradient else bentoLightSurfaceGradient, + shape = RoundedCornerShape(16.dp) + ) + .border( + width = 1.5.dp, + brush = if (state.darkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = RoundedCornerShape(16.dp) + ) + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding( + bottom = 6.dp, + start = 16.dp, + end = 16.dp + ), + verticalArrangement = Arrangement.Center + ) { + VerticalWheelPicker( + modifier = Modifier + .fillMaxWidth() + .background(Color.Transparent) + .pointerInput(Unit) { + detectHorizontalDragGestures { change, _ -> + change.consume() + } + }, + count = currenciesWithFlags.size, + state = wheelPickerState, + unfocusedCount = 1, + itemHeight = 24.dp, + focus = { + WheelPickerFocusVertical( + dividerColor = if (state.darkMode) { + Color.White.copy(0.3f) + } else { + Color.Black.copy(alpha = 0.3f) + } + ) + } + ) { index -> + Text( + text = currenciesWithFlags[index], + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + color = if (state.darkMode) Color.White else Color.Black + ) + ) + } + Text( + text = "${state.selectedCurrency.name}", + modifier = Modifier + .fillMaxWidth() + .padding(top = 4.dp), + onTextLayout = { textLayoutResult -> + if (textLayoutResult.hasVisualOverflow) { + resizedCurrencyNameFontSize *= 0.95f + } + }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Light, + fontSize = resizedCurrencyNameFontSize, + color = if (state.darkMode) Color.White else Color.Black + ), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Text( + text = state.formattedFiat, + modifier = Modifier.fillMaxWidth().padding(bottom = 4.dp), + onTextLayout = { textLayoutResult -> + if (textLayoutResult.hasVisualOverflow) { + resizedFiatFontSize *= 0.95f + } + }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = resizedFiatFontSize, + color = if (state.darkMode) Color.White else Color.Black + ), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + Text( + text = stringResource( + com.brainwallet.R.string.ltc_ticker_as_of_timestamp, + state.formattedTimeStamp + ), + modifier = Modifier + .fillMaxWidth() + .padding(top = 2.dp, bottom = 2.dp), + onTextLayout = { textLayoutResult -> + if (textLayoutResult.hasVisualOverflow) { + resizedAsOfTimestampFontSize *= 0.95f + } + }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = resizedAsOfTimestampFontSize, + color = if (state.darkMode) Color.White else Color.Black, + textAlign = TextAlign.Start + ), + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + } + } +} + +@PreviewLightDark +@Composable +private fun LTCPickerBentoScreenPreview() { + Box(modifier = Modifier.fillMaxHeight(0.7f).padding(16.dp)) { + LTCPickerBentoScreen(state = LTCPickerBentoState()) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoState.kt b/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoState.kt new file mode 100644 index 00000000..24236d69 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoState.kt @@ -0,0 +1,23 @@ +package com.brainwallet.ui.bentosections.ltcpickerbento + +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.GlobalCurrency +import com.brainwallet.data.model.LtcStats +import kotlin.text.lowercase + +data class LTCPickerBentoState( + val darkMode: Boolean = true, + val selectedCurrency: CurrencyEntity = CurrencyEntity( + "USD", + "US Dollar", + -1f, + "$" + ), + val ltcStats: LtcStats? = null, + val formattedFiat: String = "", + val formattedTimeStamp: String = "", + var globalCurrencies: List = GlobalCurrency.entries, + var selectedGlobalCurrency: GlobalCurrency = GlobalCurrency.USD +) +fun LTCPickerBentoState.getSelectedFiatRateIndex(): Int = globalCurrencies + .indexOfFirst { it.code.lowercase() == selectedCurrency.code.lowercase() } diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoViewModel.kt b/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoViewModel.kt new file mode 100644 index 00000000..0254e925 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/ltcpickerbento/LTCPickerBentoViewModel.kt @@ -0,0 +1,115 @@ +package com.brainwallet.ui.bentosections.ltcpickerbento + +import androidx.lifecycle.viewModelScope +import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.tools.sqlite.CurrencyDataSource +import com.brainwallet.ui.BrainwalletViewModel +import com.google.firebase.crashlytics.FirebaseCrashlytics +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +import timber.log.Timber + +@KoinViewModel +class LTCPickerBentoViewModel( + private val settingRepository: SettingRepository, + private val currencyDataSource: CurrencyDataSource, + private val ltcRepository: LtcRepository +) : BrainwalletViewModel() { + + private val _state = MutableStateFlow(LTCPickerBentoState()) + val state: StateFlow = _state.asStateFlow() + val formatter = java.text.SimpleDateFormat( + "MMM dd, yyyy h:mm:ss a", + java.util.Locale.getDefault() + ) + + init { + viewModelScope.launch { + while (true) { + try { fetchAndUpdateRates() } catch (e: Exception) { + Timber.e(e, "fetchRates failed") + FirebaseCrashlytics.getInstance().recordException(e) + } + delay(5000L) + } + } + viewModelScope.launch { + settingRepository.settings.collect { setting -> + _state.update { + it.copy( + darkMode = setting.isDarkMode, + selectedCurrency = setting.currency + ) + } + } + } + viewModelScope.launch { + ltcRepository.ltcStats.collect { ltcStats -> + _state.update { + Timber.d("timber: ltcStats: $ltcStats") + + it.copy( + ltcStats = ltcStats + ) + } + } + } + } + private suspend fun fetchAndUpdateRates( + currencyCode: String = settingRepository.currentSettings.value.currency.code + ) { + val rates = ltcRepository.fetchRates() + val selectedFiat = rates.find { it.code == currencyCode } + var formattedFiat = "" + val msg = "||fetchRates ${selectedFiat?.rate} fetch ltc stats: $state.ltcStats.currentBlockHeight" + Timber.d("timber: ltcStats: $state.ltcStats.value") + Timber.d(msg) + FirebaseCrashlytics.getInstance().log(msg) + + _state.update { + it.copy( + selectedCurrency = selectedFiat ?: return@update it, + formattedFiat = "${selectedFiat.symbol} ${"%6.2f".format(selectedFiat.rate)}", + formattedTimeStamp = formatter.format(java.util.Date()), + ltcStats = ltcRepository.ltcStats.value + ) + } + } + override fun onEvent(event: LTCPickerBentoEvent) { + when (event) { + is LTCPickerBentoEvent.OnGlobalCurrencyChange -> { + val newCurrency = currencyDataSource.getCurrencyByIso(event.globalCurrency.code) + if (newCurrency != null) { + viewModelScope.launch { + settingRepository.save(settingRepository.currentSettings.value.copy(currency = newCurrency)) + fetchAndUpdateRates(newCurrency.code) + } + } else { + Timber.w("Currency not found for code: ${event.globalCurrency.code}") + } + } + is LTCPickerBentoEvent.OnLoad -> { + _state.update { currentState -> + currentState.copy( + formattedTimeStamp = formatter.format(java.util.Date()) + ) + } + } + is LTCPickerBentoEvent.OnLiveCurrencyUpdate -> { + _state.update { currentState -> + currentState.copy( + formattedTimeStamp = formatter.format(java.util.Date()) + .replace("AM", "am") + .replace("PM", "pm") + ) + } + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/ConfirmationStatus.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/ConfirmationStatus.kt new file mode 100644 index 00000000..90dfa2c7 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/ConfirmationStatus.kt @@ -0,0 +1,83 @@ +package com.brainwallet.ui.bentosections.transactionbento +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.height +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import androidx.compose.ui.unit.dp +import kotlin.math.cos +import kotlin.math.sin +import com.brainwallet.ui.theme.DesignTheme + +@Composable +fun ConfirmationStatus( + modifier: Modifier = Modifier, + numberOfConfs: Int = 0 +) { + val initialStateColor = DesignTheme.colors.info.copy(0.6f) + val medianStateColor = DesignTheme.colors.affirm.copy(0.6f) + val completeStateColor = DesignTheme.colors.affirm + + val filledColor = when (numberOfConfs) { + in 3..4 -> medianStateColor + in 5..Int.MAX_VALUE -> completeStateColor + else -> initialStateColor + } + + val emptyColor = DesignTheme.colors.info.copy(0.1f) + + val segmentColors = List(6) { i -> + if (i < numberOfConfs.coerceIn(0, 6)) filledColor else emptyColor + } + + Canvas(modifier = modifier.aspectRatio(1f)) { + val cx = size.width / 2f + val cy = size.height / 2f + val r = size.width / 2f * 0.9f + + val vertices = (0..5).map { i -> + val angle = Math.toRadians(60.0 * i + 90.0) + Offset( + cx + r * cos(angle).toFloat(), + cy - r * sin(angle).toFloat() + ) + } + + vertices.forEachIndexed { i, v -> + val next = vertices[(i + 1) % 6] + val path = Path().apply { + moveTo(cx, cy) + lineTo(v.x, v.y) + lineTo(next.x, next.y) + close() + } + drawPath(path, color = segmentColors[i]) + drawPath(path, color = Color.White.copy(0.3f), style = Stroke(width = 1f)) + } + } +} + +class ConfirmationStateProvider : PreviewParameterProvider { + override val values = sequenceOf(0, 1, 2, 3, 4, 5, 6, 7) +} + +@Preview +@Composable +private fun ConfirmationStatusPreview( + @PreviewParameter(ConfirmationStateProvider::class) numberOfConfs: Int +) { + DesignTheme(isSystemInDarkTheme()) { + Box(modifier = Modifier.height(120.dp)) { + ConfirmationStatus(numberOfConfs = numberOfConfs) + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/NoTxRow.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/NoTxRow.kt new file mode 100644 index 00000000..856a8b7d --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/NoTxRow.kt @@ -0,0 +1,110 @@ +package com.brainwallet.ui.bentosections.transactionbento +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.constants.transactionRowHt +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoDarkSurfaceGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.bentoLightSurfaceGradient + +@Composable +fun NoTxRow( + isDarkMode: Boolean, + modifier: Modifier = Modifier, +) { + val context = LocalContext.current + Box( + modifier = Modifier + .height(transactionRowHt) + .background( + brush = if (isDarkMode) bentoDarkSurfaceGradient else bentoLightSurfaceGradient, + shape = RoundedCornerShape(16.dp) + ) + .border( + width = 1.5.dp, + brush = if (isDarkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = RoundedCornerShape(16.dp) + ) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 12.dp, vertical = 6.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + modifier = Modifier + .padding(top = 6.dp, bottom = 2.dp) + .align(Alignment.Start), + text = stringResource(R.string.no_transaction_title_row), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 14.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + + Text( + modifier = Modifier + .padding(top = 2.dp, bottom = 8.dp) + .align(Alignment.Start), + text = stringResource(R.string.no_transaction_detail_row), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Light, + fontSize = 13.sp, + letterSpacing = 0.5.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + } + + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Image( + painter = if (isDarkMode) { + painterResource(R.drawable.powered_by_moonpay_wht) + } else { + painterResource(R.drawable.powered_by_moonpay_blk) + }, + contentDescription = "moonpay_logo", + modifier = Modifier + .fillMaxSize() + .padding(4.dp), + contentScale = ContentScale.Fit + ) + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoEvent.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoEvent.kt new file mode 100644 index 00000000..5a0f865c --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoEvent.kt @@ -0,0 +1,7 @@ +package com.brainwallet.ui.bentosections.transactionbento + +sealed class TransactionBentoEvent { + data object OnLoad : TransactionBentoEvent() + data class ToggleTransactionViews(val shouldShowDetail: Boolean) : TransactionBentoEvent() + data class ToggleTransactionFilter(val filterState: TransactionFilterState) : TransactionBentoEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoState.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoState.kt new file mode 100644 index 00000000..5af91e27 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoState.kt @@ -0,0 +1,10 @@ +package com.brainwallet.ui.bentosections.transactionbento + +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.LtcStats + +data class TransactionBentoState( + val darkMode: Boolean = true, + val ltcStats: LtcStats? = null, + val selectedCurrency: CurrencyEntity? = null +) diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoViewModel.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoViewModel.kt new file mode 100644 index 00000000..533e635d --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionBentoViewModel.kt @@ -0,0 +1,65 @@ +package com.brainwallet.ui.bentosections.transactionbento + +import androidx.lifecycle.viewModelScope +import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.ui.BrainwalletViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +import timber.log.Timber + +@KoinViewModel +class TransactionBentoViewModel( + private val settingRepository: SettingRepository, + private val ltcRepository: LtcRepository, +) : BrainwalletViewModel() { + + private val _state = MutableStateFlow(TransactionBentoState()) + val state: StateFlow = _state.asStateFlow() + val formatter = java.text.SimpleDateFormat( + "MMM dd, yyyy h:mm:ss a", + java.util.Locale.getDefault() + ) + + init { + viewModelScope.launch { + ltcRepository.ltcStats.collect { ltcStats -> + Timber.i("ltcStats: $ltcStats") + _state.update { + it.copy( + ltcStats = ltcStats + ) + } + } + } + + viewModelScope.launch { + settingRepository.currentSettings.collect { currentSettings -> + _state.update { + it.copy( + selectedCurrency = currentSettings.currency, + darkMode = currentSettings.isDarkMode + ) + } + } + } + } + + override fun onEvent(event: TransactionBentoEvent) { + when (event) { + is TransactionBentoEvent.OnLoad -> { + Timber.i("TransactionBentoEvent.OnLoad") + } + is TransactionBentoEvent.ToggleTransactionViews -> { + Timber.i("TransactionBentoEvent.ToggleTransactionViews") + } + is TransactionBentoEvent.ToggleTransactionFilter -> { + Timber.i("TransactionBentoEvent.ToggleTransactionFilter") + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionDetail.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionDetail.kt new file mode 100644 index 00000000..f1fa28cf --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionDetail.kt @@ -0,0 +1,328 @@ +package com.brainwallet.ui.bentosections.transactionbento +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.constants.BWConstants +import com.brainwallet.constants.transactionQRSize +import com.brainwallet.presenter.entities.TxItem +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.qrcode.QRUtils +import com.brainwallet.tools.util.BRCurrency +import com.brainwallet.tools.util.BRExchange +import com.brainwallet.tools.util.BRExchange.ONE_LITECOIN_OF_LITOSHIS +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoDarkSurfaceGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.bentoLightSurfaceGradient +import timber.log.Timber +import java.math.BigDecimal +import java.util.Date + +@Composable +fun TransactionDetail( + isDarkMode: Boolean, + currentTransaction: TxItem?, + modifier: Modifier = Modifier, +) { + val context = LocalContext.current + val ltcAddressString = currentTransaction?.to?.firstOrNull() ?: "" + val formatter = java.text.SimpleDateFormat( + "MMM dd, yyyy hh:mm a", + java.util.Locale.getDefault() + ) + val dateTimestamp = formatter.format(Date(currentTransaction?.timeStamp?.times(1000L) ?: 0L)) + val wasReceived = currentTransaction?.getSent() == 0L + val amountReceived = + BigDecimal(currentTransaction?.received ?: 0L).divide( + BigDecimal(ONE_LITECOIN_OF_LITOSHIS), + 8, + BWConstants.ROUNDING_MODE + ) + + val outAmounts: LongArray? = currentTransaction?.getOutAmounts() + var opsAmount = Long.Companion.MAX_VALUE + if (outAmounts?.size == 3) { + for (i in outAmounts.indices) { + val value = outAmounts[i] + + if (value < opsAmount && value != 0L) { + opsAmount = value + Timber.d("timber: outAmounts size %d opsAmount value: %d", outAmounts.size, value) + } + } + } else { + opsAmount = 0L + } + + val txWasReceived = currentTransaction?.getReceived() ?: 0L + val txWasSent = currentTransaction?.getSent() ?: 0L + + val sentLitoshisAmount: Long = when { + wasReceived -> txWasReceived + else -> txWasSent - txWasReceived - opsAmount + } + val isBTCPreferred = BRSharedPrefs.getLTCViewingPreference(context) + val iso = if (isBTCPreferred) "LTC" else BRSharedPrefs.getIsoSymbol(context) + + val formattedAmount = BRCurrency.getFormattedCurrencyString( + context, + iso, + BRExchange.getAmountFromLitoshis(context, iso, BigDecimal(sentLitoshisAmount)) + ) + + val amountSent = + BigDecimal(currentTransaction?.sent ?: 0L).divide( + BigDecimal(ONE_LITECOIN_OF_LITOSHIS), + 8, + BWConstants.ROUNDING_MODE + ) + val combinedFees = BigDecimal(currentTransaction?.fee ?: 0L) + BigDecimal(opsAmount) + val feesLitoshis = combinedFees.divide(BigDecimal(ONE_LITECOIN_OF_LITOSHIS)) + val feesTotal = String.format("-Ł $feesLitoshis") + val amountString = + if (wasReceived) String.format("+Ł $amountReceived") else String.format("-Ł $amountSent") + val qrBitmap = QRUtils.generateQR(context, "litecoin:$ltcAddressString").asImageBitmap() + val txIDBrowserURL: String = run { + "${BWConstants.BLOCKCHAIR_EXPLORER_BASE_URL}${currentTransaction?.txHashHexReversed ?: ""}" + } + + Box( + modifier = modifier + .background( + brush = if (isDarkMode) bentoDarkSurfaceGradient else bentoLightSurfaceGradient, + shape = RoundedCornerShape(16.dp) + ) + .border( + width = 1.5.dp, + brush = if (isDarkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = RoundedCornerShape(16.dp) + ) + ) { + Column { + Row( + modifier = Modifier.padding(12.dp) + ) { + Column( + modifier = Modifier + .padding(end = 8.dp) + ) { + Text( + modifier = Modifier, + text = stringResource(R.string.amount_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + if (!wasReceived) { + Text( + modifier = Modifier, + text = stringResource(R.string.fees_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + } + Text( + modifier = Modifier, + text = stringResource(R.string.tx_id_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + Text( + modifier = Modifier, + text = stringResource(R.string.memo_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + Text( + modifier = Modifier, + text = stringResource(R.string.block_height_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + Text( + modifier = Modifier, + text = stringResource(R.string.date_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + } + Spacer(modifier = Modifier.weight(0.2f)) + Column( + modifier = Modifier + ) { + Text( + modifier = Modifier, + text = formattedAmount, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + if (!wasReceived) { + Text( + modifier = Modifier, + text = "$feesTotal", + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + } + Text( + modifier = Modifier, + text = currentTransaction?.txHashHexReversed ?: "", + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + Text( + modifier = Modifier, + text = "${currentTransaction?.metaData ?: ""}", + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 3 + ) + Text( + modifier = Modifier, + text = "${currentTransaction?.blockHeight ?: 0L}", + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + Text( + modifier = Modifier, + text = "$dateTimestamp", + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + } + Spacer(modifier = Modifier.weight(1f)) + } + Row( + modifier = Modifier + .padding(12.dp) + ) { + Column( + modifier = Modifier + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Image( + modifier = Modifier + .height(transactionQRSize) + .width(transactionQRSize), + bitmap = qrBitmap, + contentDescription = "qr address", + colorFilter = ColorFilter.tint(if (isDarkMode) Color.White else Color.Black) + ) + + Text( + modifier = Modifier + .padding(6.dp), + text = ltcAddressString, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + + Text( + modifier = Modifier + .padding(6.dp) + .testTag("EXPORT_IAP_PLACEHOLDER"), + text = "", + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 1.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + } + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionFilter.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionFilter.kt new file mode 100644 index 00000000..e5cb1da0 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionFilter.kt @@ -0,0 +1,5 @@ +package com.brainwallet.ui.bentosections.transactionbento + +enum class TransactionFilterState { + ALL, RECEIVED, SENT +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionRow.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionRow.kt new file mode 100644 index 00000000..70ff5b12 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionRow.kt @@ -0,0 +1,243 @@ +package com.brainwallet.ui.bentosections.transactionbento +import com.brainwallet.R +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.constants.transactionRowHt +import com.brainwallet.data.model.LtcStats +import com.brainwallet.presenter.entities.ServiceItems +import com.brainwallet.presenter.entities.TxItem +import com.brainwallet.tools.util.BRExchange.ONE_LITECOIN_OF_LITOSHIS +import com.brainwallet.tools.util.Utils +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoDarkSurfaceGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.bentoLightSurfaceGradient +import com.brainwallet.wallet.BRPeerManager +import org.koin.compose.viewmodel.koinViewModel +import timber.log.Timber +import java.math.BigDecimal +import java.text.SimpleDateFormat +import java.util.Date +import java.util.Locale + +@Composable +fun TransactionRow( + txItem: TxItem, + ltcStats: LtcStats?, + isDarkMode: Boolean, + modifier: Modifier = Modifier, + viewModel: TransactionBentoViewModel = koinViewModel(), +) { + val context = LocalContext.current + val state by viewModel.state.collectAsState() + val formatter = SimpleDateFormat( + "MMM dd, yyyy hh:mm a", + Locale.getDefault() + ) + + // the transactions amount + val txAmount = BigDecimal(txItem.getReceived() - txItem.getSent()) + .abs().divide(BigDecimal(ONE_LITECOIN_OF_LITOSHIS)) + + // determine sent vs received state + val wasSentVsReceived = txItem.received - txItem.sent < 0 + + // formatted transaction amount + val amountString = if (wasSentVsReceived) String.format("-Ł $txAmount") else String.format("+Ł $txAmount") + + // LTC address to recipient or Brainwallet user + val ltcAddress: String? + + // Output addresses + val outputAddressSet = txItem.to.toHashSet() + val opsSet = Utils.fetchServiceItem(context, ServiceItems.OPSALL) + .split(",") + .toHashSet() + + ltcAddress = outputAddressSet + .filter { it !in opsSet } + .filterNotNull() + .firstOrNull() ?: "ERROR-ADDRESS" + + val toFromAddressFormatting: String = if (wasSentVsReceived) { + String.format(stringResource(R.string.TransactionDetails_to), ltcAddress) + } else { + String.format(stringResource(R.string.TransactionDetails_from), ltcAddress) + } + + val currentLtcStats = state.ltcStats ?: LtcStats( + currentBlockHeight = txItem.blockHeight, + mempoolTransactions = 0, + mempoolSize = 0, + transactionsOver24H = 0 + ) + + // For the first peers in the middle of confirmation + val peerRelayCount = BRPeerManager.getRelayCount(txItem.txHash) + + val confirmationLevel: Int = when { + txItem.blockHeight == Int.MAX_VALUE -> peerRelayCount.coerceIn(0, 2) + else -> (currentLtcStats.currentBlockHeight - txItem.blockHeight + 1) + .coerceIn(3, 7) + } + + val dateTimestamp: String = when (confirmationLevel) { + 0 -> "" + 1 -> "" + 2 -> "" + else -> formatter.format(Date(txItem.timeStamp * 1000L)) + } + + val confirmationLabel: String = when (confirmationLevel) { + 0 -> "" + 1 -> "-" + 2 -> "20%" + 3 -> "40%" + 4 -> "60%" + 5 -> "80%" + 6 -> "100%" + else -> "∞" + } + + // ───────────────────────────From working Develop branch─────────────────────────── + Box( + modifier = modifier + .height(transactionRowHt) + .background( + brush = if (isDarkMode) bentoDarkSurfaceGradient else bentoLightSurfaceGradient, + shape = RoundedCornerShape(16.dp) + ) + .border( + width = 1.5.dp, + brush = if (isDarkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = RoundedCornerShape(16.dp) + ) + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Row( + modifier = Modifier + .align(Alignment.Start) + .fillMaxWidth() + .padding(horizontal = 12.dp, vertical = 4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = dateTimestamp, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = if (isDarkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + Spacer(modifier = Modifier.weight(1f)) + + Timber.d("confirmationLevel: $confirmationLevel") + Text( + text = amountString, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 14.sp, + color = if (wasSentVsReceived) DesignTheme.colors.error else DesignTheme.colors.affirm + ), + maxLines = 1 + ) + } + Row( + modifier = Modifier + .align(Alignment.End), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.End + ) { + Spacer(modifier = Modifier.weight(1f)) + Text( + modifier = Modifier + .fillMaxWidth(0.25f) + .padding(end = 12.dp), + text = confirmationLabel, + textAlign = TextAlign.End, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 10.sp, + color = if (isDarkMode) { + Color.White.copy(0.8f) + } else { + Color.Black.copy( + 0.8f + ) + } + ), + maxLines = 1, + overflow = TextOverflow.MiddleEllipsis + ) + ConfirmationStatus( + modifier = Modifier + .height(16.dp) + .width(16.dp) + .padding(end = 80.dp), + numberOfConfs = confirmationLevel + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 8.dp, vertical = 3.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Spacer(modifier = Modifier.weight(1f)) + Text( + modifier = Modifier + .fillMaxWidth(0.5f), + text = toFromAddressFormatting, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Light, + fontSize = 11.sp, + color = if (isDarkMode) { + Color.White.copy(0.5f) + } else { + Color.Black.copy( + 0.5f + ) + } + ), + maxLines = 1, + overflow = TextOverflow.MiddleEllipsis + ) + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionsBentoScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionsBentoScreen.kt new file mode 100644 index 00000000..d91ba48b --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/transactionbento/TransactionsBentoScreen.kt @@ -0,0 +1,254 @@ +package com.brainwallet.ui.bentosections.transactionbento + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.tween +import androidx.compose.animation.expandVertically +import androidx.compose.animation.shrinkVertically +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider +import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.coordinatorlayout.R +import com.brainwallet.constants.BWConstants.EXPAND_DURATION +import com.brainwallet.constants.BWConstants.SHRINK_DURATION +import com.brainwallet.constants.transactionRowDetailHt +import com.brainwallet.constants.transactionRowHt +import com.brainwallet.presenter.entities.TxItem +import com.brainwallet.ui.screens.main.MainScreenEvent +import com.brainwallet.ui.screens.main.MainViewModel +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.ui.theme.IBMPlexSans +import kotlinx.collections.immutable.ImmutableList +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun TransactionsBentoScreen( + transactions: ImmutableList, + toggleState: TransactionFilterState, + showTransactionDetail: Boolean, + shouldShowFiatValues: Boolean, + onEvent: (MainScreenEvent) -> Unit, + modifier: Modifier = Modifier, + viewModel: TransactionBentoViewModel = koinViewModel(), + mainViewModel: MainViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + + TransactionsBentoScreen( + transactions = transactions, + state = state, + toggleState = toggleState, + showTransactionDetail = showTransactionDetail, + shouldShowFiatValues = shouldShowFiatValues, + onEvent = onEvent, + modifier = modifier, + mainViewModel = mainViewModel + ) +} + +@Composable +fun TransactionsBentoScreen( + transactions: ImmutableList, + state: TransactionBentoState, + toggleState: TransactionFilterState, + showTransactionDetail: Boolean, + shouldShowFiatValues: Boolean, + onEvent: (MainScreenEvent) -> Unit, + modifier: Modifier = Modifier, + mainViewModel: MainViewModel = koinViewModel() +) { + val listState = rememberLazyListState() + val snappingLayout = remember(listState) { SnapLayoutInfoProvider(listState) } + val flingBehavior = rememberSnapFlingBehavior(snappingLayout) + + val currentTransaction = remember(listState.firstVisibleItemIndex, transactions) { + transactions.getOrNull(listState.firstVisibleItemIndex) + } + + val toggleStateIcon = if (toggleState == TransactionFilterState.ALL) { + painterResource(com.brainwallet.R.drawable.circle_circle_24dp) + } else if (toggleState == TransactionFilterState.RECEIVED) { + painterResource(com.brainwallet.R.drawable.ic_arrow_down) + } else { + painterResource(com.brainwallet.R.drawable.ic_arrow_up) + } + + val toggleStateIconTint = if (toggleState == TransactionFilterState.ALL) { + ColorFilter.tint(if (state.darkMode) Color.White else DesignTheme.colors.affirm) + } else if (toggleState == TransactionFilterState.RECEIVED) { + ColorFilter.tint(DesignTheme.colors.affirm) + } else { + ColorFilter.tint(DesignTheme.colors.error) + } + + val noTxItemsPresent = remember(transactions) { + transactions.isEmpty() + } + + Box { + Column( + modifier = Modifier + .fillMaxWidth() + ) { + AnimatedVisibility( + visible = showTransactionDetail, + enter = expandVertically(tween(EXPAND_DURATION)), + exit = shrinkVertically(animationSpec = tween(SHRINK_DURATION)) + ) { + TransactionDetail( + isDarkMode = state.darkMode, + currentTransaction = currentTransaction, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + .clipToBounds() + ) + } + Spacer(modifier = Modifier.weight(1f)) + + if (noTxItemsPresent) { + NoTxRow( + isDarkMode = state.darkMode, + modifier = Modifier + .fillMaxWidth() + .height(transactionRowHt) + ) + } else { + Box { + LazyColumn( + state = listState, + flingBehavior = flingBehavior, + contentPadding = if (showTransactionDetail) { + PaddingValues( + bottom = transactionRowHt + ) + } else { + PaddingValues(bottom = 0.dp) + }, + modifier = Modifier + .fillMaxWidth() + .height( + if (showTransactionDetail) { + transactionRowDetailHt + } else { + transactionRowHt + } + ) + .clip(RoundedCornerShape(16.dp)) + .clipToBounds(), + verticalArrangement = Arrangement.spacedBy(3.dp), + ) { + items( + items = transactions, + key = { it.id } + ) { transaction -> + TransactionRow( + isDarkMode = state.darkMode, + txItem = transaction, + ltcStats = state.ltcStats, + modifier = Modifier + .fillMaxWidth() + .height(transactionRowHt) + ) + } + } + Row( + modifier = Modifier + .fillMaxWidth(0.22f) + .height(30.dp) + .align(Alignment.BottomStart) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = { + onEvent(MainScreenEvent.OnToggleTransactionsFilter) + }, + ) + .padding(start = 12.dp, bottom = 6.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight() + .clip(RoundedCornerShape(10.dp)) + .background( + if (state.darkMode) { + Color.White.copy(alpha = 0.1f) + } else { + DesignTheme.colors.affirm.copy(alpha = 0.1f) + } + ) + .padding(6.dp), + contentAlignment = Alignment.CenterStart + ) { + Row( + modifier = Modifier.fillMaxWidth() + .wrapContentHeight(Alignment.CenterVertically) + ) { + Image( + painter = toggleStateIcon, + contentDescription = "circle_circle_icon", + contentScale = ContentScale.Fit, + colorFilter = toggleStateIconTint + ) + + Text( + text = "${transactions.size} " + + stringResource(com.brainwallet.R.string.txns_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Bold, + fontSize = 11.sp, + ), + maxLines = 1, + modifier = Modifier + .padding(start = 4.dp), + color = if (state.darkMode) Color.White else DesignTheme.colors.affirm + ) + + Spacer(modifier = Modifier.weight(1f)) + } + } + } + } + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/bentosections/tutorials/TutorialsBentoScreen.kt b/app/src/main/java/com/brainwallet/ui/bentosections/tutorials/TutorialsBentoScreen.kt new file mode 100644 index 00000000..9b72ed0a --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/bentosections/tutorials/TutorialsBentoScreen.kt @@ -0,0 +1,98 @@ +package com.brainwallet.ui.bentosections.tutorials + +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.brainwallet.ui.screens.main.MainViewModel +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoDarkSurfaceGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.bentoLightSurfaceGradient +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun TutorialsBentoScreen( + modifier: Modifier = Modifier, + onClick: () -> Unit = {}, + viewModel: MainViewModel = koinViewModel() +) { + val context = LocalContext.current + val appSetting by viewModel.appSetting.collectAsStateWithLifecycle() + val isDarkMode = appSetting.isDarkMode + + Box( + modifier = Modifier + .fillMaxSize() + .background( + brush = if (isDarkMode) bentoDarkSurfaceGradient else bentoLightSurfaceGradient, + shape = RoundedCornerShape(16.dp) + ) + .border( + width = 1.5.dp, + brush = if (isDarkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = RoundedCornerShape(16.dp) + ) + ) { + Column( + modifier = Modifier + .padding(10.dp) + .fillMaxHeight(), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.Start + ) { + Text( + text = stringResource(com.brainwallet.R.string.tutorials_label).uppercase(), + color = if (isDarkMode) Color.White else Color.Black, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 10.sp + ), + modifier = Modifier + .padding(start = 1.dp, end = 1.dp) + .background( + color = Color.White.copy(alpha = 0.2f), + shape = RoundedCornerShape(6.dp) + ) + .padding(horizontal = 6.dp, vertical = 2.dp) + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + text = stringResource(com.brainwallet.R.string.coming_soon), + modifier = Modifier + .fillMaxSize() + .padding(30.dp) + .align(Alignment.CenterHorizontally), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 14.sp, + textAlign = TextAlign.Center, + color = if (isDarkMode) Color.White else Color.Black + ) + ) + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/ActionButton.kt b/app/src/main/java/com/brainwallet/ui/composable/ActionButton.kt new file mode 100644 index 00000000..dd955dac --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/ActionButton.kt @@ -0,0 +1,36 @@ +package com.brainwallet.ui.composable + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.minimumInteractiveComponentSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp + +@Composable +fun SendActionButton( + onClick: () -> Unit, + darkMode: Boolean, + icon: ImageVector, + modifier: Modifier = Modifier +) { + IconButton( + onClick = onClick, + modifier = modifier + .minimumInteractiveComponentSize() // removes the 48dp floor + .size(30.dp) + .padding(2.dp) + .background( + if (darkMode) Color.White else Color.Black.copy(0.2f), + RoundedCornerShape(12.dp) + ) + ) { + Icon(icon, contentDescription = null) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/BentoBottomNavBar.kt b/app/src/main/java/com/brainwallet/ui/composable/BentoBottomNavBar.kt new file mode 100644 index 00000000..546665f4 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/BentoBottomNavBar.kt @@ -0,0 +1,213 @@ +package com.brainwallet.ui.composable + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.material3.Icon +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.navigation.Route +import com.brainwallet.constants.bentoBottomNavBarHt +import com.brainwallet.tools.util.capitalizeFirst +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.colorMidnite + +/** + * A custom bottom navigation bar component based on the provided design. + * + * @param modifier The modifier to be applied to the component. + * @param currentRoute The currently selected navigation route. + * @param onItemClick Callback invoked when a navigation item is clicked. + */ + +@Composable +fun BentoBottomNavBar( + isDarkMode: Boolean, + noTxItemsPresent: Boolean, + isShowingTransactionDetail: Boolean, + canUserSend: Boolean, + currentRoute: Route?, + onItemClick: (Route) -> Unit, + onToggleTransactionDetail: () -> Unit, + modifier: Modifier = Modifier, +) { + var surfaceColor = if (isDarkMode) Color.Black else Color.White + var contentsColor = if (isDarkMode) Color.White else colorMidnite + + NavigationBar( + containerColor = surfaceColor, + contentColor = contentsColor, + modifier = modifier + .navigationBarsPadding() + .height(bentoBottomNavBarHt) + ) { + NavigationBarItem( + selected = currentRoute is Route.Send, + onClick = { onItemClick(Route.Send) }, + enabled = canUserSend, + icon = { + Icon( + painter = painterResource(R.drawable.ic_send), + contentDescription = stringResource(id = R.string.send_tab_description) + ) + }, + label = { + Text( + text = stringResource(R.string.send_title).capitalizeFirst(), + textAlign = TextAlign.Center, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = contentsColor + ), + maxLines = 1 + ) + }, + colors = androidx.compose.material3.NavigationBarItemDefaults.colors( + selectedIconColor = contentsColor, + selectedTextColor = contentsColor, + indicatorColor = Color.Transparent, + unselectedIconColor = contentsColor.copy(0.8f), + unselectedTextColor = contentsColor.copy(0.8f) + ) + ) + NavigationBarItem( + selected = currentRoute is Route.BuyReceive, + onClick = { onItemClick(Route.BuyReceive) }, + icon = { + Icon( + painter = painterResource(R.drawable.ic_buy_receive), + contentDescription = stringResource(id = R.string.buy_receive_tab_description) + ) + }, + label = { + Text( + text = stringResource(R.string.bottom_nav_item_buy_receive_title), + textAlign = TextAlign.Center, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = contentsColor + ), + maxLines = 2 + ) + }, + colors = androidx.compose.material3.NavigationBarItemDefaults.colors( + selectedIconColor = contentsColor, + selectedTextColor = contentsColor, + indicatorColor = Color.Transparent, + unselectedIconColor = contentsColor.copy(0.8f), + unselectedTextColor = contentsColor.copy(0.8f) + ) + ) + + NavigationBarItem( + selected = currentRoute is Route.GameHub, + onClick = { onItemClick(Route.GameHub) }, + enabled = false, // Disabled until the game integration + icon = { + Icon( + painter = painterResource(R.drawable.ic_game_hub), + contentDescription = stringResource(id = R.string.game_hub_tab_description) + ) + }, + label = { + Text( + text = stringResource(R.string.game_hub_title), + textAlign = TextAlign.Center, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = contentsColor + ), + maxLines = 2 + ) + }, + colors = androidx.compose.material3.NavigationBarItemDefaults.colors( + selectedIconColor = contentsColor, + selectedTextColor = contentsColor, + indicatorColor = Color.Transparent, + unselectedIconColor = contentsColor.copy(0.8f), + unselectedTextColor = contentsColor.copy(0.8f) + ) + ) + NavigationBarItem( + modifier = Modifier.then( + if (noTxItemsPresent) Modifier.alpha(0.4f) else Modifier + ), + selected = isShowingTransactionDetail, + onClick = { if (!noTxItemsPresent) onToggleTransactionDetail() }, + icon = { + Icon( + painter = if (isShowingTransactionDetail) { + painterResource(R.drawable.home_24px) + } else { + painterResource(R.drawable.ic_history) + }, + contentDescription = if (isShowingTransactionDetail) { + stringResource(id = R.string.home_tab_description) + } else { + stringResource(id = R.string.history_tab_description) + } + ) + }, + label = { + Text( + text = if (isShowingTransactionDetail) { + stringResource(R.string.home_icon_label) + } else { + stringResource(R.string.history_title) + }, + textAlign = TextAlign.Center, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + color = contentsColor + ), + maxLines = 1 + ) + }, + colors = androidx.compose.material3.NavigationBarItemDefaults.colors( + selectedIconColor = contentsColor, + selectedTextColor = contentsColor, + indicatorColor = Color.Transparent, + unselectedIconColor = contentsColor.copy(0.8f), + unselectedTextColor = contentsColor.copy(0.8f) + ) + ) + } +} + +@Composable +@PreviewLightDark +fun BentoBottomNavBarPreview() { + DesignTheme(isSystemInDarkTheme()) { + BentoBottomNavBar( + currentRoute = Route.Send, + onItemClick = {}, + isDarkMode = isSystemInDarkTheme(), + isShowingTransactionDetail = false, + canUserSend = true, + noTxItemsPresent = false, + onToggleTransactionDetail = {} + ) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt b/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt deleted file mode 100644 index 07d09852..00000000 --- a/app/src/main/java/com/brainwallet/ui/composable/BrainWalletLogo.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.brainwallet.ui.composable - -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.tooling.preview.PreviewLightDark -import com.brainwallet.R -import com.brainwallet.data.model.AppSetting -import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme -import com.grunt.brainwallet.core.presentation.theme.LocalDarkModeFlag - -@Composable -fun BrainWalletLogo(modifier: Modifier = Modifier) { - val iconLogo = if (LocalDarkModeFlag.current) { - R.drawable.brainwallet_logotype_white - } else { - R.drawable.brainwallet_logotype_color - } - Image( - painterResource(iconLogo), - contentDescription = "brainwallet_logo", - modifier = modifier - ) -} - -@PreviewLightDark -@Composable -private fun BrainWalletLogoPreview() { - BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) { - Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) { - BrainWalletLogo() - } - } -} diff --git a/app/src/main/java/com/brainwallet/ui/composable/Buttons.kt b/app/src/main/java/com/brainwallet/ui/composable/Buttons.kt new file mode 100644 index 00000000..d8ebfc13 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/Buttons.kt @@ -0,0 +1,139 @@ +package com.brainwallet.ui.composable + +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.FilledTonalButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.dp +import com.brainwallet.ui.theme.DesignTheme + +@Composable +fun EditSendButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + darkMode: Boolean = false, + enabled: Boolean = true, + colors: ButtonColors = ButtonDefaults.buttonColors( + containerColor = if (darkMode) Color.Transparent else Color.White, + contentColor = if (darkMode) Color.White else Color.Black, + + ), + shape: Shape = RoundedCornerShape(16.dp), + content: @Composable RowScope.() -> Unit +) { + FilledTonalButton( + modifier = modifier + .fillMaxWidth() + .height(56.dp), + enabled = enabled, + onClick = onClick, + colors = colors, + shape = shape, + content = content + ) +} + +@Composable +fun SendContinueButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + darkMode: Boolean = false, + enabled: Boolean = true, + colors: ButtonColors = ButtonDefaults.buttonColors( + containerColor = if (darkMode) Color.White else Color.Black.copy(0.7f), + contentColor = if (darkMode) Color.Black else Color.White, + if (darkMode) { + Color.White.copy(0.4f) + } else { + Color.Black.copy(0.4f) + }, + disabledContentColor = if (darkMode) { + Color.Black.copy(0.3f) + } else { + Color.White.copy(0.3f) + } + ), + shape: Shape = RoundedCornerShape(16.dp), + content: @Composable RowScope.() -> Unit +) { + FilledTonalButton( + modifier = modifier + .fillMaxWidth() + .height(56.dp), + enabled = enabled, + onClick = onClick, + colors = colors, + shape = shape, + content = content + ) +} + +@Composable +fun LargeButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + colors: ButtonColors = ButtonDefaults.buttonColors( + containerColor = DesignTheme.colors.background, + contentColor = DesignTheme.colors.content + ), + shape: Shape = ButtonDefaults.shape, + content: @Composable RowScope.() -> Unit +) { + FilledTonalButton( + modifier = modifier + .fillMaxWidth() + .height(56.dp), + enabled = enabled, + onClick = onClick, + colors = colors, + shape = shape, + content = content + ) +} + +@Composable +fun BorderedLargeButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + colors: ButtonColors = ButtonDefaults.buttonColors( + containerColor = DesignTheme.colors.surface, + contentColor = DesignTheme.colors.content + ), + shape: Shape = RoundedCornerShape(50), + content: @Composable RowScope.() -> Unit +) { + LargeButton( + modifier = modifier.border( + 1.dp, + colors.contentColor, + shape + ), + onClick = onClick, + colors = colors, + shape = shape, + content = content + ) +} + +@Composable +fun SmallToggleButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + colors: ButtonColors = ButtonDefaults.buttonColors( + containerColor = DesignTheme.colors.background, + contentColor = DesignTheme.colors.content + ), + shape: Shape = ButtonDefaults.shape, + content: @Composable RowScope.() -> Unit +) { +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt index 8b489d0f..145b4195 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/CircleButton.kt @@ -6,7 +6,7 @@ import androidx.compose.material3.IconButtonColors import androidx.compose.material3.IconButtonDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme @Composable fun CircleButton( @@ -14,8 +14,8 @@ fun CircleButton( modifier: Modifier = Modifier, enabled: Boolean = true, colors: IconButtonColors = IconButtonDefaults.filledIconButtonColors( - containerColor = BrainwalletTheme.colors.background.copy(0.2f), - contentColor = BrainwalletTheme.colors.content + containerColor = DesignTheme.colors.background.copy(0.2f), + contentColor = DesignTheme.colors.content ), content: @Composable () -> Unit ) { diff --git a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt index c9cd756e..dd610ce5 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/DarkModeToggleButton.kt @@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme @Composable fun DarkModeToggleButton( @@ -43,16 +43,16 @@ fun DarkModeToggleButton( .clip(CircleShape) .border( 1.dp, - if (checked) BrainwalletTheme.colors.warn else BrainwalletTheme.colors.surface, + if (checked) DesignTheme.colors.warn else DesignTheme.colors.surface, CircleShape ) - .background(if (checked) BrainwalletTheme.colors.surface else BrainwalletTheme.colors.content) + .background(if (checked) DesignTheme.colors.surface else DesignTheme.colors.content) ) { Icon( modifier = Modifier .align(Alignment.Center) .size((iconButtonSizeInDp * 0.6).dp), - tint = if (checked) BrainwalletTheme.colors.warn else BrainwalletTheme.colors.surface, + tint = if (checked) DesignTheme.colors.warn else DesignTheme.colors.surface, painter = painterResource(if (checked) R.drawable.ic_light_mode else R.drawable.ic_dark_mode), contentDescription = stringResource(R.string.toggle_dark_mode), ) @@ -64,7 +64,7 @@ fun DarkModeToggleButton( @Composable private fun DarkModeToggleButtonPreview() { BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) { - Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) { + Box(modifier = Modifier.background(DesignTheme.colors.background)) { DarkModeToggleButton(checked = isSystemInDarkTheme(), onCheckedChange = {},) } } diff --git a/app/src/main/java/com/brainwallet/ui/composable/DashedDividers.kt b/app/src/main/java/com/brainwallet/ui/composable/DashedDividers.kt new file mode 100644 index 00000000..58aaf445 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/DashedDividers.kt @@ -0,0 +1,38 @@ +package com.brainwallet.ui.composable +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathEffect + +@Composable +fun DashedDivider( + modifier: Modifier = Modifier, + color: Color = Color.White.copy(alpha = 0.3f), + dashWidth: Dp = 8.dp, + gapWidth: Dp = 4.dp, + strokeWidth: Dp = 1.dp +) { + val density = LocalDensity.current + Canvas( + modifier = modifier + .height(strokeWidth) + ) { + val dashPx = with(density) { dashWidth.toPx() } + val gapPx = with(density) { gapWidth.toPx() } + val strokePx = with(density) { strokeWidth.toPx() } + + drawLine( + color = color, + start = Offset(0f, 0f), + end = Offset(size.width, 0f), + strokeWidth = strokePx, + pathEffect = PathEffect.dashPathEffect(floatArrayOf(dashPx, gapPx), 0f) + ) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt index 5de35133..146e9fb9 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/Foundation.kt @@ -21,7 +21,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme @Composable fun BrainwalletScaffold( @@ -33,8 +33,8 @@ fun BrainwalletScaffold( ) { Scaffold( modifier = modifier, - containerColor = BrainwalletTheme.colors.surface, - contentColor = BrainwalletTheme.colors.content, + containerColor = DesignTheme.colors.surface, + contentColor = DesignTheme.colors.content, topBar = topBar, bottomBar = bottomBar, floatingActionButton = floatingActionButton, @@ -51,8 +51,8 @@ fun BrainwalletTopAppBar( TopAppBar( modifier = modifier, colors = TopAppBarDefaults.topAppBarColors( - containerColor = BrainwalletTheme.colors.surface, - navigationIconContentColor = BrainwalletTheme.colors.content + containerColor = DesignTheme.colors.surface, + navigationIconContentColor = DesignTheme.colors.content ), title = title, navigationIcon = navigationIcon @@ -65,10 +65,10 @@ fun BrainwalletBottomSheet( content: @Composable ColumnScope.() -> Unit, ) { ModalBottomSheet( - containerColor = BrainwalletTheme.colors.background, - contentColor = BrainwalletTheme.colors.content, + containerColor = DesignTheme.colors.background, + contentColor = DesignTheme.colors.content, dragHandle = { - BottomSheetDefaults.DragHandle(color = BrainwalletTheme.colors.content) + BottomSheetDefaults.DragHandle(color = DesignTheme.colors.content) }, onDismissRequest = onDismissRequest, content = content @@ -82,8 +82,8 @@ fun BrainwalletButton( enabled: Boolean = true, shape: Shape = CircleShape, colors: ButtonColors = ButtonDefaults.buttonColors( - containerColor = BrainwalletTheme.colors.surface, - contentColor = BrainwalletTheme.colors.content + containerColor = DesignTheme.colors.surface, + contentColor = DesignTheme.colors.content ), content: @Composable RowScope.() -> Unit ) { @@ -93,7 +93,7 @@ fun BrainwalletButton( shape = shape, colors = colors, modifier = modifier - .border(1.dp, BrainwalletTheme.colors.border, shape) + .border(1.dp, DesignTheme.colors.border, shape) .height(50.dp), content = content ) diff --git a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt b/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt deleted file mode 100644 index 4d17fe74..00000000 --- a/app/src/main/java/com/brainwallet/ui/composable/LargeButton.kt +++ /dev/null @@ -1,63 +0,0 @@ -package com.brainwallet.ui.composable - -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.RowScope -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.ButtonColors -import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.FilledTonalButton -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.unit.dp -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme - -@Composable -fun LargeButton( - modifier: Modifier = Modifier, - enabled: Boolean = true, - onClick: () -> Unit, - colors: ButtonColors = ButtonDefaults.buttonColors( - containerColor = BrainwalletTheme.colors.background, - contentColor = BrainwalletTheme.colors.content - ), - shape: Shape = ButtonDefaults.shape, - content: @Composable RowScope.() -> Unit -) { - FilledTonalButton( - modifier = modifier - .fillMaxWidth() - .height(56.dp), - enabled = enabled, - onClick = onClick, - colors = colors, - shape = shape, - content = content - ) -} - -@Composable -fun BorderedLargeButton( - modifier: Modifier = Modifier, - onClick: () -> Unit, - colors: ButtonColors = ButtonDefaults.buttonColors( - containerColor = BrainwalletTheme.colors.surface, - contentColor = BrainwalletTheme.colors.content - ), - shape: Shape = RoundedCornerShape(50), - content: @Composable RowScope.() -> Unit -) { - LargeButton( - modifier = modifier.border( - 1.dp, - colors.contentColor, - shape - ), - onClick = onClick, - colors = colors, - shape = shape, - content = content - ) -} diff --git a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt index 566970c6..fb4240c6 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/LoadingDialog.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties import com.brainwallet.R -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme @Composable fun LoadingDialog( @@ -31,7 +31,7 @@ fun LoadingDialog( ) ) { Card( - shape = BrainwalletTheme.shapes.medium, + shape = DesignTheme.shapes.medium, modifier = Modifier .fillMaxWidth(0.8f) .wrapContentHeight(), @@ -46,7 +46,7 @@ fun LoadingDialog( modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center, text = text, - style = BrainwalletTheme.typography.bodyLarge + style = DesignTheme.typography.bodyLarge ) } } diff --git a/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt index 28140bab..d7a59ca5 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MediumButton.kt @@ -11,15 +11,15 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Shape import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme @Composable fun MediumTextButton( modifier: Modifier = Modifier, onClick: () -> Unit, colors: ButtonColors = ButtonDefaults.buttonColors( - containerColor = BrainwalletTheme.colors.surface, - contentColor = BrainwalletTheme.colors.content + containerColor = DesignTheme.colors.surface, + contentColor = DesignTheme.colors.content ), shape: Shape = ButtonDefaults.shape, content: @Composable RowScope.() -> Unit diff --git a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt index 2c91d5a0..bc518983 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/MoonpayBuyButton.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.brainwallet.R -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import com.grunt.brainwallet.core.presentation.theme.lavender import com.grunt.brainwallet.core.presentation.theme.nearBlack @@ -29,7 +29,7 @@ fun MoonpayBuyButton( ) { Button( modifier = modifier, - shape = BrainwalletTheme.shapes.large, + shape = DesignTheme.shapes.large, colors = ButtonDefaults.buttonColors( containerColor = lavender, contentColor = nearBlack @@ -43,7 +43,7 @@ fun MoonpayBuyButton( ) { Text( text = stringResource(R.string.buy_ltc).uppercase(), - style = BrainwalletTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold) + style = DesignTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold) ) Row( horizontalArrangement = Arrangement.spacedBy(12.dp), @@ -51,7 +51,7 @@ fun MoonpayBuyButton( ) { Text( text = stringResource(R.string.powered_by_moonpay).uppercase(), - style = BrainwalletTheme.typography.labelSmall.copy(fontSize = 8.sp) + style = DesignTheme.typography.labelSmall.copy(fontSize = 8.sp) ) Image( modifier = Modifier.size(16.dp), diff --git a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt index c174922c..b60ca471 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/SeedWordItem.kt @@ -36,7 +36,7 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import androidx.compose.ui.window.PopupProperties -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import com.grunt.brainwallet.core.presentation.theme.chili @Composable @@ -53,7 +53,7 @@ fun SeedWordItem( .weight(1f), text = label, style = MaterialTheme.typography.bodyMedium, - color = if (isError) chili else BrainwalletTheme.colors.content, + color = if (isError) chili else DesignTheme.colors.content, overflow = TextOverflow.Ellipsis, maxLines = 1 ) @@ -71,9 +71,9 @@ fun SeedWordItemBox( ) { Box(modifier = modifier) { Row( - modifier = modifier + modifier = Modifier .background( - color = BrainwalletTheme.colors.background.copy(alpha = 0.3f), + color = DesignTheme.colors.background.copy(alpha = 0.3f), shape = MaterialTheme.shapes.extraLarge ) .padding(horizontal = 16.dp), @@ -91,12 +91,12 @@ fun SeedWordItemTextField( suggestions: List = emptyList(), modifier: Modifier = Modifier, textStyle: TextStyle = TextStyle.Default.copy( - color = BrainwalletTheme.colors.content + color = DesignTheme.colors.content ), keyboardOptions: KeyboardOptions = KeyboardOptions.Default, keyboardActions: KeyboardActions = KeyboardActions.Default, cursorBrush: Brush = SolidColor( - BrainwalletTheme.colors.content + DesignTheme.colors.content ), // todo: change with materialtheme so it will be adapt automatically when switch darkmode prefix: @Composable (() -> Unit)? = null, ) { @@ -146,7 +146,7 @@ fun SeedWordItemTextField( modifier = Modifier .align(Alignment.BottomEnd) .background( - color = BrainwalletTheme.colors.background.copy(alpha = 0.3f), + color = DesignTheme.colors.background.copy(alpha = 0.3f), shape = MaterialTheme.shapes.medium ) .heightIn(max = 250.dp), diff --git a/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt b/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt index 6094624e..1c7f3af5 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/WheelPicker.kt @@ -14,6 +14,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.lazy.LazyColumn @@ -21,6 +22,9 @@ import androidx.compose.foundation.lazy.LazyListItemInfo import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -385,7 +389,7 @@ internal inline fun logMsg(debug: Boolean, block: () -> String) { @Composable fun WheelPickerFocusVertical( modifier: Modifier = Modifier, - dividerSize: Dp = 1.dp, + dividerSize: Dp = 0.7.dp, dividerColor: Color = DefaultDividerColor, ) { Box( @@ -395,19 +399,43 @@ fun WheelPickerFocusVertical( modifier = Modifier .background(dividerColor) .height(dividerSize) - .fillMaxWidth() + .fillMaxWidth(0.7f) .align(Alignment.TopCenter), ) Box( modifier = Modifier .background(dividerColor) .height(dividerSize) - .fillMaxWidth() + .fillMaxWidth(0.7f) .align(Alignment.BottomCenter), ) } } +/** + * The capsule implementation of focus view in vertical. + */ +@Composable +fun WheelPickerFocusCapsule( + modifier: Modifier = Modifier, + focusColor: Color = Color.Black +) { + Card( + modifier = modifier + .padding(start = 16.dp, end = 16.dp) + .fillMaxSize(), + shape = RoundedCornerShape(6.dp), + colors = CardDefaults.cardColors( + containerColor = focusColor.copy(alpha = 0.04f) + ) + ) { + Box( + modifier = Modifier + .fillMaxSize() + ) + } +} + /** * Default divider color. */ @@ -417,6 +445,12 @@ private val DefaultDividerColor: Color val color = if (isSystemInDarkTheme()) Color.White else Color.Black return color.copy(alpha = 0.2f) } +private val CapusleColor: Color + @Composable + get() { + val color = if (isSystemInDarkTheme()) Color.White else Color.Black + return color.copy(alpha = 0.2f) + } /** * Default display. diff --git a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt index c1a7010e..cd611271 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/FiatSelectorBottomSheet.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.unit.dp import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.tools.sqlite.CurrencyDataSource import com.brainwallet.ui.composable.BrainwalletBottomSheet -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import androidx.compose.foundation.layout.size import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip @@ -51,8 +51,8 @@ fun FiatSelectorBottomSheet( ) { currency -> ListItem( colors = ListItemDefaults.colors( - containerColor = BrainwalletTheme.colors.background, - headlineColor = BrainwalletTheme.colors.content, + containerColor = DesignTheme.colors.background, + headlineColor = DesignTheme.colors.content, ), modifier = Modifier.clickable { onFiatSelect.invoke(currency) @@ -62,14 +62,14 @@ fun FiatSelectorBottomSheet( Text( modifier = Modifier.padding(tinyPad.dp), text = currency.name, - style = BrainwalletTheme.typography.labelLarge + style = DesignTheme.typography.labelLarge .copy(textAlign = TextAlign.Left) ) Spacer(modifier = Modifier.weight(1f)) Text( modifier = Modifier.padding(tinyPad.dp), text = "${currency.code} (${currency.symbol})", - style = BrainwalletTheme.typography.labelLarge + style = DesignTheme.typography.labelLarge .copy(textAlign = TextAlign.Left) ) } @@ -79,7 +79,7 @@ fun FiatSelectorBottomSheet( Icon( Icons.Default.CheckCircle, contentDescription = null, - tint = BrainwalletTheme.colors.affirm + tint = DesignTheme.colors.affirm ) } else { Box( @@ -87,7 +87,7 @@ fun FiatSelectorBottomSheet( .size(unselectedCircleSize.dp) .alpha(0.1f) .clip(CircleShape) - .background(BrainwalletTheme.colors.content) + .background(DesignTheme.colors.content) ) } } diff --git a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt index 80e6dec2..9067787a 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/bottomsheet/LanguageSelectorBottomSheet.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.brainwallet.data.model.Language import com.brainwallet.ui.composable.BrainwalletBottomSheet -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme @Composable fun LanguageSelectorBottomSheet( @@ -35,8 +35,8 @@ fun LanguageSelectorBottomSheet( ) { language -> ListItem( colors = ListItemDefaults.colors( - containerColor = BrainwalletTheme.colors.background, - headlineColor = BrainwalletTheme.colors.content, + containerColor = DesignTheme.colors.background, + headlineColor = DesignTheme.colors.content, ), modifier = Modifier.clickable { if (language.code.isNotBlank()) { @@ -51,7 +51,7 @@ fun LanguageSelectorBottomSheet( Icon( Icons.Default.CheckCircle, contentDescription = null, - tint = BrainwalletTheme.colors.affirm + tint = DesignTheme.colors.affirm ) } } diff --git a/app/src/main/java/com/brainwallet/ui/composable/PasscodeIndicator.kt b/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeIndicator.kt similarity index 91% rename from app/src/main/java/com/brainwallet/ui/composable/PasscodeIndicator.kt rename to app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeIndicator.kt index 9837d962..c7abdcb1 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PasscodeIndicator.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeIndicator.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.composable +package com.brainwallet.ui.composable.passcode import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row diff --git a/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt b/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypad.kt similarity index 83% rename from app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt rename to app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypad.kt index adc97ab3..e32330cf 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PasscodeKeypad.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypad.kt @@ -1,6 +1,6 @@ @file:OptIn(ExperimentalLayoutApi::class) -package com.brainwallet.ui.composable +package com.brainwallet.ui.composable.passcode import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.ExperimentalLayoutApi @@ -25,16 +25,16 @@ fun PasscodeKeypad( onEvent: (PasscodeKeypadEvent) -> Unit ) { FlowRow( - horizontalArrangement = Arrangement.spacedBy(24.dp), - verticalArrangement = Arrangement.spacedBy(24.dp), + horizontalArrangement = Arrangement.spacedBy(18.dp), + verticalArrangement = Arrangement.spacedBy(18.dp), maxItemsInEachRow = 3 ) { // pin number button - val modifierCircleButton = Modifier.size(75.dp) + val modifierCircleButton = Modifier.size(60.dp) repeat(9) { index -> val number = index + 1 - CircleButton( + _root_ide_package_.com.brainwallet.ui.composable.CircleButton( modifier = modifierCircleButton.testTag("keypad$number"), onClick = { onEvent.invoke(PasscodeKeypadEvent.OnPressed(number)) @@ -49,7 +49,7 @@ fun PasscodeKeypad( // Bottom row with biometric, 0, and backspace if (false) { // hardcoded false for now - CircleButton( + _root_ide_package_.com.brainwallet.ui.composable.CircleButton( modifier = modifierCircleButton, onClick = { // @@ -64,7 +64,7 @@ fun PasscodeKeypad( ) } } else { - CircleButton( + _root_ide_package_.com.brainwallet.ui.composable.CircleButton( modifier = modifierCircleButton, onClick = { }, colors = IconButtonDefaults.filledIconButtonColors( @@ -76,7 +76,7 @@ fun PasscodeKeypad( } } - CircleButton( + _root_ide_package_.com.brainwallet.ui.composable.CircleButton( modifier = modifierCircleButton, onClick = { onEvent.invoke(PasscodeKeypadEvent.OnPressed(0)) @@ -88,7 +88,7 @@ fun PasscodeKeypad( ) } - CircleButton( + _root_ide_package_.com.brainwallet.ui.composable.CircleButton( modifier = modifierCircleButton, onClick = { onEvent.invoke(PasscodeKeypadEvent.OnDelete) @@ -104,8 +104,3 @@ fun PasscodeKeypad( } } } - -sealed class PasscodeKeypadEvent { - object OnDelete : PasscodeKeypadEvent() - data class OnPressed(val digit: Int) : PasscodeKeypadEvent() -} diff --git a/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypadEvent.kt b/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypadEvent.kt new file mode 100644 index 00000000..495fb4da --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypadEvent.kt @@ -0,0 +1,5 @@ +package com.brainwallet.ui.composable.passcode +sealed class PasscodeKeypadEvent { + object OnDelete : PasscodeKeypadEvent() + data class OnPressed(val digit: Int) : PasscodeKeypadEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypadWrapper.kt b/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypadWrapper.kt new file mode 100644 index 00000000..bab4b12a --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/composable/passcode/PasscodeKeypadWrapper.kt @@ -0,0 +1,19 @@ +package com.brainwallet.ui.composable.passcode +import androidx.compose.runtime.Composable + +@Composable +fun PasscodeKeypadWrapper( + onDelete: () -> Unit, + onDigitPressed: (digit: Int, isValidPin: (String) -> Boolean) -> Unit, + onValidatePin: (String) -> Boolean, +) { + PasscodeKeypad { passcodeKeypadEvent -> + when (passcodeKeypadEvent) { + PasscodeKeypadEvent.OnDelete -> onDelete() + is PasscodeKeypadEvent.OnPressed -> onDigitPressed( + passcodeKeypadEvent.digit, + onValidatePin, + ) + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt b/app/src/main/java/com/brainwallet/ui/composable/passcode/PinDotItem.kt similarity index 69% rename from app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt rename to app/src/main/java/com/brainwallet/ui/composable/passcode/PinDotItem.kt index e6d4f392..9156fc6a 100644 --- a/app/src/main/java/com/brainwallet/ui/composable/PinDotItem.kt +++ b/app/src/main/java/com/brainwallet/ui/composable/passcode/PinDotItem.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.composable +package com.brainwallet.ui.composable.passcode import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -10,7 +10,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme @Composable fun PinDotItem( @@ -21,8 +21,8 @@ fun PinDotItem( modifier = modifier .padding(horizontal = 4.dp) .size(16.dp) - .background(if (checked) BrainwalletTheme.colors.content else Color.Transparent, CircleShape) - .border(1.dp, BrainwalletTheme.colors.content, CircleShape), + .background(if (checked) DesignTheme.colors.content else Color.Transparent, CircleShape) + .border(1.dp, DesignTheme.colors.content, CircleShape), ) } diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt deleted file mode 100644 index 8a56442f..00000000 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinEvent.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.brainwallet.ui.screens.buylitecoin - -import android.content.Context - -sealed class BuyLitecoinEvent { - data class OnLoad(val context: Context) : BuyLitecoinEvent() - data class OnFiatAmountChange( - val fiatAmount: Float, - val needFetch: Boolean = true - ) : BuyLitecoinEvent() -} diff --git a/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveEvent.kt new file mode 100644 index 00000000..8afea4e4 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveEvent.kt @@ -0,0 +1,11 @@ +package com.brainwallet.ui.screens.buyreceive + +import android.content.Context + +sealed class BuyReceiveEvent { + data class OnLoad(val context: Context) : BuyReceiveEvent() + data class OnFiatAmountChange( + val fiatAmount: Float, + val needFetch: Boolean = true + ) : BuyReceiveEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveScreen.kt similarity index 86% rename from app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt rename to app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveScreen.kt index c909fb86..c70f2547 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveScreen.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.buylitecoin +package com.brainwallet.ui.screens.buyreceive import android.widget.Toast import androidx.compose.foundation.layout.Arrangement @@ -24,6 +24,7 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.brainwallet.R import com.brainwallet.navigation.MoonPayWidgetLauncher import com.brainwallet.navigation.MoonPayWidgetLauncherViewModel @@ -32,22 +33,21 @@ import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.LargeButton -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import org.koin.compose.viewmodel.koinViewModel -// TODO: wip @Composable -fun BuyLitecoinScreen( +fun BuyReceiveScreen( onNavigate: OnNavigate, - viewModel: BuyLitecoinViewModel = koinViewModel(), + viewModel: BuyReceiveViewModel = koinViewModel(), moonPayWidgetLauncherViewModel: MoonPayWidgetLauncherViewModel = koinViewModel() ) { val state by viewModel.state.collectAsState() val loadingState by viewModel.loadingState.collectAsState() - val appSetting by viewModel.appSetting.collectAsState() + val appSetting by viewModel.appSetting.collectAsStateWithLifecycle() val context = LocalContext.current LaunchedEffect(Unit) { - viewModel.onEvent(BuyLitecoinEvent.OnLoad(context)) + viewModel.onEvent(BuyReceiveEvent.OnLoad(context)) viewModel.uiEffect.collect { effect -> when (effect) { is UiEffect.ShowMessage -> @@ -96,18 +96,18 @@ fun BuyLitecoinScreen( prefix = { Text( text = appSetting.currency.symbol, - style = BrainwalletTheme.typography.titleLarge.copy(color = BrainwalletTheme.colors.content) + style = DesignTheme.typography.titleLarge.copy(color = DesignTheme.colors.content) ) }, - textStyle = BrainwalletTheme.typography.titleLarge.copy(color = BrainwalletTheme.colors.content), + textStyle = DesignTheme.typography.titleLarge.copy(color = DesignTheme.colors.content), value = "${if (state.fiatAmount < 1) "" else state.fiatAmount.toInt()}", singleLine = true, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), onValueChange = { input -> val amount = input.toFloatOrNull() ?: 0f - viewModel.onEvent(BuyLitecoinEvent.OnFiatAmountChange(amount, false)) + viewModel.onEvent(BuyReceiveEvent.OnFiatAmountChange(amount, false)) }, - shape = BrainwalletTheme.shapes.extraLarge, + shape = DesignTheme.shapes.extraLarge, isError = state.isValid().not(), supportingText = { state.errorFiatAmountStringId?.let { @@ -119,7 +119,7 @@ fun BuyLitecoinScreen( Text( text = state.getLtcAmountFormatted(loadingState.visible), style = MaterialTheme.typography.titleLarge.copy( - color = BrainwalletTheme.colors.content.copy( + color = DesignTheme.colors.content.copy( 0.7f ) ), @@ -133,7 +133,7 @@ fun BuyLitecoinScreen( Text( text = state.address, style = MaterialTheme.typography.titleMedium.copy( - color = BrainwalletTheme.colors.content.copy( + color = DesignTheme.colors.content.copy( 0.7f ) ) diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinState.kt b/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveState.kt similarity index 68% rename from app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinState.kt rename to app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveState.kt index 628d6f0c..9fd1e89c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveState.kt @@ -1,9 +1,9 @@ -package com.brainwallet.ui.screens.buylitecoin +package com.brainwallet.ui.screens.buyreceive import com.brainwallet.data.model.MoonpayCurrencyLimit import timber.log.Timber -data class BuyLitecoinState( +data class BuyReceiveState( val moonpayCurrencyLimit: MoonpayCurrencyLimit = MoonpayCurrencyLimit(), val fiatAmount: Float = moonpayCurrencyLimit.data.baseCurrency.min, val ltcAmount: Float = 0f, @@ -11,9 +11,9 @@ data class BuyLitecoinState( val errorFiatAmountStringId: Int? = null ) -fun BuyLitecoinState.isValid(): Boolean = errorFiatAmountStringId == null +fun BuyReceiveState.isValid(): Boolean = errorFiatAmountStringId == null -fun BuyLitecoinState.getLtcAmountFormatted(isLoading: Boolean): String = +fun BuyReceiveState.getLtcAmountFormatted(isLoading: Boolean): String = (if (isLoading || ltcAmount < 0f) "x.xxxŁ" else "%.3fŁ".format(ltcAmount)).also { Timber.d("TImber: ltcamount $ltcAmount") } diff --git a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveViewModel.kt similarity index 78% rename from app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt rename to app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveViewModel.kt index c2b438ec..07cfb137 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/buylitecoin/BuyLitecoinViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/buyreceive/BuyReceiveViewModel.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.buylitecoin +package com.brainwallet.ui.screens.buyreceive import androidx.lifecycle.viewModelScope import com.brainwallet.R @@ -9,7 +9,6 @@ import com.brainwallet.tools.manager.BRSharedPrefs import com.brainwallet.ui.BrainwalletViewModel import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.debounce @@ -17,27 +16,19 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.getAndUpdate import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import org.koin.android.annotation.KoinViewModel @KoinViewModel -class BuyLitecoinViewModel( +class BuyReceiveViewModel( private val settingRepository: SettingRepository, private val ltcRepository: LtcRepository -) : BrainwalletViewModel() { +) : BrainwalletViewModel() { - private val _state = MutableStateFlow(BuyLitecoinState()) - val state: StateFlow = _state.asStateFlow() - - val appSetting = settingRepository.settings - .distinctUntilChanged() - .stateIn( - viewModelScope, - SharingStarted.Eagerly, - AppSetting() - ) + private val _state = MutableStateFlow(BuyReceiveState()) + val state: StateFlow = _state.asStateFlow() + val appSetting: StateFlow = settingRepository.currentSettings init { viewModelScope.launch { @@ -49,14 +40,14 @@ class BuyLitecoinViewModel( it in min..max } .collect { - onEvent(BuyLitecoinEvent.OnFiatAmountChange(it)) + onEvent(BuyReceiveEvent.OnFiatAmountChange(it)) } } } - override fun onEvent(event: BuyLitecoinEvent) { + override fun onEvent(event: BuyReceiveEvent) { when (event) { - is BuyLitecoinEvent.OnLoad -> viewModelScope.launch { + is BuyReceiveEvent.OnLoad -> viewModelScope.launch { delay(500) _state.update { it.copy(address = BRSharedPrefs.getReceiveAddress(event.context)) } try { @@ -64,7 +55,7 @@ class BuyLitecoinViewModel( _state.getAndUpdate { val limitResult = ltcRepository.fetchLimits( - baseCurrencyCode = appSetting.value.currency.code + baseCurrencyCode = settingRepository.currentSettings.value.currency.code ) it.copy( @@ -79,7 +70,7 @@ class BuyLitecoinViewModel( } } - is BuyLitecoinEvent.OnFiatAmountChange -> viewModelScope.launch { + is BuyReceiveEvent.OnFiatAmountChange -> viewModelScope.launch { // do validation val (_, min, max) = state.value.moonpayCurrencyLimit.data.baseCurrency val errorStringId = when { @@ -105,7 +96,7 @@ class BuyLitecoinViewModel( val result = ltcRepository.fetchBuyQuote( mapOf( "currencyCode" to "ltc", - "baseCurrencyCode" to appSetting.value.currency.code, + "baseCurrencyCode" to settingRepository.currentSettings.value.currency.code, "baseCurrencyAmount" to event.fiatAmount.toString(), ) ) diff --git a/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubEvent.kt new file mode 100644 index 00000000..1d309b08 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubEvent.kt @@ -0,0 +1,7 @@ +package com.brainwallet.ui.screens.gamehub + +import android.content.Context + +sealed class GameHubEvent { + data class OnLoad(val context: Context) : GameHubEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubScreen.kt new file mode 100644 index 00000000..e66c139d --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubScreen.kt @@ -0,0 +1,89 @@ +package com.brainwallet.ui.screens.gamehub + +import com.brainwallet.R +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import com.brainwallet.data.model.AppSetting +import com.brainwallet.navigation.OnNavigate +import com.brainwallet.navigation.UiEffect +import com.brainwallet.ui.composable.BrainwalletScaffold +import com.brainwallet.ui.theme.BrainwalletAppTheme +import com.brainwallet.ui.theme.DesignTheme +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun GameHubScreen( + onNavigate: OnNavigate, + modifier: Modifier = Modifier, + viewModel: GameHubViewModel = koinViewModel() +) { + val uiState by viewModel.state.collectAsState() + val context = LocalContext.current + LaunchedEffect(Unit) { + viewModel.onEvent(GameHubEvent.OnLoad(context)) + viewModel.uiEffect.collect { effect -> + when (effect) { + is UiEffect.Navigate -> onNavigate.invoke(effect) + else -> Unit + } + } + } + GameHubScreen(uiState = uiState, modifier = modifier, onEvent = viewModel::onEvent) +} + +@Composable +private fun GameHubScreen( + uiState: GameHubState, + modifier: Modifier = Modifier, + onEvent: (GameHubEvent) -> Unit = {}, + viewModel: GameHubViewModel = koinViewModel() +) { + val horizontalVerticalSpacing = 8 + val state by viewModel.state.collectAsState() + val loadingState by viewModel.loadingState.collectAsState() + val context = LocalContext.current + BrainwalletScaffold { paddingValues -> + Box( + modifier = Modifier + .padding(paddingValues) + .padding(16.dp) + .fillMaxSize(), + contentAlignment = Alignment.TopCenter + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(24.dp) + ) { + Text( + text = stringResource(R.string.game_hub_title), + style = DesignTheme.typography.titleLarge, + ) + } + } + } +} + +@PreviewLightDark +@Composable +private fun GameHubScreenPreview() { + BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) { + GameHubScreen( + uiState = GameHubState() + ) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubState.kt b/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubState.kt new file mode 100644 index 00000000..a335eb8a --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubState.kt @@ -0,0 +1,8 @@ +package com.brainwallet.ui.screens.gamehub + +data class GameHubState( + val biometricEnabled: Boolean = false, + val iso: String = "USD", + val formattedCurrency: String = "", + val formattedVersion: String = "" +) diff --git a/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubViewModel.kt new file mode 100644 index 00000000..fbd59e95 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/gamehub/GameHubViewModel.kt @@ -0,0 +1,25 @@ +package com.brainwallet.ui.screens.gamehub + +import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.ui.BrainwalletViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import org.koin.android.annotation.KoinViewModel + +@KoinViewModel +class GameHubViewModel( + private val ltcRepository: LtcRepository +) : BrainwalletViewModel() { + + private val _state = + MutableStateFlow(GameHubState()) + val state: StateFlow = _state.asStateFlow() + + override fun onEvent(event: GameHubEvent) { + when (event) { + is GameHubEvent.OnLoad -> { + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/HomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/home/HomeScreen.kt deleted file mode 100644 index 8fe18853..00000000 --- a/app/src/main/java/com/brainwallet/ui/screens/home/HomeScreen.kt +++ /dev/null @@ -1,87 +0,0 @@ -@file:OptIn(ExperimentalMaterial3Api::class) - -package com.brainwallet.ui.screens.home - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Home -import androidx.compose.material.icons.filled.Menu -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -import androidx.compose.material3.NavigationBar -import androidx.compose.material3.NavigationBarDefaults -import androidx.compose.material3.NavigationBarItem -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.material3.TopAppBar -import androidx.compose.material3.TopAppBarDefaults -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.fragment.compose.AndroidFragment -import androidx.fragment.compose.rememberFragmentState -import com.brainwallet.navigation.OnNavigate -import com.brainwallet.presenter.history.HistoryFragment - -// TODO: wip -@Composable -fun HomeScreen( - onNavigate: OnNavigate -) { - Scaffold( - topBar = { HomeTopBar() }, - bottomBar = { HomeBottomNavBar() }, - ) { paddingValues -> - Column( - modifier = Modifier.padding(paddingValues) - ) { - val fragmentState = rememberFragmentState() - // using old fragment - AndroidFragment( - fragmentState = fragmentState - ) - } - } -} - -@Composable -fun HomeTopBar() { - TopAppBar( - title = { - // - }, - actions = { - IconButton(onClick = { - }) { - Icon(Icons.Default.Menu, contentDescription = "menu") - } - }, - colors = TopAppBarDefaults.topAppBarColors( - containerColor = NavigationBarDefaults.containerColor - ) - ) -} - -@Composable -fun HomeBottomNavBar() { - NavigationBar { - listOf("history", "send", "receive", "buy").forEach { - NavigationBarItem( - selected = false, - label = { - Text(it) - }, - icon = { - Icon( - Icons.Default.Home, - contentDescription = it - ) - }, - onClick = { - // - } - ) - } - } -} diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/history/HistoryScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/home/history/HistoryScreen.kt deleted file mode 100644 index 988ad5f5..00000000 --- a/app/src/main/java/com/brainwallet/ui/screens/home/history/HistoryScreen.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.brainwallet.ui.screens.home.history - -import androidx.compose.foundation.layout.Box -import androidx.compose.runtime.Composable - -// TODO: wip -@Composable -fun HistoryScreen() { - Box {} -} diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsEvent.kt deleted file mode 100644 index cdd3b110..00000000 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsEvent.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.brainwallet.ui.screens.inputwords - -import android.content.Context -import com.brainwallet.navigation.Route - -sealed class InputWordsEvent { - data class OnLoad( - val source: Route.InputWords.Source? = null - ) : InputWordsEvent() - - data class OnSeedWordItemChange( - val index: Int, - val text: String - ) : InputWordsEvent() - - object OnClearSeedWords : InputWordsEvent() - - data class OnRestoreClick( - val context: Context - ) : InputWordsEvent() -} diff --git a/app/src/main/java/com/brainwallet/ui/screens/main/MainScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/main/MainScreen.kt new file mode 100644 index 00000000..439b7587 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/main/MainScreen.kt @@ -0,0 +1,431 @@ +package com.brainwallet.ui.screens.home + +import android.net.Uri +import androidx.browser.customtabs.CustomTabsIntent +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.animateDpAsState +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.GridItemSpan +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.DrawerValue +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalNavigationDrawer +import androidx.compose.material3.Scaffold +import androidx.compose.material3.rememberDrawerState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import com.brainwallet.ui.theme.mainScreenLightSurfaceGradient +import androidx.compose.ui.unit.dp +import com.brainwallet.navigation.OnNavigate +import com.brainwallet.navigation.Route +import com.brainwallet.navigation.UiEffect +import com.brainwallet.ui.composable.BentoBottomNavBar +import com.brainwallet.ui.screens.main.SettingsButton +import com.brainwallet.ui.screens.main.ThemeButton +import kotlinx.coroutines.launch +import org.koin.compose.viewmodel.koinViewModel +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.brainwallet.constants.BWConstants.EXPAND_DURATION +import com.brainwallet.constants.BWConstants.FADE_IN_DURATION +import com.brainwallet.constants.BWConstants.FADE_OUT_DURATION +import com.brainwallet.data.model.AppSetting +import com.brainwallet.ui.bentosections.balancebento.BalanceBentoScreen +import com.brainwallet.ui.bentosections.ltcpickerbento.LTCPickerBentoScreen +import com.brainwallet.constants.balanceGameBentoHt +import com.brainwallet.constants.gameHubHt +import com.brainwallet.constants.statusBarPadding +import com.brainwallet.constants.topNavButtonSize +import com.brainwallet.constants.topNavStartEndPadding +import com.brainwallet.constants.transactionRowHt +import com.brainwallet.ui.bentosections.transactionbento.TransactionsBentoScreen +import com.brainwallet.ui.screens.main.MainScreenEvent +import com.brainwallet.ui.screens.main.MainViewModel +import com.brainwallet.ui.bentosections.buyreceivebento.receive.ReceiveDialog +import com.brainwallet.ui.screens.settings.settingsrows.HomeSettingDrawerSheet +import com.brainwallet.ui.theme.BrainwalletAppTheme +import com.brainwallet.ui.theme.mainScreenDarkSurfaceGradient +import com.brainwallet.util.EventBus +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.map +import androidx.compose.animation.core.animateFloatAsState +import com.brainwallet.ui.theme.blurAnimatedWith +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.imePadding +import androidx.compose.material3.BottomSheetDefaults +import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.compose.LifecycleEventEffect +import com.brainwallet.constants.BWConstants +import com.brainwallet.tools.animation.BRAnimator +import com.brainwallet.ui.bentosections.favouritesbento.FavouritesBentoScreen +import com.brainwallet.ui.bentosections.gamehubbento.GameHubBentoPagerScreen +import com.brainwallet.ui.bentosections.tutorials.TutorialsBentoScreen +import com.brainwallet.ui.screens.send.SendScreen +import com.brainwallet.ui.theme.bentoClearGradient +import com.brainwallet.ui.theme.bentoModalDarkGradient +import com.google.common.math.LinearTransformation.horizontal + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainScreen( + onNavigate: OnNavigate, + modifier: Modifier = Modifier, + viewModel: MainViewModel = koinViewModel() +) { + val context = LocalContext.current + var currentRoute by remember { mutableStateOf(Route.Main) } + val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed) + val scope = rememberCoroutineScope() + val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + var isSheetOpen by remember { mutableStateOf(false) } + var modalContentRoute by remember { mutableStateOf(null) } + val appSetting by viewModel.appSetting.collectAsStateWithLifecycle() + val isDarkMode = appSetting.isDarkMode + val state by viewModel.state.collectAsStateWithLifecycle() + val showTransactionDetail = state.showTransactionDetail + val noTxItemsPresent = state.transactionItems.isEmpty() + val blurRadiusWhen by animateFloatAsState( + targetValue = if (isSheetOpen) 40f else 0f, + animationSpec = tween(durationMillis = 400), + label = "blurRadius" + ) + + val canUserSend = !state.brainwalletIsSyncing && state.isInternetReachable + + LifecycleEventEffect(Lifecycle.Event.ON_RESUME) { + viewModel.onEvent(MainScreenEvent.OnLoad(context)) + viewModel.onResume() + } + + LifecycleEventEffect(Lifecycle.Event.ON_PAUSE) { + viewModel.onPause() + } + + LaunchedEffect(Unit) { + EventBus.events + .filter { it is EventBus.Event.Message } + .map { it as EventBus.Event.Message } + .collect { + drawerState.close() + } + } + + ModalNavigationDrawer( + drawerState = drawerState, + gesturesEnabled = drawerState.isOpen, + drawerContent = { + HomeSettingDrawerSheet( + modifier = Modifier + .fillMaxHeight() + .fillMaxWidth() + .padding( + end = topNavStartEndPadding + + topNavStartEndPadding + + topNavButtonSize + ), + ) + } + ) { + Scaffold( + modifier = modifier + .background( + if (isDarkMode) mainScreenDarkSurfaceGradient else mainScreenLightSurfaceGradient + ) + .padding( + top = statusBarPadding + ) + .blurAnimatedWith(blurRadiusWhen), + containerColor = Color.Transparent, + bottomBar = { + BentoBottomNavBar( + isDarkMode = appSetting.isDarkMode, + currentRoute = currentRoute, + isShowingTransactionDetail = showTransactionDetail, + canUserSend = canUserSend, + noTxItemsPresent = noTxItemsPresent, + onToggleTransactionDetail = { + viewModel.onEvent(MainScreenEvent.OnToggleTransactionsDetail) + if (showTransactionDetail) currentRoute = Route.Main + }, + onItemClick = { route: Route -> + currentRoute = route + + if (route == Route.Main) { + scope.launch { sheetState.hide() }.invokeOnCompletion { + if (!sheetState.isVisible) { + isSheetOpen = false + } + } + onNavigate.invoke(UiEffect.Navigate(route)) + } else if (route == Route.History) { + viewModel.onEvent(MainScreenEvent.OnToggleTransactionsDetail) + if (showTransactionDetail) currentRoute = Route.Main + } else { + modalContentRoute = route + isSheetOpen = true + } + }, + + ) + } + + ) { padding -> + BoxWithConstraints( + modifier = Modifier + .fillMaxSize() + .navigationBarsPadding() + ) { + val verticalSpacing = 12.dp + val topPadding = padding.calculateTopPadding() + val bottomPadding = padding.calculateBottomPadding() + val availableHeight = maxHeight - + (verticalSpacing * 5) - + topPadding - + balanceGameBentoHt - + transactionRowHt - + gameHubHt - + bottomPadding + val transactionsDetailHeight = availableHeight + gameHubHt + balanceGameBentoHt + val ltcPickerBentoHeight = (availableHeight * 0.75f) - (verticalSpacing / 2) + val favoritesBentoHeight = (availableHeight * 0.25f) - (verticalSpacing / 2) + val transactionBentoHeight by animateDpAsState( + targetValue = if (showTransactionDetail) transactionsDetailHeight else transactionRowHt, + animationSpec = tween(EXPAND_DURATION), + label = "transactionHeight" + ) + + Column { + Row( + modifier = Modifier + .fillMaxWidth() + .padding( + horizontal = topNavStartEndPadding, + vertical = topNavStartEndPadding + ), + verticalAlignment = Alignment.CenterVertically, + ) { + ThemeButton( + isDarkMode = isDarkMode, + onClick = { + viewModel.onEvent(MainScreenEvent.OnToggleDarkMode) + } + ) + Spacer(modifier = Modifier.weight(1f)) + SettingsButton( + isDarkMode = isDarkMode, + onClick = { + scope.launch { + drawerState.apply { + if (isClosed) open() else close() + } + } + } + ) + } + LazyVerticalGrid( + columns = GridCells.Fixed(2), + modifier = Modifier + .padding( + horizontal = 12.dp, + vertical = 1.dp + ) + .weight(1f), + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), + userScrollEnabled = false + ) { + item(span = { GridItemSpan(2) }) { + Box(modifier = Modifier.height(balanceGameBentoHt)) { + BalanceBentoScreen(transactions = state.transactionItems.toImmutableList()) + } + } + item(span = { GridItemSpan(2) }) { + Box( + modifier = Modifier + .fillMaxWidth() + .height(transactionBentoHeight) + .clickable( + indication = null, + interactionSource = remember { MutableInteractionSource() } + ) { + if (noTxItemsPresent) { + onNavigate.invoke(UiEffect.Navigate(Route.MoonPayWeb)) + } else { + viewModel.onEvent(MainScreenEvent.OnToggleTransactionsDetail) + } + } + ) { + TransactionsBentoScreen( + transactions = state.transactionItems.toImmutableList(), + toggleState = state.filterState, + onEvent = viewModel::onEvent, + showTransactionDetail = state.showTransactionDetail, + shouldShowFiatValues = state.shouldShowFiatValues, + modifier = Modifier.fillMaxSize() + ) + } + } + + item(span = { GridItemSpan(1) }) { + AnimatedVisibility( + visible = !showTransactionDetail, + enter = fadeIn(tween(FADE_IN_DURATION)), + exit = fadeOut(tween(FADE_OUT_DURATION)), + ) { + Box(modifier = Modifier.height(availableHeight)) { + TutorialsBentoScreen() + } + } + } + item(span = { GridItemSpan(1) }) { + AnimatedVisibility( + visible = !showTransactionDetail, + enter = fadeIn(tween(FADE_IN_DURATION)), + exit = fadeOut(tween(FADE_OUT_DURATION)), + ) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + Box(modifier = Modifier.height(ltcPickerBentoHeight)) { + LTCPickerBentoScreen() + } + Box(modifier = Modifier.height(favoritesBentoHeight)) { + FavouritesBentoScreen() + } + } + } + } + item(span = { GridItemSpan(2) }) { + AnimatedVisibility( + visible = !showTransactionDetail, + enter = fadeIn(tween(FADE_IN_DURATION)), + exit = fadeOut(tween(FADE_OUT_DURATION)), + ) { + Box(modifier = Modifier.height(gameHubHt)) { + GameHubBentoPagerScreen(onClick = { page -> + when (page) { + 0 -> Unit + 1 -> { + modalContentRoute = Route.BuyReceive + isSheetOpen = true + } + 2 -> { + val builder = CustomTabsIntent.Builder() + val customTabsIntent = builder.build() + customTabsIntent.launchUrl( + context, + Uri.parse(BWConstants.LINKTREE_URL) + ) + } + } + }) + } + } + } + } + } + } + } + + if (isSheetOpen) { + ModalBottomSheet( + modifier = Modifier + .imePadding(), + onDismissRequest = { isSheetOpen = false }, + sheetState = sheetState, + dragHandle = { BottomSheetDefaults.DragHandle() }, + containerColor = Color.Transparent, + contentWindowInsets = { WindowInsets(0) }, + scrimColor = if (isDarkMode) { + // Overall background of Main Screen + Color.White.copy(0.1f) + } else { + Color.Black.copy(0.1f) + }, + shape = RoundedCornerShape(24.dp) + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .wrapContentWidth() + .fillMaxHeight(0.85f) + .background( + brush = if (modalContentRoute == Route.BuyReceive) { + bentoClearGradient + } else if (isDarkMode && modalContentRoute == Route.Send) { + bentoModalDarkGradient + } else { + mainScreenLightSurfaceGradient + }, + shape = RoundedCornerShape(24.dp) + ) + + ) { + when (modalContentRoute) { + Route.Send -> SendScreen( + onNavigate = onNavigate, + onOpenScanner = { + val activity = context as? FragmentActivity + activity?.let { + BRAnimator.openScanner( + it, + BWConstants.SCANNER_REQUEST + ) + } + }, + onDimissSendModal = { isSheetOpen = false } + ) + + Route.BuyReceive -> ReceiveDialog( + modifier = Modifier + .fillMaxWidth(0.9f) + .align(Alignment.Center), + onDismissRequest = { isSheetOpen = false } + ) + else -> {} + } + } + } + } + } +} + +@Composable +@PreviewLightDark +fun MainScreenPreview() { + BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) { + MainScreen(onNavigate = {}) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/main/MainScreenEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/main/MainScreenEvent.kt new file mode 100644 index 00000000..3f0859ca --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/main/MainScreenEvent.kt @@ -0,0 +1,15 @@ +package com.brainwallet.ui.screens.main + +import android.content.Context +import java.math.BigDecimal + +sealed class MainScreenEvent { + data class OnLoad(val context: Context) : MainScreenEvent() + data class OnFiatAmountChangeFromMPLimits( + val fiatAmount: BigDecimal, + val needFetch: Boolean = true + ) : MainScreenEvent() + data object OnToggleDarkMode : MainScreenEvent() + data object OnToggleTransactionsDetail : MainScreenEvent() + data object OnToggleTransactionsFilter : MainScreenEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/main/MainScreenState.kt b/app/src/main/java/com/brainwallet/ui/screens/main/MainScreenState.kt new file mode 100644 index 00000000..b0f2a49c --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/main/MainScreenState.kt @@ -0,0 +1,51 @@ +package com.brainwallet.ui.screens.main + +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.data.model.LtcStats +import com.brainwallet.data.model.MoonpayCurrencyLimit +import com.brainwallet.presenter.entities.TxItem +import com.brainwallet.ui.bentosections.transactionbento.TransactionFilterState +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.persistentListOf +import java.math.BigDecimal + +data class MainScreenState( + val moonpayCurrencyLimit: MoonpayCurrencyLimit = MoonpayCurrencyLimit(), + val fiatAmount: BigDecimal = BigDecimal(moonpayCurrencyLimit.data.baseCurrency.min.toDouble()), + val ltcAmount: BigDecimal = BigDecimal(0), + val address: String = "", + val errorFiatAmountStringId: Int? = null, + val fiatSymbol: String = "", + val fiatiSOCode: String = "USD", + val fiatRate: BigDecimal = BigDecimal(0), + val versionLabel: String = "", + val showTransactionDetail: Boolean = false, + val shouldShowFiatValues: Boolean = false, + val brainwalletIsSyncing: Boolean = false, + val transactionItems: ImmutableList = persistentListOf(), + val filterState: TransactionFilterState = TransactionFilterState.ALL, + val allTransactionItems: ImmutableList = persistentListOf(), + val ltcStats: LtcStats = LtcStats( + 0, + 0, + 0, + 0 + ), + val ltcBalance: BigDecimal = BigDecimal(0), + val litoshiBalance: BigDecimal = BigDecimal(0), + val selectedCurrency: CurrencyEntity = CurrencyEntity( + "USD", + "US Dollar", + -1f, + "$" + ), + val isInternetReachable: Boolean = true, + val formattedCurrency: String = "" +) { + val fiatBalance: BigDecimal + get() = litoshiBalance + .multiply(BigDecimal(selectedCurrency.rate.toDouble())) + + val fiatBalanceFormatted: String + get() = "%.2f".format(fiatBalance) +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/main/MainViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/main/MainViewModel.kt new file mode 100644 index 00000000..2ca346c3 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/main/MainViewModel.kt @@ -0,0 +1,367 @@ +package com.brainwallet.ui.screens.main +import android.app.Application +import androidx.compose.runtime.getValue +import androidx.lifecycle.viewModelScope +import com.brainwallet.R +import com.brainwallet.constants.BWConstants +import com.brainwallet.data.model.AppSetting +import com.brainwallet.data.model.GlobalCurrency +import com.brainwallet.data.model.GlobalCurrency.entries +import com.brainwallet.data.repository.ConnectivityRepository +import com.brainwallet.data.repository.LtcRepository +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.data.repository.TxRepository +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.sqlite.TransactionDataSource +import com.brainwallet.tools.util.BRExchange.ONE_LITECOIN_OF_LITOSHIS +import com.brainwallet.ui.BrainwalletViewModel +import com.brainwallet.ui.bentosections.balancebento.BalanceBentoViewModel +import com.brainwallet.ui.bentosections.transactionbento.TransactionFilterState +import com.brainwallet.util.CurrencyDataGetter +import com.brainwallet.util.VersionCodeProvider +import com.brainwallet.wallet.BRPeerManager +import com.brainwallet.wallet.BRWalletManager +import com.google.firebase.crashlytics.FirebaseCrashlytics +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.filterNotNull +import kotlinx.coroutines.flow.getAndUpdate +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +import timber.log.Timber +import java.math.BigDecimal +import kotlin.math.max +import kotlin.math.min + +@OptIn(FlowPreview::class) +@KoinViewModel +class MainViewModel( + private val app: Application, + private val settingRepository: SettingRepository, + private val ltcRepository: LtcRepository, + private val txRepository: TxRepository, + private val connectivityRepository: ConnectivityRepository, + private val balanceBentoViewModel: BalanceBentoViewModel, + versionCodeProvider: VersionCodeProvider, +) : BrainwalletViewModel(), + BRWalletManager.OnBalanceChanged, + BRPeerManager.OnTxStatusUpdate, + TransactionDataSource.OnTxAddedListener { + + private val _state = + MutableStateFlow( + MainScreenState( + versionLabel = versionCodeProvider + .getFormatted() + ) + ) + val state: StateFlow = _state.asStateFlow() + val appSetting: StateFlow = settingRepository.currentSettings + + init { + + // ──────── Collecting Reachability Updates ──────── + viewModelScope.launch { + connectivityRepository.isConnected.collect { isInternetReachable -> + _state.update { it.copy(isInternetReachable = isInternetReachable) } + } + } + + viewModelScope.launch { + settingRepository.currentSettings.collect { currentSettings -> + _state.update { + it.copy( + selectedCurrency = currentSettings.currency, + ) + } + } + } + + viewModelScope.launch { + ltcRepository.rates + .combine(appSetting) { currencies, setting -> + currencies.firstOrNull { it.code == setting.currency.code } + } + .filterNotNull() + .collect { selectedCurrency -> + val msg = String.format("selectedCurrency — Name: %s", selectedCurrency.name) + Timber.d("ISO: %s", msg) + FirebaseCrashlytics.getInstance().log(msg) + _state.update { + it.copy( + fiatSymbol = selectedCurrency.symbol, + fiatiSOCode = selectedCurrency.code, + fiatRate = BigDecimal(selectedCurrency.rate.toDouble()), + ) + } + } + } + + viewModelScope.launch { + txRepository.transactionItems.collect { items -> + _state.update { + it.copy( + transactionItems = items, + allTransactionItems = items + ) + } + } + } + + viewModelScope.launch { + ltcRepository.ltcStats.collect { ltcStats -> + _state.update { + it.copy( + ltcStats = ltcStats + ) + } + } + } + + viewModelScope.launch { + state.map { it.fiatAmount } + .debounce(1000) + .distinctUntilChanged() + .filter { + val baseCurrency = state.value.moonpayCurrencyLimit.data.baseCurrency + val baseCurrencyMin = BigDecimal(baseCurrency.min.toDouble()) + val baseCurrencyMax = BigDecimal(baseCurrency.max.toDouble()) + + if (baseCurrencyMin == BigDecimal(0) && + baseCurrencyMax == BigDecimal(0) + ) { + return@filter false + } + + it in baseCurrencyMin..baseCurrencyMax + } + .collect { + onEvent(MainScreenEvent.OnFiatAmountChangeFromMPLimits(it)) + } + } + + viewModelScope.launch { + balanceBentoViewModel.state + .map { it.brainwalletIsSyncing } + .distinctUntilChanged() + .collect { brainwalletIsSyncing -> + _state.update { it.copy(brainwalletIsSyncing = brainwalletIsSyncing) } + } + } + } + + fun onResume( + isWalletCreated: () -> Boolean = { BRWalletManager.getInstance().isCreated() }, + ioDispatcher: CoroutineDispatcher = Dispatchers.IO + ) { + viewModelScope.launch(ioDispatcher) { + var attempts = 0 + + while (!isWalletCreated() && attempts < 20) { + delay(250) + attempts++ + } + if (isWalletCreated()) { + addObservers() + val balance = BigDecimal(BRSharedPrefs.getCachedBalance(app).toDouble()) + _state.update { + it.copy( + ltcBalance = balance, + litoshiBalance = balance + .divide(BigDecimal(ONE_LITECOIN_OF_LITOSHIS)), + ) + } + txRepository.refresh() + } else { + Timber.d("BalanceBentoViewModel: wallet not ready after waiting") + } + } + } + + fun onPause() { + removeObservers() + } + + override fun onCleared() { + super.onCleared() + BRWalletManager.getInstance().removeListener(this) + BRPeerManager.getInstance().removeListener(this) + TransactionDataSource.getInstance(app).removeListener(this) + } + private fun addObservers() { + BRWalletManager.getInstance().addBalanceChangedListener(this) + BRPeerManager.getInstance().addStatusUpdateListener(this) + TransactionDataSource.getInstance(app).addTxAddedListener(this) + } + private fun removeObservers() { + BRWalletManager.getInstance().removeListener(this) + BRPeerManager.getInstance().removeListener(this) + TransactionDataSource.getInstance(app).removeListener(this) + } + + override fun onBalanceChanged(balance: Long) { + _state.update { + it.copy( + ltcBalance = BigDecimal(balance.toDouble()), + litoshiBalance = BigDecimal(balance.toDouble()) + .divide(BigDecimal(ONE_LITECOIN_OF_LITOSHIS)), + ) + } + viewModelScope.launch(Dispatchers.IO) { + txRepository.refresh() + } + } + + override fun onStatusPeerManagerUpdate() { + Timber.d("timber: MainViewModel subscribed onStatusUpdate: : BRPeerManager") + } + + override fun onTxAdded() { + viewModelScope.launch(Dispatchers.IO) { + txRepository.refresh() + } + } + + override fun onEvent(event: MainScreenEvent) { + when (event) { + is MainScreenEvent.OnLoad -> viewModelScope.launch { + delay(500) + + _state.update { it.copy(address = BRSharedPrefs.getReceiveAddress(event.context)) } + try { + onLoading(true) + txRepository.refresh() + val currentSettings = settingRepository.currentSettings.value + var formattedCurrency: String? = null + val currency = currentSettings.currency + val currencyDataGetter = CurrencyDataGetter(event.context) + if (currency != null) { + val roundedPriceAmount: BigDecimal = + BigDecimal(currency.rate.toDouble()).multiply(BigDecimal(100)) + .divide(BigDecimal(100), 2, BWConstants.ROUNDING_MODE) + formattedCurrency = + currencyDataGetter.getFormattedCurrencyString( + currency.code, + roundedPriceAmount + ) + } else { + Timber.w("The currency related to %s is NULL", currency.code) + } + + fun from(code: String): GlobalCurrency? { + return entries.find { it.code == code } + } + + _state.getAndUpdate { + val limitResult = ltcRepository.fetchLimits( + baseCurrencyCode = appSetting.value.currency.code + ) + + it.copy( + moonpayCurrencyLimit = limitResult, + fiatAmount = BigDecimal(limitResult.data.baseCurrency.min.toDouble()), + selectedCurrency = currentSettings.currency, + fiatiSOCode = currentSettings.currency.code, + fiatSymbol = currentSettings.currency.symbol, + formattedCurrency = formattedCurrency ?: "" + ) + } + } catch (e: Exception) { + handleError(e) + } finally { + onLoading(false) + } + } + + is MainScreenEvent.OnFiatAmountChangeFromMPLimits -> viewModelScope.launch { + // do validation based on the MP Limits + val (_, min, max) = state.value.moonpayCurrencyLimit.data.baseCurrency + val errorStringId = when { + event.fiatAmount < BigDecimal(min.toDouble()) -> R.string.buy_litecoin_fiat_amount_validation_min + event.fiatAmount > BigDecimal(max.toDouble()) -> R.string.buy_litecoin_fiat_amount_validation_max + else -> null + } + _state.update { + it.copy( + errorFiatAmountStringId = errorStringId, + fiatAmount = event.fiatAmount + ) + } + + if (event.needFetch.not()) { + return@launch + } + + try { + onLoading(true) + + _state.update { + val result = ltcRepository.fetchBuyQuote( + mapOf( + "currencyCode" to "ltc", + "baseCurrencyCode" to appSetting.value.currency.code, + "baseCurrencyAmount" to event.fiatAmount.toString(), + ) + ) + + it.copy( + ltcAmount = BigDecimal(result.data.quoteCurrencyAmount.toDouble()), + ) + } + } catch (e: Exception) { + handleError(e) + } finally { + onLoading(false) + } + } + is MainScreenEvent.OnToggleDarkMode -> viewModelScope.launch { + val currentSettings = appSetting.value + settingRepository.save( + currentSettings.copy(isDarkMode = !currentSettings.isDarkMode) + ) + } + + is MainScreenEvent.OnToggleTransactionsDetail -> viewModelScope.launch { + _state.update { it.copy(showTransactionDetail = !it.showTransactionDetail) } + } + + is MainScreenEvent.OnToggleTransactionsFilter -> viewModelScope.launch { + _state.update { + val nextFilter = TransactionFilterState.entries[ + (it.filterState.ordinal + 1) % TransactionFilterState.entries.size + ] + + val filteredTransactions = when (nextFilter) { + TransactionFilterState.ALL -> it.allTransactionItems + TransactionFilterState.RECEIVED -> it.allTransactionItems.filter { + txItem -> + (txItem.received - txItem.sent > 0) + }.toImmutableList() + TransactionFilterState.SENT -> it.allTransactionItems.filter { + txItem -> + (txItem.received - txItem.sent < 0) + }.toImmutableList() + } + Timber.d("timber: filtered state: $nextFilter and transactions: ${filteredTransactions.size}") + + it.copy( + filterState = nextFilter, + transactionItems = filteredTransactions + ) + } + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/main/SettingsButton.kt b/app/src/main/java/com/brainwallet/ui/screens/main/SettingsButton.kt new file mode 100644 index 00000000..4e4263ab --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/main/SettingsButton.kt @@ -0,0 +1,64 @@ +package com.brainwallet.ui.screens.main + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.R +import com.brainwallet.constants.topNavButtonSize +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoDarkSurfaceGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.bentoLightSurfaceGradient +import com.brainwallet.ui.theme.midnight + +@Composable +fun SettingsButton( + modifier: Modifier = Modifier, + isDarkMode: Boolean = false, + onClick: () -> Unit +) { + Box( + contentAlignment = Alignment.Center, + modifier = modifier + .size(topNavButtonSize) + .clip(CircleShape) + .background( + brush = if (isDarkMode) bentoDarkSurfaceGradient else bentoLightSurfaceGradient, + shape = CircleShape + ) + .border( + width = 1.5.dp, + brush = if (isDarkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = CircleShape + ) + .clickable(onClick = onClick) + ) { + Icon( + painter = painterResource(id = R.drawable.ic_burger_menu), + contentDescription = "Menu", + tint = if (isDarkMode) Color.White else midnight + ) + } +} + +@Composable +@PreviewLightDark +fun SettingsButtonPreview() { + DesignTheme(isSystemInDarkTheme()) { + SettingsButton {} + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/main/ThemeButton.kt b/app/src/main/java/com/brainwallet/ui/screens/main/ThemeButton.kt new file mode 100644 index 00000000..fecfa754 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/main/ThemeButton.kt @@ -0,0 +1,64 @@ +package com.brainwallet.ui.screens.main + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import com.brainwallet.R +import com.brainwallet.constants.topNavButtonSize +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.ui.theme.bentoDarkBorderGradient +import com.brainwallet.ui.theme.bentoDarkSurfaceGradient +import com.brainwallet.ui.theme.bentoLightBorderGradient +import com.brainwallet.ui.theme.bentoLightSurfaceGradient +import com.brainwallet.ui.theme.midnight + +@Composable +fun ThemeButton( + modifier: Modifier = Modifier, + isDarkMode: Boolean = false, + onClick: () -> Unit +) { + Box( + contentAlignment = Alignment.Center, + modifier = modifier + .size(topNavButtonSize) + .clip(CircleShape) + .background( + brush = if (isDarkMode) bentoDarkSurfaceGradient else bentoLightSurfaceGradient, + shape = CircleShape + ) + .border( + width = 1.5.dp, + brush = if (isDarkMode) bentoDarkBorderGradient else bentoLightBorderGradient, + shape = CircleShape + ) + .clickable(onClick = onClick) + ) { + Icon( + painter = painterResource(id = if (isDarkMode) R.drawable.ic_moon_stars else R.drawable.ic_sunny), + contentDescription = "Mode", + tint = if (isDarkMode) Color.White else midnight + ) + } +} + +@Composable +@PreviewLightDark +fun BentoThemeButtonPreview() { + DesignTheme(isSystemInDarkTheme()) { + ThemeButton {} + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreEvent.kt new file mode 100644 index 00000000..34708a18 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreEvent.kt @@ -0,0 +1,21 @@ +package com.brainwallet.ui.screens.restore + +import android.content.Context +import com.brainwallet.navigation.Route + +sealed class RestoreEvent { + data class OnLoad( + val source: Route.Restore.Source? = null + ) : RestoreEvent() + + data class OnSeedWordItemChange( + val index: Int, + val text: String + ) : RestoreEvent() + + object OnClearSeedWords : RestoreEvent() + + data class OnRestoreClick( + val context: Context + ) : RestoreEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreScreen.kt similarity index 87% rename from app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt rename to app/src/main/java/com/brainwallet/ui/screens/restore/RestoreScreen.kt index d3c839fd..755e481b 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreScreen.kt @@ -4,7 +4,7 @@ ExperimentalComposeUiApi::class ) -package com.brainwallet.ui.screens.inputwords +package com.brainwallet.ui.screens.restore import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -59,14 +59,14 @@ import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.SeedWordItemTextField -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import org.koin.compose.koinInject @Composable -fun InputWordsScreen( +fun RestoreScreen( onNavigate: OnNavigate, - source: Route.InputWords.Source? = null, - viewModel: InputWordsViewModel = koinInject() + source: Route.Restore.Source? = null, + viewModel: RestoreViewModel = koinInject() ) { val state by viewModel.state.collectAsState() val focusRequesters = List(12) { FocusRequester() } // 12 seed words @@ -89,7 +89,10 @@ fun InputWordsScreen( val activeRowHeight = 70 LaunchedEffect(Unit) { - viewModel.onEvent(InputWordsEvent.OnLoad(source)) + viewModel.onEvent(RestoreEvent.OnLoad(source)) + } + + LaunchedEffect(Unit) { viewModel.uiEffect.collect { effect -> when (effect) { is UiEffect.Navigate -> onNavigate.invoke(effect) @@ -98,13 +101,11 @@ fun InputWordsScreen( } } - // / Layout values + // Layout values val columnPadding = 16 val horizontalVerticalSpacing = 8 - val spacerHeight = 48 val mediumHeight = 24 val maxItemsPerRow = 3 - val buttonFontSize = 24 BrainwalletScaffold( modifier = Modifier.semantics { testTagsAsResourceId = true }, @@ -116,7 +117,7 @@ fun InputWordsScreen( ) { Icon( imageVector = Icons.AutoMirrored.Filled.ArrowBack, - tint = BrainwalletTheme.colors.content, + tint = DesignTheme.colors.content, contentDescription = stringResource(R.string.back), ) } @@ -133,14 +134,14 @@ fun InputWordsScreen( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(horizontalVerticalSpacing.dp), ) { - Spacer(modifier = Modifier.height(mediumHeight.dp)) + Spacer(modifier = Modifier.height(4.dp)) Text( text = stringResource(R.string.restore_your_power), style = MaterialTheme.typography.headlineLarge, ) - Spacer(modifier = Modifier.height(columnPadding.dp)) + Spacer(modifier = Modifier.height(4.dp)) Text( modifier = Modifier @@ -154,7 +155,7 @@ fun InputWordsScreen( ) - Spacer(modifier = Modifier.height(mediumHeight.dp)) + Spacer(modifier = Modifier.height(4.dp)) FlowRow( modifier = Modifier @@ -173,7 +174,7 @@ fun InputWordsScreen( suggestions = state.suggestionsSeedWords, onValueChange = { viewModel.onEvent( - InputWordsEvent.OnSeedWordItemChange( + RestoreEvent.OnSeedWordItemChange( index = index, text = it, ) @@ -189,22 +190,22 @@ fun InputWordsScreen( } } - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(4.dp)) FilledTonalButton( colors = ButtonDefaults.filledTonalButtonColors( - containerColor = BrainwalletTheme.colors.surface, - contentColor = BrainwalletTheme.colors.content + containerColor = DesignTheme.colors.surface, + contentColor = DesignTheme.colors.content ), onClick = { - viewModel.onEvent(InputWordsEvent.OnClearSeedWords) + viewModel.onEvent(RestoreEvent.OnClearSeedWords) focusRequesters.first().requestFocus() }, ) { Text(stringResource(R.string.clear)) } - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(4.dp)) Text( modifier = Modifier @@ -216,14 +217,14 @@ fun InputWordsScreen( lineHeight = 1.6.em ) ) - Spacer(modifier = Modifier.weight(0.5f)) + Spacer(modifier = Modifier.weight(0.02f)) Text( text = stringResource(R.string.blockchain_litecoin), style = MaterialTheme.typography.titleMedium.copy(textAlign = TextAlign.Center) ) - Spacer(modifier = Modifier.weight(0.5f)) + Spacer(modifier = Modifier.weight(0.02f)) BorderedLargeButton( modifier = Modifier @@ -232,7 +233,7 @@ fun InputWordsScreen( .padding(vertical = rowPadding.dp) .height(activeRowHeight.dp), onClick = { - viewModel.onEvent(InputWordsEvent.OnRestoreClick(context = context)) + viewModel.onEvent(RestoreEvent.OnRestoreClick(context = context)) focusManager.clearFocus() }, ) { diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsState.kt b/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreState.kt similarity index 59% rename from app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsState.kt rename to app/src/main/java/com/brainwallet/ui/screens/restore/RestoreState.kt index 811f5a98..71c4936f 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreState.kt @@ -1,9 +1,9 @@ -package com.brainwallet.ui.screens.inputwords +package com.brainwallet.ui.screens.restore import com.brainwallet.navigation.Route -data class InputWordsState( - val source: Route.InputWords.Source? = null, +data class RestoreState( + val source: Route.Restore.Source? = null, val bip39Words: List = emptyList(), val suggestionsSeedWords: List = emptyList(), val seedWords: SeedWords = (0..11).associateWith { "" } // 12 seed words @@ -15,8 +15,8 @@ fun SeedWords.asPaperKey(): String { return values.joinToString(" ") } -fun InputWordsState.isFrom(from: Route.InputWords.Source): Boolean { +fun RestoreState.isFrom(from: Route.Restore.Source): Boolean { return source == from } -fun InputWordsState.isFromWelcome(): Boolean = source == null +fun RestoreState.isFromWelcome(): Boolean = source == null diff --git a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreViewModel.kt similarity index 66% rename from app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt rename to app/src/main/java/com/brainwallet/ui/screens/restore/RestoreViewModel.kt index fd15aaf9..6cf178be 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/inputwords/InputWordsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/restore/RestoreViewModel.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.inputwords +package com.brainwallet.ui.screens.restore import androidx.lifecycle.viewModelScope import com.brainwallet.BrainwalletApp @@ -19,10 +19,10 @@ import kotlinx.coroutines.launch import org.koin.android.annotation.KoinViewModel @KoinViewModel -class InputWordsViewModel : BrainwalletViewModel() { +class RestoreViewModel : BrainwalletViewModel() { - private val _state = MutableStateFlow(InputWordsState()) - val state: StateFlow = _state.asStateFlow() + private val _state = MutableStateFlow(RestoreState()) + val state: StateFlow = _state.asStateFlow() init { // TODO: revisit later, please move to repository, for now just reuse the existing @@ -32,9 +32,9 @@ class InputWordsViewModel : BrainwalletViewModel() { } } - override fun onEvent(event: InputWordsEvent) { + override fun onEvent(event: RestoreEvent) { when (event) { - is InputWordsEvent.OnSeedWordItemChange -> _state.update { + is RestoreEvent.OnSeedWordItemChange -> _state.update { it.copy( seedWords = it.seedWords.toMutableMap().apply { put(event.index, Bip39Reader.cleanWord(event.text.lowercase())) @@ -45,15 +45,14 @@ class InputWordsViewModel : BrainwalletViewModel() { ) } - InputWordsEvent.OnClearSeedWords -> _state.update { - InputWordsState(bip39Words = it.bip39Words) + RestoreEvent.OnClearSeedWords -> _state.update { + RestoreState(bip39Words = it.bip39Words) } - is InputWordsEvent.OnLoad -> _state.update { it.copy(source = event.source) } - is InputWordsEvent.OnRestoreClick -> { + is RestoreEvent.OnLoad -> _state.update { it.copy(source = event.source) } + is RestoreEvent.OnRestoreClick -> { val currentState = state.value val paperKey = currentState.seedWords.asPaperKey() - val cleanPhrase = SmartValidator.cleanPaperKey(event.context, paperKey) if (currentState.isFromWelcome() && @@ -62,7 +61,8 @@ class InputWordsViewModel : BrainwalletViewModel() { viewModelScope.launch { EventBus.emit( EventBus.Event.Message( - LEGACY_DIALOG_INVALID + LEGACY_DIALOG_INVALID, + address = null ) ) } @@ -75,36 +75,50 @@ class InputWordsViewModel : BrainwalletViewModel() { viewModelScope.launch { EventBus.emit( EventBus.Event.Message( - LEGACY_DIALOG_INVALID + LEGACY_DIALOG_INVALID, + address = null ) ) } return } - if (currentState.isFrom(Route.InputWords.Source.RESET_PIN)) { + if (currentState.isFrom(Route.Restore.Source.RESET_PIN)) { viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_RESET_PIN)) + EventBus.emit( + EventBus.Event.Message( + LEGACY_EFFECT_RESET_PIN, + address = null + ) + ) } return } - if (currentState.isFrom(Route.InputWords.Source.SETTING_WIPE)) { + if (currentState.isFrom(Route.Restore.Source.SETTING_WIPE)) { viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_DIALOG_WIPE_ALERT)) + EventBus.emit( + EventBus.Event.Message( + LEGACY_DIALOG_WIPE_ALERT, + address = null + ) + ) } return } BRWalletManager.getInstance().wipeAll(event.context) - BRSharedPrefs.putAllowSpend(event.context, false) BRSharedPrefs.putStartHeight(event.context, 0) - PostAuth.getInstance().setPhraseForKeyStore(cleanPhrase) viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(EFFECT_LEGACY_RECOVER_WALLET_AUTH)) + EventBus.emit( + EventBus.Event.Message( + EFFECT_LEGACY_RECOVER_WALLET_AUTH, + address = null + ) + ) } } } @@ -113,7 +127,6 @@ class InputWordsViewModel : BrainwalletViewModel() { companion object { const val LEGACY_DIALOG_INVALID = "dialog_invalid" const val LEGACY_DIALOG_WIPE_ALERT = "dialog_wipe_alert" - const val EFFECT_LEGACY_RECOVER_WALLET_AUTH = "onRecoverWalletAuth" const val LEGACY_EFFECT_RESET_PIN = "onResetPin" } diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/BWSendResult.kt b/app/src/main/java/com/brainwallet/ui/screens/send/BWSendResult.kt new file mode 100644 index 00000000..a9a7b5b2 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/BWSendResult.kt @@ -0,0 +1,13 @@ +package com.brainwallet.ui.screens.send + +// SendResult.kt +sealed class BWSendResult { + data object Success : BWSendResult() + sealed class Error : BWSendResult() { + data object InsufficientFunds : Error() + data class AmountTooSmall(val minAmount: Long) : Error() + data object AlreadySending : Error() + data object TimedOut : Error() + data class Unknown(val cause: Throwable) : Error() + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/BWSender.kt b/app/src/main/java/com/brainwallet/ui/screens/send/BWSender.kt new file mode 100644 index 00000000..ed11842d --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/BWSender.kt @@ -0,0 +1,92 @@ +package com.brainwallet.ui.screens.send + +import android.content.Context +import com.brainwallet.presenter.entities.TransactionItem +import com.brainwallet.tools.security.PostAuth +import com.brainwallet.wallet.BRWalletManager +import kotlinx.coroutines.Dispatchers +import org.koin.core.annotation.Single +import timber.log.Timber +import kotlinx.coroutines.withContext + +@Single +class BWSender( + private val context: Context, + private val getWalletManager: () -> BRWalletManager = { BRWalletManager.getInstance() }, + private val getPostAuth: () -> PostAuth = { PostAuth.getInstance() } +) { + + @Volatile var timedOut = false + + @Volatile var isSending = false + + suspend fun prepareTransaction( + transactionItem: TransactionItem, + ): BWSendResult = withContext(Dispatchers.IO) { + try { + if (isSending) { + Timber.e("sendTransaction returned because already sending..") + return@withContext BWSendResult.Error.AlreadySending + } + isSending = true + + if (timedOut) { + Timber.e("sendTransaction returned because timed out..") + return@withContext BWSendResult.Error.TimedOut + } + + verifyAndSetTransaction(transactionItem) + } catch (e: Exception) { + Timber.e(e) + BWSendResult.Error.Unknown(e) + } finally { + isSending = false + timedOut = false + } + } + private suspend fun verifyAndSetTransaction(transactionItem: TransactionItem): BWSendResult { + if (transactionItem.sendAddress == null) { + val ex = RuntimeException("transactionItem is malformed: sendAddress is null") + Timber.e(ex) + return BWSendResult.Error.Unknown(ex) + } + + val walletManager = getWalletManager() + + // Transaction creation is CPU/IO-bound — run on IO dispatcher + val temporaryTransaction = withContext(Dispatchers.IO) { + walletManager.tryTransactionWithOps( + transactionItem.sendAddress, + transactionItem.sendAmount, + transactionItem.opsAddress, + transactionItem.opsFee, + ) + } ?: return BWSendResult.Error.Unknown(RuntimeException("tryTransactionWithOps returned null")) + + // Back on the calling dispatcher — mutate and hand off to PostAuth + transactionItem.serializedTx = temporaryTransaction + getPostAuth().setTransactionItem(transactionItem) + return tryToPublishToMainnet(transactionItem) + } + + private suspend fun tryToPublishToMainnet(transactionItem: TransactionItem): BWSendResult { + val walletManager = getWalletManager() + + val minOutput = if (transactionItem.isAmountRequested) { + walletManager.getMinOutputAmountRequested() + } else { + walletManager.getMinOutputAmount() + } + + if (transactionItem.sendAmount < minOutput) { + return BWSendResult.Error.AmountTooSmall(minOutput) + } + + // onPublishTxAuth is a blocking native call — keep it off the main thread + withContext(Dispatchers.IO) { + getPostAuth().onPublishTxAuth(context, false) + } + + return BWSendResult.Success + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/ConfirmSend.kt b/app/src/main/java/com/brainwallet/ui/screens/send/ConfirmSend.kt new file mode 100644 index 00000000..1e15320c --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/ConfirmSend.kt @@ -0,0 +1,190 @@ + +package com.brainwallet.ui.screens.send +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.constants.BWConstants +import com.brainwallet.tools.util.BRExchange +import com.brainwallet.ui.composable.EditSendButton +import com.brainwallet.ui.theme.IBMPlexSans +import org.koin.compose.viewmodel.koinViewModel +import java.math.BigDecimal + +@Composable +fun ConfirmSend( + onEdit: () -> Unit, + modifier: Modifier = Modifier, + viewModel: SendViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + val sectionBorder = 0.8.dp + val sectionDarkColor = Color.White.copy(alpha = 0.3f) + val sectionLightColor = Color.Black.copy(alpha = 0.95f) + + val amountInLTC = state.amountInLitoshi + .divide(BigDecimal(BRExchange.ONE_LITECOIN_OF_LITOSHIS), 6, BWConstants.ROUNDING_MODE) + + val networkFeesInLTC = state.networkFees + .divide(BigDecimal(BRExchange.ONE_LITECOIN_OF_LITOSHIS), 6, BWConstants.ROUNDING_MODE) + + val serviceFeesInLTC = state.serviceFees + .divide(BigDecimal(BRExchange.ONE_LITECOIN_OF_LITOSHIS), 6, BWConstants.ROUNDING_MODE) + + val totalInLTC = amountInLTC + .add(networkFeesInLTC) + .add(serviceFeesInLTC) + + val fiatValue = totalInLTC + .multiply(BigDecimal(state.selectedCurrency.rate.toDouble())) + + val formattedFiatValue = "%s %4.2f".format(state.selectedCurrency.symbol, fiatValue) + + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.TopCenter + ) { + Column( + modifier = Modifier + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Box( + modifier = Modifier + .fillMaxHeight(0.8f) + .padding(start = 12.dp, end = 12.dp, bottom = 4.dp) + .border( + width = sectionBorder, + color = if (state.darkMode) sectionDarkColor else sectionLightColor, + shape = RoundedCornerShape(16.dp) + ) + .background( + color = if (state.darkMode) Color.Transparent else Color.White, + shape = RoundedCornerShape(16.dp) + ) + ) { + Column( + modifier = Modifier.fillMaxWidth() + ) { + Spacer(modifier = Modifier.width(8.dp)) + + SendDetailRow( + label = stringResource(R.string.amount_label), + valueLabel = "Ł " + amountInLTC + ) + SendDetailRow( + label = stringResource(R.string.network_fees_label), + valueLabel = "Ł %4.4f".format(networkFeesInLTC) + ) + SendDetailRow( + label = stringResource(R.string.service_fees_label), + valueLabel = "Ł %4.4f".format(serviceFeesInLTC) + ) + SendDetailRow( + label = stringResource(R.string.amount_in_fiat_label), + valueLabel = formattedFiatValue + ) + Text( + modifier = Modifier.padding( + start = 14.dp, + top = 10.dp, + ), + text = stringResource(R.string.memo_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 13.sp, + textAlign = TextAlign.Start, + color = if (state.darkMode) Color.White else Color.Black + ) + ) + Text( + modifier = Modifier.padding( + 12.dp + ), + text = state.userMemorandum.ifEmpty { " " }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Light, + fontSize = 12.sp, + textAlign = TextAlign.Start, + color = if (state.darkMode) Color.White else Color.Black + ), + maxLines = 4 + ) + + Spacer(modifier = Modifier.weight(0.5f)) + + HorizontalDivider( + modifier = Modifier.padding( + all = 12.dp + ) + ) + Text( + modifier = Modifier.padding( + start = 12.dp, + ), + text = stringResource(R.string.recipient_label), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 15.sp, + textAlign = TextAlign.Start, + color = if (state.darkMode) Color.White else Color.Black + ) + ) + Text( + modifier = Modifier.padding( + 12.dp + ), + text = state.recipientLTCAddress, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + letterSpacing = 1.3.sp, + fontSize = 13.sp, + textAlign = TextAlign.Start, + color = if (state.darkMode) Color.White else Color.Black + ) + ) + } + } + Spacer(modifier = Modifier.width(4.dp)) + EditSendButton( + modifier = modifier.padding( + start = 24.dp, + end = 24.dp, + ), + darkMode = state.darkMode, + onClick = { + viewModel.onEvent(SendEvent.OnEditSend) + onEdit() + } + ) { + Text(stringResource(R.string.edit_send_details)) + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/PasscodeConfirmWidget.kt b/app/src/main/java/com/brainwallet/ui/screens/send/PasscodeConfirmWidget.kt new file mode 100644 index 00000000..eb52846f --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/PasscodeConfirmWidget.kt @@ -0,0 +1,99 @@ +package com.brainwallet.ui.screens.send + +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.togetherWith +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.brainwallet.R +import com.brainwallet.ui.composable.EditSendButton +import com.brainwallet.ui.composable.passcode.PasscodeIndicator +import org.koin.compose.viewmodel.koinViewModel +import com.brainwallet.ui.composable.passcode.PasscodeKeypad +import com.brainwallet.ui.composable.passcode.PasscodeKeypadEvent +import com.grunt.brainwallet.core.presentation.component.AnimatedSuccessBadge + +@Composable +fun PasscodeConfirmWidget( + onEdit: () -> Unit, + onSentTransaction: (Boolean) -> Unit, + modifier: Modifier = Modifier, + viewModel: SendViewModel = koinViewModel(), + onEvent: (PasscodeKeypadEvent) -> Unit = {} +) { + val context = LocalContext.current + val state by viewModel.state.collectAsState() + + Box( + modifier = modifier.fillMaxSize(), + contentAlignment = Alignment.TopCenter + ) { + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + AnimatedContent( + targetState = state.isPasscodeAuthenticated, + transitionSpec = { + fadeIn(tween(400)) togetherWith fadeOut(tween(400)) + } + ) { isAuthenticated -> + if (isAuthenticated) { + Column( + modifier = Modifier.weight(1f), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + AnimatedSuccessBadge( + size = 100.dp, + onFinished = { + onSentTransaction(true) + } + ) + } + } else { + Column( + modifier = Modifier.weight(1f), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + PasscodeIndicator( + state.passcode, + modifier = Modifier.weight(1f).padding(24.dp) + ) + PasscodeKeypad { passcodeKeypadEvent -> + when (passcodeKeypadEvent) { + PasscodeKeypadEvent.OnDelete -> viewModel.onEvent(SendEvent.OnPasscodeDigitDeleted) + is PasscodeKeypadEvent.OnPressed -> viewModel.onEvent( + SendEvent.OnPasscodeDigitAdded(passcodeKeypadEvent.digit) + ) + } + } + EditSendButton( + modifier = Modifier.padding(8.dp), + darkMode = state.darkMode, + onClick = { onEdit() } + ) { + Text(stringResource(R.string.back)) + } + } + } + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/PreSend.kt b/app/src/main/java/com/brainwallet/ui/screens/send/PreSend.kt new file mode 100644 index 00000000..e10a4537 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/PreSend.kt @@ -0,0 +1,49 @@ +package com.brainwallet.ui.screens.send +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import org.koin.compose.viewmodel.koinViewModel +import com.brainwallet.R + +@Composable +fun PreSend( + modifier: Modifier = Modifier, + viewModel: SendViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + + Box( + modifier = Modifier + .background(if (state.darkMode) Color.Transparent else Color.White), + contentAlignment = Alignment.TopCenter + ) { + Column( + modifier = Modifier + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + PreSendAddressRow( + label = stringResource(R.string.recipient_label), + value = state.recipientLTCAddress + ) + PreSendAmountRow( + label = stringResource(R.string.amount_label), + value = state.amountString + ) + PreSendMemoRow( + label = stringResource(R.string.memo_label), + value = state.userMemorandum + ) + Spacer(modifier = Modifier.weight(1f)) + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/PreSendAddressRow.kt b/app/src/main/java/com/brainwallet/ui/screens/send/PreSendAddressRow.kt new file mode 100644 index 00000000..02c564c8 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/PreSendAddressRow.kt @@ -0,0 +1,141 @@ +package com.brainwallet.ui.screens.send + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ContentPaste +import androidx.compose.material.icons.filled.QrCode +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.ui.composable.SendActionButton +import com.brainwallet.ui.theme.IBMPlexSans +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun PreSendAddressRow( + label: String, + value: String, + modifier: Modifier = Modifier, + viewModel: SendViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + + val sectionHeight = 68.dp + val sectionBorder = 0.8.dp + val sectionDarkColor = Color.White.copy(alpha = 0.3f) + val sectionLightColor = Color.Black.copy(alpha = 0.95f) + val onEvent = viewModel::onEvent + + val fieldTextStyle = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + textAlign = TextAlign.Start, + ) + val context = LocalContext.current + + Box( + modifier = Modifier + .height(sectionHeight) + .fillMaxSize() + .padding(start = 12.dp, end = 12.dp, bottom = 8.dp) + .border( + width = sectionBorder, + color = if (state.darkMode) sectionDarkColor else sectionLightColor, + shape = RoundedCornerShape(16.dp) + ) + .background( + color = if (state.darkMode) Color.Transparent else Color.White, + shape = RoundedCornerShape(16.dp) + ) + ) { + Row( + modifier = Modifier.fillMaxSize(), + verticalAlignment = Alignment.CenterVertically + ) { + Column( + modifier = Modifier.fillMaxWidth(0.65F) + ) { + TextField( + modifier = Modifier.height(sectionHeight) + .onFocusChanged { focusState -> + if (focusState.hasFocus) { + onEvent(SendEvent.OnFieldFocused) + } + }, + value = value, + onValueChange = { + onEvent(SendEvent.OnRecipientAddressChanged(it)) + }, + singleLine = true, + textStyle = fieldTextStyle, + colors = TextFieldDefaults.colors( + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + cursorColor = if (state.darkMode) Color.White else Color.Black, + focusedTextColor = if (state.darkMode) { + if (state.isLTCAddressValid) Color.White else Color.Red + } else { + Color.Black + }, + unfocusedTextColor = if (state.darkMode) Color.White else Color.Black, + ), + label = { + Text(label) + } + + ) + } + Spacer(modifier = Modifier.weight(0.1f)) + SendActionButton( + modifier = Modifier + .padding( + start = 8.dp, + end = 2.dp, + ), + darkMode = state.darkMode, + icon = Icons.Default.ContentPaste, + onClick = { onEvent(SendEvent.OnTapPasteLTCAddress) } + ) + Spacer(modifier = Modifier.width(4.dp)) + SendActionButton( + modifier = Modifier + .padding( + start = 2.dp, + end = 4.dp + ), + darkMode = state.darkMode, + icon = Icons.Default.QrCode, + onClick = { onEvent(SendEvent.OnTapShowCameraForQRLTCAddress) } + ) + Spacer(modifier = Modifier.width(1.dp)) + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/PreSendAmountRow.kt b/app/src/main/java/com/brainwallet/ui/screens/send/PreSendAmountRow.kt new file mode 100644 index 00000000..15ca4f0a --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/PreSendAmountRow.kt @@ -0,0 +1,200 @@ +package com.brainwallet.ui.screens.send + +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.togetherWith +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.ui.screens.main.MainViewModel +import com.brainwallet.ui.theme.IBMPlexSans +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun PreSendAmountRow( + label: String, + value: String, + modifier: Modifier = Modifier, + viewModel: SendViewModel = koinViewModel(), + mainViewModel: MainViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + val mainState by mainViewModel.state.collectAsState() + val sectionHeight = 68.dp + val sectionBorder = 0.8.dp + val sectionDarkColor = Color.White.copy(alpha = 0.3f) + val sectionLightColor = Color.Black.copy(alpha = 0.95f) + val onEvent = viewModel::onEvent + + val fieldTextStyle = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + textAlign = TextAlign.Start, + ) + + Box( + modifier = Modifier + .height(sectionHeight) + .fillMaxSize() + .padding(start = 12.dp, end = 12.dp, bottom = 8.dp) + .border( + width = sectionBorder, + color = if (state.darkMode) sectionDarkColor else sectionLightColor, + shape = RoundedCornerShape(16.dp) + ) + .background( + color = if (state.darkMode) Color.Transparent else Color.White, + shape = RoundedCornerShape(16.dp) + ) + ) { + Row( + modifier = Modifier.fillMaxSize(), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + modifier = Modifier.padding(start = 16.dp), + text = if (state.userViewsFiat) state.selectedCurrency.symbol else "Ł", + textAlign = TextAlign.End, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 14.sp, + color = if (state.darkMode) Color.White else Color.Black + ), + ) + TextField( + modifier = Modifier.height(sectionHeight) + .onFocusChanged { focusState -> + if (focusState.hasFocus) { + onEvent(SendEvent.OnFieldFocused) + } + }, + value = value, + keyboardActions = KeyboardActions(), + keyboardOptions = KeyboardOptions( + keyboardType = KeyboardType.Decimal + ), + singleLine = true, + onValueChange = { + onEvent(SendEvent.OnAmountChanged(it)) + }, + textStyle = fieldTextStyle, + colors = TextFieldDefaults.colors( + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + cursorColor = if (state.darkMode) Color.White else Color.Black, + focusedTextColor = if (state.darkMode) { + if (state.isAmountBelowBalance) Color.White else Color.Red + } else { + Color.Black + }, + unfocusedTextColor = if (state.darkMode) Color.White else Color.Black + ), + label = { + Text(label) + } + ) + Spacer(modifier = Modifier.weight(0.6f)) + Box( + modifier = Modifier, + contentAlignment = Alignment.Center + ) { + Column( + modifier = Modifier + .padding(6.dp) + .background( + if (state.darkMode) { + Color.White.copy(0.15f) + } else { + Color.Black.copy(0.15f) + }, + shape = RoundedCornerShape(12.dp) + ) + .align(Alignment.Center) + .clickable { + onEvent(SendEvent.OnToggleFiatOrLTC) + } + ) { + AnimatedContent( + targetState = state.userViewsFiat, + transitionSpec = { + fadeIn(animationSpec = tween(400)) togetherWith + fadeOut(animationSpec = tween(400)) + }, + label = "fiatLtcToggle" + ) { shouldShowFiat -> + if (shouldShowFiat) { + Text( + modifier = Modifier + .padding(8.dp), + text = mainState.selectedCurrency.symbol + + " " + mainState.selectedCurrency.code, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Bold, + fontSize = 15.sp, + textAlign = TextAlign.Center, + color = if (state.darkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + } else { + Image( + modifier = Modifier + .fillMaxSize() + .padding(8.dp) + .align(alignment = Alignment.End), + painter = painterResource( + if (state.darkMode) { + R.drawable.white_ltc_coin + } else { + R.drawable.black_ltc_coin + } + ), + contentDescription = "litecoin_coin", + contentScale = ContentScale.Fit + ) + } + } + } + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/PreSendMemoRow.kt b/app/src/main/java/com/brainwallet/ui/screens/send/PreSendMemoRow.kt new file mode 100644 index 00000000..769f04db --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/PreSendMemoRow.kt @@ -0,0 +1,101 @@ +package com.brainwallet.ui.screens.send + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.ui.theme.IBMPlexSans +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun PreSendMemoRow( + label: String, + value: String, + modifier: Modifier = Modifier, + viewModel: SendViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + + val sectionHeight = 68.dp + val sectionBorder = 0.8.dp + val sectionDarkColor = Color.White.copy(alpha = 0.3f) + val sectionLightColor = Color.Black.copy(alpha = 0.95f) + val onEvent = viewModel::onEvent + + val fieldTextStyle = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + textAlign = TextAlign.Start, + ) + Box( + modifier = Modifier + .height(sectionHeight) + .fillMaxSize() + .padding(start = 12.dp, end = 12.dp, bottom = 8.dp) + .border( + width = sectionBorder, + color = if (state.darkMode) sectionDarkColor else sectionLightColor, + shape = RoundedCornerShape(16.dp) + ) + .background( + color = if (state.darkMode) Color.Transparent else Color.White, + shape = RoundedCornerShape(16.dp) + ) + ) { + Row( + modifier = Modifier.fillMaxSize(), + verticalAlignment = Alignment.CenterVertically + ) { + Column( + modifier = Modifier.fillMaxWidth() + ) { + TextField( + modifier = Modifier.height(sectionHeight), + value = value, + onValueChange = { + if (it.length <= 128) { + onEvent(SendEvent.OnUserMemorandumChanged(memo = it)) + } + }, + singleLine = true, + textStyle = fieldTextStyle, + colors = TextFieldDefaults.colors( + focusedIndicatorColor = Color.Transparent, + unfocusedIndicatorColor = Color.Transparent, + disabledIndicatorColor = Color.Transparent, + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + cursorColor = if (state.darkMode) Color.White else Color.Black, + focusedTextColor = if (state.darkMode) Color.White else Color.Black, + unfocusedTextColor = if (state.darkMode) Color.White else Color.Black, + ), + label = { + Text(label) + }, + ) + } + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/SendDetailRow.kt b/app/src/main/java/com/brainwallet/ui/screens/send/SendDetailRow.kt new file mode 100644 index 00000000..3c6a8c40 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/SendDetailRow.kt @@ -0,0 +1,79 @@ +package com.brainwallet.ui.screens.send + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.ui.composable.DashedDivider +import com.brainwallet.ui.theme.IBMPlexSans +import org.koin.compose.viewmodel.koinViewModel + +@Composable +fun SendDetailRow( + label: String, + valueLabel: String, + modifier: Modifier = Modifier, + viewModel: SendViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + val topBottomPad = 10.dp + Row( + modifier = modifier + .fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + modifier = Modifier.padding( + start = 14.dp, + top = topBottomPad, + bottom = topBottomPad + ), + text = label, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 13.sp, + textAlign = TextAlign.Start, + color = if (state.darkMode) Color.White else Color.Black + ) + ) + DashedDivider( + modifier = Modifier.weight(1f) + .align(Alignment.CenterVertically) + .padding(topBottomPad), + color = if (state.darkMode) Color.White else Color.Black, + dashWidth = 2.dp, + gapWidth = 4.dp + ) + Text( + modifier = Modifier.weight(0.38f) + .padding( + end = 14.dp, + top = topBottomPad, + bottom = topBottomPad + ), + text = valueLabel, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 13.sp, + textAlign = TextAlign.End, + color = if (state.darkMode) Color.White else Color.Black + ) + ) + Spacer(modifier = Modifier.width(1.dp)) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/SendEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/send/SendEvent.kt new file mode 100644 index 00000000..7cfb5dc9 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/SendEvent.kt @@ -0,0 +1,22 @@ +package com.brainwallet.ui.screens.send + +import com.brainwallet.presenter.entities.TransactionItem + +sealed class SendEvent { + + data object OnLoad : SendEvent() + data class OnSend(val transactionItem: TransactionItem) : SendEvent() + data object OnAuthPasscode : SendEvent() + data object OnTapPasteLTCAddress : SendEvent() + data object OnTapShowCameraForQRLTCAddress : SendEvent() + data object OnToggleFiatOrLTC : SendEvent() + data class OnRecipientAddressChanged(val address: String) : SendEvent() + data class OnAmountChanged(val amountInLTCString: String) : SendEvent() + data class OnUserMemorandumChanged(val memo: String) : SendEvent() + + data object OnFieldFocused : SendEvent() + + data class OnPasscodeDigitAdded(val digit: Int) : SendEvent() + data object OnPasscodeDigitDeleted : SendEvent() + data object OnEditSend : SendEvent() +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/SendScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/send/SendScreen.kt new file mode 100644 index 00000000..d7d59269 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/SendScreen.kt @@ -0,0 +1,270 @@ +package com.brainwallet.ui.screens.send + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.brainwallet.R +import com.brainwallet.navigation.OnNavigate +import com.brainwallet.navigation.UiEffect +import com.brainwallet.ui.composable.SendContinueButton +import com.brainwallet.ui.screens.main.MainViewModel +import com.brainwallet.ui.theme.DesignTheme +import org.koin.compose.viewmodel.koinViewModel +import com.brainwallet.ui.theme.IBMPlexSans +import kotlinx.coroutines.launch +import timber.log.Timber + +@Composable +fun SendScreen( + onNavigate: OnNavigate, + modifier: Modifier = Modifier, + onOpenScanner: () -> Unit = {}, + onDimissSendModal: () -> Unit = {}, + viewModel: SendViewModel = koinViewModel(), + mainViewModel: MainViewModel = koinViewModel() +) { + val uiState by viewModel.state.collectAsState() + val context = LocalContext.current + SendScreen( + uiState = uiState, + onNavigate = onNavigate, + modifier = modifier, + onEvent = viewModel::onEvent, + onOpenScanner = onOpenScanner, + onDimissSendModal = onDimissSendModal + ) +} + +@Composable +private fun SendScreen( + uiState: SendState, + onNavigate: OnNavigate, + modifier: Modifier = Modifier, + onOpenScanner: () -> Unit = {}, + onDimissSendModal: () -> Unit = {}, + onEvent: (SendEvent) -> Unit = {}, + viewModel: SendViewModel = koinViewModel(), + mainViewModel: MainViewModel = koinViewModel() +) { + val state by viewModel.state.collectAsState() + val mainState by mainViewModel.state.collectAsState() + val context = LocalContext.current + val bottomButtonPadding = 60.dp + val modalFactor = 0.85f + val pageCount = 3 + val pagerState = rememberPagerState(pageCount = { pageCount }) + val coroutineScope = rememberCoroutineScope() + + LaunchedEffect(Unit) { + viewModel.onEvent(SendEvent.OnLoad) + viewModel.uiEffect.collect { effect -> + when (effect) { + is UiEffect.Navigate -> onNavigate.invoke(effect) + is UiEffect.OpenQRScanner -> onOpenScanner() + is UiEffect.OnEnterAuthPasscode -> + coroutineScope.launch { + pagerState.animateScrollToPage(2) + } + else -> Unit + } + } + } + + Box( + modifier = Modifier + .fillMaxSize(), + contentAlignment = Alignment.TopCenter + ) { + Column( + modifier = Modifier + .fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + modifier = Modifier + .weight(0.12f) + .padding(14.dp), + text = if (pagerState.targetPage == 0) { + stringResource(R.string.send_litecoin_label) + } else if (pagerState.targetPage == 1) { + stringResource( + R.string.confirm_send_label + ) + } else { + stringResource( + R.string.enter_pin + ) + }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 24.sp, + color = if (state.darkMode) Color.White else Color.Black + ), + maxLines = 1 + ) + HorizontalPager( + state = pagerState, + userScrollEnabled = false, + modifier = Modifier + .weight(modalFactor) + ) { page -> + if (page == 0) { + PreSend( + modifier = Modifier.weight(modalFactor) + ) + } else if (page == 1) { + ConfirmSend( + modifier = Modifier.weight(modalFactor), + onEdit = { + coroutineScope.launch { + pagerState.animateScrollToPage(0) + } + } + ) + } else { + PasscodeConfirmWidget( + modifier = Modifier.weight(modalFactor), + onSentTransaction = { + onDimissSendModal() + }, + onEdit = { + coroutineScope.launch { + pagerState.animateScrollToPage(1) + } + } + ) + } + } + Text( + modifier = Modifier + .weight(0.05f) + .padding(4.dp), + text = if (state.isReadyToSend) { + " " + } else { + stringResource( + R.string.send_error_message + ) + }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 14.sp, + color = if (state.darkMode) Color.White else Color.Black + ) + ) + Spacer(modifier = Modifier.weight(0.01f)) + + Row( + modifier = Modifier + .weight(0.04f) + ) { + Text( + modifier = Modifier + .padding( + start = 16.dp + ), + text = stringResource(R.string.balance_label) + if (state.userViewsFiat) { + " " + mainState.selectedCurrency.symbol + mainState.fiatBalanceFormatted + } else { + " Ł" + mainState.litoshiBalance + }, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.SemiBold, + fontSize = 12.sp, + textAlign = TextAlign.Start, + color = if (state.darkMode) Color.White else Color.Black + ) + ) + Spacer(modifier = Modifier.weight(1f)) + Text( + modifier = Modifier.padding( + end = 16.dp, + ), + text = stringResource(R.string.exchange_rate_label) + " " + stringResource( + R.string.Login_ltcPrice, + mainState.formattedCurrency + ), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Normal, + fontSize = 12.sp, + textAlign = TextAlign.Start, + color = if (state.darkMode) Color.White else Color.Black + ), + ) + } + SendContinueButton( + modifier = Modifier + .weight(0.22f) + .padding( + start = 12.dp, + end = 12.dp, + bottom = bottomButtonPadding + ), + darkMode = state.darkMode, + enabled = when (pagerState.currentPage) { + 0 -> state.isLTCAddressValid && state.isAmountBelowBalance + 1 -> state.isReadyToSend + 2 -> state.isPasscodeAuthenticated + else -> false + }, + onClick = { + when (pagerState.currentPage) { + 0 -> coroutineScope.launch { pagerState.animateScrollToPage(1) } + 1 -> { + onEvent(SendEvent.OnAuthPasscode) + } + 2 -> { + Timber.d("OnSend triggered: transactionItem=${state.transactionItem}") + onEvent(SendEvent.OnSend(state.transactionItem)) + } + else -> null + } + } + ) { + when (pagerState.currentPage) { + 0 -> Text(stringResource(R.string.continue_cta)) + 1 -> Text(stringResource(R.string.ok)) + 2 -> Text(stringResource(R.string.send_title)) + else -> null + } + } + } + } +} + +@Composable +@PreviewLightDark +fun SendScreenPreview() { + DesignTheme(isSystemInDarkTheme()) { + SendScreen( + onNavigate = {}, + ) + } +} diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/SendState.kt b/app/src/main/java/com/brainwallet/ui/screens/send/SendState.kt new file mode 100644 index 00000000..8cfaa15e --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/SendState.kt @@ -0,0 +1,41 @@ +package com.brainwallet.ui.screens.send + +import com.brainwallet.data.model.CurrencyEntity +import com.brainwallet.presenter.entities.TransactionItem +import java.math.BigDecimal + +data class SendState( + val biometricEnabled: Boolean = false, + val darkMode: Boolean = false, + val formattedCurrency: String = "$ USD", + val recipientLTCAddress: String = "", + val userMemorandum: String = "", + val networkFees: BigDecimal = BigDecimal(0), + val serviceFees: BigDecimal = BigDecimal(0), + val amountInLitoshi: BigDecimal = BigDecimal(0), + val amountString: String = "", + val userViewsFiat: Boolean = false, + val isReadyToSend: Boolean = false, + val brainwalletIsPublishing: Boolean = false, + val isLTCAddressValid: Boolean = false, + val isAmountBelowBalance: Boolean = false, + val selectedCurrency: CurrencyEntity = CurrencyEntity( + "USD", + "US Dollar", + -1f, + "$" + ), + val transactionItem: TransactionItem = TransactionItem( + "", + null, + null, + 0L, + 0L, + null, + false, + "" + ), + val errorResultString: String = "", + val passcode: List = emptyList(), + val isPasscodeAuthenticated: Boolean = false +) diff --git a/app/src/main/java/com/brainwallet/ui/screens/send/SendViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/send/SendViewModel.kt new file mode 100644 index 00000000..398bd1e4 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/screens/send/SendViewModel.kt @@ -0,0 +1,362 @@ +package com.brainwallet.ui.screens.send + +import android.app.Application +import androidx.lifecycle.viewModelScope +import com.brainwallet.R +import com.brainwallet.constants.BWConstants +import com.brainwallet.data.repository.SettingRepository +import com.brainwallet.data.repository.TxRepository +import com.brainwallet.navigation.UiEffect +import com.brainwallet.presenter.entities.ServiceItems +import com.brainwallet.presenter.entities.TransactionItem +import com.brainwallet.tools.manager.AnalyticsManager +import com.brainwallet.tools.manager.BRClipboardManager +import com.brainwallet.tools.manager.BRSharedPrefs +import com.brainwallet.tools.manager.FeeManager +import com.brainwallet.tools.security.BRKeyStore +import com.brainwallet.tools.util.BRExchange +import com.brainwallet.tools.util.Utils +import com.brainwallet.ui.BrainwalletViewModel +import com.brainwallet.ui.screens.send.BWSendResult.Error +import com.brainwallet.util.EventBus +import com.brainwallet.wallet.BRWalletManager +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import org.koin.android.annotation.KoinViewModel +import timber.log.Timber +import java.math.BigDecimal +import java.util.Locale + +@KoinViewModel +class SendViewModel( + private val app: Application, + private val bwSender: BWSender, + private val txRepository: TxRepository, + private val settingRepository: SettingRepository, +) : BrainwalletViewModel() { + private val _state = + MutableStateFlow(SendState()) + val state: StateFlow = _state.asStateFlow() + private val _effect = MutableSharedFlow(extraBufferCapacity = 1) + val effect: SharedFlow = _effect.asSharedFlow() + + init { + viewModelScope.launch { + settingRepository.currentSettings.collect { currentSettings -> + _state.update { + it.copy( + darkMode = currentSettings.isDarkMode, + selectedCurrency = currentSettings.currency + ) + } + } + } + viewModelScope.launch { + EventBus.events + .filterIsInstance() + .collect { event -> + _state.update { it.copy(recipientLTCAddress = event.url ?: "") } + } + } + } + + fun onResume( + isWalletCreated: () -> Boolean = { BRWalletManager.getInstance().isCreated() }, + ioDispatcher: CoroutineDispatcher = Dispatchers.IO + ) { + viewModelScope.launch(ioDispatcher) { + var attempts = 0 + + while (!isWalletCreated() && attempts < 20) { + delay(250) + attempts++ + } + if (isWalletCreated()) { + txRepository.refresh() + val address = _state.value.recipientLTCAddress + if (address.isNotBlank()) { + val isValid = BRWalletManager.validateAddress(address) + _state.update { + it.copy( + isLTCAddressValid = isValid, + isReadyToSend = isValid && it.isAmountBelowBalance + ) + } + } + } else { + Timber.d("BalanceBentoViewModel: wallet not ready after waiting") + } + } + } + + override fun onEvent(event: SendEvent) { + when (event) { + is SendEvent.OnLoad -> { + Timber.i("SendEvent.OnLoad") + } + is SendEvent.OnTapPasteLTCAddress -> { + val litecoinUrl = BRClipboardManager.getClipboard(app) + val isAddressValid = BRWalletManager.validateAddress(litecoinUrl) + if (isAddressValid) { + _state.update { + it.copy( + recipientLTCAddress = litecoinUrl, + isLTCAddressValid = true, + isReadyToSend = isAddressValid && it.isAmountBelowBalance + ) + } + } else { + val error = app.resources.getString(R.string.Alert_error) + _state.update { + it.copy( + recipientLTCAddress = error + ) + } + } + } + is SendEvent.OnTapShowCameraForQRLTCAddress -> { + sendUiEffect(UiEffect.OpenQRScanner) + } + is SendEvent.OnToggleFiatOrLTC -> { + val currentState = _state.value + val rate = _state.value.selectedCurrency.rate + + val convertedAmount = if (rate != null && currentState.amountString.isNotBlank()) { + val current = currentState.amountString.toBigDecimalOrNull() ?: BigDecimal.ZERO + if (currentState.userViewsFiat) { + // switching fiat → LTC: divide by rate + current.divide(BigDecimal(rate.toString()), 8, BWConstants.ROUNDING_MODE) + } else { + // switching LTC → fiat: multiply by rate + current.multiply(BigDecimal(rate.toString())) + .setScale(2, BWConstants.ROUNDING_MODE) + } + } else { + null + } + _state.update { + it.copy( + userViewsFiat = !it.userViewsFiat, + amountString = convertedAmount?.toPlainString() ?: it.amountString, + amountInLitoshi = if (currentState.userViewsFiat) { + BigDecimal(rate.toDouble()).divide( + convertedAmount, + 8, + BWConstants.ROUNDING_MODE + ) + } else { + convertedAmount ?: BigDecimal.ZERO + } + ) + } + } + is SendEvent.OnRecipientAddressChanged -> { + val isAddressValid = if (BRWalletManager.getInstance().isCreated()) { + BRWalletManager.validateAddress(event.address) + } else { + null + } + _state.update { + it.copy( + recipientLTCAddress = event.address, + isLTCAddressValid = isAddressValid ?: true, + isReadyToSend = (isAddressValid == true) && it.isAmountBelowBalance + ) + } + } + is SendEvent.OnAmountChanged -> { + val currentState = _state.value + val enteredAmount = event + .amountInLTCString.toBigDecimalOrNull() ?: BigDecimal.ZERO + + // Resolve rate safely + val rate = _state.value.selectedCurrency.rate + + // Always convert to LTC first + val amountInLTC = when { + currentState.userViewsFiat && rate != null -> { + enteredAmount.divide( + BigDecimal(rate.toString()), + 8, + BWConstants.ROUNDING_MODE + ) + } + currentState.userViewsFiat && rate == null -> { + // rate not available yet — block send + null + } + else -> enteredAmount // already in LTC + } + + // Convert LTC → litoshis safely + val litoshiAmount = amountInLTC + ?.multiply( + BigDecimal( + BRExchange + .ONE_LITECOIN_OF_LITOSHIS + ) + ) + ?.toLong() + ?: 0L + + val currentBalance = BRWalletManager.getInstance().getBalance(app) + val networkFee = FeeManager.getInstance().currentFeeValue + val opsFee = Utils.tieredOpsFee(app, litoshiAmount) + + // isAmountValid is false if rate was unavailable in fiat mode + val isAmountValid = amountInLTC != null && + enteredAmount > BigDecimal.ZERO && + currentBalance >= (litoshiAmount + opsFee + networkFee) + + _state.update { + it.copy( + amountString = event.amountInLTCString, + isAmountBelowBalance = isAmountValid, + isReadyToSend = isAmountValid && + BRWalletManager.validateAddress(it.recipientLTCAddress), + networkFees = BigDecimal(networkFee.toDouble()), + serviceFees = BigDecimal(opsFee), + amountInLitoshi = BigDecimal(litoshiAmount) + ) + } + } + is SendEvent.OnAuthPasscode -> { + sendUiEffect(UiEffect.OnEnterAuthPasscode) + } + is SendEvent.OnSend -> { + val amountInLitoshi = _state.value.amountInLitoshi.toLong() + val transactionItem = TransactionItem( + _state.value.recipientLTCAddress, + Utils.fetchServiceItem(app, ServiceItems.WALLETOPS), + null, + amountInLitoshi, + Utils.tieredOpsFee(app, amountInLitoshi), + null, + false, + _state.value.userMemorandum + ) + + _state.update { + it.copy( + transactionItem = transactionItem, + brainwalletIsPublishing = true + ) + } + + viewModelScope.launch { + when (val result = bwSender.prepareTransaction(transactionItem)) { + BWSendResult.Success -> { + _effect.emit(SendEffect.DismissSheet) + AnalyticsManager.logCustomEvent(BWConstants._20191105_DSL) + BRSharedPrefs.incrementSendTransactionCount(app) + } + is BWSendResult.Error.InsufficientFunds -> { + _state.update { + it.copy( + errorResultString = String.format( + Locale.getDefault(), + "%s", + app.getString(R.string.Import_Error_notValid) + ) + ) + } + } + is BWSendResult.Error.AmountTooSmall -> { + _state.update { + it.copy( + errorResultString = String.format( + Locale.getDefault(), + "%s", + app.getString(R.string.Send_isRescanning) + ) + ) + } + } + BWSendResult.Error.AlreadySending, + BWSendResult.Error.TimedOut, + is BWSendResult.Error.Unknown -> { + Timber.e("Send unknown error: $result") + _state.update { + it.copy( + errorResultString = String.format( + Locale.getDefault(), + "%s", + app.getString(R.string.Alerts_sendFailure) + ) + ) + } + } + } + + _state.update { it.copy(isPasscodeAuthenticated = true) } + _state.update { it.copy(brainwalletIsPublishing = false) } + } + } + is SendEvent.OnUserMemorandumChanged -> { + _state.update { it.copy(userMemorandum = event.memo) } + } + is SendEvent.OnFieldFocused -> { + _state.update { + it.copy( + isReadyToSend = it.isAmountBelowBalance && + BRWalletManager.validateAddress(it.recipientLTCAddress), + ) + } + } + is SendEvent.OnPasscodeDigitAdded -> { + if (_state.value.passcode.size < 4) { + _state.update { it.copy(passcode = it.passcode + event.digit) } + } + if (_state.value.passcode.size == 4) { + val pin = BRKeyStore.getPinCode(app) + val enteredPin = _state.value.passcode.map { it.toString() }.joinToString("") + if (pin == enteredPin) { + onEvent(SendEvent.OnSend(_state.value.transactionItem)) + } else { + _state.update { it.copy(isPasscodeAuthenticated = false) } + } + } + } + is SendEvent.OnPasscodeDigitDeleted -> { + _state.update { it.copy(passcode = it.passcode.dropLast(1)) } + } + is SendEvent.OnEditSend -> { + _state.update { + it.copy(amountString = "") + } + } + } + } + + sealed class SendEffect { + data object DismissSheet : SendEffect() + } +} + +// if (allFilled) { +// BRSender.getInstance().sendTransaction( +// context, +// TransactionItem( +// sendAddress, +// Utils.fetchServiceItem(context, ServiceItems.WALLETOPS), +// null, +// litoshiAmount.toLong(), +// Utils.tieredOpsFee(context, litoshiAmount.toLong()), +// null, +// false, +// comment +// ), +// ) +// AnalyticsManager.logCustomEvent(BWConstants._20191105_DSL) +// BRSharedPrefs.incrementSendTransactionCount(context) +// } diff --git a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeScreen.kt index d9314d39..9a37d157 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/setpasscode/SetPasscodeScreen.kt @@ -36,9 +36,9 @@ import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar -import com.brainwallet.ui.composable.PasscodeIndicator -import com.brainwallet.ui.composable.PasscodeKeypad -import com.brainwallet.ui.composable.PasscodeKeypadEvent +import com.brainwallet.ui.composable.passcode.PasscodeIndicator +import com.brainwallet.ui.composable.passcode.PasscodeKeypad +import com.brainwallet.ui.composable.passcode.PasscodeKeypadEvent import org.koin.compose.koinInject @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/SettingsEvent.kt similarity index 96% rename from app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/SettingsEvent.kt index 76bd8feb..0ed4df00 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/SettingsEvent.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home +package com.brainwallet.ui.screens.settings import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Language diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/SettingsState.kt similarity index 87% rename from app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/SettingsState.kt index 16719088..145b6f7b 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsState.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/SettingsState.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home +package com.brainwallet.ui.screens.settings import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.Fee @@ -23,5 +23,6 @@ data class SettingsState( val shareAnalyticsDataEnabled: Boolean = false, val lastSyncMetadata: SyncAnalyticsRepository.SyncMetadata? = null, val currentFeeOptions: List = Fee.Default.toFeeOptions(), - val selectedFeeType: String = FeeManager.LUXURY + val selectedFeeType: String = FeeManager.LUXURY, + val formattedVersion: String = "" ) diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/SettingsViewModel.kt similarity index 74% rename from app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/SettingsViewModel.kt index 9d73dcd4..9f25d4d8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/SettingsViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/SettingsViewModel.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home +package com.brainwallet.ui.screens.settings import androidx.appcompat.app.AppCompatDelegate import androidx.core.os.LocaleListCompat @@ -12,6 +12,9 @@ import com.brainwallet.domain.LanguageSwitcherUseCase import com.brainwallet.tools.manager.FeeManager import com.brainwallet.ui.BrainwalletViewModel import com.brainwallet.util.EventBus +import com.brainwallet.util.VersionCodeProvider +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -29,10 +32,12 @@ import org.koin.android.annotation.KoinViewModel class SettingsViewModel( private val settingRepository: SettingRepository, private val languageSwitcherUseCase: LanguageSwitcherUseCase, - private val ltcRepository: LtcRepository + private val ltcRepository: LtcRepository, + versionCodeProvider: VersionCodeProvider, + private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO ) : BrainwalletViewModel() { - private val _state = MutableStateFlow(SettingsState()) + private val _state = MutableStateFlow(SettingsState(formattedVersion = versionCodeProvider.getFormatted())) val state: StateFlow = _state.asStateFlow() val appSetting = settingRepository.settings @@ -53,7 +58,19 @@ class SettingsViewModel( ) init { + viewModelScope.launch { + settingRepository.settings.collect { appSetting -> + _state.update { + it.copy( + darkMode = appSetting.isDarkMode, + selectedLanguage = Language.find(appSetting.languageCode), + selectedCurrency = appSetting.currency, + ) + } + } + } + viewModelScope.launch(ioDispatcher) { while (true) { /** * need update fee options every 4s, since we are fetching every 4s @@ -95,11 +112,16 @@ class SettingsViewModel( it.copy(darkMode = toggled) } - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_TOGGLE_DARK_MODE)) + EventBus.emit( + EventBus.Event.Message( + LEGACY_EFFECT_ON_TOGGLE_DARK_MODE, + address = null + ) + ) } SettingsEvent.OnToggleLock -> viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_LOCK)) + EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_LOCK, null)) } SettingsEvent.OnFiatButtonClick -> _state.update { @@ -138,34 +160,47 @@ class SettingsViewModel( } } - is SettingsEvent.OnFiatChange -> _state.updateAndGet { - it.copy(selectedCurrency = event.currency) - }.let { - viewModelScope.launch { - settingRepository.save( - appSetting.value.copy( - currency = event.currency - ) + is SettingsEvent.OnFiatChange -> viewModelScope.launch { + settingRepository.save( + AppSetting( + isDarkMode = _state.value.darkMode, + languageCode = _state.value.selectedLanguage.code, + currency = event.currency ) - } + ) } is SettingsEvent.OnBlockchainSyncClick -> viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_SYNC)) + EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_SYNC, address = null)) } SettingsEvent.OnSecuritySeedPhraseClick -> viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_SEED_PHRASE)) + EventBus.emit( + EventBus.Event.Message( + LEGACY_EFFECT_ON_SEED_PHRASE, + address = null + ) + ) } SettingsEvent.OnSecurityUpdatePinClick -> viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_SEC_UPDATE_PIN)) + EventBus.emit( + EventBus.Event.Message( + LEGACY_EFFECT_ON_SEC_UPDATE_PIN, + address = null + ) + ) } SettingsEvent.OnSecurityShareAnalyticsDataClick -> viewModelScope.launch { _state.update { it.copy(shareAnalyticsDataEnabled = it.shareAnalyticsDataEnabled.not()) } - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_SHARE_ANALYTICS_DATA_TOGGLE)) + EventBus.emit( + EventBus.Event.Message( + LEGACY_EFFECT_ON_SHARE_ANALYTICS_DATA_TOGGLE, + address = null + ) + ) } is SettingsEvent.OnFeeTypeChange -> _state.update { diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/CurrencyDetail.kt similarity index 68% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/CurrencyDetail.kt index cc792a6b..a0cee888 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/CurrencyDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/CurrencyDetail.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.composable.settingsrows +package com.brainwallet.ui.screens.settings.settingsrows import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.CheckCircle @@ -19,6 +20,8 @@ import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip @@ -28,8 +31,8 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.CurrencyEntity -import com.brainwallet.tools.sqlite.CurrencyDataSource -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.data.model.GlobalCurrency +import com.brainwallet.ui.theme.DesignTheme @Composable fun CurrencyDetail( @@ -39,31 +42,49 @@ fun CurrencyDetail( ) { val context = LocalContext.current - // / Layout values - val closedHeight = 60 - val expandedHeight = 100 - val dividerThickness = 1 + // Layout values + val expandedHeight = 200 val unselectedCircleSize = 20 val tinyPad = 2 + val rowHeight = 44.dp + + val globalCurrencies = remember { GlobalCurrency.entries } + val listState = rememberLazyListState() + val selectedIndex = remember(selectedCurrency) { + globalCurrencies.indexOfFirst { it.code == selectedCurrency.code } + } + + LaunchedEffect(selectedIndex) { + if (selectedIndex >= 0) { + listState.scrollToItem(selectedIndex) + } + } SettingRowItemExpandable( modifier = modifier, title = stringResource(R.string.settings_title_currency) ) { LazyColumn( + state = listState, modifier = Modifier.height(expandedHeight.dp) ) { - items( - items = CurrencyDataSource.getInstance(context).getAllCurrencies(true) - ) { currency -> + items(items = globalCurrencies) { currency -> + val currencyEntity = CurrencyEntity() + currencyEntity.code = currency.code + currencyEntity.name = currency.fullCurrencyName + currencyEntity.rate = 1f + currencyEntity.symbol = currency.symbol + ListItem( colors = ListItemDefaults.colors( - containerColor = BrainwalletTheme.colors.background, - headlineColor = BrainwalletTheme.colors.content, + containerColor = DesignTheme.colors.background, + headlineColor = DesignTheme.colors.content, ), - modifier = Modifier.clickable { - onFiatSelect.invoke(currency) - }, + modifier = Modifier + .height(rowHeight) + .clickable { + onFiatSelect.invoke(currencyEntity) + }, headlineContent = { Row { Text( @@ -86,7 +107,7 @@ fun CurrencyDetail( Icon( Icons.Default.CheckCircle, contentDescription = null, - tint = BrainwalletTheme.colors.affirm + tint = DesignTheme.colors.affirm ) } else { Box( @@ -94,7 +115,7 @@ fun CurrencyDetail( .size(unselectedCircleSize.dp) .alpha(0.1f) .clip(CircleShape) - .background(BrainwalletTheme.colors.content) + .background(DesignTheme.colors.content) ) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/GamesDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/GamesDetail.kt similarity index 97% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/GamesDetail.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/GamesDetail.kt index 8a8e3af0..18637684 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/GamesDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/GamesDetail.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.composable.settingsrows +package com.brainwallet.ui.screens.settings.settingsrows import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/HomeSettingDrawerSheet.kt similarity index 87% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/HomeSettingDrawerSheet.kt index bb70ddca..7bcca907 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/HomeSettingDrawerSheet.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/HomeSettingDrawerSheet.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.composable +package com.brainwallet.ui.screens.settings.settingsrows import android.content.Context import android.net.Uri @@ -30,19 +30,11 @@ import com.brainwallet.R import com.brainwallet.data.model.AppSetting import com.brainwallet.data.repository.SyncAnalyticsRepository import com.brainwallet.tools.manager.BRSharedPrefs -import com.brainwallet.tools.util.BRConstants -import com.brainwallet.ui.screens.home.SettingsEvent -import com.brainwallet.ui.screens.home.SettingsViewModel -import com.brainwallet.ui.screens.home.composable.settingsrows.CurrencyDetail -import com.brainwallet.ui.screens.home.composable.settingsrows.GamesDetail -import com.brainwallet.ui.screens.home.composable.settingsrows.LanguageDetail -import com.brainwallet.ui.screens.home.composable.settingsrows.LitecoinBlockchainDetail -import com.brainwallet.ui.screens.home.composable.settingsrows.LockSettingRowItem -import com.brainwallet.ui.screens.home.composable.settingsrows.SecurityDetail -import com.brainwallet.ui.screens.home.composable.settingsrows.SettingRowItem -import com.brainwallet.ui.screens.home.composable.settingsrows.ThemeSettingRowItem +import com.brainwallet.constants.BWConstants +import com.brainwallet.ui.screens.settings.SettingsEvent +import com.brainwallet.ui.screens.settings.SettingsViewModel import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import com.brainwallet.util.EventBus import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.launchIn @@ -79,8 +71,8 @@ fun HomeSettingDrawerSheet( modifier = modifier .fillMaxWidth() .verticalScroll(rememberScrollState()), - drawerContainerColor = BrainwalletTheme.colors.surface, - drawerContentColor = BrainwalletTheme.colors.content + drawerContainerColor = DesignTheme.colors.surface, + drawerContentColor = DesignTheme.colors.content ) { LazyColumn( modifier = Modifier @@ -159,11 +151,11 @@ fun HomeSettingDrawerSheet( SettingRowItem( modifier = Modifier.testTag("settingSupport"), title = stringResource(R.string.settings_title_support), - description = "brainwallet.co/support.html", + description = "support.brainwallet.co", onClick = { val builder = CustomTabsIntent.Builder() val customTabsIntent = builder.build() - customTabsIntent.launchUrl(context, Uri.parse(BRConstants.SUPPORT_WEB_LINK)) + customTabsIntent.launchUrl(context, Uri.parse(BWConstants.SUPPORT_WEB_LINK)) } ) } @@ -175,7 +167,7 @@ fun HomeSettingDrawerSheet( onClick = { val builder = CustomTabsIntent.Builder() val customTabsIntent = builder.build() - customTabsIntent.launchUrl(context, Uri.parse(BRConstants.LINKTREE_URL)) + customTabsIntent.launchUrl(context, Uri.parse(BWConstants.LINKTREE_URL)) } ) } @@ -213,7 +205,7 @@ fun HomeSettingDrawerSheet( item { SettingRowItem( title = stringResource(R.string.settings_title_app_version), - description = BRConstants.APP_VERSION_NAME_CODE + description = BWConstants.APP_VERSION_NAME_CODE ) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LanguageDetail.kt similarity index 68% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LanguageDetail.kt index c9f7211d..e71e4c0c 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LanguageDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LanguageDetail.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.composable.settingsrows +package com.brainwallet.ui.screens.settings.settingsrows import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.CheckCircle @@ -16,6 +17,8 @@ import androidx.compose.material3.ListItemDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip @@ -24,20 +27,30 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.data.model.Language -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme -// TODO @Composable fun LanguageDetail( modifier: Modifier = Modifier, selectedLanguage: Language, onLanguageSelect: (Language) -> Unit ) { - val languages = Language.entries.toTypedArray() + val languages = remember { Language.entries } + val listState = rememberLazyListState() + val selectedIndex = remember(selectedLanguage) { + languages.indexOfFirst { it.code == selectedLanguage.code } + } - // / Layout values + // Layout values val expandedHeight = 150 val unselectedCircleSize = 20 + val rowHeight = 44.dp + + LaunchedEffect(selectedIndex) { + if (selectedIndex >= 0) { + listState.scrollToItem(selectedIndex) + } + } SettingRowItemExpandable( modifier = modifier, @@ -49,14 +62,16 @@ fun LanguageDetail( ) { language -> ListItem( colors = ListItemDefaults.colors( - containerColor = BrainwalletTheme.colors.background, - headlineColor = BrainwalletTheme.colors.content, + containerColor = DesignTheme.colors.background, + headlineColor = DesignTheme.colors.content, ), - modifier = Modifier.clickable { - if (language.code.isNotBlank()) { - onLanguageSelect.invoke(language) - } - }, + modifier = Modifier + .height(rowHeight) + .clickable { + if (language.code.isNotBlank()) { + onLanguageSelect.invoke(language) + } + }, headlineContent = { Text( modifier = Modifier, @@ -70,7 +85,7 @@ fun LanguageDetail( Icon( Icons.Default.CheckCircle, contentDescription = null, - tint = BrainwalletTheme.colors.affirm + tint = DesignTheme.colors.affirm ) } else { Box( @@ -78,7 +93,7 @@ fun LanguageDetail( .size(unselectedCircleSize.dp) .alpha(0.1f) .clip(CircleShape) - .background(BrainwalletTheme.colors.content) + .background(DesignTheme.colors.content) ) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LitecoinBlockchainDetail.kt similarity index 94% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LitecoinBlockchainDetail.kt index 324c0276..5942dd6f 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LitecoinBlockchainDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LitecoinBlockchainDetail.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.composable.settingsrows +package com.brainwallet.ui.screens.settings.settingsrows import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -25,8 +25,8 @@ import com.brainwallet.data.model.CurrencyEntity import com.brainwallet.data.model.FeeOption import com.brainwallet.data.model.getFiatFormatted import com.brainwallet.data.model.getSelectedIndex -import com.brainwallet.ui.screens.home.SettingsEvent -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.screens.settings.SettingsEvent +import com.brainwallet.ui.theme.DesignTheme // TODO @Composable @@ -67,7 +67,7 @@ fun LitecoinBlockchainDetail( } } - HorizontalDivider(color = BrainwalletTheme.colors.content) + HorizontalDivider(color = DesignTheme.colors.content) NetworkFeeSelector( selectedCurrency = selectedCurrency, diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LockSettingRowItem.kt similarity index 69% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LockSettingRowItem.kt index f65592ad..73d77fc0 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/LockSettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/LockSettingRowItem.kt @@ -1,7 +1,7 @@ -package com.brainwallet.ui.screens.home.composable.settingsrows +package com.brainwallet.ui.screens.settings.settingsrows import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Lock +import androidx.compose.material.icons.filled.LockOpen import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -18,6 +18,6 @@ fun LockSettingRowItem( title = stringResource(R.string.settings_title_lock), onClick = onClick ) { - Icon(Icons.Default.Lock, contentDescription = stringResource(R.string.settings_title_lock)) + Icon(Icons.Default.LockOpen, contentDescription = stringResource(R.string.settings_title_unlock)) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SecurityDetail.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/SecurityDetail.kt similarity index 96% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SecurityDetail.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/SecurityDetail.kt index 40eaf22e..3fc9c2df 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SecurityDetail.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/SecurityDetail.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.composable.settingsrows +package com.brainwallet.ui.screens.settings.settingsrows import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -13,7 +13,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.brainwallet.R -import com.brainwallet.ui.screens.home.SettingsEvent +import com.brainwallet.ui.screens.settings.SettingsEvent // TODO @Composable diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/SettingRowItem.kt similarity index 84% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/SettingRowItem.kt index a312e1df..2c3c25e7 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/SettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/SettingRowItem.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.composable.settingsrows +package com.brainwallet.ui.screens.settings.settingsrows import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.background @@ -22,8 +22,8 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import com.brainwallet.ui.theme.DesignTheme import com.grunt.brainwallet.core.presentation.theme.BrainwalletColors -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme /** * main composable for [SettingRowItem] and [SettingRowItemExpandable] @@ -56,10 +56,10 @@ fun SettingRowItemExpandable( trailingIcon: @Composable (() -> Unit)? = null, onClick: (() -> Unit)? = null, colors: ListItemColors = ListItemDefaults.colors( - containerColor = BrainwalletTheme.colors.surface, - headlineColor = BrainwalletTheme.colors.content, - supportingColor = BrainwalletTheme.colors.content.copy(0.6f), - trailingIconColor = BrainwalletTheme.colors.content, + containerColor = DesignTheme.colors.surface, + headlineColor = DesignTheme.colors.content, + supportingColor = DesignTheme.colors.content.copy(0.6f), + trailingIconColor = DesignTheme.colors.content, ), content: @Composable () -> Unit, ) { @@ -72,9 +72,16 @@ fun SettingRowItemExpandable( val horizontalPadding = 14 Column( - modifier = modifier.background(BrainwalletTheme.colors.settingRowItemBackground(expanded)) + modifier = Modifier + .background( + if (expanded) { + DesignTheme.colors.surface + } else { + DesignTheme.colors.background + } + ) ) { - HorizontalDivider(thickness = dividerThickness.dp, color = BrainwalletTheme.colors.content) + HorizontalDivider(thickness = dividerThickness.dp, color = DesignTheme.colors.content) ListItem( colors = colors, modifier = Modifier.clickable { @@ -87,7 +94,7 @@ fun SettingRowItemExpandable( headlineContent = { Text( text = title, - style = BrainwalletTheme.typography.labelLarge + style = DesignTheme.typography.labelLarge .copy(textAlign = TextAlign.Left) ) }, diff --git a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/ThemeSettingRowItem.kt b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/ThemeSettingRowItem.kt similarity index 93% rename from app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/ThemeSettingRowItem.kt rename to app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/ThemeSettingRowItem.kt index d764bd58..7577d911 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/home/composable/settingsrows/ThemeSettingRowItem.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/settings/settingsrows/ThemeSettingRowItem.kt @@ -1,4 +1,4 @@ -package com.brainwallet.ui.screens.home.composable.settingsrows +package com.brainwallet.ui.screens.settings.settingsrows import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.width diff --git a/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt index 5f7d600d..4e50d64d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/topup/TopUpScreen.kt @@ -27,23 +27,22 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import androidx.lifecycle.viewmodel.compose.viewModel import com.brainwallet.R import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect import com.brainwallet.tools.manager.AnalyticsManager -import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar -import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItEvent +import com.brainwallet.constants.BWConstants import com.brainwallet.ui.screens.yourseedproveit.YourSeedProveItViewModel +import org.koin.compose.viewmodel.koinViewModel @Composable fun TopUpScreen( onNavigate: OnNavigate, - viewModel: YourSeedProveItViewModel = viewModel() + viewModel: YourSeedProveItViewModel = koinViewModel() ) { val context = LocalContext.current @@ -107,7 +106,7 @@ fun TopUpScreen( modifier = Modifier.fillMaxWidth() ) BorderedLargeButton( - onClick = { onNavigate.invoke(UiEffect.Navigate(destinationRoute = Route.BuyLitecoin)) }, + onClick = { onNavigate.invoke(UiEffect.Navigate(destinationRoute = Route.BuyReceive)) }, modifier = Modifier.fillMaxWidth() ) { @@ -118,8 +117,13 @@ fun TopUpScreen( } BorderedLargeButton( onClick = { - viewModel.onEvent(YourSeedProveItEvent.OnGameAndSync) - AnalyticsManager.logCustomEvent(BRConstants._20250303_DSTU) + AnalyticsManager.logCustomEvent(BWConstants._20250303_DSTU) + onNavigate.invoke( + UiEffect.Navigate( + destinationRoute = Route.Main, + forcePopBackStack = true + ) + ) }, modifier = Modifier.fillMaxWidth() diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt index cdec09a0..16ae0fb8 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockEvent.kt @@ -12,5 +12,3 @@ sealed class UnLockEvent { object OnQrClicked : UnLockEvent() object OnDeletePinDigit : UnLockEvent() } - -// todo diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt index 53012da6..4a52313b 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockScreen.kt @@ -24,7 +24,7 @@ import com.brainwallet.data.model.AppSetting import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.composable.BrainwalletScaffold -import com.brainwallet.ui.screens.home.receive.ReceiveDialogFragment +import com.brainwallet.ui.bentosections.buyreceivebento.receive.ReceiveDialogFragment import com.brainwallet.ui.screens.unlock.components.UnLockScreenBody import com.brainwallet.ui.screens.unlock.components.UnLockScreenFooter import com.brainwallet.ui.screens.unlock.components.UnLockScreenHeader diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt index c183d675..6578edb5 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/UnLockViewModel.kt @@ -4,8 +4,8 @@ import androidx.lifecycle.viewModelScope import com.brainwallet.data.repository.SettingRepository import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect -import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.BrainwalletViewModel +import com.brainwallet.constants.BWConstants import com.brainwallet.util.CurrencyDataGetter import com.brainwallet.util.EventBus import com.brainwallet.util.VersionCodeProvider @@ -85,7 +85,7 @@ class UnLockViewModel( if (currency != null) { val roundedPriceAmount: BigDecimal = BigDecimal(currency.rate.toDouble()).multiply(BigDecimal(100)) - .divide(BigDecimal(100), 2, BRConstants.ROUNDING_MODE) + .divide(BigDecimal(100), 2, BWConstants.ROUNDING_MODE) formattedCurrency = currencyDataGetter.getFormattedCurrencyString( iso, diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt index ca279e29..8a47a525 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenBody.kt @@ -25,13 +25,12 @@ import com.brainwallet.R import com.brainwallet.data.model.AppSetting import com.brainwallet.tools.manager.AnalyticsManager import com.brainwallet.tools.security.AuthManager -import com.brainwallet.tools.util.BRConstants -import com.brainwallet.ui.composable.PasscodeIndicator -import com.brainwallet.ui.composable.PasscodeKeypad -import com.brainwallet.ui.composable.PasscodeKeypadEvent +import com.brainwallet.constants.BWConstants +import com.brainwallet.ui.composable.passcode.PasscodeIndicator +import com.brainwallet.ui.composable.passcode.PasscodeKeypadWrapper import com.brainwallet.ui.screens.unlock.UnLockEvent import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme import com.google.common.collect.ImmutableList @Composable @@ -60,36 +59,22 @@ fun UnLockScreenBody( Spacer(modifier = Modifier.weight(1f)) PasscodeIndicator(passcode = passcode, modifier = Modifier) Spacer(modifier = Modifier.weight(1f)) - PasscodeKeypad { passcodeKeypadEvent -> - when (passcodeKeypadEvent) { - PasscodeKeypadEvent.OnDelete -> onEvent(UnLockEvent.OnDeletePinDigit) - is PasscodeKeypadEvent.OnPressed -> onEvent( - UnLockEvent.OnPinDigitChange( - digit = passcodeKeypadEvent.digit, - isValidPin = { pin -> - - // provide old logic here, its like on the BrainwalletActivity.onUnlock - return@OnPinDigitChange AuthManager.getInstance() - .checkAuth(pin, context).also { isValid -> - if (isValid) { - AuthManager.getInstance().authSuccess(context) - AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) - AnalyticsManager.logCustomEvent(BRConstants._20200217_DUWB) - } else { - AuthManager.getInstance().authFail(context) - // for now just toast - Toast.makeText( - context, - R.string.incorrect_passcode, - Toast.LENGTH_SHORT - ).show() - } - } - } - ) - ) - } - } + PasscodeKeypadWrapper( + onDelete = { onEvent(UnLockEvent.OnDeletePinDigit) }, + onDigitPressed = { digit, isValidPin -> + onEvent(UnLockEvent.OnPinDigitChange(digit = digit, isValidPin = isValidPin)) + }, + onValidatePin = { pin -> + AuthManager.getInstance().checkAuth(pin, context).also { isValid -> + if (isValid) { + AuthManager.getInstance().authSuccess(context) + AnalyticsManager.logCustomEvent(BWConstants._20200217_DUWB) + } else { + Toast.makeText(context, R.string.incorrect_passcode, Toast.LENGTH_SHORT).show() + } + } + }, + ) Spacer(modifier = Modifier.weight(1f)) } } @@ -100,7 +85,7 @@ private fun UnLockScreenBodyPreview() { BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) { Box( modifier = Modifier - .background(BrainwalletTheme.colors.background) + .background(DesignTheme.colors.background) .fillMaxWidth() ) { UnLockScreenBody(isUpdatePin = true, passcode = ImmutableList.of(1, 2)) diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt index 74352675..8a2e2ca0 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenFooter.kt @@ -11,22 +11,25 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import com.brainwallet.R import com.brainwallet.data.model.AppSetting import com.brainwallet.ui.composable.DarkModeToggleButton import com.brainwallet.ui.screens.unlock.UnLockEvent import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.ui.theme.IBMPlexSans import com.grunt.brainwallet.core.presentation.theme.LocalDarkModeFlag @Composable @@ -59,19 +62,24 @@ fun UnLockScreenFooter( onEvent(UnLockEvent.OnQrClicked) }, colorFilter = ColorFilter.tint( - BrainwalletTheme.colors.border + DesignTheme.colors.border ) ) } Text( version, - modifier = Modifier.fillMaxWidth(), - style = MaterialTheme.typography - .bodyMedium - .copy( - textAlign = TextAlign.Center, - color = BrainwalletTheme.colors.border - ) + modifier = Modifier + .fillMaxWidth() + .padding( + top = 10.dp, + bottom = 30.dp + ), + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Light, + fontSize = 11.sp + ), + textAlign = TextAlign.Center ) } } @@ -82,7 +90,7 @@ private fun UnLockScreenFooterPreview() { BrainwalletAppTheme(AppSetting(isDarkMode = isSystemInDarkTheme())) { Box( modifier = Modifier - .background(BrainwalletTheme.colors.background) + .background(DesignTheme.colors.background) .fillMaxWidth() ) { UnLockScreenFooter(version = "v4.0.0 (202501201)") diff --git a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt index fd01ce6a..3428eff3 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/unlock/components/UnLockScreenHeader.kt @@ -1,5 +1,7 @@ package com.brainwallet.ui.screens.unlock.components +import androidx.compose.foundation.Image +import androidx.compose.foundation.R import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box @@ -11,13 +13,19 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import com.brainwallet.data.model.AppSetting -import com.brainwallet.ui.composable.BrainWalletLogo import com.brainwallet.ui.theme.BrainwalletAppTheme -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.ui.theme.DesignTheme +import com.brainwallet.R.drawable +import com.brainwallet.ui.theme.IBMPlexSans +import com.brainwallet.ui.theme.LocalIsDarkModeFlag @Composable fun UnLockScreenHeader( @@ -28,15 +36,35 @@ fun UnLockScreenHeader( modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { + val iconLogo = if (LocalIsDarkModeFlag.current) { + com.brainwallet.R.drawable.brainwallet_logotype_white + } else { + com.brainwallet.R.drawable.brainwallet_logotype_color + } + Text( modifier = Modifier - .padding(bottom = 52.dp) + .padding( + top = 40.dp, + bottom = 20.dp + ) .fillMaxWidth(), text = formattedLtcPrice, + style = TextStyle( + fontFamily = IBMPlexSans, + fontWeight = FontWeight.Medium, + fontSize = 13.sp + ), textAlign = TextAlign.End, - color = BrainwalletTheme.colors.border + color = DesignTheme.colors.border + ) + Image( + painterResource( + iconLogo + ), + contentDescription = "brainwallet_logo", + modifier = Modifier.width(268.dp) ) - BrainWalletLogo(modifier = Modifier.width(268.dp)) } } @@ -44,7 +72,7 @@ fun UnLockScreenHeader( @Composable private fun UnLockScreenHeaderPreview() { BrainwalletAppTheme(appSetting = AppSetting(isDarkMode = isSystemInDarkTheme())) { - Box(modifier = Modifier.background(BrainwalletTheme.colors.background)) { + Box(modifier = Modifier.background(DesignTheme.colors.background)) { UnLockScreenHeader(formattedLtcPrice = "100") } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt index 4261a557..6d67583d 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/welcome/WelcomeScreen.kt @@ -44,17 +44,18 @@ import com.airbnb.lottie.compose.LottieCompositionSpec import com.airbnb.lottie.compose.LottieConstants import com.airbnb.lottie.compose.animateLottieCompositionAsState import com.airbnb.lottie.compose.rememberLottieComposition +import com.brainwallet.BuildConfig import com.brainwallet.R import com.brainwallet.navigation.OnNavigate import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect -import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.composable.BorderedLargeButton import com.brainwallet.ui.composable.BrainwalletButton import com.brainwallet.ui.composable.DarkModeToggleButton import com.brainwallet.ui.composable.bottomsheet.FiatSelectorBottomSheet import com.brainwallet.ui.composable.bottomsheet.LanguageSelectorBottomSheet -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme +import com.brainwallet.constants.BWConstants +import com.brainwallet.ui.theme.DesignTheme import org.koin.compose.koinInject @Composable @@ -94,7 +95,7 @@ fun WelcomeScreen( Box( modifier = Modifier .fillMaxSize() - .background(BrainwalletTheme.colors.surface) + .background(DesignTheme.colors.surface) .verticalScroll(rememberScrollState()) .padding(WindowInsets.systemBars.asPaddingValues()), ) { @@ -108,7 +109,7 @@ fun WelcomeScreen( contentDescription = "brainwallet_logotype_white", contentScale = ContentScale.Fit, colorFilter = ColorFilter.tint( - BrainwalletTheme.colors.content, + DesignTheme.colors.content, ), modifier = Modifier .fillMaxWidth() @@ -116,21 +117,24 @@ fun WelcomeScreen( ) // Animation Placeholder - LottieAnimation( - modifier = Modifier - .fillMaxWidth() - .padding(leadTrailPadding.dp) - .background( - BrainwalletTheme.colors.surface, - BrainwalletTheme.shapes.large - ) - .height(thirdOfScreenHeight.dp) - .clip(BrainwalletTheme.shapes.large), - composition = composition, - contentScale = ContentScale.FillWidth, - alignment = Alignment.Center, - progress = { progress } - ) + // Shows only during Prod + if (!BuildConfig.DEBUG) { + LottieAnimation( + modifier = Modifier + .fillMaxWidth() + .padding(leadTrailPadding.dp) + .background( + DesignTheme.colors.surface, + DesignTheme.shapes.large + ) + .height(thirdOfScreenHeight.dp) + .clip(DesignTheme.shapes.large), + composition = composition, + contentScale = ContentScale.FillWidth, + alignment = Alignment.Center, + progress = { progress } + ) + } } Column( @@ -158,7 +162,7 @@ fun WelcomeScreen( Text( text = state.selectedLanguage.title, fontSize = 14.sp, - color = BrainwalletTheme.colors.content + color = DesignTheme.colors.content ) } @@ -185,7 +189,7 @@ fun WelcomeScreen( Text( text = state.selectedCurrency.name, fontSize = 14.sp, - color = BrainwalletTheme.colors.content + color = DesignTheme.colors.content ) } } @@ -210,7 +214,7 @@ fun WelcomeScreen( // Restore Button BorderedLargeButton( onClick = { - onNavigate.invoke(UiEffect.Navigate(Route.InputWords())) + onNavigate.invoke(UiEffect.Navigate(Route.Restore())) }, shape = RoundedCornerShape(50), modifier = Modifier @@ -228,9 +232,9 @@ fun WelcomeScreen( Text( modifier = Modifier.padding(vertical = versionPadding.dp), - text = BRConstants.APP_VERSION_NAME_CODE, + text = BWConstants.APP_VERSION_NAME_CODE, fontSize = 13.sp, - color = BrainwalletTheme.colors.content + color = DesignTheme.colors.content ) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt index 0f126cf1..14168cbb 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItScreen.kt @@ -51,15 +51,15 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.brainwallet.R import com.brainwallet.navigation.OnNavigate -import com.brainwallet.navigation.Route import com.brainwallet.navigation.UiEffect import com.brainwallet.tools.manager.AnalyticsManager -import com.brainwallet.tools.util.BRConstants import com.brainwallet.ui.composable.BrainwalletScaffold import com.brainwallet.ui.composable.BrainwalletTopAppBar import com.brainwallet.ui.composable.LargeButton import com.brainwallet.ui.composable.SeedWordItem import com.brainwallet.ui.composable.SeedWordsLayout +import com.brainwallet.constants.BWConstants +import com.brainwallet.navigation.Route import org.koin.compose.koinInject @Composable @@ -89,7 +89,7 @@ fun YourSeedProveItScreen( if (state.orderCorrected) { coinAudioPlayer.start() viewModel.onEvent(YourSeedProveItEvent.OnCompletedPaperKey) - AnalyticsManager.logCustomEvent(BRConstants._20250303_DSTU) + AnalyticsManager.logCustomEvent(BWConstants._20250303_DSTU) } } diff --git a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt index 2895cab6..84709e8f 100644 --- a/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt +++ b/app/src/main/java/com/brainwallet/ui/screens/yourseedproveit/YourSeedProveItViewModel.kt @@ -1,17 +1,19 @@ package com.brainwallet.ui.screens.yourseedproveit import androidx.lifecycle.viewModelScope +import com.brainwallet.navigation.Route +import com.brainwallet.navigation.UiEffect import com.brainwallet.ui.BrainwalletViewModel -import com.brainwallet.util.EventBus import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import org.koin.android.annotation.KoinViewModel +import com.brainwallet.util.EventBus @KoinViewModel -class YourSeedProveItViewModel : BrainwalletViewModel() { +class YourSeedProveItViewModel() : BrainwalletViewModel() { private val _state = MutableStateFlow(YourSeedProveItState()) val state: StateFlow = _state.asStateFlow() @@ -50,18 +52,25 @@ class YourSeedProveItViewModel : BrainwalletViewModel() { ) } - YourSeedProveItEvent.OnGameAndSync -> viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_NAVIGATE_TO_HOME)) - } + YourSeedProveItEvent.OnGameAndSync -> sendUiEffect( + UiEffect.Navigate( + destinationRoute = Route.Main, + forcePopBackStack = true + ) + ) YourSeedProveItEvent.OnCompletedPaperKey -> viewModelScope.launch { - EventBus.emit(EventBus.Event.Message(LEGACY_EFFECT_ON_PAPERKEY_PROVED)) + EventBus.emit( + EventBus.Event.Message( + LEGACY_EFFECT_ON_PAPERKEY_PROVED, + address = null + ) + ) } } } companion object { const val LEGACY_EFFECT_ON_PAPERKEY_PROVED = "onPaperKeyProved" - const val LEGACY_NAVIGATE_TO_HOME = "navigateToHome" } } diff --git a/app/src/main/java/com/brainwallet/ui/theme/Colors.kt b/app/src/main/java/com/brainwallet/ui/theme/Colors.kt new file mode 100644 index 00000000..e8a92b4d --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/theme/Colors.kt @@ -0,0 +1,12 @@ +package com.brainwallet.ui.theme +import androidx.compose.ui.graphics.Color + +public val midnight = Color(0xFF0F0853) +public val grape = Color(0xFF402DAE) +public val cheddar = Color(0xFFFFAE00) +public val chili = Color(0xFFCE3025) +public val pesto = Color(0xFF25AA2C) +public val blue = Color(0xFF2968F2) +public val nearBlack = Color(0xFF151515) +public val lavender = Color(0xFFDDD5FA) +public val white = Color.White diff --git a/app/src/main/java/com/brainwallet/ui/theme/DesignCore.kt b/app/src/main/java/com/brainwallet/ui/theme/DesignCore.kt new file mode 100644 index 00000000..6f08fc9a --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/theme/DesignCore.kt @@ -0,0 +1,146 @@ +package com.brainwallet.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Shapes +import androidx.compose.material3.Typography +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.Immutable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.BlurEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.TileMode +import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +val LocalLanguageISOCode = staticCompositionLocalOf { + "en" +} +val LocalIsDarkModeFlag = staticCompositionLocalOf { + false +} + +val LocalBWColors = staticCompositionLocalOf { + BWColors() +} + +@Composable +fun DesignTheme( + isDarkMode: Boolean, + languageCode: String = "en", + content: @Composable () -> Unit +) { + val view = LocalView.current + val colors = if (isDarkMode) darkScheme else lightScheme + + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + + // Sets the color to transparent + window.statusBarColor = Color.Transparent.toArgb() + + // Adjusts the icon colors (dark icons for light theme, light icons for dark theme) + val insetsController = WindowCompat.getInsetsController(window, view) + insetsController.isAppearanceLightStatusBars = !isDarkMode + insetsController.isAppearanceLightNavigationBars = !isDarkMode + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !isDarkMode + } + } + + CompositionLocalProvider( + LocalBWColors provides colors, + LocalLanguageISOCode provides languageCode, + LocalIsDarkModeFlag provides isDarkMode, + ) { + MaterialTheme( + typography = BWTypography, + content = content + ) + } +} +private val darkScheme = BWColors( + surface = midnight, + background = grape, + content = white, + border = white, + info = blue, + affirm = pesto, + warn = cheddar, + error = chili +) + +private val lightScheme = BWColors( + surface = white, + background = lavender, + content = midnight, + border = midnight, + info = blue, + affirm = pesto, + warn = cheddar, + error = chili +) + +/** + * define custom colors naming for brainwallet colors + */ +@Immutable +data class BWColors( + val surface: Color = Color.Unspecified, + val background: Color = Color.Unspecified, + val content: Color = Color.Unspecified, + val border: Color = Color.Unspecified, + val info: Color = Color.Unspecified, + val affirm: Color = Color.Unspecified, + val warn: Color = Color.Unspecified, + val error: Color = Color.Unspecified +) + +object DesignTheme { + val colors: BWColors + @Composable + get() = LocalBWColors.current + + val typography: Typography + @Composable @ReadOnlyComposable + get() = MaterialTheme.typography + + val shapes: Shapes + @Composable @ReadOnlyComposable + get() = MaterialTheme.shapes +} + +fun Modifier.blurWhen(condition: Boolean): Modifier = this.graphicsLayer { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + renderEffect = if (condition) { + BlurEffect( + radiusX = 40f, + radiusY = 40f, + edgeTreatment = TileMode.Decal + ) + } else { + null + } + } +} + +fun Modifier.blurAnimatedWith(radius: Float): Modifier = this.graphicsLayer { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + renderEffect = if (radius > 0f) { + BlurEffect( + radiusX = radius, + radiusY = radius, + edgeTreatment = TileMode.Decal + ) + } else { + null + } + } +} diff --git a/app/src/main/java/com/brainwallet/ui/theme/Fonts.kt b/app/src/main/java/com/brainwallet/ui/theme/Fonts.kt new file mode 100644 index 00000000..066293a4 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/theme/Fonts.kt @@ -0,0 +1,22 @@ +package com.brainwallet.ui.theme + +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import com.brainwallet.R + +val BoldenVan = FontFamily( + Font(R.font.bolden_van, FontWeight.Normal) +) + +val IBMPlexSans = FontFamily( + Font(R.font.ibm_plex_sans_regular, FontWeight.Normal), + Font(R.font.ibm_plex_sans_medium, FontWeight.Medium), + Font(R.font.ibm_plex_sans_semi_bold, FontWeight.SemiBold), + Font(R.font.ibm_plex_sans_bold, FontWeight.Bold), + Font(R.font.ibm_plex_sans_extra_light, FontWeight.ExtraLight), + Font(R.font.ibm_plex_sans_light, FontWeight.Light), + Font(R.font.ibm_plex_sans_thin, FontWeight.Thin), + Font(R.font.ibm_plex_sans_italic, FontWeight.Normal, FontStyle.Italic) +) diff --git a/app/src/main/java/com/brainwallet/ui/theme/Gradient.kt b/app/src/main/java/com/brainwallet/ui/theme/Gradient.kt new file mode 100644 index 00000000..3aa2d7b9 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/theme/Gradient.kt @@ -0,0 +1,157 @@ +package com.brainwallet.ui.theme +import androidx.compose.runtime.Composable +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.TileMode + +val colorWhite = Color(0xFFFFFFFF) +val colorBlue = Color(0xFF114CD4) +val color80PercentMidnite = Color(0xFF0F0853).copy(alpha = 0.8f) +val colorMidnite = Color(0xFF0F0853) +val colorSemiWhite = Color(0xFFFFFFFF).copy(alpha = 0.8f) +val colorLightWhite = Color(0x08FFFFFF) + +// / Main Screen Background Colors +val colorMainScreenBackground1 = Color(0xFF0F0853) +val colorMainScreenBackground2 = Color(0xFF121348) +val colorMainScreenBackground3 = Color(0xFF491FA3) +val colorMainScreenBackground4 = Color(0xFF000000) +val colorMainScreenBackground5 = Color(0xFF000000) + +/** + * A reusable vertical gradient brush for text and backgrounds.33 + */ +val gameTitleGradient: Brush + @Composable + get() = Brush.verticalGradient( + colors = listOf( + colorWhite, + colorWhite, + colorBlue, + ) + ) +val gameTaglineGradient: Brush + @Composable + get() = Brush.verticalGradient( + colors = listOf( + colorWhite, + colorWhite, + colorWhite, + colorBlue, + ) + ) +val gameHubBackgroundGradient: Brush + + @Composable + get() = Brush.radialGradient( + colors = listOf( + Color(0x80000000), + Color(0x4D5827E2) + ), + center = Offset(100 / 2.0f, 200 / 2.0f), + radius = 100 / 2.0f, + tileMode = TileMode.Clamp + ) + +val balanceBackgroundGradient: Brush + + @Composable + get() = Brush.verticalGradient( + 0.0f to colorMainScreenBackground5, + 1.0f to colorMainScreenBackground1, + startY = 0f, + endY = Float.POSITIVE_INFINITY, + tileMode = TileMode.Clamp + ) +val bentoDarkSurfaceGradient: Brush + @Composable + get() = Brush.verticalGradient( + colors = listOf( + colorLightWhite, + colorLightWhite + ), + startY = 0f, + endY = 100f + ) + +val bentoLightSurfaceGradient: Brush + @Composable + get() = Brush.verticalGradient( + colors = listOf( + colorWhite, + colorWhite + ), + startY = 0f, + endY = 100f + ) +val mainScreenDarkSurfaceGradient: Brush + @Composable + get() = Brush.verticalGradient( + 0.0f to colorMainScreenBackground1, + 0.35f to colorMainScreenBackground2, + 0.70f to colorMainScreenBackground3, + 0.8f to colorMainScreenBackground4, + 1.0f to colorMainScreenBackground5, + startY = 0f, + endY = Float.POSITIVE_INFINITY + ) + +val mainScreenLightSurfaceGradient: Brush + @Composable + get() = Brush.verticalGradient( + colors = listOf( + colorWhite, + colorWhite + ), + startY = 0f, + endY = 100f + ) +val bentoLightBorderGradient: Brush + + @Composable + get() = Brush.linearGradient( + colors = listOf( + Color(0xFFD9D9D9), + Color(0xFFDfDfDf), + ), + start = Offset.Zero, + end = Offset(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY) + ) +val bentoClearGradient: Brush + + @Composable + get() = Brush.linearGradient( + colors = listOf( + Color(0xFFFFFFFF).copy(alpha = 0.0f), + Color(0xFFFFFFFF).copy(alpha = 0.0f) + ), + start = Offset(Float.MIN_VALUE, Float.POSITIVE_INFINITY), + end = Offset(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY), + ) +val bentoDarkBorderGradient: Brush + + @Composable + get() = Brush.linearGradient( + colors = listOf( + Color(0xFFFFFFFF).copy(alpha = 0.2f), + Color(0xFF9074FF).copy(alpha = 0.8f), + Color(0xFF020148).copy(alpha = 1f), + Color(0xFF2B193B).copy(alpha = 1f), + Color(0xFF6944BE).copy(alpha = 0.2f) + ), + start = Offset.Zero, + end = Offset(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY), + ) + +val bentoModalDarkGradient: Brush + + @Composable + get() = Brush.linearGradient( + colors = listOf( + Color(0xFF09082B).copy(alpha = 1f), + Color(0xFF280589).copy(alpha = 0.7f) + ), + start = Offset(Float.MIN_VALUE, Float.POSITIVE_INFINITY), + end = Offset(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY), + ) diff --git a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt index 8e624813..1d21f1f9 100644 --- a/app/src/main/java/com/brainwallet/ui/theme/Theme.kt +++ b/app/src/main/java/com/brainwallet/ui/theme/Theme.kt @@ -5,7 +5,6 @@ import androidx.compose.ui.platform.ComposeView import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.brainwallet.data.model.AppSetting import com.brainwallet.data.repository.SettingRepository -import com.grunt.brainwallet.core.presentation.theme.BrainwalletTheme import org.koin.compose.koinInject @Composable @@ -17,13 +16,12 @@ fun BrainwalletAppTheme( @Composable() () -> Unit ) { - BrainwalletTheme( - darkTheme = appSetting.isDarkMode, + DesignTheme( + isDarkMode = appSetting.isDarkMode, languageCode = appSetting.languageCode, content = content ) } - fun ComposeView.setContentWithTheme(content: @Composable () -> Unit) { setContent { BrainwalletAppTheme { content.invoke() } diff --git a/app/src/main/java/com/brainwallet/ui/theme/Typography.kt b/app/src/main/java/com/brainwallet/ui/theme/Typography.kt new file mode 100644 index 00000000..7819ae33 --- /dev/null +++ b/app/src/main/java/com/brainwallet/ui/theme/Typography.kt @@ -0,0 +1,85 @@ +package com.brainwallet.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp +import com.grunt.brainwallet.core.presentation.theme.openSauceOneFamily + +val BWTypography = Typography( + displayLarge = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.SemiBold, + fontSize = 57.sp + ), + displayMedium = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 45.sp + ), + displaySmall = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 36.sp + ), + headlineLarge = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 32.sp + ), + headlineMedium = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 28.sp + ), + headlineSmall = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 24.sp + ), + titleLarge = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 22.sp + ), + titleMedium = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Medium, + fontSize = 16.sp + ), + titleSmall = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Medium, + fontSize = 14.sp + ), + bodyLarge = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 16.sp + ), + bodyMedium = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 14.sp + ), + bodySmall = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Normal, + fontSize = 12.sp + ), + labelLarge = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.SemiBold, + fontSize = 14.sp + ), + labelMedium = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Medium, + fontSize = 12.sp + ), + labelSmall = TextStyle( + fontFamily = openSauceOneFamily, + fontWeight = FontWeight.Thin, + fontSize = 11.sp + ) +) diff --git a/app/src/main/java/com/brainwallet/util/EventBus.kt b/app/src/main/java/com/brainwallet/util/EventBus.kt index 3fdb667c..15646ea3 100644 --- a/app/src/main/java/com/brainwallet/util/EventBus.kt +++ b/app/src/main/java/com/brainwallet/util/EventBus.kt @@ -19,9 +19,14 @@ object EventBus { _events.emit(event) } + fun postQRCodeScanned(url: String?) { + _events.tryEmit(Event.QRCodeScanned(url)) + } + sealed class Event { data class Message( val message: String, + val address: String?, ) : Event() // provide this for old flow @@ -32,5 +37,7 @@ object EventBus { data class LegacyUnLock( val passcode: List, ) : Event() + + data class QRCodeScanned(val url: String?) : Event() } } diff --git a/app/src/main/java/com/brainwallet/util/VersionCodeProvider.kt b/app/src/main/java/com/brainwallet/util/VersionCodeProvider.kt index 264ccccf..3c786d3d 100644 --- a/app/src/main/java/com/brainwallet/util/VersionCodeProvider.kt +++ b/app/src/main/java/com/brainwallet/util/VersionCodeProvider.kt @@ -19,4 +19,10 @@ class VersionCodeProvider( fun getFormatted(): String { return "${getVersionName()} (${getVersionCode()})" } + + companion object { + fun getVersionLabel() { + TODO("Not yet implemented") + } + } } diff --git a/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java b/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java index 6f591402..b561b816 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRPeerManager.java @@ -5,12 +5,13 @@ import android.content.Context; import com.brainwallet.BrainwalletApp; +import com.brainwallet.data.model.LtcStats; import com.brainwallet.data.repository.SelectedPeersRepository; import com.brainwallet.data.source.RemoteConfigSource; import com.brainwallet.presenter.entities.BlockEntity; import com.brainwallet.presenter.entities.PeerEntity; import com.brainwallet.tools.manager.BRSharedPrefs; -import com.brainwallet.tools.manager.SyncManager; +import com.brainwallet.tools.manager.sync.SyncThreadManager; import com.brainwallet.tools.sqlite.MerkleBlockDataSource; import com.brainwallet.tools.sqlite.PeerDataSource; import com.brainwallet.tools.threads.BRExecutor; @@ -25,6 +26,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutionException; +import kotlin.Suppress; import kotlin.coroutines.EmptyCoroutineContext; import kotlinx.coroutines.CoroutineScopeKt; import kotlinx.coroutines.CoroutineStart; @@ -60,21 +62,21 @@ public static BRPeerManager getInstance() { * void (*savePeers)(void *info, const BRPeer peers[], size_t count), * int (*networkIsReachable)(void *info)) */ - + @Suppress(names = "unused") // called via BRPeerManager callback public static void syncStarted() { Context ctx = BrainwalletApp.getBreadContext(); - int startHeight = BRSharedPrefs.getStartHeight(ctx); + + LtcStats ltcStats = BRSharedPrefs.getLiveLtcStats(ctx); + int startHeight = ltcStats.currentBlockHeight; int lastHeight = BRSharedPrefs.getLastBlockHeight(ctx); if (startHeight > lastHeight) BRSharedPrefs.putStartHeight(ctx, lastHeight); - SyncManager.getInstance().startSyncingProgressThread(ctx); + SyncThreadManager.getInstance().startSyncing(startHeight); } - + @Suppress(names = "unused") // called via BRPeerManager callback public static void syncSucceeded() { Context ctx = BrainwalletApp.getBreadContext(); if (ctx == null) return; - SyncManager.getInstance().updateAlarms(ctx); - BRSharedPrefs.putAllowSpend(ctx, true); - SyncManager.getInstance().stopSyncingProgressThread(ctx); + SyncThreadManager.getInstance().stopSyncing(); BRExecutor.getInstance().forLightWeightBackgroundTasks().execute(new Runnable() { @Override public void run() { @@ -83,24 +85,19 @@ public void run() { }); if (onSyncFinished != null) onSyncFinished.onFinished(); } - + @Suppress(names = "unused") // called via BRPeerManager callback public static void syncFailed() { - Context ctx = BrainwalletApp.getBreadContext(); - SyncManager.getInstance().stopSyncingProgressThread(ctx); - - if (ctx == null) return; - Timber.d("timber: Network Not Available, showing not connected bar"); - - SyncManager.getInstance().stopSyncingProgressThread(ctx); + SyncThreadManager.getInstance().stopSyncing(); if (onSyncFinished != null) onSyncFinished.onFinished(); } + @Suppress(names = "unused") // called via BRPeerManager callback public static void txStatusUpdate() { Timber.d("timber: txStatusUpdate"); synchronized (statusUpdateListeners) { for (OnTxStatusUpdate listener : statusUpdateListeners) { - if (listener != null) listener.onStatusUpdate(); + if (listener != null) listener.onStatusPeerManagerUpdate(); } } @@ -111,7 +108,7 @@ public void run() { } }); } - + @Suppress(names = "unused") // called via BRPeerManager callback public static void saveBlocks(final BlockEntity[] blockEntities, final boolean replace) { Timber.d("timber: saveBlocks: %s", blockEntities.length); @@ -126,7 +123,7 @@ public void run() { }); } - + @Suppress(names = "unused") // called via BRPeerManager callback public static void savePeers(final PeerEntity[] peerEntities, final boolean replace) { Timber.d("timber: savePeers: %s", peerEntities.length); final Context ctx = BrainwalletApp.getBreadContext(); @@ -139,12 +136,12 @@ public void run() { } }); } - + @Suppress(names = "unused") // called via BRPeerManager callback public static boolean networkIsReachable() { Timber.d("timber: networkIsReachable"); return BRWalletManager.getInstance().isNetworkAvailable(BrainwalletApp.getBreadContext()); } - + @Suppress(names = "unused") // called via BRPeerManager callback public static void deleteBlocks() { Timber.d("timber: deleteBlocks"); final Context ctx = BrainwalletApp.getBreadContext(); @@ -156,7 +153,7 @@ public void run() { } }); } - + @Suppress(names = "unused") // called via BRPeerManager callback public static void deletePeers() { Timber.d("timber: deletePeers"); final Context ctx = BrainwalletApp.getBreadContext(); @@ -242,7 +239,7 @@ public static void setOnSyncFinished(OnSyncSucceeded listener) { } public interface OnTxStatusUpdate { - void onStatusUpdate(); + void onStatusPeerManagerUpdate(); } public interface OnSyncSucceeded { diff --git a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java index b1031ea8..496141b9 100644 --- a/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java +++ b/app/src/main/java/com/brainwallet/wallet/BRWalletManager.java @@ -1,5 +1,4 @@ package com.brainwallet.wallet; - import android.app.Activity; import android.app.AlertDialog; import android.app.KeyguardManager; @@ -19,23 +18,20 @@ import android.widget.EditText; import android.widget.Toast; -import androidx.annotation.WorkerThread; import androidx.fragment.app.FragmentActivity; import com.brainwallet.BrainwalletApp; import com.brainwallet.R; import com.brainwallet.presenter.activities.BreadActivity; import com.brainwallet.presenter.activities.util.ActivityUTILS; -import com.brainwallet.presenter.customviews.BRDialogView; import com.brainwallet.presenter.customviews.BRToast; import com.brainwallet.presenter.entities.BRMerkleBlockEntity; import com.brainwallet.presenter.entities.BRPeerEntity; -import com.brainwallet.presenter.entities.BRTransactionEntity; +import com.brainwallet.presenter.entities.BWDatabaseTransactionEntity; import com.brainwallet.presenter.entities.ImportPrivKeyEntity; import com.brainwallet.presenter.entities.TxItem; import com.brainwallet.presenter.interfaces.BROnSignalCompletion; import com.brainwallet.tools.animation.BRAnimator; -import com.brainwallet.tools.animation.BRDialog; import com.brainwallet.tools.animation.SpringAnimator; import com.brainwallet.tools.manager.AnalyticsManager; import com.brainwallet.tools.manager.BRNotificationManager; @@ -47,7 +43,7 @@ import com.brainwallet.tools.sqlite.TransactionDataSource; import com.brainwallet.tools.threads.BRExecutor; import com.brainwallet.tools.threads.ImportPrivKeyTask; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.BRCurrency; import com.brainwallet.tools.util.BRExchange; import com.brainwallet.tools.util.Bip39Reader; @@ -61,19 +57,22 @@ import java.util.Arrays; import java.util.List; +import kotlin.Suppress; import timber.log.Timber; public class BRWalletManager { private static BRWalletManager instance; public List balanceListeners = new ArrayList<>(); - private boolean itInitiatingWallet; + private boolean isInitiatingWallet; public void setBalance(final Context context, long balance) { if (context == null) { Timber.i("timber: setBalance: FAILED TO SET THE BALANCE NULL context"); return; } - BRSharedPrefs.putCatchedBalance(context, balance); + BRSharedPrefs.putCachedBalance(context, balance); + Timber.i("timber: BRWalletManager setBalance: %d", balance); + refreshAddress(context); for (OnBalanceChanged listener : balanceListeners) { @@ -85,13 +84,14 @@ public void refreshBalance(Activity app) { long nativeBalance = nativeBalance(); if (nativeBalance != -1) { setBalance(app, nativeBalance); + Timber.i("timber: BRWalletManager refreshBalance: %d", nativeBalance); } else { Timber.i("timber: UpdateUI, nativeBalance is -1 meaning _wallet was null!"); } } public long getBalance(Context context) { - return BRSharedPrefs.getCatchedBalance(context); + return BRSharedPrefs.getCachedBalance(context); } private BRWalletManager() { @@ -103,7 +103,6 @@ public static BRWalletManager getInstance() { } return instance; } - public synchronized boolean generateRandomSeed(final Context ctx) { SecureRandom sr = new SecureRandom(); final String[] words; @@ -134,7 +133,7 @@ public synchronized boolean generateRandomSeed(final Context ctx) { boolean success; try { - success = BRKeyStore.putPhrase(strPhrase, ctx, BRConstants.PUT_PHRASE_NEW_WALLET_REQUEST_CODE); + success = BRKeyStore.putPhrase(strPhrase, ctx, BWConstants.PUT_PHRASE_NEW_WALLET_REQUEST_CODE); } catch (UserNotAuthenticatedException e) { return false; } @@ -333,38 +332,15 @@ public void onClick(DialogInterface dialog, int which) { /** * Wallet callbacks */ + @Suppress(names = "unused") // called via BRPeerManager callback public static void publishCallback(final String message, final int error, byte[] txHash) { Timber.d("timber: publishCallback: " + message + ", err:" + error + ", txHash: " + Arrays.toString(txHash)); - Bundle params = new Bundle(); params.putString("function", "BRWalletManager.publishCallback"); params.putString("message", message); params.putInt("error", error); params.putString("txHash", Arrays.toString(txHash)); - AnalyticsManager.logCustomEventWithParams(BRConstants._20250517_WCINFO, params); - - final Context app = BrainwalletApp.getBreadContext(); - BRExecutor.getInstance().forMainThreadTasks().execute(new Runnable() { - @Override - public void run() { - new Handler().postDelayed(new Runnable() { - @Override - public void run() { - if (app instanceof FragmentActivity) - BRAnimator.showBreadSignal((FragmentActivity) app, error == 0 ? app.getString(R.string.Alerts_sendSuccess) : app.getString(R.string.Alert_error), - error == 0 ? app.getString(R.string.Alerts_sendSuccessSubheader) : message, error == 0 ? R.drawable.ic_check_mark_white : R.drawable.ic_error_outline_black_24dp, new BROnSignalCompletion() { - @Override - public void onComplete() { - /** - * no-op, since the fragment already closed, please check [FragmentSignal] - */ - } - }); - } - }, 500); - } - }); - + AnalyticsManager.logCustomEventWithParams(BWConstants._20250517_WCINFO, params); } public static void onBalanceChanged(final long balance) { @@ -373,11 +349,11 @@ public static void onBalanceChanged(final long balance) { BRWalletManager.getInstance().setBalance(app, balance); } - + @Suppress(names = "unused") // called via BRPeerManager callback public static void onTxAdded(byte[] tx, int blockHeight, long timestamp, final long amount, String hash) { // DEV Uncomment to see values - // Timber.d("timber: onTxAdded: tx.length: %d, blockHeight: %d, timestamp: %d, amount: %d, hash: %s", tx.length, blockHeight, timestamp, amount, hash)); + Timber.d("timber: onTxAdded: tx.length: %d, blockHeight: %d, timestamp: %d, amount: %d, hash: %s", tx.length, blockHeight, timestamp, amount, hash); final Context ctx = BrainwalletApp.getBreadContext(); if (amount > 0) { @@ -393,7 +369,7 @@ public void run() { }); } if (ctx != null) - TransactionDataSource.getInstance(ctx).putTransaction(new BRTransactionEntity(tx, blockHeight, timestamp, hash)); + TransactionDataSource.getInstance(ctx).putTransaction(new BWDatabaseTransactionEntity(tx, blockHeight, timestamp, hash)); else Timber.i("timber: onTxAdded: ctx is null!"); } @@ -429,10 +405,11 @@ public void run() { Timber.i("timber: showToastWithMessage: failed, ctx is null"); } } - + @Suppress(names = "unused") // called via BRPeerManager callback public static void onTxUpdated(String hash, int blockHeight, int timeStamp) { // DEV Uncomment to see values - // Timber.d("timber: onTxUpdated: " + String.format("hash: %s, blockHeight: %d, timestamp: %d", hash, blockHeight, timeStamp)); + String variables = String.format("hash: %s, blockHeight: %d, timeStamp: %d", hash, blockHeight, timeStamp); + Timber.d("timber: onTxUpdated: %s",variables); Context ctx; ctx = BrainwalletApp.getBreadContext(); if (ctx != null) { @@ -445,7 +422,8 @@ public static void onTxUpdated(String hash, int blockHeight, int timeStamp) { public static void onTxDeleted(String hash, int notifyUser, final int recommendRescan) { // DEV Uncomment to see values - // Timber.d("timber: onTxDeleted: " + String.format("hash: %s, notifyUser: %d, recommendRescan: %d", hash, notifyUser, recommendRescan)); + String variables = String.format("hash: %s, notifyUser: %d, recommendRescan: %d", hash, notifyUser, recommendRescan); + Timber.d("timber: onTxDeleted: %s", variables); final Context ctx = BrainwalletApp.getBreadContext(); if (ctx != null) { BRSharedPrefs.putScanRecommended(ctx, true); @@ -456,22 +434,19 @@ public static void onTxDeleted(String hash, int notifyUser, final int recommendR } public void startTheWalletIfExists(final Activity app) { - final BRWalletManager m = BRWalletManager.getInstance(); - if (!m.noWallet(app) && BRSharedPrefs.getPhraseWroteDown(app)) { + final BRWalletManager walletManager = BRWalletManager.getInstance(); + if (!walletManager.noWallet(app) && BRSharedPrefs.getPhraseWroteDown(app)) { BRAnimator.startBreadActivity(app, true); } - //else just sit in the intro screen } - - @WorkerThread public void initWallet(final Context ctx) { if (ActivityUTILS.isMainThread()) throw new NetworkOnMainThreadException(); - if (itInitiatingWallet) { - AnalyticsManager.logCustomEvent(BRConstants._20200111_WNI); + if (isInitiatingWallet) { + AnalyticsManager.logCustomEvent(BWConstants._20200111_WNI); return; } - itInitiatingWallet = true; + isInitiatingWallet = true; try { Timber.d("timber: initWallet:%s", Thread.currentThread().getName()); @@ -486,13 +461,13 @@ public void initWallet(final Context ctx) { Timber.d("timber: Showing seed fragment"); if (!m.isCreated()) { - List transactions = TransactionDataSource.getInstance(ctx).getAllTransactions(); + List transactions = TransactionDataSource.getInstance(ctx).getAllTransactions(); Timber.d("timber: All transactions : %d", transactions.size()); int transactionsCount = transactions.size(); if (transactionsCount > 0) { m.createTxArrayWithCount(transactionsCount); - for (BRTransactionEntity entity : transactions) { + for (BWDatabaseTransactionEntity entity : transactions) { m.putTransaction(entity.getBuff(), entity.getBlockheight(), entity.getTimestamp()); } } @@ -549,7 +524,7 @@ public void run() { } finally { - itInitiatingWallet = false; + isInitiatingWallet = false; } } @@ -565,7 +540,7 @@ public void removeListener(OnBalanceChanged listener) { public String getSeedPhrase(Context context) { byte[] phraseBytes; try { - phraseBytes = BRKeyStore.getPhrase(context, BRConstants.PUT_PHRASE_NEW_WALLET_REQUEST_CODE); + phraseBytes = BRKeyStore.getPhrase(context, BWConstants.PUT_PHRASE_NEW_WALLET_REQUEST_CODE); } catch (UserNotAuthenticatedException e) { phraseBytes = new byte[0]; } @@ -678,5 +653,4 @@ public void setFeePerKb(long fee) { public static native int getTxSize(byte[] serializedTx); - } diff --git a/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt b/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt index ef69a1d0..c2f1f6ce 100644 --- a/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt +++ b/app/src/main/java/com/brainwallet/worker/CurrencyUpdateWorker.kt @@ -1,6 +1,7 @@ package com.brainwallet.worker import com.brainwallet.data.repository.LtcRepository +import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -12,20 +13,20 @@ import org.koin.core.annotation.Single @Single class CurrencyUpdateWorker( - private val ltcRepository: LtcRepository + private val ltcRepository: LtcRepository, + private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, + private val workerScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) ) { - private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private var job: Job? = null fun start() { - if (job?.isActive == true && job != null) { + if (job?.isActive == true) { job?.cancel() } - - job = scope.launch(Dispatchers.IO) { + job = workerScope.launch(ioDispatcher) { while (isActive) { ltcRepository.fetchRates() - delay(4000L) // 4secs + delay(4000L) } } } diff --git a/app/src/main/java/com/platform/kvstore/ReplicatedKVStore.java b/app/src/main/java/com/platform/kvstore/ReplicatedKVStore.java index 88c7a6b9..6ef324b7 100644 --- a/app/src/main/java/com/platform/kvstore/ReplicatedKVStore.java +++ b/app/src/main/java/com/platform/kvstore/ReplicatedKVStore.java @@ -9,7 +9,7 @@ import com.brainwallet.BrainwalletApp; import com.brainwallet.tools.security.BRKeyStore; import com.brainwallet.tools.threads.BRExecutor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.Utils; import com.jniwrappers.BRKey; import com.platform.interfaces.KVStoreAdaptor; @@ -76,7 +76,7 @@ public SQLiteDatabase getWritable() { // if (ActivityUTILS.isMainThread()) throw new NetworkOnMainThreadException(); if (mDatabase == null || !mDatabase.isOpen()) mDatabase = dbHelper.getWritableDatabase(); - dbHelper.setWriteAheadLoggingEnabled(BRConstants.WAL); + dbHelper.setWriteAheadLoggingEnabled(BWConstants.WAL); // } return mDatabase; } diff --git a/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java b/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java index f89c2569..d4c4aaa3 100644 --- a/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java +++ b/app/src/main/java/com/platform/sqlite/PlatformSqliteHelper.java @@ -4,7 +4,7 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import timber.log.Timber; @@ -49,7 +49,7 @@ public static synchronized PlatformSqliteHelper getInstance(Context context) { private PlatformSqliteHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); - setWriteAheadLoggingEnabled(BRConstants.WAL); + setWriteAheadLoggingEnabled(BWConstants.WAL); } @Override diff --git a/app/src/main/java/com/platform/tools/KVStoreManager.java b/app/src/main/java/com/platform/tools/KVStoreManager.java index a99edc66..e328721e 100644 --- a/app/src/main/java/com/platform/tools/KVStoreManager.java +++ b/app/src/main/java/com/platform/tools/KVStoreManager.java @@ -5,7 +5,7 @@ import com.brainwallet.tools.crypto.CryptoHelper; import com.brainwallet.tools.manager.AnalyticsManager; import com.brainwallet.tools.util.BRCompressor; -import com.brainwallet.tools.util.BRConstants; +import com.brainwallet.constants.BWConstants; import com.brainwallet.tools.util.Utils; import com.platform.APIClient; import com.platform.entities.TxMetaData; @@ -80,7 +80,7 @@ public TxMetaData valueToMetaData(byte[] value) { JSONObject json; if (value == null) { Timber.d("timber: valueToMetaData: value is null!"); - AnalyticsManager.logCustomEvent(BRConstants._20200111_TNI); + AnalyticsManager.logCustomEvent(BWConstants._20200111_TNI); return null; } try { diff --git a/app/src/main/res/anim/anticipate_interpolator.xml b/app/src/main/res/anim/anticipate_interpolator.xml deleted file mode 100644 index f381f34f..00000000 --- a/app/src/main/res/anim/anticipate_interpolator.xml +++ /dev/null @@ -1,4 +0,0 @@ - - diff --git a/app/src/main/res/anim/enter_from_top.xml b/app/src/main/res/anim/enter_from_top.xml deleted file mode 100644 index bbc4aa49..00000000 --- a/app/src/main/res/anim/enter_from_top.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/anim/exit_to_top.xml b/app/src/main/res/anim/exit_to_top.xml deleted file mode 100644 index 692223bb..00000000 --- a/app/src/main/res/anim/exit_to_top.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml deleted file mode 100644 index f95d42e7..00000000 --- a/app/src/main/res/anim/fade_in.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml deleted file mode 100644 index 84e9e105..00000000 --- a/app/src/main/res/anim/fade_out.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/animator/from_left.xml b/app/src/main/res/animator/from_left.xml deleted file mode 100644 index abcc7b99..00000000 --- a/app/src/main/res/animator/from_left.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/animator/from_top.xml b/app/src/main/res/animator/from_top.xml deleted file mode 100644 index e31fbff2..00000000 --- a/app/src/main/res/animator/from_top.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/animator/to_right.xml b/app/src/main/res/animator/to_right.xml deleted file mode 100644 index 9897539e..00000000 --- a/app/src/main/res/animator/to_right.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/animator/to_top.xml b/app/src/main/res/animator/to_top.xml deleted file mode 100644 index 21941f83..00000000 --- a/app/src/main/res/animator/to_top.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/color/bottom_nav_icon_tint_selector.xml b/app/src/main/res/color/bottom_nav_icon_tint_selector.xml deleted file mode 100644 index 4dff2ef9..00000000 --- a/app/src/main/res/color/bottom_nav_icon_tint_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/color/fee_selector_text_selector.xml b/app/src/main/res/color/fee_selector_text_selector.xml deleted file mode 100644 index a15a2d05..00000000 --- a/app/src/main/res/color/fee_selector_text_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/color/fiat_option_text_selector.xml b/app/src/main/res/color/fiat_option_text_selector.xml deleted file mode 100644 index 11679db8..00000000 --- a/app/src/main/res/color/fiat_option_text_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/color/transfer_fiat_option_text_selector.xml b/app/src/main/res/color/transfer_fiat_option_text_selector.xml deleted file mode 100644 index 249f78f4..00000000 --- a/app/src/main/res/color/transfer_fiat_option_text_selector.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/bubble_up.9.png b/app/src/main/res/drawable-hdpi/bubble_up.9.png deleted file mode 100644 index 254f3526497f1815ed4b7a5f5487f2b24a51a999..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 713 zcmeAS@N?(olHy`uVBq!ia0y~yU}OZcy*b!`WI=?HGXn$D1Wy;okcwMxZyju(QYdr$ zqrSI`%kqxI&eYBqSL!cle#`IZcp-Js*tqn?m8JFyR;kKKFGXULBW0DQrFM4somM-# z{{H1lXHNMTTVI~>{QDleJ!{IY%ha9SV|)IMi_iWemm-$^{Qn`wz<9Hpu5HKGE4}3_ zyZSC0WG6GM`Y}a$!lu7}-iIzvx;Bj=q_9wf!IR?*%L9+UwTcGXzr+$sQy5wf_%QUf zD#ROFm~NiL6mb8uzfi;DaF%Sp^J{*-XDnI9*B~&16Nsk@G-!QG<2rC4UC|&rh(YdH zt0h~4K$F(Bx$7dWnH5;ldO01;%l-$04g9w!@`o$Ot#2&WzZRUl`=)Z+*-0;t{eE-X ziOJxD^6v+Kre8Y!rta18r8ndMe0_dq_s67z{(1>@_nut;_;fPcgQ~g)=5~(W@3vnb z9V=mcakQ-#wzZrgNi zR$@?6U{YYhMLlS6U||qsaA6Q&B!Q6;z~aQRV5=a9AcLR)W5(RG5t5>fvg|BJe@iW% zR{!G)qvOYIZte@jrTI9xu6IW-Rt`A2@{jj!KCV-HMNh2%Tx^)Pj%~q<)eY8$CqL=i z7bXPE2{(NC%3i)=vOw1-E8D)yhHpRZJ$&~5cL6?uS+5lCGu`Qq46EO?qHcmrOD;PX zZ{X46f3{BFKd--XecgpC{n`hFRxJ|dj$oR0uJb#$1CNF7l+EIiz$D7x>FVdQ&MBb@ E0M-60a{vGU diff --git a/app/src/main/res/drawable-hdpi/bug.png b/app/src/main/res/drawable-hdpi/bug.png deleted file mode 100644 index b67d3261c1d4e289a9169004ac6a5590e1a99a5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4176 zcmV-W5U=lvP)uJ@VVD_UC<6{NG_fI~0ue<-1QkJoA_k0xBC#Thg@9ne9*`iQ#9$Or zQF$}6R&?d%y_c8YA7_1QpS|}zXYYO1x&V;8{kgn!SPFnNo`4_X6{c}T{8k*B#$jdxfFg<9uYy1K45IaYvHg`_dOZM)Sy63ve6hvv z1)yUy0P^?0*fb9UASvow`@mQCp^4`uNg&9uGcn1|&Nk+9SjOUl{-OWr@Hh0;_l(8q z{wNRKos+;6rV8ldy0Owz(}jF`W(JeRp&R{qi2rfmU!TJ;gp(Kmm5I1s5m_f-n#TRsj}B0%?E`vOzxB2#P=n*a3EfYETOrKoe*ICqM@{4K9Go;5xVgZi5G4 z1dM~{UdP6d+Yd3o?MrAqM0Kc|iV92owdyL5UC#5<>aVCa44|hpM4E zs0sQWIt5*Tu0n&*J!lk~f_{hI!w5`*sjxDv4V%CW*ah~3!{C*0BD@;TgA3v9a1~q+ zAA{TB3-ERLHar49hi4Ih5D^-ph8Q6X#0?2VqLBoIkE}zAkxHZUgRb+f=nat zP#6>iMMoK->`~sRLq)(kHo*Vn{;LcG6+edD1=7D>9j^O?D{Qg|tCDK{ym)H7&wDr6*;uGTJg8GHjVbnL{!cWyUB7MT6o-VNo_w8Yq`2<5Ub)hw4L3rj}5@qxMs0 zWMyP6Wy582WNT#4$d1qunl{acmP#w5ouJ*Jy_Zv#bCKi7ZIf$}8d zZdVy&)LYdbX%I9R8VMQ|8r>Q*nyQ)sn)#Z|n)kKvS`4iu ztvy=3T65Yu+7a4Yv^%sXb>ww?bn(=Yu(!=O6^iuTp>)p_Y^{w=i z^lS773}6Fm1Fpe-gF!>Ip{*g$u-szvGhed;vo5pW&GpS$<~8QGEXWp~7V9lKEnZq0SaK{6Sl+dwSOr*Z zvFf(^Xl-N7w{EeXveC4Ov)N}e%%C!Y7^RFWwrE>d+x51mZQt2h+X?JW*!^a2WS?Sx z)P8cQ&Qi|OhNWW;>JChYI)@QQx?`Nj^#uJBl~d&PK+RZLOLos~K(b5>qmrMN0})tOkySZ3_W zICNY@+|jrX%s^&6b2i>5eqa0y%Z;^%^_=a@u3%4b9605ii3Ep)@`TAmhs0fpQ%O!q zl}XcFH*PieWwLj2ZSq`7V9Mc?h17`D)-+sNT-qs~3@?S(ldh7UlRlVXkWrK|vf6I- z?$tAVKYn8-l({mqQ$Q8{O!WzMg`0(=S&msXS#Pt$vrpzo=kRj+a`kh!z=6$;c zwT88(J6|n-WB%w`m$h~4pmp)YIh_ z3ETV2tjiAU!0h1dxU-n=E9e!)6|Z;4?!H=SSy{V>ut&IOq{_dl zbFb#!9eY1iCsp6Bajj|Hr?hX|zPbJE{X++w546-O*Ot`2Kgd0Jx6Z4syT zu9enWavU5N9)I?I-1m1*_?_rJ$vD~agVqoG+9++s?NEDe`%Fht$4F;X=in*dQ{7$m zU2Q)a|9JSc+Uc4zvS-T963!N$T{xF_ZuWe}`RNOZ7sk3{yB}PPym+f8xTpV;-=!;; zJuhGEb?H5K#o@~7t9DmUU1MD9xNd#Dz0azz?I)|B+WM{g+Xrk0I&awC=o(x)cy`EX z=)z6+o0o6-+`4{y+3mqQ%kSJBju{@g%f35#FZJHb`&swrA8dGtepviS>QUumrN{L@ z>;2q1Vm)$Z)P1z?N$8UYW2~{~zhwUMVZ87u`Dx{Z>O|9|`Q+&->FRy-Sjp7DHs zy69KwU-!MxeeuI@&cF4|M9z%AfP?@5 z`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u00v@9M??Vs0RI60puMM)00009a7bBm z000XU000XU0RWnu7ytkO2XskIMF-#p3Ksx009(E7>1ws z474m@U<*aVs)VXgP(n4BC;}!R!38D)5wK|@VWTF7pU`$X1(T9!A|_}TlAuuugoTX; zLm@K0RI&6A1 z<$`MpWjt!mNx#Sn&o8zmm%jmJ8)l$ae;lKP4P&|YTa?Jy8Wfxoiy zaGahv-VSRovnz7~F~1W}d@O3C%a;hk=jh4kiWBoYD^vq|t)Q!p`M@P5nT}^Y=2w80 z=5Ms$kvof{#}eEl#{6sw=G&R9M`kv;jUCJ(ZKozkgFBdh0NW8F7+)ZJ6Jt)HueMLm zMG7F(HtjE}^jN2!tw0yDo~%rTm-SSph@CqG+#}okE41!q?L-g2I=F+=7GR`8&X3@< z#X7hXc@d8j+QkfNtp})!Fzs*iK%+>F#)Wn~AkoW{G)Z9li4NCK+-WPJ470C?c`+W|(V1l(B#%*?)Qz}W`1*+t|IS|=CB zX_`tLv)_=GMVCKzQLU=W4Vrc_gBn&Ldl%6#7Po0$;C2Q9T+bWpQWIE{5_W>LJ2$;C9=`NpL6C%2PNtW29^!U*;9DC3y1Pr(7S{y2=A^ zR|>+)1h%W3LH27I-9#bnRN!7H#x2rS01)F=^mIB&oV4{;r3xnt1H@Dhq#_28%IX~m zfM}%V$tU58ME(o}oEHN;)GA9bh}04(0I9_i4DwK`PyhrpQfp@>0^uffeyW|tSUko> zj4M3QO6$r@Kuhu?s3jUMq?U|6ur5+O&`OLe0o#k2YG(_9D0~7nY(;^{8<%;c6{F4v zruR3X=JHNJ%^5uby3AW;y#UqYP{jscggXk0tp! a_xpeQxsVPfYa7l000008sQ!Q diff --git a/app/src/main/res/drawable-hdpi/burger.png b/app/src/main/res/drawable-hdpi/burger.png deleted file mode 100644 index e02367e0603172828fcc9282d86ce9de5173a022..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 446 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9E$svykh8Km+7D5#L^ z5#-CjkXy>YP`rSF;m=(LhUOFohJqIi3~w?R7!2$f7z8Ffc{B4B0|TRrr;B4q#jQ7Y z9rF%32)G2E*Wm6uyK!@|*%}7T2Hujb_w5~ou1?Oi5jqudz4YSuS!xUn4h#$&K%EQ< z3=Av`4M4LP7?>~wFMO-B`^)YBeCZc)p}O;@3s`rsavpG$3f-q{cI@ri^7Z@Q&b8lt zR5SiFb)_?TkC!W+>3giMcxK(>*@di0Zd6m zK~z}7?U*rc!Y~wuzgkEjW$4JvQn6&u$So?i9Dy5Hz5z$*#x)qTvs7Kum9ax4Sga0l zz(^&y4kWJXe@kRPfBN5Zl=mQTJzYFW{S0J43M4moE1{fDky<+P6hMIzU(E|)1$hBh z1~3`Ounbrk77MU;ZW&N!mxk%&U>0EcWj0_MAYf_(CIJE_03(NmdteKcC~@>U>ZjW- z^&D6L)3&W62e>zsINaSICEk(x6Uf^j#f>oAhrpd74<zVK-Ah=C4 prxsShe*kMkUJdBl+OYf$eFH;mP#XofiGlzC002ovPDHLkV1mESupj^c diff --git a/app/src/main/res/drawable-hdpi/caret_right.png b/app/src/main/res/drawable-hdpi/caret_right.png deleted file mode 100644 index 7ff8abd7df20d1c28caf10f1064f7010e39e98fb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 374 zcmV-+0g3*JP)Px$FiAu~R45f=T(W9I`2T-@7c($0umUkzfRT~$1QR3Uzu!RJWE%pt`9C9wv3SMW znLsKHDo7H=$jI=HnT^Sq38YJyk24SGywfC^08#vpfr%+5GBEG~*dQ-2ub*s;tRajH zjBiLWjERw{DJC>qg=l}rhXaE2(J^%m^kmT%{ z>Hq)%Q%OWYRCwCF*2^kIaTLe#FDA$R9wH)MgGAyv3_Zl}5e&`D%nXbSM3R!+Ng@&P z2yU~V$zPqccJ1TrW3Wd1zt^Y#ZLL4H`Og5ks>n<%*ZmuaTtePNUaC2W+=#q|>=a8i z1Cg7Mx681fSS%bwZbse>uvg@XLP6vf|d=@kqb5cush_zytQ;ANU(}r{|oCuz6i$NA`etjycdwaf<$Y`4GHT-z6!?NAou^JTg)SW z1_{@Zhmfy>Z`a6u)wHL%3^bbkRho6x{cslfBLK?dGVLctfFRExzh_|Q>7-I52=a7* zo+5YU?f8FrVoV{wCG0p|cxnlPJei6@d!=uhtoR-PY%Ew{Ozu|v00000NkvXXu0mjf DVsFJk diff --git a/app/src/main/res/drawable-hdpi/chevron.png b/app/src/main/res/drawable-hdpi/chevron.png deleted file mode 100644 index bf9e25faf38bd0088536b491dda67f8c5ad5e0f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^0zfRq!3HGvW!zy0Qk(@Ik;M!QVyYm_=ozH)0Vt@D z>=ES4z>r(Yz)-w^f#J_x28QMo28Mzc3=D5F7#IxffCf!?@@D2MpxV`*E{-7;x7J*Z zNd n->~ml?uoxC?~bbP0l+XkKO&V-j diff --git a/app/src/main/res/drawable-hdpi/clickable_layout.xml b/app/src/main/res/drawable-hdpi/clickable_layout.xml deleted file mode 100644 index 5686d899..00000000 --- a/app/src/main/res/drawable-hdpi/clickable_layout.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable-hdpi/cross_icon.png b/app/src/main/res/drawable-hdpi/cross_icon.png deleted file mode 100644 index e6c71ebb23d015c5809182d5129fd3dead13a054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 679 zcmV;Y0$BZtP)Px%VM#S=`aR?!T*y&&3Utk~b zIuVQky&_j6rQ{mZU7-jUIqbAi3lmV`dAj3#o7;Q4d+~`rbMScc^P71yJ3Gfz@LS#3 zI8I-)%Rh-P8Y?Hrm}Ab|+Ffh-(;<@Abfoffaen^u?_hX8#iMq6>hOTBTWhbVeqWow zPmD2J-zRDPR=vIx$Q?Q6yz+GI5|i8(qDpF9#4AuH#1EHlEW8Tsq5zLuYjZ}ZAtI4H zbSR>kSu9iQW@BN~+Zj(F^D^MTL1MrFmdAAgP;*z7f6Uy2`5?doCU_SB4gK4ihoC79 zEMP*;IEwa5b|3VZA@ds++SJls6QT2=o|*dk!Oyi@b1X6w>V~wKqm_FG=UfG2;4lI> zPQ}dGGt2t1y`iJNOb;^XV3W%uih*q~M3FdPka@S;ovc=?gA3#V1om&ik6z2gn?9{Swr_ zi4qllg<>1riaA(J;V6a;MOpCpo5u#%>nKeqsyX95cmQk+-j}|Vb%w_GJT)}UHU!<-v8ro%P$QrQuToMirWAH N002ovPDHLkV1lq;Kb`;p diff --git a/app/src/main/res/drawable-hdpi/faq_question_white.png b/app/src/main/res/drawable-hdpi/faq_question_white.png deleted file mode 100644 index ba02325ed6b01a546659219e7d84d17f53208142..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 618 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 FV1nT#-y{G4 diff --git a/app/src/main/res/drawable-hdpi/flash_off.png b/app/src/main/res/drawable-hdpi/flash_off.png deleted file mode 100644 index 7c968d99f7ec95423376b0469343e8582f4cc985..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1249 zcmV<71Rnc|P)(_`g8%^ZB>(_~(EtE#UjP8;Yybc}ivR!{ScB&W zcmMzdXGugsRCwCdn>}b#Q5c5bTiar4(O8SEM8#q&qOGDrM5VSB+Gtza{D_b^2t_&= zu?T{L;vhPRT?7^BPzqu*2$Dg;Iw~$%9CQ%cO)7Q?#lZ|&9O5-;?$7zoxhFU0yi;=S z9}oAOyx)2G0_d+HLwkf_9M&760q1c5FtkRvfF3|+h(?T|tMt*(79on=<`+X#gcw5Q zuR20BBY}>}0sSCa5J&sQAwxTa1a?#p>IKn?1h!j;b%F@uB3kVZ82TgV1JRBcwm2Qs z1EK>_1e_1+0I>^`*z9(K`Vb*ZqS^fv)gihtiYC@cYD4VDC^oTAQyJm_A`}FbA$l=H zLr@pu2nNwWJy}hNV;JB$T}6nKIK_8?dJv}(=DkEUh_g7(f00@cLpUmOnMx2NI3#wV zDiHs&Je?sL5h-PP`a(2f9Q(Z7z)%38BFobgq8XEwS)Ps%n-RxO@3*NZgiV&G8$>H& z)+|p^h(+7c)K(<0jdg8j;8%fWGIdZYh)ZmQ{?M%`)hYc)Xmif;DiLPV3ro~rX}=M6 zBIXu^l{6h5iGI(0%PaXNQXPm>5XO?g(>|jI$z`&cOYtj&1;WndK|L{6QdOd7Xhr>0k%|mUEw0m4iqf z#4rn?KXh%Xr40azh1o3M{e6H)_2L}sSFk@clWzL=tMz$_zNG!Cod{Xpba*6cBCM}o zndRS-)K(|ZPjdxRue1CQsVxK{%PYBpsUKh8uBZh;$nr|AV5(SnkrjDR?I4&zSlJa! zefdbOmi&Pj#$l=}nEI1{_+B(?sD+qWUfC7OdX*6mOl0eSQya|{Os%bmEa}?#L`74Z zqxtp4lTDU#{9Wc})q0>q8Ilp0S>8rha8_=KzCsMC2r*U=cISLJLb=tu3{NR855m&a z#&QKG6$@`Ni(l)pCYV`XXW(vfPag&0$uqt}Towc~%d@(Iz5e8%&+{V4fpBPQbJxv* z!D#i^`s(dxyk)o?pCDy<)#`0KV_D#9EBEF_5WGVKDM6T3H!M!EoV!&g$98RMbDK&V z3qNlN-XKU>p4}p^o=SYKAQOTVgxTqC)l~9|APzxjYICZbD&3-3SeO?t{JcSsvON2# z6i<3HHdzpaEYC^TBju^IzWR7xY$xX(g51<*)p&O~6c9Bw84!dl&v`0cPL@-R2N_ui zyby#e&uuE18&Yqs;0=PasjYfTYEC7d?T%~+LYC*It4Ud|AP&LZmsh=`3x(_`g8%^ZB>(_~(EtE#UjP8;Yybc}ivR!{ScB&W zcmMzddr3q=RCwCdn@wmFK@`XTtFbj&YOT^JQ8BTWVy&WLL_urC8b8~7_>q7I5d|^o zNjwO8Q1Bq0v^^0fTlFU32X&ahVbDOLe)PtWf5Z7pnuU6MTjG4 zd{q&m4M_xQ52y#R0tu{Ld`MFcA&E8h2i1b;KoYAP532;xg|p}|JE5tMpbo@Z#Ie%q zq#6(b#Nf9+tpdb)jA6Om0Qn(;7(<)=5ZNI@IEiJfL2^TE!AUG-50e?94^aw&%n;i# zOhb?tVh0Xm33afX5W6tMGh9Z9eb~=;fqW1L5aGQLN^jtUS2K2t4#EXq!3yU z;$Vi!v&hxhx8j#sDZ@z%AVER6kp`|5==rjl2uv>z06xcthk)n#-(_i**m>ho8!^f@ z!iwp=5ny^MJi$}BG;0<@IL)$P!v0T}L%jfSH_umoH3xy<<%RvwVCPN@zE&dR^z#w#a4tA(bU8SYNm(TOD62&>mn_qm1_e0u6=Rs_L0giTYMonAI%itojUaK?59VcXPZ z7fOo@KW7NeYNs9~MG(UN`cN9rIYDqT6C@+dOdsk(i7&Ca2|;LTv#OkGvqhzRCrhu9 z++AWxUY>akV$&Ckik6;x}1TRk} znL!Y|JlP>uAm&D2UMnF?f1s)sgpijf7ep5l=mb=T5cKk7f)MobWP)J)Kve|@VJ}Y} f2w^Wz9{n2tNG|oRY_0K z^ae-;C6r`d-#Bq<8z=VI>9>Fx+cWd!{l7ub#7@0AcTfElA&hwmU?R~hAkNw^iLObA zHWIW+_AdHpobQ(kZO{Zp{cy8>SrjPV@X!Pe5MqmDzqVIeJc+s{l+;%JtBII8CV)9e z06wVQCs~O?ZY-&ds=s@tTv}wZf`1-#%(8J1kCI!%lGfD6`~OrEpJd z8;U6*Dd~&nK%$kfH5^WIPwzTq|ML+k04x-&ClIpeK*(;UUF5D?&o@^Aey0Wfd;>ZwzrkB-{30Ji3Uur1rrsO?t5X>Dz&ljPoXG0RDFb{IW@LOlU<~AdKbrN6nvr zDOCU#rxe9~XAEpq+@sfn#)4}f942j&(j#4i3Bwf7mjf`_4W-9m6P`XC{zkJQK7 z8D57FH=+FrZF^vqpgvA_y7@>prcbG+y5dRqR-xH*v)(Lnjx8rur;@z#@PR{3hQ_5? zv&e~ZJx1cSRB-lt*i=Y4upNOrAQaqiB1=z|)9&j&3rd9h(r# S_$Yk<0000Px%uSrBfR7efAR?TZuK@k7#%d3q|YpYfpLQz2w4}y3QL=m)zN(%-FC_+7W@GAHh zi2sM+!HOuPB`LKEdJ)BsgCKbDQt)77Y*cLX^^&GZMfHt7mx^_a9E* zfQy+;gEI&RM79dU1KK=+ik!iL7N;KFZl^9GT+}B~4*1R+&f2Fxiaf|IU6&n=9OO5# zd7mFN3_RA?ha-m%A-;PUmSv&v<0syK_=x4@l^}R^T?!MpF4j{KpH11arKbnu=f=<< zi@|XmfYK(~+lwmAXXl@xUato_;p~EqeHQ1r37jqW?ip3!ONH-9XXi1UeT-ie`POI@ z@sVAD;4D;_gl#j4j9Rp@n9F1C>2p-84jBpT+bCLI#_KV8pQcCr!anYOmU!tI`ff;CNmZ{ z3$Ev#3@XHfa;1WmVhJ?^d%YNp$=IqEakHS>ahdYZ*aJ8vXJ(&xG0bx+c8tjiDos@< zqGmyB*KF1Gj?0Zlcef@FxPBAsZvLecmoaoN;EPx#5OfpNMG3769j_%=RHWLWv&)co`4TVhSdGpf7|sLeSGp9dmV@ z^X>71*yx_l*J8~FNz#hCYk9`Z!HQxV-Mm^|I%JO@4z{j%0f+|# zT8^cZ=F4$t7|$@6GznS~iTnf7kXRKq^tLgFwybe=8kYa9M>7VQX4{P%#Sqt#<`JTx wW~-7wGj8^buLk!S@%$o5lH&I#$r&-d0jdB|82kAGC;$Ke07*qoM6N<$f@({Aj{pDw diff --git a/app/src/main/res/drawable-hdpi/ic_stat_name.png b/app/src/main/res/drawable-hdpi/ic_stat_name.png deleted file mode 100644 index c0e6667e46d54651b341eeaeeb84f20fcc905285..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 549 zcmV+=0^0qFP)_ z-oQ`CTe$NRksI%DlJnAnhCcX23;BtD)We+X2@2cAybIgh!7%5$KtTmOr$(C$@eD3d z(9Io|S>hR7pkR(WEVIcoxIn=gcUWeDXK;anMeeXn56|EN1q0k+5&fd9IE? z3;4|uEalvkh&hrz&?0{E2xFZ2FKFtJ-{YxYT);SIWel2I;T0{KDSC|2-fOrI$6$yv zvPR5BJ`NAX9NgaEs}q`zSr}A#Ofc;bq+s|49;QBkEv^v+00000NkvXXu0mjf0cP?d diff --git a/app/src/main/res/drawable-hdpi/ic_wallet_locked.png b/app/src/main/res/drawable-hdpi/ic_wallet_locked.png deleted file mode 100644 index afae10faddd79a85b5e6c1358269eaf8452dd5bd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2131 zcmd^>`9Bkk1IMw$%$3_bu8o#s_&VyDLeUUO&JaV62OAykVy;+zvf7PwX8t>xs#=$7F9BJk*X04&%D#*n!3(9vKPiS zS^f`q)U?zeX&+pytE&CXy}g;c?j+(Qe=Xcw);E+?Fw630R=~-FLRS({pFYWb_z`IN zibu1sOefuyzGVr~Dh0O$D5DMX_(8uXDc_L;qQNJw@SYeDH1H&|lCy(_E2~WmLAygf(vN6^+CBmk^ z=>4Y>C32E-UAaB}ki&|M_z$0ZJ!+J`?^w?u^|&t&XrAnivXy@Mm$K{EyOx%x7hE9Q z?*bCvBvFb!RQmNNDIOoRu-OqXF^0KioWWcbzG$FD=cEK$Z&N z5jcC@K69-{liH{I1I;p&2Wkc}r8@AEX=1PB&5$;r zCIC+R(995@Lb7xuBD&=(y(M0(&fP;Z=vuNAqGoJuxIWtO#J#OO{RDut<);bY4ZuP? zwN*cT#d}GFnB+SnL)iQmLQ77Dpj+=_pp1V|ibo$wej#vT`+O{EXdr_VI6q$zb7bLm z(9|{dlKiic7GO<1yXJowlHg%EbG z%|hvb8)r`=WpqkdFlurcJ1;Xxvv=QRp1aevDm7&F*iR7#NYAhFff9~z7M+nGL0 z-Ii4`?P0R&AGFFh9pmoCnqo*R_7O)1*(*aknpX*xdOy`?5ycN*evibbTW|4i6gaoI zG=JmEACK?3S6J%*jU~LWJ0fe6^sy5=jEl>|trH`q_o{^>o+YvRKjCL(OcTG&Bc`I? z&SC{A$*b`;UE53GV9AX|{KXvuIg5z#lNS>dj3-I`GS4&q{SR`Hg4HHI>lC@#(>|C= zDYsp$8&w~|rg!D>1sS!xAVq^vY^6?gIc^bA+*(%a{re`M@(*t-I+R;q2$|ass+~Dg z_&(^Uaf(Nvc?igjmY$T)C?>1auKdV(;QwP;HPS@M*mZgvbeO*N#$^0F@>~&PNg5Z% zZwf4W>P9n&%Ct#E$H7+yrb;YB^p1dD&7jb`gWC_(kqzBU6Uj1%A1v{T_u`jiZ+vX&LZ9Qb-nZX zX~Oh(H{F=h+L)Xz+b+8^YrngzDOM0G&EB~}LP4v3-#Z_u)S+oz9WZ=tg_j-jqwm)B zX3iH5+D^LFqAXE^k`}=MKZ-TG{b%+i=A4K9vWSZ9d48j)$JDIelAUz-IrSH0Y(l*< zYt=1HkZ^6tWyGP1iM|g~&5;^F#eyRA2r4#rqW^K95WrO({wL^WmF+;I_NIocN~Bd_KnwNsg0-KX+_5DoYfM2VkcG&-Ud>0{!WrovnlKjX<@+zaMYYw%oU8JU zCi}zB>eQBY+nrm2L@MC(?AFeVc2?ibi+oZefh<;hl>3An8D`j+g=m}#Ko(a+4XSbF z|3Bh$)%hPum%q>mM@2^tvv>#76!0nDCHBr+Dg_u?YvM*6uDEPpp3cyiL4ANGZX6p4 zBvs@cJTAT0{wusV0u~PMs5#ZL(Dz@D)0?)adwm>xxMsF6vu2lZU!5LmR>w`~2DlfV5;v|) lN+svWhRP!1=IMSrI!_wHpa#k$r~Q{8=Hlp%X>kb6`5zn^<`n<{ diff --git a/app/src/main/res/drawable-hdpi/icon_delete_cirlce_grey.png b/app/src/main/res/drawable-hdpi/icon_delete_cirlce_grey.png deleted file mode 100644 index e6c71ebb23d015c5809182d5129fd3dead13a054..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 679 zcmV;Y0$BZtP)Px%VM#S=`aR?!T*y&&3Utk~b zIuVQky&_j6rQ{mZU7-jUIqbAi3lmV`dAj3#o7;Q4d+~`rbMScc^P71yJ3Gfz@LS#3 zI8I-)%Rh-P8Y?Hrm}Ab|+Ffh-(;<@Abfoffaen^u?_hX8#iMq6>hOTBTWhbVeqWow zPmD2J-zRDPR=vIx$Q?Q6yz+GI5|i8(qDpF9#4AuH#1EHlEW8Tsq5zLuYjZ}ZAtI4H zbSR>kSu9iQW@BN~+Zj(F^D^MTL1MrFmdAAgP;*z7f6Uy2`5?doCU_SB4gK4ihoC79 zEMP*;IEwa5b|3VZA@ds++SJls6QT2=o|*dk!Oyi@b1X6w>V~wKqm_FG=UfG2;4lI> zPQ}dGGt2t1y`iJNOb;^XV3W%uih*q~M3FdPka@S;ovc=?gA3#V1om&ik6z2gn?9{Swr_ zi4qllg<>1riaA(J;V6a;MOpCpo5u#%>nKeqsyX95cmQk+-j}|Vb%w_GJT)}UHU!<-v8ro%P$QrQuToMirWAH N002ovPDHLkV1lq;Kb`;p diff --git a/app/src/main/res/drawable-hdpi/locker.png b/app/src/main/res/drawable-hdpi/locker.png deleted file mode 100644 index e167884aae2d9dc0b4204de049e6d6412cc0b316..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3245 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 T=Ldd1O$5->G1RWqv=93aJ534c diff --git a/app/src/main/res/drawable-hdpi/navigationback.png b/app/src/main/res/drawable-hdpi/navigationback.png deleted file mode 100644 index 52153aed71232fc4f384415d9ced142682e575ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 753 zcmeAS@N?(olHy`uVBq!ia0vp^2_VeD1|%QND7OGooCO|{#S9GG!XV7ZFl&wkP*5S+ zBgmJ5A-9x)p?CoU!=Jkh49zJF3Li#cRXS`*dX1NEg=4f zrH+}qSJ1G`%*jEZuv)CRRpEQs!@l=?&r3eX8Q;18`~FQipT(=R-u%D%RER^Nfs<%- zcJDhYyOqagTE>TnH`FcQtXbzar=iS@YYu}Mv+x0IMLK5V?Qy{Pnl)3gh}?9{jY2!2?xu{-`d zXN1(cKe?UackV9DvsU#vQ1zfP>ErT-wTz66pT0={m}X(l{AY>tD(wT>3H~#h>Tk2` zVfe*z;`a0pndM521^h2W74qYm4=rXn#GJ5`q4GDY3{Q9s&qK)#K@EHUGVn2OSAK5R z=J`TcA^$$}p|dA;{@dXDm1DyHw=WYPL?sE$n_|Yf^q*3h$POvXeT)@6YlIa3tH`kH zxu09heLHYHL*?p>yA7p=jUTqOyj>xj=Pk*0&b@Cv?|RPFtS9b!K8ShpW7d)Dl1wQt zL<-D`{!C_go6TZj`}(7ILjK(O1?F?F-=BS(J>zefP4IK|+aLZj-)UkoU?d)Oy+6-j Y`!#mWv?L27U~*;fboFyt=akR{0NJ=KEC2ui diff --git a/app/src/main/res/drawable-hdpi/no_eye.png b/app/src/main/res/drawable-hdpi/no_eye.png deleted file mode 100644 index 45020ef0c066029afc6ef5945679317c4ddd4a20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6090 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 QUjP6A07*qoM6N<$f;B$if&c&j diff --git a/app/src/main/res/drawable-hdpi/no_key.png b/app/src/main/res/drawable-hdpi/no_key.png deleted file mode 100644 index 42f2fdac5b6bce2e8db4d2b750a2bcd3a3746107..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2395 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 D6Y^nI diff --git a/app/src/main/res/drawable-mdpi/faq_question_white.png b/app/src/main/res/drawable-mdpi/faq_question_white.png deleted file mode 100644 index 305b7c8e764e10ee8f653baada2facb87ba1b360..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 386 zcmV-|0e$|7P)Px$JV``BR5%fxlRZiUK^TU21-o1z)mmt^AhGZoUce*RY8&tXlEzZ7@(vQvF60F1 ztkT)25Ckj7=SgP&W*0;U9_IVr?`LOrX0j|9A%qfUu!2oQTdhpev%N|nxDU7Z3wVcf z7)P|#7Ur0X-HcfL#4JS<=~~8Oj(JTJ9J?y!-IBg%PRw<+S%%}DKcMqv{7ZO+H@I%M z!Y{y@(gyyVX_9b?=D2{Xtrfy?k~2l0*}y+MNrEG^12yIoa2zE$6SS2H9@VHFtZei# zyuf{>RkJm)`K`enNlU1YJ8fWK4Tn`AnV0xCd7ghKx~?^A8_eMhhQ=r2*H8e>nz>sT zJVuL%J;H-_d!QAtJ4ORIgBJPx)5=lfsR9FeMm~Cj)RT#kUwHIxhXnm@xZe)zpbi!XC{q1_KFVFtnNFuiDQ8YdAPYNT7&@Q@ z8lfI)0@l@O(??(XWT%}8K{Bud`k@)-PBy5%p^tryk(q4Ym>(URU;B2fAv$cZTgb8Pp=z)tTv@=sPW{6!m8Jye>S7Oph;Cm@} zK%as~VMV31v73xzl;0){8SqRbZU?q4aEAj?u7qwF0l$uS;bRzuPayGY!R9u3W=an* zN>6rM(rmEZ2`8Wq?uDb!40B)^tOt`@1kb>2NwLC2{0Mf$d{AV;&#dg%f&M&jwKl*l zFaQm36&!?N_yUf@A@I_3)t1ARvB5$EeHA$7#LCfdX`9P+P>1ae_yA1E&bPuE_!XXj zGhhLvVI#P5Cj1C|ULme4x-)O5QVq_i>}7?1KAeOV@H)H+wcs8<2sgqHFb;=dEj$qF z=Tn;0#H&mM;CnFkd+>NH zXh8#8hkgcs2U-eju_`tL-WMsU*TX4T3h#qSErDKei++Ra!30e3EqE^KUtD5qfwyO2 zSO(t~JJ`mdp2A<)k8B6oM7bLl!5Y{M+u&2U8qNZLfww?A%!8AVB#vF@V9vw=O9Z_a zRDN3`BkewT3|<9S(=&1mJgocRmB`nUwugIVp{}rw%@yv|aRh1#jZq!_c6b?XfOX)l zs4NB(Qui8cgL}Y)=D~hg4Sqr2Kst(9Tw?P)jhu-g2T6|J0e)T^U>wedgK!+a1GmE! zcpmPD?a&BrM=yK`ck@7Uj3jaFoM&VJY7@M?f`5cd;4s)eMBp*-s&^$XhtJ?9*a!ZG znEXRvqF*!PYble&u?I|~A3TsTq4OLR3*jeN0w$6#v3XZ)qP-M`K)DRM;Tq_H)zAeS z;U!2C$L=?gK5$ksVaBIXtfd^Lj8-HnZ${^U1{nlrH6H3F)CJSJTz9k7bfL_AV3Y1W)+fBv15i)9-K& z_%hemm5NFSKLH+6V_H||{bAB0P$FSWx3F^-vo`Qvc(}w91 zI5dF|+t}lowx6o@21r8&d?I?~*J@L!`|Fzx^@hB%=uhb57)?c{coTk4N6ueV$pPm)QH$pK!_31m#<86z^^>gko;`1VzZoMmpnoxIZ~sb;fWRYw9puM+Ac_HTPCC6#(YgBE z>qK=ru;a7A07h)e{|Rhmd88-@!UqaCg_gdc5p%PtWto$FGgYvNY1sT=NcfCwMF#0P6j~@ zMQ3iHg)n4Rv|&BMWg$u7t6C|dc199VVo8bw79gZ+S^d)+amHIC?g`CRQ>ZHj78J_5 z*x2xF{w{TCL5WTL$4ddt$j)hSGP&y`(P>!$yB$CS*!!pDS;o0P z{&@I&{GR~dLp;vS^pv5PMU{1bRPORB`~j7^0R;j1WZ(b*002ovPDHLkV1nUQJiq_| diff --git a/app/src/main/res/drawable-mdpi/ic_question_mark.png b/app/src/main/res/drawable-mdpi/ic_question_mark.png deleted file mode 100644 index ae31f068b5ba2f3af8731c61e16348d58367b73b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 487 zcmVPx$p-DtRR5%fpQ!z`!P!PVCR;`O|b+#=?skO8U4i18YL&3#Cq=GoQh)(_xCyR@t z2o_P$LFwQs2rk7~gBG!?I#_LKYm(>PYmz1*Qhg9|_kH)>%e{P$fomNepQUt7TL<7- zd?Fp1RRLI0^7-~xmltKbgqca9AosVqvcoywKuj`m*IQ?d?e(+7b}pA{6DJywxW$zV z;C$XC@J<=K8eoY9Y9e-`o&PMRmbj77V901@P5mxm?D*_tA`YqXI50^9<*@>#yD~}b zOZWNvGE(QjoZ^w;FicOSp(HX#Jhjc5)xJ8l0YALcP&|a40B9 zP1Br3BI8+VVEn2suc{iTY6AuX0hpVefy(m>e16rt1y;l(j=3$|2qx1L&}_Eg`sUV6 zSvfW!lX$P!w|6KjPu`?JS(O?Tf2&Y&ZtvMm1-g^$iK%Wv_V-vU3bE*@9kRzdX@wIH zj!t&b!kc!sSB#dWY}>IEI)mQ{KD>gju)I dD1iT7=O2sroM>8M*zW)U002ovPDHLkV1k`L+@t^i diff --git a/app/src/main/res/drawable-mdpi/ic_share_vertical_blue.png b/app/src/main/res/drawable-mdpi/ic_share_vertical_blue.png deleted file mode 100644 index 7221b92627e2fcc47055a0b18576678efee3acca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^JV4CP!3HERJk;|9QjEnx?oJHr&dIz4a;AB@IEHA5 zCZ{+s@7w(E_W%FizcYBunAmwUu~_P{V~T3e37H8=ZT0`J{Yy`|!E)`x{Db|CothG{ z!kgp_Zl^!HUnOvC0t1&pqVN&*V@xJ5tpJD<{ajo$FF9E%DHh_miL^Lr*5d`3uGg UHo<>-fi7h5boFyt=akR{08*J(H~;_u diff --git a/app/src/main/res/drawable-mdpi/ic_stat_name.png b/app/src/main/res/drawable-mdpi/ic_stat_name.png deleted file mode 100644 index 790700b52048b7d57666ab675c5bcc3c2c878d0b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 363 zcmV-x0hIoUP)0+gthi!XGANWETyB!axQK3tL@ST$x}nne3uiwfGOLHk(-#6@`61 zXJq}H2fW5(ENU(aiVpD0W_iR8cCn`C=0dPM zIdD6%kDsA3ojY97&Vc#P@FIt@a-+Rt7%bzHrXv{PhW5J!bxr2rRQuh6rlxYx(0;ez zP*ah(PgK=@w_p`NBpl0@_K#uE(qtq}?G7+})^r3X+8bbasp*XT;+pmb7_Q^D9LmB# zJ7*wtgg<)nAKtNtOWHRVf}7^=qBrxe?S4PS-BJ6vZE1H<8s@K%65c19;T88ZpBYLj zcwzo6rnqG#%|=1dd7^mAmFA+MtdS@lVjIhv%LRoyxU0_>gFn-}H~z20l}P{q002ov JPDHLkV1n_~q{;vQ diff --git a/app/src/main/res/drawable-mdpi/ic_wallet_locked.png b/app/src/main/res/drawable-mdpi/ic_wallet_locked.png deleted file mode 100644 index 27fdbdcc35dea87628820ff098d747d1a346596d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1340 zcmbu9eK^wz0LOpxvh!?~VIyphlhSZyJ33R*wlI{JC80(X=vlT4< z+e_U}m=1KieNEzuw+E7Vf=U4dQp^Vc&|39$C7(=&D8Vy1-r=ae1PzPpGT)G zTiYGZKUR&mPWdc)cla+wF>ion&Eq9=r!~F2^$j}U`dp|z6JbK&$bSQ!h~w(6xQ~fa z7yFp8Yf_iAbouF+t#itzHJ2}7iH+@(mgZ(%%enIohWTX6VdNnkDgCu~;q(fy%CQ2~4iElhhV6t^q*^HM}ejhM`@&8#&-PZ#);*4lvwd?>%{zPLTd z-8COQvI!U0DTcQ8M?dw52S!*L(kclJo}2Q`d-kP95ooV{CguHck+Y(@Y6Asq&WG#cRe`v?$AhJ| z!pg-|ey2{rxQDKsQZ{0)q~5<&nX7gt@9udnS}ZSXn=!@m^UlS%R^m4e&Ek1w{6$8AU%~Oc~R1HF(qApYs&D(WSI$ zxW)>x@8}}sCnCxS%O1}YmTrKfEy$z>M%d)Dxuv%f`X4V$>Km}C3MAe|Veni%_!eF8 z+UHZF`?n@px)qzVr|;;zvkJ6rV}XNcpSYT+Sk~f{k*aG&Y~LII>XSOl(oq46?CJow zh6V99huc=}EUe>t)8#u}ru0mo=GcPcpFFSds%{oKZB2+a}E;YV9X_Y2Wy&Su~meiR%|H1_%_0nEkFE(Nn z?v$TiEN6FpfA)-i9ZV=W6q`8gEFbLdbNt-CLwzYk+L=3PypMW+ZK%5SK<%BIONFnX z&;e$vmc;q4QxuTbTmDXmtKX~Mz(x49x~X&e_avdPGhZz_uobNi7|{wt8SZdIsSJV_ zPQHEsaAlCq=E``$K8w*3HQF$SU2V8x6QP|^0M9%{+#4j|q0dFeh2xD#h`FSE5&<6@ zVqs@Dt*FBkS7#gb8#XyWoHBHas{F4mo7bp#iYyGG1_n;Zj(QpNb-U>q5Y=D(WZj;} zBE7RkgfDs!mdYG2ocfQRhi`m347f*-%%%bmbj z|8dGp-Bk*3&5c2j)0r2VedSfOX}sW;ih9*G#UvV+x{ZdhGKx=B$Mh%f>Mr{U8&a}> z9W|X?wh0<-W?tK<9}&*3?QaF$)N>!|qL9%td0(n*)tRz)m??TXPl!DN5V`e6<&Tov Qx9QF8}}l diff --git a/app/src/main/res/drawable-mdpi/icon_delete_cirlce_grey.png b/app/src/main/res/drawable-mdpi/icon_delete_cirlce_grey.png deleted file mode 100644 index 4410d4b09c5ab5d92ecdbc266e67dd182c08e804..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 449 zcmV;y0Y3hTP)Px$dr3q=R5%f(lf6y?K@i7hmMds9YN654lh{LLV(tkL4fp|-^mbZW_z3n|`4xyk zp5S6)B|V1Tm}sE}8w%KU{(IhK?;0R(0y{H1zuDQDIi}RQ?R3^gL%l(y*O}B3jt%Kg zBGvP<>S@1JdUFwulpqMa*N^WCli4)J#P;YMJ2M+Y{Fqx_X!*WBvNrr#`2Fih?#e@- zyttoRSv*G&1!vqmJq*I+Lq@W~o5#cPX(Dar0U0w7*J#O`ehkrEtjlvU+02h2x^NaQXx+r@NNU_G=- z+LVZ)wLSz~-`nZpK;!~!2`5p&+9IY8X3@QHNNClC*1-qdZhu+v&hrEMc-8{?VC!f}l4DH|BDwuqQ*scAoU ro+!vDTLzu@TmSl)q9E93{hWURW4g`S4fG>!00000NkvXXu0mjfro+lx diff --git a/app/src/main/res/drawable-xhdpi/cameraguide_blue_small.png b/app/src/main/res/drawable-xhdpi/cameraguide_blue_small.png deleted file mode 100644 index 3b874e90359d911e638c3577bdc6a9a1fdb75464..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 447 zcmV;w0YLtVP)*@di0Zd6m zK~z}7?U*rc!Y~wuzgkEjW$4JvQn6&u$So?i9Dy5Hz5z$*#x)qTvs7Kum9ax4Sga0l zz(^&y4kWJXe@kRPfBN5Zl=mQTJzYFW{S0J43M4moE1{fDky<+P6hMIzU(E|)1$hBh z1~3`Ounbrk77MU;ZW&N!mxk%&U>0EcWj0_MAYf_(CIJE_03(NmdteKcC~@>U>ZjW- z^&D6L)3&W62e>zsINaSICEk(x6Uf^j#f>oAhrpd74<zVK-Ah=C4 prxsShe*kMkUJdBl+OYf$eFH;mP#XofiGlzC002ovPDHLkV1mESupj^c diff --git a/app/src/main/res/drawable-xhdpi/caret_right.png b/app/src/main/res/drawable-xhdpi/caret_right.png deleted file mode 100644 index e9b97d6c4fe289ea1a18cd0507244c919dc74443..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 491 zcmVPx$rAb6VR5%f>Q@<|+K@@&(mb(Pa2~i-?DJcB|SDoS#cGgagy-OrI5z%OB~cKCgpg2(_>nu~jo8iX-k$Sgr4%VI z|0M?rG2}BOup7+lF(MnM_kN=1bX@fWiX;S<8|pDbN59gGTuk{T5?^uSu=!g9RlqsF zrT<~mN#1k;5Z%fN*ET*^m%DK2vX91M~oXKGrt3OqAG1 hKXo}{n&&^M`~X-TTs1NA*pmPN002ovPDHLkV1hIs*4+RA diff --git a/app/src/main/res/drawable-xhdpi/faq_question_white.png b/app/src/main/res/drawable-xhdpi/faq_question_white.png deleted file mode 100644 index e72abc0f9c89ad77a41ff799ec5e85d69809be88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 832 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 diff --git a/app/src/main/res/drawable-xhdpi/ic_nav_buy.png b/app/src/main/res/drawable-xhdpi/ic_nav_buy.png deleted file mode 100644 index 02b7d071cfae0a6f2f53e2a85698a0057036b912..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1275 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 A7XSbN diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_name.png b/app/src/main/res/drawable-xhdpi/ic_stat_name.png deleted file mode 100644 index 07fed6c9b80f414dc44302f95024815f2a8b758c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 726 zcmV;{0xA88P)^)PFYd280BMQqgW7D7A6}DEUYFeQfw?FWg}mi z8YEfx$Y;ps-~Z`(W!^vMb*}Dv&sp4G{py`M&vXBG-h0nI_q-h)H8nMD0l*ZxhVG>M z=nlG?PS&wm!GOK=FnvjXpc(u71wBZoX>D>CY8idp6gkWzx`cMoi4D87XJzo<{q*(k zd{Mli_vovJ_W1-|iLy_|8q(Qx1N?fnYui50p;PG?%Hun|Oc!X5!mvpvT|qC=FYxPl zykF@9KW^zfr%N?cG%W6>2jC%7@r=&XZ2ts)$qeJqnIr}0X{Tmv2@AF$kMPDf+OHXd zz#l?SrAcZIY0e-VyczlY_kVFka|Yqy(^{PY_cdn_4!)t)8E{u~27x~jbK|1s48p@UJfiMm1v;$Y(~nrP-oj;Ysb3h!M>e1q-(#{fuPCAJlA7uy7{*APuX=-j}Cq zwkY5?^D${yHM=!eA=qFBeWG0}Vubc+roynva{6AHw-cMbPti%5<-dXN*Vs#TJFy$~ zCf$g#_l68MolDQ5ya(I`_*SGjL>JR;J#MMMZ*1EZJW6lVxAZgp2!8>O#rBhWwSQ&6 zPsFxgY!kq4blaiZhPZFXCWS@XGb!*BIwC>GW7oHRQ)g(O)+dF5X3=%<4cid=>3kI3 zq-r2t#I30%{z2WO-&yB1TYOC!O4*?!~g&Q07*qo IM6N<$g0sY6ZvX%Q diff --git a/app/src/main/res/drawable-xhdpi/ic_wallet_locked.png b/app/src/main/res/drawable-xhdpi/ic_wallet_locked.png deleted file mode 100644 index 03f5efc6f45768c3368d78b4bec510ed71b6f794..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3075 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 UgdpXkub#)o%FgnQg=gx20SDW_<^TWy diff --git a/app/src/main/res/drawable-xhdpi/icon_delete_cirlce_grey.png b/app/src/main/res/drawable-xhdpi/icon_delete_cirlce_grey.png deleted file mode 100644 index eb3ba8b5592d106b9b61669a2f4f0fa2407dab4d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 920 zcmV;J184k+P)Px&Qb|NXR9FecS3PJIK@gtZckdLN7y@dNDp;tEmX?yjLc~9WBS-|hkVdghE7&Ob zS4cXGpy5CiMJy~HmX=m37*c6O2<9~sFE6{!H~043ciz2wflIP*-0sY`^Udzg&dn(r zu(evPU}bgnh%xE}SsEon`$_8|nQly*G_8@M6|L>Z(UFlalarI3K}@SEP#niY3593L znv>Sry;XSVl~U`Z^oNj=H&GO|`^_nJV19nSxo`N;88V&IY#{7sq>nBk9lZPf>&M%f znVF3uT%iN9Y7@*_vJ*v z-1OAt`&KpXGRdDj46?wgJHP;oIeARam^s0%kzT7Z9G}~gORZO<3tu~=ANWq7582ez zr6rK0So^()FgE}vxV7Z=oH9RDN*`Zbd~w*xuQ8Ex!jVJf^nz9Ds2i8P!L8-PQikZt ztu;Z1%#9~GCqmu4hsP%e23TGp`&QBTqox*~J-@}!0~JtF7p>Nx2l4>qM0DW@6kAN$g0h%NC0}k8nABTTC1~5tB)+nQ@z{qd`-*cZF0hgGKn|SiK1K55UGvkvI zj%&C~P}Z^bvr967_|fhH(|1C!Jg3Z@lcRprC?MI}btf!-t1(I0tVEK@N4s;vC94#x z#)@sFQg8}4h70k_E7okD>N|mu+c~{*hAT@lvhA{RHOA??r|`(zR=V+iI=c8&t|6*d z1|)fqKZZeG>9I0$V4)LC1vx{LE+@w!Hz^jmdPRRn8gsbLJf|00SscIs=GtolR^u>5)$k`#n402-BU|r5_XL u#IF9DIVbRz-PnzvQ{M^nk=?fA_xvw5Ww_bT&(28z0000zC zHb_`sNdc^+B->Ug!Z$#{Ilm}X!Bo#g&p^qJOF==wrYI%ND#*nRsvXF)RmvzSDX`Ml zFE20GD>v55FG|-pw6wI;H!#vSGSUUA&@HaaD@m--%_~-h7y>iLCAB!YD6^m>Ge1uO zWNuz7iBo^o!>KW)`(^Qg~hHxH=E|3gPZK)NR zIJALeAlkrz0db=ZFhs3<^HVa@DqRvwQtgZk3@vmGEOm_yLJSS93@oh-jBNDL)F6Ba z*6m!Bnpl!w6q28xV;7KFk(!eW;wl*Hnd_NC^dhT3(hTy4m48uYDlmXS!Dwe_qmLnm zu0ANWI6tQpq&ze)v&0VQIA@(+Zh;`K6<)1hD2~)oq0M-Bv7EuSnb$~jvopiMOhp>zk7>_ z#&X+Dc;Hr`ydqGzXZwrWzD5Lue6_rL<$CCIx9>+> zn!o)18~wt)M0jtz+y&(uE8E;}zb-3yV|nG%>N2wp#&eyR3?iBDtY5e?TEG2B|ANMa1O4t9Dzw-un&c7Kd8x;E= z=67;!?0p)yxVHTIgyW4DET&9R2+zEKS#-%}WA>I~vzM^^Z2Oj_bBoKuRYsti>1%|J zV-sns;W+i=M*!^^7y)^5n1P zwfIy$zj);1jFin+AR`au;Tc`im5x=iZf@com77JopJltEWTAn zQ!IO}yN}EcT8)^fn|c{T=6ro$S{p?A**dGy0uTvDWJE*DuY8UbH{z z{vW5d+_P2!-$Yg|bq;E(_N-o>`t?zCQ#9MT-JZX4uDUM?OpRT5|964Z9R8`lo;>Wi zd2I9CQ?IHoKZsd%sokf7Eq?d4T`ki4&*!Bae*7Zi#H7<+mlcX%|FAP!I`wKnJLf;q zsTJWJ|Fpz^{`cX?I&gcD_?9*U8rlU)70qfBwV$6YmMlzuFJ2 z{6#`8Zur>pDE6`K+uyJL%`r58b+vJ4XPrant=$=?^bL&vvhBJly=d*PyDXq;!_(Ez JWt~$(69B+rs2TtO diff --git a/app/src/main/res/drawable-xxhdpi/caret_right.png b/app/src/main/res/drawable-xxhdpi/caret_right.png deleted file mode 100644 index 6ed5921c1481d52eedb304c651ba2c570af2ca1d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 708 zcmV;#0z3VQP)Px%en~_@R7efQSIuh^Q4pVbo0y>XP@xFD3xeSPkW*v@?d~S8X?6nzOA$pBv3T$x z6!a?f(u2oVh}7nypa^==OF;z>3JO96Q9%?xD1Ie<&V*($o41?Is+)ItZ{{~2Kj!7l zP7r7<)mLW#;UXv)V|f@00pEa7CxucFqF>bew0LkHdR^-|-0sqqZL;hWV!?Bq*9KyRUR{gj6xMgTDo4r#A3M3a z2(hv%?R&)fT*u&l?o^fIwTkoj&m8pR^=tWBqd`5&(xZQ`B{EmMNqaUJsi#7|!AO3Z zZuo^S|J%dET_gDux{#rSJk$JQWHL56ZRi{m>kvPPY`$cg<_}$rP(o~6EggC)0B3ZL z33Zz&u+O>laXu#KDIFd1dDg)LGiJ{H5y zHyNlx9j~#`ok!^Eo^|AqeQj%k2!ZwLM1+dP;)X)QrkD3s8R_U) q*Kh2>R&zgYgGW=AwI0L=k$(fqREf{ffcjqm0000Px)2}wjjRA>d&nonp{R}{uGTChngl7f|1MTBZqsL<6&abci>6igRxQwa#!xDg7? zCe&=Y=&mR(Erk}LxR6#?mLjg*)QHBCl>VV4AVMVCrqYJ=_l0|A&fJ;I-22{S)B_*q z{yFD6=T7ds@80`T>Fa{5tgQ4ya}*4Lec&xH2sQ)BW3T{b!F_N8{7|V>me9{eNO};A zf-B%JkSp?$uQ)W=-Uz`4zyw$X-4bz$b0BvVl~f1FH)4AVOoBH+EO%)59^3~m?p|4Z8~A72iDJd5xrU}qXN!~3H%_G zQ~L)SgN?wiHu_Wc?3a(nso20zC*`K)ytU9d22AuYt^1sBok_h_IRO7)kJWo!38Mkv zr_Lv?JGltQPVfb|0p`IYpkMB5a44C`8R9n%Oq65u8=J-nvp{Q2&RQz5uYgJLH)to9 z=*)Viu-6jn-xCvVe0_a%4g$ZoIoV*4P{IFGkSbp#P&SxAtQV(=a;HAwqvyBLWj1sCTD6Li3J=ln{&`t(VNVj z@@C*yH<_KY{#1>R_FX1dR{f~;1HYfo+L+<1rFQ{%*%2p2=Lg<^^3B+$Qyrh(jzc;3 zzl4)cQub6&v5oz;6H(Ov3iXd&+dpvp>FQSe%?d%k7S%gel^aPXr*|WpnW&yxy^5g*AQ{rbsxz#~v=zFk`PH_;_gTdGZB$RK>cC{OPfO?w zFgap9-O>EelaRR7 zf8g!1$;%&}hAE^~NH=CCrT)A|LJ++h1e0l&+n=pcQu`biG=N!0=sR6=c2VyaFAsdB zWZCC9t3bM|JQhd~lq5Ize<@tE3i`Gymo54n?`uvC0~5WbpKBpezat&i07`Ap!N2{X zUaT0!*DB+MqSd*sg~XT9pBLqlAO4-MRf6GI2r5a~yPudGaTW48;6)d$&;Lh0HwZo0@ztOPq-}?;`?7BH#4DfR z>vxwlt%_o`{~8mLOTOBGu+xWbZN+slHVxW+=-yAiK6KmV6vdj%Q diff --git a/app/src/main/res/drawable-xxhdpi/fingerprint_icon.png b/app/src/main/res/drawable-xxhdpi/fingerprint_icon.png deleted file mode 100644 index 5b234fe8007994ba2e9f3754e501d1b40ea22a4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5805 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 diff --git a/app/src/main/res/drawable-xxhdpi/ic_nav_buy.png b/app/src/main/res/drawable-xxhdpi/ic_nav_buy.png deleted file mode 100644 index 5bd7829e5e717131d2ac862990687ea889c24883..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1823 zcmV+)2jKXLP) zh!aHIKvltCAoWYX5fYND?$L~Tx`lrWyR05dn*a3s=zebo!66$@-b_!OoXj9nC7Z=h<;g{uR@OGB2bqo03qZ{EY_p7n}?7CRs~{Vu6{UM2T2>2X3D^*6R8ryVO_#g zo3qM_Kt6@(r6p8(b$%NxFtk8h`+tRq!4v9nvc6%V>hj~}zW zq-M&k$A(CL_(c1iBzcCIF0m8pv1FA13t?i5^ z#$To&;R!fKs^x=jY>X(iqtznDp7A*v577;9p2MNsgF`khKuO>d*g`pOK1V)R-62|m z;v~>RC|ADWPu*B)=Q*E92sS@Yo#VChQ?1kPE6~=juWtLwkf~0QZmd2&9zq_U3An-e zUB9uu0-?Yi@BnX;J^JBhMK_K%&8zpl)q1j@sa+6=^Bs>_a+EM0LQe2GUp+gyU^QI= zu}4ReMeu}_djGSve-!3^;Y4A*cNTRC6bP~GbB%R6IT>jO(PDVlp`u#vEE3({!Qbpr zM8+)%gj?W(o>|lu=-&RzqR-i53h!|;M>q>kz6ecU`EXin{n-{spjZZvn8LdN8G=L9 zf_CZiXTzr}lz;U>OHz0*G^-;n30r0+nm^oLp*}>WK_UkZx`&pTH3jl)UP$$)x-rh` z!2>NbYx$rMJYw2%$TNF3f;h`&CO82DzeEY+A^1Q=Gwvf0NaQAbYEYYFTJyU1`#-Zj zQx6O<6eRpsCrq1Tg?c>%k08N}@-Z^_#31aKdh}2fd@#N%TYeBoU|FWds z1M(!U$bu(G$`{6QlDvZ5em^m>o3-)42L1#BG`6Lb?=IZw_xh)Hn`Kwa4{rj=W*|Q) zmI&lKd+vtb1}LFQsr$^#l<&?j_IsWEN<$Q;AFnR-H8CzN*F9&?oe(M?)Cht|$Ohy^ zZv;{oWJPyuUZv%%plnovua1wa^@;JC%`Og81Tuwp-W($s9e5*8lr|SxoC?^4`xpsI zeMC>Xw<3hmA>tpg_d!F+*CwXgmy^+g32Owv0gGvQ0eGJ34IJ0yWJH zbK9jewYGRDEo(uwR_y${Yq1)fo$aceXg!C{R%2@m$;Mmt>n&ISF?){_&z=T|!>;%1 zJxGOHmA}Bit@;Cf@PJ+I!!q<;NF=w*Yd1@sFI`xL@hpn(IJSr}yjx_L4mm#OUU8TU z0I>(Zv>Nlh)MbjJTsDXdozL+?9Pcz!n8C^XV1a^i+}=7vQWCGRTs>HT;SU-+ zJ)3jYqca?|cRW5Zm-UG-!#~`F?@koBGitLb?m19PrnDy2i?xy}?*gbo+p>3|n!aYw zR$r0TnsYPrhN2gtEDO^jx7LY!`$t8ggaQYT=t|QZk(S(hOL$hPNDx{Ri)RXVq~s_{ zC(fI1;sPPjEXED&c!S%Jxzo1qV*=wZNW7Qyj=0H!C_0&%s=Dl1{2wewBVX#2!sP$} N002ovPDHLkV1iu%R5<_u diff --git a/app/src/main/res/drawable-xxhdpi/ic_question_mark.png b/app/src/main/res/drawable-xxhdpi/ic_question_mark.png deleted file mode 100644 index 6f30fc78308c9bf8f15e34d8011b9e02b9bc8119..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1478 zcmV;%1v&bOP)Px)fJsC_RA>d&T3u`uRTMsVcD75mly*VwA8n}=(-vDvgh&JeL`r<1p-s#h13nq` z)%f5u4?gkWyCxPhNJIq5QmB_C68!sw+Xe-R z8&YVeLsWGt8h!Jb*X~833XY#V8KLCVK}~808Q6Z3GMtw#A(CuVpCXhK6b_y^bl?CR zm_OxhKyPnvIG&vTR3rHrgVskl|88eV2$4`o99g?mmR#0XzUg4FqSG%C_=BwZO0i}lu|w8OJt+A+M4t_2PF z?uVW?(rK;xd5!vf0P!{g0j2A`cRKs$<3YQU>*2BQyAMxKr_U@lcwj=G=o=VvVVw63 zKu}8U+g!qn^-Kum{lo8e9dqi>(Ezv&tY?8$PC`r2HleD4Jx=a4#{f*&NjdfNQn*d7 zfx(<862Wb=C$?=4V5!7vv)sVLFkk{UV6+-)GXU#6KU}P((u%`vdFu>Dlize9d|^kE zQ-fYdKU`c)%}tvqQeH-7rKJ=I1Sl~!Mx*fr-5mUz9{>BF*?A!axKdd-*l2vQRYM8F z1FzuQHaAmC(<{Ui&QPo0*R72Zu9r8|(Vd~Y)IabG@gia4aa#dKU}gT#A)~(m1ZLX! zPj1bUKI>9Ff-{clnIIRQek7>w6THMH_f(t_ebdLPyM86 zn%?&7?^mgP?=Ibq45q4zmuUF@1EZSveFpP43N|BpJfF9Ui~w*0jFm18Trt6;eR_JD ze*5#9m4zpHxvidmMeGN56+0>3GUc}!vGk?}RJwfS53?nmPE+#P+>O@wxZRCHML|=h zpaO58QevcC&1?fRueuOLQ#`tulnYTLVjuB1FRfk)*p6L@t=)=M8gdQ3xi7u>7303{pQ01zPxOWDW6D; z(b@AC&APXOh^RRFklwU7N(X}~y|sG>S-~Tm`0?~PN~Ico9jngR|e9DcuYaX7&ICS!#Hq@;*m1>&g58Fi^d4ItJJ0@{K2TCS7hXNu{Rn5NK zcsx#V_I>|JA{G*Zek)d#Y*+!^6F!f87OxoONz7-JB;U?9dN09c5DyvjfrSUAuA1Tt@j6fv#S^Ne>=ADqNvO5*UHiXtI5Aj>oz`;(hFw#zU|7P^gIbXkOn^ zdevpfD~j^*p=j4vX5A>@j?4((2CQvf%7{9#ANG+3W-yv6O&3B7(mKeD_~lAwFFq82 zDU-Far=DyEWQ^z-MrMS|6F&6omx>8sntd`2<#P-`BhKMDsqi7n%YlH!DK`LYjt1ZX zG9t)~aB(T$#6+&_3~<_3AvDaU<(}kQ&;S^;qSLI#8(GnbZo>%NSL|O6tVW=`V*l(h g+Yr>3^6xhP184P24*UFTi2wiq07*qoM6N<$f)qHyaR2}S diff --git a/app/src/main/res/drawable-xxhdpi/ic_share_vertical_blue.png b/app/src/main/res/drawable-xxhdpi/ic_share_vertical_blue.png deleted file mode 100644 index 0a5730bcbc333582bac76c296b414c2e89a6d614..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 390 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 diff --git a/app/src/main/res/drawable-xxhdpi/icon_delete_cirlce_grey.png b/app/src/main/res/drawable-xxhdpi/icon_delete_cirlce_grey.png deleted file mode 100644 index a29ea487895130a1e54af486334e3fc6022d20c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1414 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 R6$k(T002ovPDHLkV1iWOj>rH2 diff --git a/app/src/main/res/drawable-xxxhdpi/fingerprint_icon.png b/app/src/main/res/drawable-xxxhdpi/fingerprint_icon.png deleted file mode 100644 index 92f16ee121a26c1fb4c1df3c378e4b1d3a4ca4be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8165 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 LNkvXXu0mjfOMT;y diff --git a/app/src/main/res/drawable-xxxhdpi/ic_nav_buy.png b/app/src/main/res/drawable-xxxhdpi/ic_nav_buy.png deleted file mode 100644 index 7e2fb0e472a69c57fea5f8b02e8301c69190495f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2364 zcmV-C3B&e@P)@~0drDELIAGL9O(c600d`2O+f$vv5yPJIK~#7F?VU|h zTSpLpyGPGK#C8=q0m=yis~Eddew@JEz<7mm7T{e9QwCzNvjZ;@Og4rS7@vSgrEHvR ztQ!R1fK;#%M0%a+(T|0GThjZP0e@A1C683n^t|q#?w)=KmNNhH{m8Y#@fZ<~sf;&D z1UW*;0nrHRA3z*A_X46LLOeo%Lje63;V>)}KOj>6ID0L>ac}$xECj(4c*4Ife45Ij zx*Y=e`h(>lLbP!5iYQ;Aa6beU{4zUn2o{j40C>``o_w4}mARuI`j9L^Na0S}!bn8` zi<^J=fZh@$Kk042-4cd7&t`7!Lc$~_fa+>jDlI_J0H`aTx2! z1@L(5&%0q*+HghPNQvueh)e)%WUrr{E)mf@TwoArji74qyQK z7C^AeJYF)0H(56O`A9|4Wlsw4K-}nT9nTfdnPj*~0A`14tDmpakgKyl1l@)$ zukZ1M_>cfRSJzKZmLy}l3SeRL&9u$o1q#D`$++UskPit$fb)_)LPr4@y^l&H$+Xa4 zRFuWSB-Bp>?5cOO2OR~Vb(y`Yr$Q(+z>r4zQ`-X%alO-!wgND!2Vfd3hJf;tfY{>Z zfuG(&qA8ODZ$n!F*sgjQy@?U&f9)ovni%4&V7vcoDS*oA&w=ewNmj*xa2ryD=dxYA zsHFg0Sp8D>(-=X*fy2gwf}oaK?G2g);L7Tkx}OR{A8bGyN?*LNw)2VX`2&2l84=i#&yOtgj9cg2-qJJjA0uWxz`G_wy=kzN{30wDzY;r8&r5Dx6H| zgs}C_h4w&?JVf@5EpkKaJeW112eY_!u%vy}dA^c~pRnAmuEGw6hoBA#tO&^U<-wFo z4`JDrNv}soA^!1*!Vf97jtfY~cs>pfZ};mqmXj|7cU(vX?(FDc2#1vH=MVIX-9OG| zH=^*>Ir*Yj61WJl0JxnaB*^OhiH>oYss|(OX6Q^YSqm^M_Tmk z)ph_VOnS#p_tJC6iiw-3&+yd*kU2fwhLn+(p1XCHp_zIcR}+9GYABEla-sCF9op-A zU2o&g2O+p(AVtKb=Z=&fwnD3)?fS>(1h6_g5sH+j^-yKE}}_K5UL6NwRp*6hL|j@7^2ZuK)AlaWQjhe;S@iTjxZQLlb7cirf` zx9TVW-m!(Cg%B@+HFca(uYSROXS$~2%a>1ldjo0ddE7*=`{{Wn)l)@O58<7hF305+ zg|-;r2v!`KggAn!g!oJ zW_zILABVEzQQg`$@{<{C7f|miFWl9@N2hdLY!H3lidc@u7?lLHjF?cpY3$H0M~0oa zp>sX1Uk$A5*~=;CM&con!(q+|LaQ56u+pz@-wTPJ&a+(*CgK}vBRjyM!Cpz_c%(U6 zq(IvTw57&}4-T%xscPDh>fu^8*4hvD^=_JtwGYWM@DbT4u;z4gRTv25qk`|E?q$mA zMZbSgqHy1)b~e@?FE_1a3WYHu8pCpD$5H)p`5<4e(&g)XVu%eV_q{N!7fkl<1BKd) iLCha#vw2(l2mKF@<0XIO!TR(70000!rHj^3wt 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 diff --git a/app/src/main/res/drawable-xxxhdpi/ic_question_mark.png b/app/src/main/res/drawable-xxxhdpi/ic_question_mark.png deleted file mode 100644 index cabef76cd7bbf44229f3f9acf62e797d86dc35e3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1965 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 V&#H4S!;Sy|002ovPDHLkV1l^KO>Y1I diff --git a/app/src/main/res/drawable-xxxhdpi/ic_wallet_locked.png b/app/src/main/res/drawable-xxxhdpi/ic_wallet_locked.png deleted file mode 100644 index b96e669e265b668faccf0590b5350b138c763116..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7620 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
~$3R6;tP<5IG|&;~88?NVPhLv{7yd>_;x1+g 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 JHE1{^{|5yv`Dg$D diff --git a/app/src/main/res/drawable-xxxhdpi/icon_delete_cirlce_grey.png b/app/src/main/res/drawable-xxxhdpi/icon_delete_cirlce_grey.png deleted file mode 100644 index 82a7553cf4460864d8f6b490ea1c93bef55bc1f4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1826 zcmV+-2i^FIP)Px*+(|@1RCod9ThD78RUCisZ4#51*jgxQ^&nz|G3&5VG{3k%&(JXn3TEae#{*>OK(sqb-izrgv8?W0d$zf>$fPOXm=q$Xf) zZmxHAbNifNg|kvxy;(FWN(bj+Q!xHxe{bR1(9qCklzdouVgjU;eA1j5q-2CK*%xLc zzcRkTxttj{Ms9M-B(al-0Mq>b$d3H)eJR-sNsMM)hjVtfi$D35VZ8n@uI|_bd~MF2 z;L`elUibdE#`2V>Zm}-8`0`z2`1d$=Vi9oV+vzj()W^v{A&!xKlr7WSFnRHv(Hpup zwFsd8F0Po<7ntPdbQL#Lj>~HojnOF@7p$muL=ph-ljhYADLoyfteMIQ{NlLr))!GE zM83)=PQCOt&Fil;6FAMb3@k1!^<14Ye+`otVTI`PE%Vy@0iiByWAH1h+zTWCqkUz- z3#s1xMZf?oK`r$q0P{SiI;s@eMS>JJ(ftCj0Fz&v>IlFJ&spR&*F5jnc-?zgvpAS! z-JoChgioG2jk&(4tGtEej{LH8`{B%#`Io!RHE#emHqP4KEpl-3zy^$NL^T9pSJ$|W zjk{TSo>1lXROBpO|H z0KQ9mjqq#&>43oiNa!^ zR*|>oJTnSL%u>jI-sNZ5q zw{9FcU?&17EG4Ha33%0%{U8C@sSAh|Wi-oF2RsJ6uz@jm5(vAXX)1F9biiY(TYj+m z34X{2k?)XDiserT(&fDm?6eN>-@|)_b^q&vS5uwNIsv|cJO)N!7YIeu1s5d;A0FIT zcxpkiev2GE5(c-R8#aP;$Gs2i0&#fs)RyB`_LCRn!1TJY+;V>4Rk;oc&|5n)wP zr!=NG*EiH3ddsRrsm| z;09uEiR#?;2FhroQkteW9E^J{s38FJEMjl>iVs$fqF-jb>y#P-0M`jTW_J%3bb7BT zo*3A?xatT%)HMQ+5qs+uZq@(5;$W(eD6b;`AQ5$qz+=kVgL$h0ue7@iEJ2avz678m zqOK8m+~VNz>Q9D6kOvX~;C9qC1s=C72?&~wh#U_kz$U?ox?XHG5)dqni1Da)SC_(J zf`}Mzt#Elk;qq^06E5#2rfol%aFfv1pUfyC+WMm@MFN7V8~xcF*7jK5?)ztRiUg!^ zS|I!s5twPW(r&$Bd2DI1t83_olimhiZr4v|y+q)DTYfz4M+ELQ`{(oj1HfFTn4}(| Q#Q*>R07*qoM6N<$f~O;Ne*gdg diff --git a/app/src/main/res/drawable/b_blue.xml b/app/src/main/res/drawable/b_blue.xml deleted file mode 100644 index 6b854449..00000000 --- a/app/src/main/res/drawable/b_blue.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/b_blue_pressed.xml b/app/src/main/res/drawable/b_blue_pressed.xml deleted file mode 100644 index 582953d6..00000000 --- a/app/src/main/res/drawable/b_blue_pressed.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/drawable/b_blue_stroke.xml b/app/src/main/res/drawable/b_blue_stroke.xml deleted file mode 100644 index 96a2f7b7..00000000 --- a/app/src/main/res/drawable/b_blue_stroke.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/b_blue_stroke_pressed.xml b/app/src/main/res/drawable/b_blue_stroke_pressed.xml deleted file mode 100644 index 97b17079..00000000 --- a/app/src/main/res/drawable/b_blue_stroke_pressed.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/b_gray_stroke.xml b/app/src/main/res/drawable/b_gray_stroke.xml deleted file mode 100644 index 4ee0be5f..00000000 --- a/app/src/main/res/drawable/b_gray_stroke.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/b_gray_stroke_pressed.xml b/app/src/main/res/drawable/b_gray_stroke_pressed.xml deleted file mode 100644 index 0f7a2162..00000000 --- a/app/src/main/res/drawable/b_gray_stroke_pressed.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - diff --git a/app/src/main/res/drawable/b_half_left_white.xml b/app/src/main/res/drawable/b_half_left_white.xml deleted file mode 100644 index 5d046b06..00000000 --- a/app/src/main/res/drawable/b_half_left_white.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/b_half_right_white.xml b/app/src/main/res/drawable/b_half_right_white.xml deleted file mode 100644 index 06b4495e..00000000 --- a/app/src/main/res/drawable/b_half_right_white.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/black_ltc_coin.png b/app/src/main/res/drawable/black_ltc_coin.png new file mode 100644 index 0000000000000000000000000000000000000000..adbbd5e95e966038200bfcbfa8ad3ed1cc8845a1 GIT binary patch literal 62089 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ΜK_@-4Zdz>V@!1$aq{&J`kH&oX~ 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 C^ieYa literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/border_shape.xml b/app/src/main/res/drawable/border_shape.xml deleted file mode 100644 index 7c20f501..00000000 --- a/app/src/main/res/drawable/border_shape.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/border_shape_pressed.xml b/app/src/main/res/drawable/border_shape_pressed.xml deleted file mode 100644 index 51a3cc46..00000000 --- a/app/src/main/res/drawable/border_shape_pressed.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bread_dialog_rounded.xml b/app/src/main/res/drawable/bread_dialog_rounded.xml deleted file mode 100644 index 79080eaa..00000000 --- a/app/src/main/res/drawable/bread_dialog_rounded.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bread_gradient.xml b/app/src/main/res/drawable/bread_gradient.xml deleted file mode 100644 index e15b14b2..00000000 --- a/app/src/main/res/drawable/bread_gradient.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_intro_left.xml b/app/src/main/res/drawable/button_intro_left.xml deleted file mode 100644 index 67972874..00000000 --- a/app/src/main/res/drawable/button_intro_left.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_intro_right.xml b/app/src/main/res/drawable/button_intro_right.xml deleted file mode 100644 index e3c1822c..00000000 --- a/app/src/main/res/drawable/button_intro_right.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_no_thanks_emails.xml b/app/src/main/res/drawable/button_no_thanks_emails.xml deleted file mode 100644 index 21621bbb..00000000 --- a/app/src/main/res/drawable/button_no_thanks_emails.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/buy_partner_shape.xml b/app/src/main/res/drawable/buy_partner_shape.xml deleted file mode 100644 index c01369ff..00000000 --- a/app/src/main/res/drawable/buy_partner_shape.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/bw_logo_white.png b/app/src/main/res/drawable/bw_logo_white.png deleted file mode 100644 index b03cb21863775bc93d381851bc32dfa306ba6326..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46985 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 diff --git a/app/src/main/res/drawable/cancel_24dp.xml b/app/src/main/res/drawable/cancel_24dp.xml new file mode 100644 index 00000000..96cd3594 --- /dev/null +++ b/app/src/main/res/drawable/cancel_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/check_circle_24dp.xml b/app/src/main/res/drawable/check_circle_24dp.xml new file mode 100644 index 00000000..9e5f2496 --- /dev/null +++ b/app/src/main/res/drawable/check_circle_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/circle_circle_24dp.xml b/app/src/main/res/drawable/circle_circle_24dp.xml new file mode 100644 index 00000000..3911bb9a --- /dev/null +++ b/app/src/main/res/drawable/circle_circle_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/circle_indicator.xml b/app/src/main/res/drawable/circle_indicator.xml deleted file mode 100644 index 0af7eb0b..00000000 --- a/app/src/main/res/drawable/circle_indicator.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/copy_button.xml b/app/src/main/res/drawable/copy_button.xml deleted file mode 100644 index 8fd229a1..00000000 --- a/app/src/main/res/drawable/copy_button.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/divider_white_shape.xml b/app/src/main/res/drawable/divider_white_shape.xml deleted file mode 100644 index db3e62ea..00000000 --- a/app/src/main/res/drawable/divider_white_shape.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/donate_slider_thumb.xml b/app/src/main/res/drawable/donate_slider_thumb.xml deleted file mode 100644 index aa3f0be8..00000000 --- a/app/src/main/res/drawable/donate_slider_thumb.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/edit.png b/app/src/main/res/drawable/edit.png deleted file mode 100644 index 23e85c6a74e2abcbc358a98e0aad2bce68de7911..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5845 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 diff --git a/app/src/main/res/drawable/fee_selector_bg_end.xml b/app/src/main/res/drawable/fee_selector_bg_end.xml deleted file mode 100644 index d9398eb6..00000000 --- a/app/src/main/res/drawable/fee_selector_bg_end.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/fee_selector_bg_middle.xml b/app/src/main/res/drawable/fee_selector_bg_middle.xml deleted file mode 100644 index 8db145f5..00000000 --- a/app/src/main/res/drawable/fee_selector_bg_middle.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/fee_selector_bg_start.xml b/app/src/main/res/drawable/fee_selector_bg_start.xml deleted file mode 100644 index f36197dc..00000000 --- a/app/src/main/res/drawable/fee_selector_bg_start.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/fiat_option_bg_selector.xml b/app/src/main/res/drawable/fiat_option_bg_selector.xml deleted file mode 100644 index c5696865..00000000 --- a/app/src/main/res/drawable/fiat_option_bg_selector.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/finger_gradient.xml b/app/src/main/res/drawable/finger_gradient.xml deleted file mode 100644 index 0c0655b3..00000000 --- a/app/src/main/res/drawable/finger_gradient.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/game_hub_bk.png b/app/src/main/res/drawable/game_hub_bk.png new file mode 100644 index 0000000000000000000000000000000000000000..73004f5a4341bc16b7ce8f1dfba9e13b440ea616 GIT binary patch literal 115055 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 z zUy92K-up^JUEWKpD=*K_weIP|h|;v-l;NVR+=k8|_ob79@OXbIM~WUHFn__tUMZ<$B+XlK(Kl0)iml z5y1e{NEZ_g-Z>9|$qH-4&n*qWtcbDX$2-a-%p=@>^B0Y^I&WK@}=VqEwUX}=c3##e4TCQs}mJO%7zG#404ECn_$lU z7J42U`;cImIl*?UHj08V$70Tmp3c=x4doxI_R>pP=>S^x<2q3PyW^aQi5ir)&sJAc z&n*-gsd8QyI4{-m>qoOw$RGE8E+6(yOSG{XwU57_^xO9xfW|v3-0f-I9g925`arBR4Q~ln|rEl|s&Zam)!q*Z- zzq`!lQQ`1-S8!y8iXPUei3KhbSbyV&5vA#f$aSABhDbIMjCP~;y(hZV@28DUNA_{9 z?!>VD``)^w=OoR>y>>Gk4jl<{R13a~O~@$VCR~9{H;X1`GBr=yiuuU&mrKD?*v-p( zyMSUSOXJJq3~=In2@zMZZAPV{>+3CmMZW9aj>~?_R#*kOJyE6;ozk?WKW3VJk*x3{G`w>WY=_7+#G&uk(q)6h+UVH0;f;s*`0 zw{2ICM}K_UlDyb*i|fPVr>pJqoKZbJKf?3nI$1_9zD_c<%u=bGK`Lk*hN&q<&&uMm z34%N)&w=7unreQY5~oI@{4))6fd@(z+UKDh>zmp#mz<-ozxgKl3Gma8Kb7xGyj(;H zdPnjYTvBaXI%FK`I5y%nmhpV#Z)LO#H_91=6$7Ye4AQQn;Qm_ik6(Wc-+udTzKG+8 zAFfN8FE3SqUZAWhUGiqTyi}WS0DKXAlkaD#N~SqWZEM}76a;M(8aQ?I`>>=8_eQsq z8s)SyfXIo13A`X<7#)gfv+;Iag?#t^UEUv?1~5Fgu|mJ;0t(j%A<$&0}ZPkeMK?3d084N9OP@| zV%vc@))beGi}#2c!%Y1-IYsGTdzV`UFO$5hGW#VB2Xl>bQKR4!V%zxLz1yZ7+bbv5wa-Mf4V+LxCH_;+{C41j!Mh%j3J~*keqdZrV@nwN+Gr5Z-4t+_}%Y*13&)wDX*$N z)kC5UjyoL+o1rrpeQwD8j;+Ue3vvDygWFxTH#otY@M;e@4)_yTA%?o0ERJcNP%5%M zJBfn}`#32d1O|r7KdM(kV_AvDGG$n0!#Fyiq{pj+ z7CA+xvr}KRGa_jE?r9fx(i>KI#a4S{?Lae`-gNeby>q;%o_82wB`+C&A)U;t!=N`G z5#i1eXC^JS{M8_vt5lnPEvFrJP=$~8rkZ0yqiWD90fY3GKn`HHoQ7Bb^!Ri&f_}_|6eRYQ=fmtKCWdo&KWumYIbK%NOfb?h--Kq=%%5GLCPJ!KB_A-FS?7%BZPZS|SN zn9lJ%eEB?9_|&z#{kcC7_~XT=jY7Jq+}f6$qw5UvZ$5kr|A*iG4gAe-e*=%#S@?hW z=YNKO`2P3sBk@&7sx$iCTB^~WN$;HxwDir=ixipF7u_5(qK#=Uho%*EbRVkiozu+i z#bThBlq1Wvq-;yt0bXm&+C)2u$jM=Wg8XLFurm&DI06n1?mp=4$NIAU933zkvNmn! z08kNS>ZEW9TJ+H3&&VikxC6_b%W00I^(hxoT9wNOux-H=vm?=V!wLJf))Rv~okM|R zeR_F>AFeA$Ne(<-XIsnnRz}H4Gfq_{s7A7MoT)jd`z->ptE)%nt|{`yhUJ@6bro_G zPM3c!lrtHpu#m>koCj`eG?{w2fvY(e4jZqJ5`13eicxNrQs*_>f^5?bZpH!vHhhn8!AQm85>iG3sDvl|q z=UzdR?&p%!YEiGB!Ms-p)PpC|>YAFt2%Jfuo*&9G9u8xJ(=Cj8fsMZ+!%qelxz>*G z@Oai3`L6tQSnaXg`Tp|KW?!6|k&IUy4E1Be{yX z1h{K2qb_?4Vg$#$Y29qvRX~Y&5($30>e$X(oe>*%D5I3q&;`E|8EMA5E*i;g3zl>G zEq*5byn-qOVg4r0J-&lqfBY5vhkyHjg8%D(_@Ay$?<4%r|KI;V{P6h`e7W*?nLDes z@w6AlrNs0(Bb*{U1apa_KtU?rHuH@_Ekoy1Z>8Krt(m7Mw+~+<<&SWF_oqMRF_F)8 zJU%E?^KtAoCFgolxX5yHe~+XD=XqT5Jn6O{5NLo|769Xv^<4vgHcph0gry&ecW;zi zMab(6T)Cm7FNgO+zNr&q6QXTf9PBb5pQ1c2>ygPoZj^;%knETcGDp@kZK*3~X+|5M zJnR_qkWauE7$zTi->-{!%Z6Ao-bNq$Gn##i3UV=Xh%+Q{IphLtVkR$3sQm)iObqtd zz6HBp*mZP$Rz6&sH)FnulLWw>0KFA`N^{9{tCm5+dV+=E8mmd*fQxo&RrV#BiX)Rh&ZEjh5I6BXJ*FEx zKIODab5@`+zpkuT3tI|*&NqM6gY9=|JKy_vS+J&CLtfG?QmvF~Xyt?5x|DE#207&( zCWWVhuw-$H@z#L)fgb{gn6_~~y!HSGJS1mpJj9Bkz&>(~%1YG`u6>jip<3n5{gr^! zci(>fF*~{Ge8N$cV*77M84~3bZkqGvfR#@oHr%j$gc!Rs?6wKAk1meijFB6G-ViX< zGKUK>fIRY8`0-6X3L(WmFXFA>H?8{5;!r)rzr$z10c|TAr3oM zSCv?#Bj;kMTi#|3wdNGshU7RYppD_BsI>K{*=a4usrCm>Q85*Dp~K`j7GYo zH0D;CV6b^6a9A;s&bu>eosoh&H2Cy*R+?AyDc(Gx3~dGJU_yu)R;p;*vcJJD27Z2*>2s=(57t;&fe#B1ZV1GGE zO3RhFBfu!j8V0sqZ&w+}MvL!#wLK@Ur7TQNhzpq&PfM66u1gA(DddXB;r`zm+$KZG z_aw^XW=5nCK`xRt1bras7H+?-5MQ=S!m$@5wki>q3kcdWw{No^SyIu<8RS^Ggyi8y zSj);;@c3WFg)5aI2G#?6@G@n>_o&FqadpZ#zh7YG4pNaGE)< z@G+rqiW~I-#`ftN)6V34ysoPJt8f1X{`PnODsLP9$3Ola{_%%@f}fr**9qx%E+^%? z09h)x!cE*&h=$py@v_K>!9hh*U+a7S0eR0g3zyDMIFmMwz{qm%wbF*9~ zAMZvWmom{KPL83?0X$j5#>MntpqbWj%GwFE1*3Ml!;Oa)RdASE=t*)Y5kL+Uv99ox zbH1bjs`1564WTtWv{_`$B)it+hk06HcJ)+&@Aqh2DMFXq2f;q&rL9>&pa>I=c691 zE+5ss42&34!do|=X}>DC=gTwv@bDx2=fD5o;J^RVKjxLjPfwq(|GvNzy@2jP3|d}N z&tS`4%W9OMi_1TABxMRHh>9M#c0hMjfvttz2WG;-+AglUgPSSd5EcV$O*qvToUtwO zwr`H`kay9DYCL6Qoh)eOq~)j@Z=1s{!qW1JAjN!dj+I;?j{utGVdiaS?J>4j1m+2> zt9(uu=e($o*fw6Ipi}@&B#)EyMR{#Mp|!7(oJqM`uN$_E5Vn)KT3H8LmN4ts0+ zs>=WL*Z&s&pa1bc=1I{1`G5IO@MGG3{qp5%V>}nxPGq=bJtkfksM2`5u}ytQ<@3*1 zUHEu;fPeV@AL0M~pZ+ua`tN@QfB#Sa1HSwG9XwOHCc1!AzjDVYqPV2dW<|&*_ZORoOkfJYE&z4>|QE z-v;(lw`Ee^K6!tXb8Ig!sSQ3h>-K`iO)A9^II(mZ5EH|s zOFguB$3+Zs6i!N#zvSxzKPTl$$FINs8ov4Z8~F6)3;d8Sw@It}o=1tT|H!4m1`M8M zo?>GW@UyKLlsz)+_B*<9x7a~OnA`iI{cHi0YJuq}RlS^dMEvz%{SEww|MS1U>NtY` z{J;Je_{V?xyYihCw+yYbDWG=MGPk8G$?MRdwUC3kFkcs{_s1Q)fB!x^_sL13etsMo zJp6fryBfI;57(8WckuZ-QTW5-_waD}k}sgj`jGlP zy9^fq8&q3uLE#(2QFjk$=V*>mjg>A-G~5c$ZlHeqXMdjs9Ja$&wTwa6{*M0hVb2F8 zbsXM;at5gwUUw`Lx*{0GGmlM0=nW~6*@0rndT>P%k-OtLL7% zn6Zk&qXF5kA51rhSPTrwI20Pw2eKa1*Mf^R4VF6ozGn`Qq6xtcLw-eMqJcVW)ZgfOO!SfU_+oV?eWm_YI z^32~$={qXCL+nGbd0z0^F6o1k>3dD-W0GG!f6g}|7Qs6dB!XNQlI_bVB-I#(I@t!i zelZlV&XN6I&QGcQjE40X8$F7>@p+2Nd=T#AR`nk68XvhC18x+h7U*;h|B*jJoW^Ck zG$Qd#R!n{W{JQo{_mP2b9BU6h?*$CxH;DF`Zld8glA*;#HV5=JL<8R8Wf_tzyS-&L z;u{1qa-DU%pwYyg2{HO*&@#J4Ec;528vtiZqAp90QQV+wgMdjUn&kw`1=MeMLk7zY z$njX9@;9Tt`Bj#C@7~=*`>aRfPi^Q?K#AlU^g#d?+oR3~ZzDHNprNb?VbKX+E}!AQ z{{HU({y*iz=KuYl|KYlN^ttN|Y$dSC+_$BFKe%#$U}8~}kJST~V+c>z72Q8Qy}%Do zWumZrmod3c&)qqapG_x#&zUS0cRz)mJp4 zgGJ7eYj!vnTJw)?;4R(wMd0Pq+zoYbU9>8c3Z{K$2ty2-eHm_$YeJ-;TXjZV1}&PZ zC}0@7b6Q98pBL*Jv+^tl25_ipz>zneVI6(U%OV(DXX-_*qzlVa+aA4s0^p-5W))t` z_DjWP&MS|l$ZS01-I;a!50)*r>B{(*m(;FlY+nRM41PyhqbBu#P15qJXk8X>6Ata? zr&2Lg=bXY^jdINg)am!9j7HW{&alMP7Js8SHK%wnJjV+5xI6MkYrpySt9&!z58r!W2=+aiYzx&hQ!S8?iLq?u1Xh3M!}a|#3Ief1$00=6JB=@#@rjHMnc{1Czm(g;oAwb|JEtdY$lcR{ z8!NRuExT_GG%NFx&mbMyAo8}kaVC@IK{Fl>1JB=QVk1(}nP?oYgx3{>HcxxwOowa; zabwb4$X&I79ZA&O3c>`32Pm~E3o(H^7dvpga&0xjh&FJH>t+StHeL`bsh zs}Eo0mDMi~U*O^Ci(mmc+Awc7{?m`&!4E(E0L2l#^zZ$Jr?b$}1*GsBqlJPRp4-~m zvEF0=H;qvy&Jwc6^r;YhgwKzkIv-!!ItmR3$))8Ljvl8c3X#6!ec6UrZ$*-M+qCbc z-r!eQil;(fahG+aUckx)$mJo~NK=n9J^eNT*(EZ!*tZ4A1crh!Ep+BwpS)YOel9Wu5YkQ9uQMc`Zl=6RM+a%9^w?e~cn zJL0BWx4_%h!+TNWSXH8RSQx?QzV~QZuH^2#*UnSUB{N+ za?DI(wHQ|B^-o^0`1JYOZY*c>f;Wzk7dO$$Nswr_su8Tjz*Nz4VA?C7X=G zjpy=IMeu_BUA@`_ zalZ|tkJCPdbz{(pufJ)gJRKfQw?kc5Ii8=Mg50B>dk>5KA}zI1*@U1{bb=Pqn=IB> z9X5`;(ql9cE0+{3&s+YGsGCs4T&N41K>&GJdr0SxzWVy(b>{mSK7al+4wegp(C<@E zel%+PH;Pa~;1*6)d2|+kRZWzi$HI`SXo-}JMoD+7|OpD*3dNdg#X!)s>PmJ~w z$JId_$1N_&#^fM<{`>{TH#_`GFwhjm&tcR^6cH7+jX_xtGB;(Oy9te${GxzZe|%lk zA{RMqgiMh#U@AwnTKsu~w8{&&Jb->(J6dBjeh2W^nagj!1@Gb+s^o9Uqljv71}nnO z{=YTE;19`D;vv9I8&GlX!nabUr#AcY<>uWo{G4H}Rw=9B|kRsP<|4gBV}zk%=m_#OP|4}Z)DD0yEZ+ zz7i#TOvwcbtH;68(AVae$778?k9z^UZ7y?>fI<5K=<&qo!7TpNj_>Z@!{w!7MZ3D( zvAX(7D#2!=Bl4*PISOY14K#+iEJlAy$LAGrl%zy{GckRoM1TC`K% zM*wkG4ks9F+|-xo0)~tt@Y}*+434h-W_oANr;;S|p``#<<$JN70C4K!Zi@qzXH{O1 z)ul_qf63b%YtCbhM3Rf_*)OA%vu7&n3;M`wMx$772~zWr7zYJoYB_1so4&&7kIa#iBvYPc;;j3WPfyiHx?b! zX^B7X^ET9EOQr4gbn|up4hct@XgK31S@u}jKS91%hWlYeScS^X1W$wqbKE`9Bu%np zWQ=lL(v09U!lkd({FB&Mih~(CekCc#-1Ur4=UvOvaU%#b zABQyHKw!2n;4prt7hP}~c%}GgC+f+uG996P4^x*qdTd}KPF%+UZho$N3KL0kqU)29<6Et$2F1t)*|eT;c%CvIFy_6G&Zm2kexkgN?4C& z0?SY7_v!HozW>wrdFC~J7w~`s{Ph`dI=jNKvO8FBPSszcA(+r+JjNX~zB6h+plDZp z^OjvT1bc>vkFow6DK&p{R~fG5i5$L{+*}|Cq?M zNVg9)aGIQSs@4WH%dk;UoS1$;y!!yZ{?+f`;qeQ6|HF6iLIm4otVkeOoW0!$n|t?8 zw$6a|SRbL>Vu$PwI~1H7nns8 zmE@P*AmcQCrh-Gskka_v@qXZKc@U3*(vDc-rQlJ{;Po*b^lkUF_zquS|MrC1_s!cO zo=@T9f~cmC^F!^Ir}CEJ=Jb)bnEdeFckt!YCwP8(1Y&#cIVM?$k&dIO@=D29-+Tj) z506(|?_l~1a z7r?nv+<+{#;=E8BcWRueI{OOUYsekrc;qKL@Br9&odufUjX5RetpT7oa^qGuV!yiq z!$^jA(*W`ViN9hb6W8v<`eVNJDJoy;*BK;#-yJ(ur{*#w&mrstBLLz4IuZEwSKnrm zKR>h!7-}*y?L<~5xHxqT`c&Xnb!9o{xTXRzL+o3Trbrr0F>zo6&LsL8S_)Z~(v*UdA(4n&g~`G8BLP z4h*b@{^l6cq%qrB^WLHt1x%_GGoDb8hCPkI}TRqRYJ$EoMuYj=F~HP(Ds8D30A4G76*gjv1pyO>T7Ih=jI%DhMa34;9>;LBN}7*Wc_ki#y3yKf?e^O4 zcXvmA%PU*cjnW8`>yX8Qc&2c~qWC3MOHa0SW*wD>Fc2R#-Abw3_pEdg8GCZ04oy88 zELOZ+@eQiwgwTvDdZDabTOK?_4gu^&~u^SU~#f5^n4 zUhx!vb!a`T>*$p#lR7K)bj=gf$3@Qh%q%zES_b+eob3+Emo(g=Z&dJ=nOH>HVZ=iu(7AvbCWe;M zV^yGIqHd!KTyo0`W`|Fg?NN%8CT#5C)xqC%IKYs6Q`8g2K9p1{XmF^q`L&X*ftaL2 z9^dJA=#fa>vDdFf$4OQnn|MmU@2*R`AHVqsPuEq8&!0bw1KR_ha*qz%jIT8Cw$V2T zdSwrOetCL^FHg@Ik96E@-zxp8IKgttXyK6!IbV0BA~zJa+GZ*$xR7mJ9p|r96SQys zG(N$=R>h^XM@B=Vq{Rb(QoYT&p?nSQ0c|Gg!^e-;8OwL@<;$16%IB4%N1w)yf*#7w ztcHoO4n80A#s7PA?-p!ZawG<2uD#E>_uPB?-L3AHTHR`mdPb6sW;CEdwqs&!;}0OP z0oy+_1SY`d1A-tRu)`l1e-J?g1Rn$Z5cbCeeBf~q0mRq=4jh)omeFV)9&5&<$4F{P z-K~Ci-$&o~dF+*}s>)|ot-aT|=d|tWzGv^fR#jG3RaQPKv#NYZXRL*QX81#0)BG-@ z$a`WUg{D1=?OZ5dV~vFd%tIu^;JrpQW_9glv8W>jux)RDzfh!Es)$l41}pe;$w-Wq zr;3rwSFNk$?;HYEgKH`xSCA^Y?gHa{ewYE zlXhNLJs2WL%I`q+p8wIV+GkQY^17B=5k$MHzNAjyCW0Q75Ntsot9LZtnjZgZjoCU` za4d9l#@}Afp5|maDU;IX_z>7hwza>&p1DvMS}9aZ7G$p>L%Juo6)7%$J{>Z{ z+P7q$X@^N>u)Ei zJ?kk~`FYL|xsbTtTR)SpZJxPPh`o2pQ^RFiW>)tky1$|@&8F%l4j9lZS)x+tpIhHM zP}Qm)&R5sRhdOYe%&&ys-lR;A8v;FX&oSoW1sTBCCW@6ANB-N)jDaXVv8M81JRr2H z#qK8dLfOVpzFp6aY|eXlsLR*_hFQwTR!OII=jV(^M?6#HaYU}IL*n&3nwD6YjFWd~ z1rJ@h0+$}T0@vQZ2Dgunbt5Z<@(4zW^*je?6dD&IgCP$>?A?f|_6*K(rD$T~7Og2l z@6%XJX39WSZhno_%(nc?Em9Hh3f40Kz|&pJMT2^du5Lc;q)|BK=+|(3YQ>dmJ{R9M zPkZh2ZI6nm(LBvT!VWBoGq+cErbcK+qI=2S7UeUX))Wg8oHZ1ure}byCkTdezPu$l zv34YKa}S%a)me-j*`J4=l%fZQd{|Dpi)XVVZ@>W zI7o?J?h3Z=0+m^g_s{aBmdg_C!jVir66iDCR`aCYZ9jdQ=bXJ79<){wRwRN$;RVTb zE{$3a#PeR-g+RUSq2fz54$`s<`}?q7ucw90dx4bZDC(b%p~S!H!&Snx5kzSg9qF>> zd?xDVWGWkN4-x@XYG{qTDK&l)U??fiVpTSQeHje7>r=q6C#S3msE;nL+YJ!i(y9jW zEcaMsX2DC$$dx11Yl*IMw|~gTuOigO1?SPh#p)eEB#WAfBh;<$x?XiMbUK4&K~x;f z!&XAF94=I|QmE>0tLSHRAN4AvdwFzx3^#AwDxp(k0y}?V1q|Fc>Mw_{$_Zl*-Xv+; z$Q z{SIA;K3wRQZu_Xp;ri2mBeI%m5nYT8-+vJ{=}0pDGXDYcJTjnZIC@3U$4*i;sUb)V zs3B?e9(V!JPoBr*ve+wuDsZBr#_z!IxwCH&Sq(J&kGA7xc`e_F^&0>S521M&UXHkC z1vtV$yJ=V18nK$kd%iI)tD}Bf?Ui&x+|vH^{L;ZCcW zl!>3NhN_=p7a+in)(9V^E{^_*`|d<-Y=4C7Xjxs^;;l4uH-G*(cOSx3_ z^)}WJ^r_Nc`|ArC?(yb$(os%gWeN|q_M(5HKjvG+cZ;lii>j$$V!M6#q1G6fD!Hfe z2ont*^5SEJP%Og2ey|IMzfr`+PLFG@B|-^16W)sm|IByfw#2nGMn`WC$9&I2$Y*~` zHm5xGc&YR|Hdvi1^(Ke)f?+=`P(__0$DfGWEj78xk1JIU3$6*UzjiPT%4ZzK!q)hJbUxcTgd@?_} zIvGecSApu+B4sBq^zHeF9D;i(e@_Nc!YSYH|`^+S%j3 zMTLpn(lqND04a~7>R^IxxGtNe;1(-(!E9@=nxdSTgF?O_%ny_Aud<)YLvJ9u@5}mU zk+E>r?SQ@@6PR3x&ywR~HC%wF9{-upE}+e><$y2e*$476Pi^Y zX?s<0HyFv&xe@HC`F%swtFw}intXf!MU=edjc7sSUq!YD0e`31X}N8}GXC)WqmQx9 z8(W4@`4Tka(9|5^llv7%IP_@6WUvYwYK6ZW-_(I469F>hn&YL?r}6ChUnme!>pyBL065&lQAp*tq;rb1|-iF zSk??as>;z6sG*IeXuz(I54yi~Yhr8Vdoxmm@p5D^Wc^%>YNw}8Xu^Q_Aw2Z(BXDr} z61@NJyRf-;!flP=X5qJ+!}1&}uzvjFM(cJ@l6kmrrae@_h9HE+TRF$&1d{hgx}`Hn z#`FLZN>y)CkIN0hhAh}Na%CaqF~I13=ikkIk_Wwab>fls!%8)$UY@ky13WJm=SBl6 z>V-IQW|@VhbRWsBJ2&CG-~aBU3>|X~OI5O}9`tzXTWE$0OwOc(fs)7h(P=KE(CT;J zdnd0}-??+A^l~pcVrR%>i(>RFZOiXxiOKN9$;K|FZ=C1AtvYI@F`ySs0d3VA#?(o#}a$!wvmpLAv^?@Db z+x0WYm5QPQ^ORQc9nCgwDI*0ut&iQ&JiTEgm<;gj(;tVAee_xQ;VZAe+wZ}0F6{5`!4pqC35WOZ!;NbuFE*QF_~7O>-XlA-jZ~0=1a{j|bG1SrytfUg z3zqo8$eXus<$N1GvVU~Uj^#RZ`ih`E*aNmlaoFN6_2s3upl#!Wtg10Td5@Ss|A(x zv$I@=1%^^%DPc8NE8YkVzDu6X)D5U(d6pEp&yX*g1#mh>Z^2^`io5dDDO#KO%n`hM z^_~1Hh1b<;Zf_AKFZNC^*0M>`TdvxL7%TFHA?9>KvE&=UtB&@(hLGOb{;L{Ed*Y{7 zP!E;19ll7QYpxX?hOZ>WWFVnUSVX4BMX6VmIDJYUtZSzabTOfg5e@w=Ph#7lqYhx* z5RbN0r8#y^+POC*g1OF%s)k_&v%@a$67Tk+mGga-f zUy(q za#-*;-FM`vOvXKewKWFh0De@_L1$$)SM)Lpjo6%i+jUr1>?BMJj0{aV#uwcWgOTRDcm!6 z<;KiqO7qFPxzpE)Ct{C&$dMND{NJ%?7PvW2kZ9mj*us%Q>h7ey4p3kx&$C0cw7#RT z)b&M4lhrexA0yD*ey-4;k@g_`qP{K=Inzw4q&5OXuOZDftqX=KyxcH`KIr8RN#(C^ zgG^M>H)@(#f+%#*u5=sB&qOPa3*DZ;0%&e#Ud5J)|Bz(HHTaaO{=NG-w!QWZ zh?0?x5>LlOkDKFwNBuqEJ=4iFQ^sF7SSyX=3>?i1^L0^|r`M~dSiOq|iganzhXF)4o1oHtiKz#My`0kt`sG4*c3@*9z*6z#um+VBRs< zF^-W3Mgf^TM-M&pD17qMFTm{^cj1RWcy%)R4^=rOFq*3QORr`ETdXk0B7s*=2x~=@ z0=~*Q$wJ=rJ=MA8xhY0{HKdH2>^Z5A(Do`>V+zssxzhA6w5{<^dJ?1M&5;&;o0Erm zy|;$V$;LtksVljl)0!@|CMbK8r|r_k%Wya;8tLvDtZ^coDP6Z_SDuouk?yn$%ieph zwnz94eJsKXc7!Wop3uYw^Zx1po_PF8I5^mctM7jRx9(n_@@%%^65o)`>m4+&Nv-zum-=LhR=4+|FC@g?kuooQ22X z$TbWhbTTpq@o0BSm0WaABuTUz^ZhoVDH$O3m1CojD7_oGCy5 z1OS_j$F9d+o3%eZA?DZCwzOb#aBvA;__62V#bej|q! z4&YjVGy|gM_45hA_<`p(>LlyN`S&2y&*p0?^UHp3Q))zZ*?7m1P8-7a_V?iM{yjLJ z4AgY!!>4}YS$Oj4OYp7V-h(@@+@8#%lkV)Ct5Lj}8V^HrnDwX*x>r`ERF*1w+<}8{ zGp&)4Ikq*{wU0161sC894eq(s2wRNfrTw@7o64JTc8I5~pH6>}1q^%>LY z!s2FgHDRj*Jo&`a@bE(q!Rv3n0rw7X0phNPRW*rjh3=V8AzZ&+PJHm*InTp6dh}lo zX-Fqg<;mK=WK){dGzyWK0+&Dw?x|NgC_s+kHulQ)9M#E0Hp+N_7yWwG4~6E1(x!L` ziy>b%uPl_j8QxsH9b-uyA>sSUi+}9&g=d+ue*kKqLkK+q>O5Z}9HmD_Jr>uua6qSY z%}_y1l#g`2^}$_u|E>FQ>&AT!4Qf3(pihNnhHhKC1`dA?Rj%X_I=Wj7pB1YRu>=bq zUeU18g$6fik3Dj2s0g+7u2?qebX`%{fSCwCL5zYJYuwOd#7a9>aw^V9QFsK)0D~et zk5hxJgN60o0}daxf=8oufDR>A{THi>Odp+Ao#x|u*n=mYdHP&0_6?sH*Q>mU;onYz!9GUGz=I# zJOdbiOt3}@L?xZ3u*E_d8DHOy5xkOs+T`NcX?oeU#@?fP*S%CgXw9A)ka?u2L-jqc zman;i>x8eaO}2zLlT2O>Tu!Pl5@PWldayN_EIOVq$gVa5lOk+;9M zm-pwDD<=9WJzw$n`lR3aggbIM{tFOzLoBxo&hq5<#GVt#Q`D{B7AVgnlIAnd{cE?&3@4_&&fC(fP{pfOF{o(;fwwc{$#%q99T34&&y z$#x56rRmonefmG6C-xuLt*Oe&2pVrrPbr+Mw!bP#GpNOU05rpjJQs?Jh<{J65H$+! z=xXo`ovJ#_-ROl$Daot9)!_p9D?b`_g;?6|u%&vEG7vQQZJHw*?DlFcr1AvLRga?#Mm!RtEtCuvbhVPAE_`x^uMK({882@$`L|+D2O*M zu$o-87@wz5=dTNfy$oCw0vO6lDm&4#Qr%UGELY3MS|(tO7rF+klrlnAU14X!x_T(2 zI=bI=q6$~40a1+?Xn36ZW)MPu)O!);Qlv%Sjv=oWZ^q4}1f4YHklOATwopK>XX=F2 z-UWE-nJ031)YW&da>$p9??*rHhgpn0trNGg<|^fzpFwI4f}f|EZZ?#a7RwMaKbc;QoZqhIZke(sn!5O8%z64#?r zcK2Y_A_(DA6$VxZVuf)>;JdbLPVU3q@FAb)+46bWynz#NdZIS~!VqKnsu{$1hFQU#3P>PgMkBT66 zX=ZUkYe(v@5qorHy{HuErUo!_; z>1Fwjo?3Wp5-qMg)%DqVrb4p1BVJ&A!#{+s5;miBy5F$NWo7S~=h5WGRlg8~MJICk zm3M|dDl}&;a)krm>$Mh~5iaF{S2~eB)*ZM4UJebAl2mhhzvpww1S43IYP#`!+E2eO z$C}!pCULbtV;^-Ql7y#*C?G)S&` z;(AL38#vnBnLbb#+mxnrmTlu^e8)lVrp!N??<`y8rtm2>cnzeqV}$pwy$>JUypivb z5pP6(FSJ82OQFV%j3Q`uQx~wV6Dw z$vEo!jUOQKs>Xw!0(sg47?!06gSAfQ*`yF9uOhTcXn%6nD|#|PSLU7>8;e2`f7v2ggTeT6_~;bL3IEh3ZxJQ@K5H40|BUBdBT`g{M{;q2JchuU^r$(sIX8 z^dPk`I@|S`hV;HKfsIA!KzZO=OBIEP$nrZ9NKq#6wC1#Au8XukoJtD5ucbY`@2vnQ z2;=LPp1O*Mkjx6=Doe}QU!9b3K{*z?H` zho;9!;d%oaE1ZgbmF_`6I5|0lSHJsuJ{%#RK-PqO4iHU+2+QZR_l3ckJRX!jBF22; zB1PU*j$JOblG_ud{Y(@vnBy-h;N^B#^u8VrlX7q*yQc|LPMqg^`f};u5*!>{gc~<* zOak@T^^nKPX03SIW5`ax6#OeeJ3P<0Ir^SH(`C*F7cauw@4Q>xsT5Pq$NZgOghn|f zM5g5=t$^Ov^ShI^)%6?IwAxFqC8@pWA=a(zV~O$4Ofzui`#fHy4Woq^Ia#1dEft~1 zSp+=jkZA6g@R|YpnHMQpb-RVf#8yGpkVd>bBWZK1+Q^hj%8=(R`?uHHP~A;n7DQo%(Q(BM6qv8|c(!-yigd`6Vr$E$iuyn%18_kq@JLFeuymVGE(Q zkYL-q7HG8&m}%@^efBTW<9m-gL1SuUy}H~3UMmk&DUfN!)}N57C{{vg=8)*wI{k{J zua%%tS7TYMC%Dgz&7_poSJMCV1+Tga4A3zv`D$0?@`>YdqiXuJt*R$ED#uXc5~#|F zU~gmvDI_SX>Z@X^3=LMc$3%@8-4Klqwqay&q%F{dniM6y6(mNp=pi)U z%aC+kUjme zkHEF}Zor+JcR1$&9l6j&&g($ERugzmA`1=Fp&twJ_505}aR1wTaXjCuH-B61_L;3F zQ!5CF8vMjq^5He<`{m15;E{)~z@iCbR-M&BGki`-Xkl?(vk4pgR~$-Lkepf=kcw^5jr!YJncW%x9r+(=PGsZqiPS)(quS@zOdO8 zSmmmh8CYaXCd+$KxB*xnEiAmvtE4D_NT~T)mX1hYulMt!$2gwA;?&ID2bmM&_C~N_ zZHKymtBvJiQ)q5{7UZdmP*X4f9PnZ`Fpp2}Of5Nvvm}~F;Cx{&DoAj)nq5NMzxW`A z-}!qk3m@4AHQ{@*$*0(r8_qos8C1ZFLN=I14^HtB1)Mi+#|t%uMQut+8AQhOS7WAyDRYfD zs)+K;&-dj#@Ai07Uy)VZtp|JIkjkCX{tfQaAoM&n>)|3i_V_b7+~wMhcP0UH z7Z9M6SDuO=2*LpYL#Rbi7%a>RJubChYzXw`>x)~X-6syc1uJd4g3=kKPHHwO1U}KCIIir(%u8569T97424tW{vVs;SR^Efu%$U-&L+R8 zLekG-Ns(`{0paMS6%qsUHqSpxKi;`}2X5cFllhttKQ5rjEf_%q8N(9<2zxZQBy7#_ zJ9o=Pvx7TOqtKx5O=7++{LcT|QKzpjWXFCUeT!Wgn%evLKzF|DfgoPYx#qQTc*9PmB=aV^0AKvV&%h^NdItXA|L51?-RrMa z_ZoRrh3E{f?EOo7hXiI_Oa0yNLyZ!ix@FrrUGwo+Mtd&k0(HFUmmpuiXC;zOXAb;VXjNf>kG3AEe75rmBfnD963y3^7(O$gxNY*Sb!n* zG!)of9=N^*(=l8?tRLtUDu7uXrnWd$fcEEWtheH6RX?B59XLL|?Re3HCzJaX0swGU zL+SL$@Ekjjda0uGQ=?*BaCbk%aqW*Xf=2n^44reqb=sVjFIh7U2~=5S9+2FK2Ujk@ z-JAFFW_;8mF-0-LX4)BvuF5KTMYQSHMt@cNjTmqgWhDYQ=V65b5I^t0rL69VK{Qya z@-Mp$q^q|5RXvxcAH&mG-ib2?0 zcn-S$vYxiq;!JzIs;9^@^UEUEO&A&n_~_Fw!k_$epM$*%1N`m(^&9ZYYu|)bG6)eX zNLFtqZa#7_9#-7D7kUq$(a%;9c1vP;HZ@deVUm@4s_3hvFa_?X+7`5fCfm z0HRW94^W?{1)sq+M!1M>Fs~VoGfYWwKp`D4W5_XZl)9{L6JXIaiwdQubD^q2lPT-YDrul~jV9lrbe*Qb^H74!r+TE#~F)DYlI zE82I|VMf~ydq5vTR#z<#CZLZ$`3Su5;#07{e*xkNZ6=!{{eaTiqmMk1n|S@kHQ26S z&WuZ#f7?_rY-~X4!Y!ef;HGPq36s40i64Iv9(n8$`2BBx2aY!PoPji-O!ferT0xw$ zf99o6XCvvm-~Z0Ux8h<|r?QG4Fc|CrE(M^At3BzI*2N1<`a0;ubrb$`6aAAL94wvEh?gqwm_d_j= zshq?Wga=<7C94u;z^zpJrhAg}dm&m`Nv|b)wO4@RY9adP{6mZ+kCz!6PL*&9U$9ow zv#|`gsnwoT2FLJ;Cyyz-DB%D)V5k!;|I*m8HZ(!jMC~95gs$VB3Ah**)#|Swbna(W z-Ox3X+hT_}NFM?C!zTt->_|30Ct{?+pavQn{7_HhAoZZFpgk^^d>{GC zKP#rI{Zs9o&(FzdgOs)iB*bpyu^E`3=)ntN@d-h_?CcekxhH#jTAAnCO{E_!0JOj) z$695v#*|xXl<8;^aa)Kgx)(Y!erGz29V`)*6sAx@CmS$AMT5+>N94G!ksCy+M+^by zm}tvy?Bp-Wywb)Y3FeaPuc`5S!^80TFT4OxJ&*A9FW-a@Zr;xFk0}$jC8O^_`#ks7 zDOPu7P8+~&b?V4id6!*|H6}cSzxSoDz(4r=)8gs<8?aiLzndw|V_@Z{uj9!GpZf!U z5Z3#9@TFh zOIrpv7&}sLBVs5|Te_n+CKU7-lf%pBPg@P1dJZm4eq^Xquh8diKq@@BY&GU{FzSkj zI`52ZC$2MRIp2N>RHr(blWWuW{q+HS_A@WR)vF)Ct8b(OGj_w3C18_@k!Rt*`Rsp1 zkEK0G?1Kq-h*CKbeR6}-cmi^Jbxol*b>@h#+?!)3w210pxjoZr14sbGkSID(iIpF- zP_$4sITRuuGYkBTO$Qe6!iZ{o<&BJY9X}u3$$51%9-Upanm^IC4l6hSesj3g5~qr3 ztmu_cl>QJUc{|(IfEC1cVViO5@ty&^QIf(U4&bpXADIN(FbVs2rhdN%{*VV$kBw_W zSog&yY$|$pr1Z%3gM;s3n<1w@Ch~1D&rz4Bl8kfPV}8DSo^6bg0ww_hng>L5!+P!r z6_}yzl}^8oWGx+ox7F<~VLZ#pa_!s``Vu8ijM>yH*%Zz9q1hsdc#{eRmwB_vM-Y#B zj%7Ti@0%2#&x;{yI5BQDCEAGY=3E6vI#eRTS#8Pb1ADnX+2`h5w^-p}pR!kp@+ohp zS?RS!2tG&xj6ap2ORuo|nN1b90Tp_($D*{%h5YFGfn&p$y0F|63gOKdaY0}Y4TbXa zr+*1q@-$51&n??&$JwK{?}dg)|yeowRj809KKqN zqw+puK$VstMO8PWd_6=`=@iv!lu(m4lV*`Pm9~oTRiBwm2+Nbrv2i2G;|Gg?h>3&KesZ%>PVk^t4r`1 zHjrL_^VLphD((0U7Pgue7Sl1`t7%narTa35z{m7^G5|J-t+)`J4x8~}r1f@is1|1_ zVG*phpi?xpW4U%TWvPVIArJNt%Bs?XqBc4O6RobOoM3DK#b7@R@xgM!p5QElGDw^J z&GeEibvj_JjKSIHL{uNP?=oP@PFm(7dVw5ZE>(hB;hs52}-;<9Gl6Q}4}Hq|@c zhpQ>(9J8Jc;yLq%ROO2@2xL#&Jy5E~fs7wkb$fU|i~$*YpKqrs?!v8n8iA_0;Favu zXy=ihCIQgs#C+<9HRv40VgO~o z+LSpNMyu&Fofs$2^6~%Eo4nM(^I}Z*(~o0T7EY%BMq1^gmWK(6P4;}ThcfUT^U0q;?Uet(fLBUlF z4kJx7l)wuN#~Tb06-c2Qvj@_+%$&R$XOs)Q+lgVv5V+XZJm~I7`J^}T3RO77}+Jxf;rJ)*2!_V#JT$mW|;I%~8=H!t+gzx?E z_u%(m{^n#%oIugDhb`^%E%5a1%NfqdbfXZ+AmD5r*m>sD{GK4)KbYpt8d)~l-1YR1 z9vOLx=?MQjMSim;Lm?DDvWaRk@T2YCjGU8!sOPn5C%L+eS05i9!T$b!xsW#X?xZJ? z_d=XQ+U4yj-Ljktm((+_$Uk7KL@`ODu|at5=}*9)`uASS?CPx_eE{!$=XF>Q8&!wm zB7&bUv=jI9HkKarw73~yjq5Lp{z>#~sLFu--7J>VKSi+R=`qWC z2_6~+oaC)_6vc@2!|N0B+r(lFuPE!?knca4EWL>kyxW&oQI(aqf>Do$WszD!Oh%_< z_^IxMUiQ)qsu1Xk_CVmhE#~O+tu2iTp?w&~N0i99;YUFpz;s3JG;kYtopQ<2wZzt1 zo3y1Inv~0|%R5gU2y&o@D9hEIM+B|~sQqL|yK|Uh#YhKNDy;YN7)b8H1>>xs3WwA; zt}CiU+N(uXws}_C6a8Wm(^su}q8YTlZ+)xFDt+;0=Ku0hxqK{x#`D?kBc*2HVeX_4 zLi3_Hdokh!JgU5)FysKc9ApQ3Ls=wA|JM263ifc&zD#>4Hq(E{;{eCgYT$92Ka@78 zj+q2baFfSx!{eRXhc46b|~+*r%^pBBNz8s;g910OhFAT?f!4~@aJT2JG)I+-bp)o1VBvgfFKiph0wU4}cjsdrAAKrs6A?+UE#w=-B# z2avoxVuSUgggQ5M%ICoNa+Bin7r`9f8fC;t%JQ1|x?{P`v;g$b(xTm%(d_V=2$wg8V^=$+Ze4=dfNnz-MGDtjCWPlwGdWZr# zh6#?5YKR?hC|!Y{;S`1?l2793?-8rchJ6+j}A-#>NqQOVXuw$wXRB z?Mh0(1zf|$)f)CEgK2Ndw~smK4vy#q4kvmzoa#SJ3}~7|`3fN{hEiS($D;W8-A)A$ zYnz}rfQ&bS1?G;R-XIa4A=Tn*01LlF@HFQ0dzvCQQ=J$Kik_<7So`((7dqMxA#S9) zXq=~{SxfXmq!is_SlwX00Sf%4G=rHH%qX56PGA`F{t#YCj93`2@uW9DMXs4UTZo|&Ex>tOSgZu2`k@It#hxsfHGIpNNJu{hz;ouY6 zQf>|=1r8XJfag!rESblNFYduJ&pr$5^vp%d=@-3f^e_+1Cdw0;~j8|!ED;D%;hohY#@dERCj3d&{_vb|~ zXQjUnhi<9+o2dmfAR?uKwYu?ic#Ituoag*6eC)rWNB17F)gdZs*HV;K`03KM3j+ag zCo+{iNcmnQo|FP(bYgc@UB~Sq63}e?_|?r#P;RDGRovu_)pCka2_Y#!)2c>-F{)w{ zUHS!rtajHOY)aS&edqq1*tF>`18cAv<^lagiroOXUOdB6=8_*)Ds_t zPkrVi@a`M8;k8#@o$?-K6I{awmI|Y-S5yX72hvFW=_oP4ui53dGP{ zqp#4pEP>VNrV{pNwzAE?s9?u>WAY)72%cBO0~$yfHtCa!hdF#VP}2o-9)cLs!(KXK zFOTLWgDZ8Cr!Z>yCslP4v>eZwN>GoO`vZZyxjVgly}jgjj`fqrrWl5!GwcSQBqPkN zw%{j{Z#ixQ7OnDl2&CR^s`7O|}N`F&}0;~5in^Mg#b23~$j z-4a_As(Ir{>D-5q5_C;Ql69updRlxF+@qrn?C-B&_JlH>q`>69O^P%HxBTvuSg3Sv z(;XHiw{L85nQn3#h6`KVUU%GzP}s=0sO_i2l@=E`TOU-gPGdOWgV%f(1LZu8oAWi4 z`aGphwULu>7$`!~&mGe=QQ*n67`#q<4F=?ZBAS~VIQzs_UV!zsLF4EBiAlCsD5+)} zR%hL6n1(%!ssKb0ET`NIML`8S!z*`=tmBa1)4|{P6t6Mwvm6}K1AtzXYR4&1Eu6uG zhJ3U2>$Xo|>+{-A*Dpcf)n2L7BLA_0E>F$l6Kn8>Nqi#e9*hG#_Si%4@gKjG6@u4( zcwrir<2+x>J~hhYR2(0CSGVrT8!9Y3jd))T_aUFSH}KeJ<(WLT9y@~;%&d&g;BpN* zP8l8xF5J@B23h*m;N_>tb*j6R;W@%@CLAv|XnRS6zk=ea{UZm62q0E8%IY3tm=rbM zIMxUf#e=kZ(j&Xc;Zw|`(x6q|XO!+ON#S%CCIjipRN^V#n_cPM+aYx9v4nlE4IQPWKK#LpL+N?%r`WMpQD3O>Zu{eGQIlyA!Ig4Se-C+ zdIiH%qdl8n>?|ER1_Y_e(yysMUfYbCUjBX?cefi=PbtD@1X~=y8Ul%aL2le=Yh7vV zE?j8$KE_P^2SFFF+zZ%Iu#@K7y>wN7ZuW+7+HFH5`?RzvJI0gdd8J2c$zHMGkyK_T z8qbcC^Q@``Nf^ljIy)8I9k5R0nd$8pIz>I(>hKrtewg0M^W8hv=drz9RMj``nvOF` z=F&RvLzomEm{x(yC6U`FdVdn~DOZvM<9+68yzuHJxeYPFkA!k~fT^tZw$zgqFo-6M zKa|0Unz-husH#FCWjSmGgZP#Dq0>?f{m>t-x|c*yjWfBok0Q>D3hLXK$DR_1LQg^6 zU}eEIAR81D8T{y#x8T0S=+7?ai>icljTvnN^w+8*l$KkDCdl9ak{1e!p@*b}SIGGUK5b$2Fk(V3L8S;@L ziE)tg^jOtx$H+||`|3}{8?>L1JY^SR5Z{jM7)yqr8EiaW>EGM*g%zQ`*EV9{G?2&Ox38$qZYx-=YoXng;VU_~5y~RZ{+m2<((=VpxVn#K?Sl zg9~>g*UyGw83&5J0;+UOG|BGd6~8KOxR2Yy|3K*1SA1 zk)o+)IyCmcly+dv-+7v%4!A1KcCT8^xmy|GRkC=fM8DT!^4xCzaD}#%j9-*br$713 zCcv_?F@)5NTlu$T%u(i|6J9i%yYm!b7cI?EYBy(42FDHzJViaUu%0C?CFLbrlN{

;pDPgu3p$r}G0a}0wIa@^7PZXcxS1LMxJ%X<={60i#$%X#K>szVjD^3&A3 zi${uJT{=(CC!KYFQ_zuTP8>e3x-twXL$Dsi+(5r#pVH7RB|CJ8C!aAY+lZ}-LqI!a z994m#Fj+|diV9y(^Z|wtPEn4gMOF~}#!EYGPfozn6$qzvnMig_$LFn^?g&dkbwZ~w z^qu9UF5%WjjfVk&j}I7?hrykMS85uZS4H5gT+6s54PmuXM~mT{jCbL^_wJTEI?}0T z>0k@xs@fUa!(Mhrug@wp0$qLRo)*1-VA?8WA_pFn5cEr3g_0~j8gzI@bC;*-<&r*L|Ag-^J{d~)l+T5n!uPvenJ zw8Nrcd%iAnJMXX3HpM=}?hi}oLMJT?x}Nm&!;fDK-B5h6sx$Drm6f5<=10Iw%mvvm zR9=p(9OpXRaFcIW;6r3Gx@q?a(XA4X}&4p)e(kXod>|Nyh`DV)6qUH#@`-t3-_1aS8jm1$c=y&$=mc$V& z3k)SKzBHHg%`S8n!CRJ=8%hvl{d+u{ndKwzaB#WWC{reAB0-NY&o2GRBM;Gh&wMZJRSM>`5ztaFD3@CcEEuj+ALC@+evs2M(p(lc{%B~?jP z!%MIkJ8ofHL-(lK{CCGygQul|m7)Q}C_*iP*~m^Fiw)Y{HSZn02S?u@VgK(=W&RZ^ zcJ9{@j=u@;#^GD}q`Kra%J+}uu|k!NR)3k_5(1XP-AL%u7>LJLXGc(Kg+C@BD~Gvc zkhTtPMo|Fb`D#>;OtCMZxIGjXQ^5JF3+XZ~knuwm`&5a2&)n7PAcC$mYXt2=9nd-? zPdz&0n7v)2=S5l>*Gy8zP}n$yq~K}cb_6HZSLExh`;u?Na*r|(&K|465!RD5`TxH9 zn{a#bKJTsLwFMFehz?!!V*rMC2;Q5rY&PZ2t@V0soeuT9FDYL;kmX3}i*XqBvTq?O z(x?H5JL;eW#3%Mg;=^J=n4zV*0BKlxg*18aa9Gbx85460XS8>!&Wsj0`nXnX8n ziLQ*uGlH#YOpMukfBY=>pZ$amIlr$?z{GG$trX%6pNym9V|eko&%n?9u`j?c|MIWE zG2H}Y9@5fzO9^L9h=Xf`Z@cG|-ICSkj_@*7kOlq>On#M);{N#4pM}r;%BD;J1yN1y9^iH2CY*+Q`BsCQU0vZ(xeTjr`oXHJV0 z`7qaG-Ul@TKFs6Ochy_hx1BT8^7wRhWw@QW!MjDk-w6mcR!Qd2#58j3ypu?x4wlGu z((ej}%wZaohw52ureDb|IW{T^OW<6|=W-#qkP`mOjiMeM=XV}^4l_btV;(usE#*Vo zw-E1NKwUNT$Lo6Ba~=)lDfPuLIClbChQVGN@;zL>$x+lRX#k*Cqreny&v1-d3jZ(z z!|z@YrNHmdATaSeh?0qFUa9gaVQV%m)kg&;#Gz2gW>T^bFTncZu^xmmgqq7YF%)yp zpkeE47B84oRK{F{GqS?XJ>n)!_&&?JoFRq)X7V^1)KRo&ooJ@lB1dchJj|CK&im2_<5GDXm zaiY~D*is6H5km0%EYC44%qs6WQcte5&M9(*m;ul$JtakdRV!8r9p@ryly4shNM87p z?BZ#;9&-Qm)~fx117bkQUP)<-g#L}(u0k)ibOhx2ZAm?ji;=23z_R;sxh z2<6kdm?ZoL-J~UWrjh=@hx?bbpT&LR&;l0eG;>R?VO{9|0c6EI&Mj9jv*h1BMrhKU(mi74< zeU}fM$D%BTI4YWfKwap)oZ*{vpPQfleWGC>SY6WAjW3Wd5!jr-YPA=}mJnyLEQ(g` zEi-J>7@mxq$y2fce|lvp%fF~Dch*GBcQt7BQLjFP`J|Eowj~WS->U3R%OS`6@Gt%3 zXW-BL$Df3gUqpEA?|l#U4>m!7Zta(CsD^xQc99axgTa!*Isb;?44{Tv2 zL*^Cf@F2MmfuZa|oTuKRoJRL>%I0`Dr|<${)K<C@)At@p{EmCf^{uuW+xSgxwsXRCyAnp2wuM?Mvf$H=!)#xAxH`Pf}>83C{od$MVK zb3DT5|K&dff8ysq1^?TB_Z#r`JKurTdd)f$<-IO@!yfFzdRhP<^WKExF`a&PqWBcW zqt9N@YoC)*C@kznd)(8 z*GSk^lN8`#)1R(s?8d0hqOTc+xyIdjo{I9mt-%b$wD)i?AJ9;a_)e$T9pry|)4vrw zHe7)xhsSft_czz!`m_RjZ&Ft8P2+ZVbC{3&J{phVC|wy#BcEW$9^w2chN8`ym`1lQ z={$ZIjgvH&?Qj8bQ5Wd?7<9GS(h&M9^nWfss-Ok=4Q0-Ij;iyY`?%;1{^l=503h&% zG4MZmV>!t6guNACo^nPKo(PH`Z95qXg=auEU>ifwhXgy%d7Y=X?S-_Ry_W^((O2>(z(QKV`1KA7^lsvL4rbeJq*zzAKe} z20o&k0#1cnn1MVp{}RTF5efk8?%O4)gxA{MvZ7q}73}#HRR7G6k;!;@f^LDPU7V`N zw;tz7Mhq9=p}mj7&HJxU-Ev&Kq_j-2#!X+zctW^^OwT0B^NgDGVI^g04Yrzjt z;^ak9^_!wuz_T#rHEOUe*F~)?YR!ffhmF3;t9Wh^F~^<{CdkT*72}L9zM2mSAlsr% zdO@7TbCrHU!VngMd}3G%Wy-7b1g3~1fSh<$zDxTD#@Uqi;Qi48L#5u6wiHzm7M;!( zJ_vLboxp|0aT}C4D90e%uL%eCJrcuIP~buc9heQ1+B${QU@>A+@5%{stI0!oWpxo= zy7UqF15bY({>fXf!prxr!kx{%9ImCjnWAE#C%B>WVv#AuX<`jbV^L= z`V=}HBajXEc6Op24o+Zu-%9@y#yKE6mF5y@rBUt4bR~T#%I@ITfw<>246Vl8PE2!V zLzv*6H_y5#znGe3&Xx%{uuCG_B3LtU6DSy-vqy}_odygGHKTWj>BvBsXQHUd zqJ{Kh{^Wec$l=^Jcu8Gj&yO%qGfa&wj*5?NZbzGY#^=zCDrgl$U>-{9kN4$C@eSM+ z%NVVg?~MGPv>=?|Q;V%!pPy%eBb)6rlZsbM_z&|94+^cH@;f!;N=CB5;p8ie70XoG z-`|JtzWg2d_IJMnd;0^}=@T-$lw)@Ajq@hYcbB=y3Dg4{%JsLX!dN`)an;tFRE5e0 zEU-81<&(YwhN7kuIf6%#qq2w3WcGhhKmcbll*l|Mv-JRUJrn8C&EwbM`YS(zz2uD@wuIJU9d>)R zB!`&Lxxq_tHejcIu8O~X8uGvKrT-JI-hN+0WarZkrU%e^AjmN~4@a2R(&p7u4y*cz znmpA0sDPa@g~q0npEtblT*HsDMVIWO1Aj|BWL(uP7L|jZI!O<$=qT!L1+R-aKz_IO6 zdz3^$a6*>xvf#E&3H4!tU9z|sY$~gECFdraAVZ~7O6y8kkO)A4xTwO1OAtY&Hy6db zo8#)h%N?cW$W~jB^W5jAR6o1N~J#1^Ka?0GG z{h#|PjpyXf9uN0n@8B?p*N7pTs@Na);W4@df9|J#7Jl+?z6iheuYVK%k01Ot+=9DV z(U#DFfhwU3&}kQfv^P`C~lvYk&2Z;o?I>^nkh6X(H=CQ-Bp} zX&u>|%yR{sBS$(b?VZWT3K!|haq*D)_Y(YL9;^{6p6Qg=g81k$W?~&_biKsES$yFv zkCqw42`yX|Pf|L;4$J9+D_rMezso6isq9$7@TSjW{&%#Qyhdq8B@ZH%&x|wWB@6Y; zY2SfY$!#nKA{Q#;?)Xs!p#1SM{IYKlYepH!o}vsP_AHakH|{SKjL^aNxO$iXaxYA7 zkM|ha&=yYud1xL*<7H+P2^>;IChQqu9$@q@JaS}O8m*H@s`|>+J)@0L^|#M4BLDK- zJ^QDb?kI#$_=#aEw#+sXoB`%o)Rt7}Wzf*h$RTQQLvMwgl~ky3jR*Cl=NpJQA|H;X zZOK_Ee8=txuS83jEaPH}c4tY9O_E!@xVa&kF$9*@HIu)yx?83o^%vVinxyjNt$yyA zPfs3=Z^F^Z-Rj_g$Qk>|EAqG---YRXyh?4~#7aaDKzQ&m7a6c))%+aVa~2qh_BLsO z?fxNLym%3iuY`GET)^gg8GiXTW^ zeIiH=-cJu@@fZL63%^JQ!+{fAhCmkhKoK`ZT~<*CunXnP<72;EBlE+cJ{9AWzs6~1f9&~Bz~Qa?aQ*sQc@LD$A$DK*-wKUsg_}fZQxdCjAoX;{UNEepV3PWE zp$Tf1;pduvZ^tW(@l(QbDELjq=#mSU%M(^oU1*qkd3j#tlL_;9@c|piAqoiDNXn+| zWZ!YEO35fpsi=$Iljdx@o7Jd8x#_~_bXCID1VC~!~VpXNpIVRn`T zf>6;IAd>JrB7hmg2`7#`NJIU)I}m62Ez5sU9?;H#RiU!?q|=@fU6D#FAFIX)ceRU zhtY#sA5gM9A;8Z44(U~iQlSy6e7L);<|8)-hGNw(dCC;L)++&{jN=jJ@bQc|TME@);wpHi8zy4+RxEd$NJvG8K#47kJ!_MQ!1kOGy% z15nLnlbtdx{!Rwc|BwwN31joD8iAlU^dgXrRf@4BM+%fu8x3n=b+1-Nz!^uP5>Y|8 zOmd-&)FR^Cs`0#cpFN5`;Eiv4;W4>8DnHHQ9T)RYm} zUumh)J%C@|j~O#a(I)^nREFP>FD*(UnKb}?=3&%Fc3gCR*bjqfLa1Og!w7h(!W~$k z`^z#erKJNOmXT`6_fw&Tx9P>Z`OgL<6nEqH8$sSnCI>c{PAlbddswIx&*-QvM(da2J9;uV&g2{zZO~MB+V9YjWh8L3rQ>JdcRHp2%)< zEAJ}Y_-WabwxtoS)wh`zG9G^TiFC;!ynpTeawpYXIr7wj4xW69 zl!NM-G=)OnSh9sT&C10QJQZ&nhpMi{i78z>(bEgSQkW9{=*M}hk~-@y^DUmOjX#Y4 zRr?h3K{~4ew}Qy`=%Jq*Gg+Az4buYV{_0`4e{`c zPWeZE>d(Mm|K)#Y`uxjqd;Gy9xA#5z=bFyXP^tt!M4t3v;W9Vhcfq0#oTW)U=!u5X z)g5qgl12Am*a{@hX#eCi7quG8^V+-}prZ@EAl$0rFIeyEbWjPLbt571o(mxu4=lP0 zZH@u|!%zH=bYZxt;W?6>>V{)oNp8L~k_@<<&{Py)UhTvZ0u(~vzycVGj2OYk=8_9* z@)z%otl$-f;FX6;=4g@=@*fwx<_92BA9IQs|lhIdR00rqbz^wMNMQHD0ElG zyzs%X+bM>bpDzrEY6cf4Y_S)_LxN68W%{eCBj@`IgPiUj0@Rb#KuuurM{W2tsIoxd zjacccfyc2JNgPUww%?-|YNL9r7^>2EIh4WZiyGw?lopUZQg&|R=nOqW-*$}K2I^E2JnGlB`neQjh2wwvKSTV@aVYkk##z-a46weN@<}#=9BWg>WTFh zFwG9lq?;G^wNi`LHvR2Kp@mcUfZE6+Q zswzWnp`dTx=8&_j6bv95lWbtPC z6y?v@uyEw3qI4h|VWN=6bxQ(&FOaP$i$ESiy{sNU*lgxQPtdTCU?YVQj4hW>l}>9w zR`P>_rMsORuF{vKAIfuNLkYS`dOqK29SkZ{TxR&4Vj^qW=#~NW6h7>TX4h`ypV`Fb z37|$1&FnMa{_!;BMI^aQvLA&)sGzi(DSr}5h#NMV*}xec4OK%c{mcPs*}%lw&DKey zdQm8JidP4f*+_jnFSQ&LA4a0b4f`ktWfR5tlc|jElIWsb2lfIe%!2DCGG$B_Rx(N` z%&25ccZ7|ObP3|XAlO{$_eJW#!9_F=J#FB$9eb?Ed00Dl~?^&#`R+|a_b1K(z& zkfdI!N~(9yW|kR7+$tKw8$JR+IjWTx<-_9~c^U9tBXZtJn;z1CfAjZWhU3i#fj(t9OJ|A$8x|rQnU2L8%Au}3G-lWfNJrXA9#qH+?+^o0 z`c{s`w)IAbjiWK(g&j%tK9?C~d|~*EDdCk2%^*Zk9o+cySaq3Ztw`1NOVokQ$Cc4tc#l#BiW4ya>D0kM8%3qFwb(dpFTgeJ2MKT)7&jC5qVTQ`-+)+SZ3qm4|sn z6_>YR(eci>g1u=KBZVTGoLTW9IRIPET7Wr2DKD_3MYGLifW6yJX!Sg-%Kcfftm{~s zC?6JtxWvFaMcQiYFg??0%2W`}!5~pRnIbQ&Io@f~hr2(C1NSRh#&H2Ztn`+4jxR}l zei8NNqO+_(qF;D>fO8BG%gquIQhGicNm-Xu44W!axph7jDu=R2Slh?~k5_8J!a%ez z71gUCQWT|ff!@${k>eh*V;G_ztY-pJk;M1=rN8IibBQ4k&KJ&2mu{)40Xh?d0WV5e$r^e8vGNeQHM#$Eo$bS5B`0UldIf0xOV%88AG{_OY^an(> z${QNC&&g`c)PST4hGD~=Hx#Z_FYmAtJ^<4exmK|7Bf+M;+b|6hI2tFzB|JXBd`SAhXcboawe-lK?+BtXGJs#% zpb9gWyitW_M3F9{Iav{C1Qg4xh{DPpUG2)~qtU@G@05Rq8blrv7e`;Hw14`Vu3E6i zqr+-fl6Ki_8AobY`>~G4fa=sVPd)x_r#2aE>KHKq%kbWv=IilGpEGsku~_FrY&LWs zRGM`Uy#S+|1%}d+%R{(JDv8pmI~he$DtFyqH4lE?CSvhX)zEa9hza z5_GZ5c;AEUFA#-@Tsc-!(zEsY0zCf0Ww`$4y@_~k7s3N_iVqJsf+~6<7P68=Ls#iy znNkRa(Cgu#icXQm;P==FUD@;(fep+rB4d|B4|HFFJ}-66D4id_WHHxc{ z8!Sd0Il>3q3Fi2F{ywTgVMp$2JFpc=Wn9L5x{G&8`Dl&wcn#RB5EWgtr-YPJ5?Uv1 z@vHjY*VOhV>049`W&|k&HVuB;G5G)&zRSjMrY>)avPIS#739)sx_MlUH||(<504R> zTt-g*V`V|c6_{CKY>BF&Oe@xo;+4^|`R}Op+W`hv!2BaJ4}8BM8$bo`O$NYyLuC{b z16)Dz3X0cQm`0&1zd#{AHLU6@-ZVt-qpRmBu`!CS_sC-|-2+wJTdAEqU7M%GcddnU zIj@p>T?Bi9r&?XJHV}3`W zK2c0dki?)s$i_lKKqp1#sYjoK3kUn~`rEHgCGL63oSB7H5<@**aWL7k&ph+Qq_}P1 z>ecIwffR}boE1fg2jqau1#T~zpV>ACJ;JR?FodT?Ek;)Z6*@-<-be0akp9kj$y2W9 zF|mDq>^8BbJCn%If;DX^<-*&_N0sVO#RaLSFiM+sLO7m@t%o8XHn7wCCWF>DBGO9r z;ynzf@CF17GK#yy4^K8H@UdrJfEPdcQTXatf2)MK$*6lWY!p?Q&mBHDi_^lkh!Ozi zWiJ45TLA#aJ9k&W^v?z{)vHNc#%J+}ENJgyShyfJ%~V;-)}|aS#v`5Xx}rzmkN@1y z!VkXx2E6>*KhArkKTMC$>0tNeE^W!#t3!0^MK#iCytQ))dEYwn;(NJXChetLr-P>Q z$-HH69ns$O?q1%LnQG1_?~W;+X2T1kc8N4~7BaF2N%s86;k=&D*d|(F11c&lqWFmm zt0;2Vb^-FVoEmaCt$Mus+8r1-CALumyb=xr??mC#Ds-=f>{}RDd0AWPD@w({VM21m z@rntZ#lmP<%Sy6^uDN&C{ovQeGCTtCN9`hS{8!^d_$2YkT!Ztk5$U8w{;zCwEDHU= zVNpf#W7To6&b4#=Q5l~oiMFbVfLC<PJ|l8!AsUx`HmoPVQtb9_HvQ- zsLkWj*`>fnR$$O8?L!GIOD<^+qZF@TSW z2u}WTe_?@506{q}-ci&wO}|T}WV1yEf+}b@cY!l8nWqIgOTH$Lm(X=z;jjfID}}NE zMb1RW<-S%3i?m$W7z?=CvPYT=v$5FP8aT;0(@n68=?2mFEijUW&UlM^_`xR8#tj zI?vsRIK#-eiNLKChbm`YpT}(%ptj0}EMCkfH@hg#HcR77sX}*%eiUlLcS-nF;tDzFTTib`vVWBqX49RU>9DRxE_@a~z5j2)M=m}D-?;rP zc>U;C;NJ1|EYC(90hL$EX~8G+)&2XE2WdZhkXlCSSEdWAqZ~?StCl>;3Ln!%=+~`S z>@!X@!?4ZqW5PzJaJ~AMpAdUc#F%m_Oi(<<&C=OqTl&cD6>?skqB$|sLFfGu2&#P) z=D6x84>t9LWeuvZ0hmHx6i4BAI~av{pF(X2xR6qN7C%ae6|iBzo&+5S61`dsh*4Mb z!L8~>Ek*K@O+FNbd(?))Y@D|w8~0+s z)bBiml9zaomIzNVK2X~j&$$A(kA^~}xyE6Ca?MX>5^i*3cHVriFb5u>=+hvGdxqpb zu)G^ey~R>LloO1|`-@}y$|#hTaDTDewmu_wFO%O7#7?XV27%w;T_T1D@Sf;x^_4UN zsxYtL#S$Yy<+&4c#e}9A@vYDq(ak_PdCbG}NTBm(0XQXDMyeH<#PcjFCXt(rMAg15 zYT5}doOGMO&jKb1jG+kHaG9`YaSD73^3YiEcM<|_q&FXZY|qMIQA9a zZAIKdA+SP8<2GeH*4NLoZBf8yU$}yQ3U5tY2X=IIazajXZ3z8Dt)frBvKk(lzd+yovFQLmQ1Sm(Zkb^`;$?941VwR9N#~E>hmFq zRPc*hkv?4cZASZyVc#=&#Jjvr6(u^$!7GKY$~6!9o-0a=amjnM&Rak(uAhg0`(u9@ z{>%UQ3amd1@bZ5T@E8A=ufg~3{t_IGhmdY?OvlY{h;L9GSq9^Yi87fw(|`XzVRqI# TYtT(|00000NkvXXu0mjf#NShs literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/home_24px.xml b/app/src/main/res/drawable/home_24px.xml new file mode 100644 index 00000000..16b05380 --- /dev/null +++ b/app/src/main/res/drawable/home_24px.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/ic_burger_menu.xml b/app/src/main/res/drawable/ic_burger_menu.xml new file mode 100644 index 00000000..bacec338 --- /dev/null +++ b/app/src/main/res/drawable/ic_burger_menu.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_buy_receive.xml b/app/src/main/res/drawable/ic_buy_receive.xml new file mode 100644 index 00000000..2a5b6a65 --- /dev/null +++ b/app/src/main/res/drawable/ic_buy_receive.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_fingerprint_large.xml b/app/src/main/res/drawable/ic_fingerprint_large.xml deleted file mode 100644 index dc94ced4..00000000 --- a/app/src/main/res/drawable/ic_fingerprint_large.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - diff --git a/app/src/main/res/drawable/ic_game_hub.xml b/app/src/main/res/drawable/ic_game_hub.xml new file mode 100644 index 00000000..b5d78123 --- /dev/null +++ b/app/src/main/res/drawable/ic_game_hub.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_history.xml b/app/src/main/res/drawable/ic_history.xml new file mode 100644 index 00000000..76a538bf --- /dev/null +++ b/app/src/main/res/drawable/ic_history.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_import.xml b/app/src/main/res/drawable/ic_import.xml deleted file mode 100644 index 33f6260c..00000000 --- a/app/src/main/res/drawable/ic_import.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - diff --git a/app/src/main/res/drawable/ic_moon_stars.xml b/app/src/main/res/drawable/ic_moon_stars.xml new file mode 100644 index 00000000..c25a8a7e --- /dev/null +++ b/app/src/main/res/drawable/ic_moon_stars.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_no_wifi.xml b/app/src/main/res/drawable/ic_no_wifi.xml new file mode 100644 index 00000000..f64f8536 --- /dev/null +++ b/app/src/main/res/drawable/ic_no_wifi.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_search_black_24dp.xml b/app/src/main/res/drawable/ic_search_black_24dp.xml deleted file mode 100644 index 61d91f49..00000000 --- a/app/src/main/res/drawable/ic_search_black_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_search_gray_24dp.xml b/app/src/main/res/drawable/ic_search_gray_24dp.xml deleted file mode 100644 index e5f82282..00000000 --- a/app/src/main/res/drawable/ic_search_gray_24dp.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_send.xml b/app/src/main/res/drawable/ic_send.xml new file mode 100644 index 00000000..f07ae57c --- /dev/null +++ b/app/src/main/res/drawable/ic_send.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_sunny.xml b/app/src/main/res/drawable/ic_sunny.xml new file mode 100644 index 00000000..f37acfde --- /dev/null +++ b/app/src/main/res/drawable/ic_sunny.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/import_gradient.xml b/app/src/main/res/drawable/import_gradient.xml deleted file mode 100644 index 0c0655b3..00000000 --- a/app/src/main/res/drawable/import_gradient.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/keyboard_trans_button.xml b/app/src/main/res/drawable/keyboard_trans_button.xml deleted file mode 100644 index 001754f9..00000000 --- a/app/src/main/res/drawable/keyboard_trans_button.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/lang_rounded_background.xml b/app/src/main/res/drawable/lang_rounded_background.xml deleted file mode 100644 index d169d0a4..00000000 --- a/app/src/main/res/drawable/lang_rounded_background.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/load_wallet_progress.xml b/app/src/main/res/drawable/load_wallet_progress.xml deleted file mode 100644 index 13b3878e..00000000 --- a/app/src/main/res/drawable/load_wallet_progress.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/loading_wallet_layout.xml b/app/src/main/res/drawable/loading_wallet_layout.xml deleted file mode 100644 index f7db91c7..00000000 --- a/app/src/main/res/drawable/loading_wallet_layout.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/logo_circle.xml b/app/src/main/res/drawable/logo_circle.xml deleted file mode 100644 index 06f1c1c3..00000000 --- a/app/src/main/res/drawable/logo_circle.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/paper_key_gradient.xml b/app/src/main/res/drawable/paper_key_gradient.xml deleted file mode 100644 index b598fd33..00000000 --- a/app/src/main/res/drawable/paper_key_gradient.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/phrase_field.xml b/app/src/main/res/drawable/phrase_field.xml deleted file mode 100644 index 45e13728..00000000 --- a/app/src/main/res/drawable/phrase_field.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/pin_round_corner.xml b/app/src/main/res/drawable/pin_round_corner.xml deleted file mode 100644 index dd3bc258..00000000 --- a/app/src/main/res/drawable/pin_round_corner.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/powered_by_moonpay_blk.xml b/app/src/main/res/drawable/powered_by_moonpay_blk.xml new file mode 100644 index 00000000..e50847a7 --- /dev/null +++ b/app/src/main/res/drawable/powered_by_moonpay_blk.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/powered_by_moonpay_wht.xml b/app/src/main/res/drawable/powered_by_moonpay_wht.xml new file mode 100644 index 00000000..f32694d4 --- /dev/null +++ b/app/src/main/res/drawable/powered_by_moonpay_wht.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/drawable/progress_blue.xml b/app/src/main/res/drawable/progress_blue.xml deleted file mode 100644 index 7a39dec6..00000000 --- a/app/src/main/res/drawable/progress_blue.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/recover_gradient.xml b/app/src/main/res/drawable/recover_gradient.xml deleted file mode 100644 index d2c4bbfd..00000000 --- a/app/src/main/res/drawable/recover_gradient.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/restore_gradient.xml b/app/src/main/res/drawable/restore_gradient.xml deleted file mode 100644 index 0c0655b3..00000000 --- a/app/src/main/res/drawable/restore_gradient.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/rice_partner_03.jpg b/app/src/main/res/drawable/rice_partner_03.jpg new file mode 100644 index 0000000000000000000000000000000000000000..31184179b6849aa369855ea85299827a0b3b19bf GIT binary patch literal 106705 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable/rounded_16_jade_green.xml b/app/src/main/res/drawable/rounded_16_jade_green.xml deleted file mode 100644 index 0131f223..00000000 --- a/app/src/main/res/drawable/rounded_16_jade_green.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_16_lite_blue.xml b/app/src/main/res/drawable/rounded_16_lite_blue.xml deleted file mode 100644 index a0f69c26..00000000 --- a/app/src/main/res/drawable/rounded_16_lite_blue.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_16_lite_blue_stroke.xml b/app/src/main/res/drawable/rounded_16_lite_blue_stroke.xml deleted file mode 100644 index fb99be1b..00000000 --- a/app/src/main/res/drawable/rounded_16_lite_blue_stroke.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_dialog.xml b/app/src/main/res/drawable/rounded_dialog.xml deleted file mode 100644 index 1966e963..00000000 --- a/app/src/main/res/drawable/rounded_dialog.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_gradient_header.xml b/app/src/main/res/drawable/rounded_gradient_header.xml deleted file mode 100644 index f7f52e7b..00000000 --- a/app/src/main/res/drawable/rounded_gradient_header.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_phrase_word.xml b/app/src/main/res/drawable/rounded_phrase_word.xml deleted file mode 100644 index d1a039d5..00000000 --- a/app/src/main/res/drawable/rounded_phrase_word.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_pop_up_intro.xml b/app/src/main/res/drawable/rounded_pop_up_intro.xml deleted file mode 100644 index 92a31865..00000000 --- a/app/src/main/res/drawable/rounded_pop_up_intro.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/search_background.xml b/app/src/main/res/drawable/search_background.xml deleted file mode 100644 index e0905ce2..00000000 --- a/app/src/main/res/drawable/search_background.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_blue.xml b/app/src/main/res/drawable/selector_blue.xml deleted file mode 100644 index b15a11a0..00000000 --- a/app/src/main/res/drawable/selector_blue.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_blue_stroke.xml b/app/src/main/res/drawable/selector_blue_stroke.xml deleted file mode 100644 index 09411dc3..00000000 --- a/app/src/main/res/drawable/selector_blue_stroke.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/selector_gray_stroke.xml b/app/src/main/res/drawable/selector_gray_stroke.xml deleted file mode 100644 index 6b058272..00000000 --- a/app/src/main/res/drawable/selector_gray_stroke.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/shadow_back.xml b/app/src/main/res/drawable/shadow_back.xml deleted file mode 100644 index e9ce59bc..00000000 --- a/app/src/main/res/drawable/shadow_back.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/syncing_rounded.xml b/app/src/main/res/drawable/syncing_rounded.xml deleted file mode 100644 index fe3e9214..00000000 --- a/app/src/main/res/drawable/syncing_rounded.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/transfer_amount_max_shape.xml b/app/src/main/res/drawable/transfer_amount_max_shape.xml deleted file mode 100644 index a3f5fa30..00000000 --- a/app/src/main/res/drawable/transfer_amount_max_shape.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/transfer_fiat_option_bg_selector.xml b/app/src/main/res/drawable/transfer_fiat_option_bg_selector.xml deleted file mode 100644 index a59117ee..00000000 --- a/app/src/main/res/drawable/transfer_fiat_option_bg_selector.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/transfer_fiat_options_bg.xml b/app/src/main/res/drawable/transfer_fiat_options_bg.xml deleted file mode 100644 index c5cb8e63..00000000 --- a/app/src/main/res/drawable/transfer_fiat_options_bg.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/transfer_up_down_circle.xml b/app/src/main/res/drawable/transfer_up_down_circle.xml deleted file mode 100644 index 4987b161..00000000 --- a/app/src/main/res/drawable/transfer_up_down_circle.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/unagi_social_01.jpg b/app/src/main/res/drawable/unagi_social_01.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a6e1522ae28d2c0058f2083265fd52e7a1581cc GIT binary patch literal 160320 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

wXogejiL5!Pt-Nm0S3tYHbvvYpJ{GsE+ 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 + + diff --git a/app/src/main/res/drawable/visibility_svg.xml b/app/src/main/res/drawable/visibility_svg.xml new file mode 100644 index 00000000..f3545116 --- /dev/null +++ b/app/src/main/res/drawable/visibility_svg.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/white_ltc_coin.png b/app/src/main/res/drawable/white_ltc_coin.png new file mode 100644 index 0000000000000000000000000000000000000000..332e12a529200907b4bd5ea9fcaa9d3ff24ba872 GIT binary patch literal 62986 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 z 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/font/ibm_plex_sans_bold.ttf b/app/src/main/res/font/ibm_plex_sans_bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..258c10a96a9c949899883aa2f6b2794f8d1391ad GIT binary patch literal 218212 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%0Dt)?|ZenVk6tGn+p#T|0OZtI}57*Pwtj_P7} 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 z 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

hshK#+6Zjj*N-ArT&)tHow8O0e-%s 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%0AQ_&pM1}9mbR0ai}>C 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 b+27VnY~9P&r`Wo))aviH-e8Yhr_}!eucjlR literal 0 HcmV?d00001 diff --git a/app/src/main/res/font/ibm_plex_sans_italic.ttf b/app/src/main/res/font/ibm_plex_sans_italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bf4395636e534a2d0a20f77840cb51777ff03750 GIT binary patch literal 233508 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

Z;0$NfSd%{!{6Gv#HEh)?vz+O7@$~D4H{- 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 ev^vF>SJ{z6R_dC^pr?9dN;g7Ft4p#0h~Uo4RRi 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

bg{Wd^k0mZBS@A(pE;LQMdaGx1 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

G$yh?hx}5Z8UvzY{8GLaCA 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%0AsV0KdBO7B%_Q@u9Ti(=~w2f#rPl!*Oz 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 z z%JT(P{U=5b5t^hvB&VSU*^mi<8K+hAxqK3#`%~E}MZJNg>ohb7#(dLcGpf^FdBOX; zn-*XlU-RyrrPbA?JHd8ushHO~XMmrw3Gu60FoU8J_jTM;O$Z8Egj8v#KkG#Njv_r5G7=DYGGCcrc$?O?1moib<; zRCBMVk)(5Et!V|!{Gkh*=hvX(7Y$RzhsF8m8>o6)n_2Y{crKxnz}EsDg~mrJJrH+g zjTUWc&@d<(c%HDl`9r%^S$lStRaKSk99IzGcp7B%_fdvh3lom9tye(-b|V6gRo`Q4 z7DCM`98=CD}oHi$JD#QiZ`EBBzJEsv}y*j?dh2%zCuX0AWe zanjJxrpz;rn|b1-Nhi*1>+Ec6>*~rpYx4m}u^Uf^W6d!;yI1t|F72B(t#4^B859|o zzw#_~G3G&Xix?DIJ_2X}huu)$xFL8R#DpX@cF8EQ6C~o$x--+44-Ku%Fd>=L(J=|o zFeHB+Su_zSl2%9w017)v1X#%}%(mykb0u47n9v5FPtK1LD8!J^zmqyK`Jpzk;79Ur zE|v@_n^MK3Kt?dPYi9L=ro%(0wB$aN0MbjMqrB~TYbr*sC=bqH$w82295eLvO1MrhAr!A=9_TA zOJ>LPdQ)W_5D$&q@u>2Fe)NGN+7+aTR;b_7ye8hgx_Mn*Ww0_-kw+2=jE|!;Ip`m_ zrkR`+YmiZ@QJ{N3Ts#7!G(5ZkYgXbUc>qs4!JEm>C3EetykHALvb?B?0J3QCCq;8H zEHCiNX9Xr}c44_kJbvQF5wT8Gzv&8kuK2uo!{sMFclgH7uejoK@xiWjm#twAos04w zMR^(EA6OCK)U&La(ryLo#_S4oCAEb#BtXnTr<4lK#w?N)oZP;rE_QqA8fM4P^{B0f?i@{dCI0}T`--krt|+#J%U;wusiZaUgrVWh zC+4-3OzK*c9r5_0uEDOp;>P?_HV+S-nqMDX|6r)dX0-)^x2%s=zCfFCy-*ole@ifc z#G=rH>x*k%q3v{Dslg5nf)=xPDht~>ooCxM*vle2Hee<#o(>Q(2MFI9XQKeewW)FVXIGs7t$C!o#Z&; zsfvXwd&)$n6}J1RNmfy~@T}^2;l=GW@#4;Dr=C>N;_v8eT~IKuVoU$FUGqB1dn>!P zWlnADE3fg^7iZKrulLpzr&rgPMY@~Xk00opmu|JhrZ;!3ZUL0k&uB$ticJM1i#}oo z9RW2^7lRXJQ=0%|bHk=01~zBty(05?{LC2n5Gx>0+jE|{2D5~h?m2IS=OH;?{YS8) z+z9Sr)A#WVJEdYeQ47#&EYo7LyGY>g;Ue)ef2SBwMxkJlf+-Y`7`*OF32|Wfj9uQw zl9sOHT}7UPm}_&#jBvg0!ZQHt^Dmai*56s=gPFW2{LuPP)$3?5g$at~kV~Tv+fg)O z7*fWU&oKH__Po4cohVvl(oe{nvg{kHo;lnr z2exha_J;2K0o*y&6YT$wVx5ru|RCiLez^j(r1JX4- zf{lr(craaqKP6{kjhqoF1X?DTB(7mQ8=X%@Nw8W#>%0#Zpu%`IbSNH8urvv~$Wh;g zMbzX$=&mr?ptHgu`NGZqLp#oGv(ya@|1&$__|oR8-i&y=4B`I zyevgh#ooCsMdgJ>8HGNPotdF!i24k%CPQc+@sF3l4j1Hs@S}> zsgd_yhZl5IoEcqt(X5&OwlcbJminxZs$@ z7tUM0eBOnNkGWvp@_WP{e@$l$pBjJi1ndnqmA(2@cs`nTg}gvrozq`h>P6hGOzHJ% zG`odG<}3^uvf0;y-gKfFoh5dQvqCE`o;~~G!QhtQ;5X;Y`Q~8oTaoaT#nsivyg}cK zr$i<#oqySy<1U-Gbm_dyj$3ot{H1q^hiaE}bWRapamRcPSl{yGe@N1?wHIQsxa!x$EJd3;#3m<@NQ; z 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

BMSC{T$4l_*e&0+lFGi2{`< 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≠@`*rf4E6Otw;4dl$ZZ^O9zT(^;w zbGGdXo}%tHmghR#HlC+G*KGptceZUZZ-3@CkQzDLcAH;svcH2XC;K%jPc1bnbtyIE zz4=)ChVsPTli2b==kmtTMr9H!!*tn<%Wd zV>L$AZgrE|18Vz%+EUdIEAt06K$WW>Y1#aw@iS-#9FGFW$>1_YH&kPF3()*~i{|kb z&CiHVQO{ySbyCmktMt{hoT_gAy^UHWeIw!TN- zqvq;C`hN8e{P3Wfr$@jQ3*d_1sgLwy`dRgDg+No}=fg zkbYNxq;}{};FbcoIeNToKs~v=cwMGH>hJ+ctLesZ^p{2)?0K) zoz&TEN=I~5YrRt!pe2iRiEga->I1r|uFwZ{D_zNUA=>RH-9{hRHM*VA#?_a?hxPP- znEK`d-O;o%7wI0tjrvCPT~~dR=sSHgJo#&Vi|9Ljn`k`U7oB&f{tbF>fbJ){Pv3#| zyI1!Yjzw+`GsE;<@awhoS|i>fz|XbUi}!pdN`PoT*0(59^1~ zhVSVy!pZs(bm0;`7G1bZqan;n{RF(7smBR#>+vSn?AFhiy=I?&-Vk{~Pcqe}T2B#f z*Dr~#)YIVk2KrCJ^ZI4sdHt%>!Re%Dp*_3nzo0>T>Dfqu-uiX1?ev@aEwO*F3%g@| zO~Eo-Uz(~bf-J%P6+!+Y@?M}QNx|>*kv=ZyzUjN2y1H*)@Dn$ z$Q_I=n2lYfoY~l6k775?BL8#Q(y+q*^)?Ypt-H55Z?nzEZu{jegXiLX&fMe;WwXC8 z!q%K~#wO2l=Gi&48NQZUkqw)cx;eKETh(sVVeMvfp+?VT3t)#1_cm+w=2|OTEbX7$ zikt$wmD+zO%D;5_w#$2SYa`45c8;4PR<``ZV%Hy&|M?uZM9?4`?S)g@EU+=l*0Nw~ z9mj&E^J7RN_e~&3{)Ls+j$g#DV#{x`7W)*g7mIy5zstWY7XDl?>gCm+yg;LG;|u=e z{}d}MnkeJ?G3dySrulo48_qa;;~;Nn<3Nm{4c^d?DFjXiE-(}gy@(57u|>b+e{ rd;FH9>aa~2H%2~}+w?q}-fq(hn|8Blcbi@*sbcIF=>dCY1gZL85c+v@ literal 0 HcmV?d00001 diff --git a/app/src/main/res/font/ibm_plex_sans_regular.ttf b/app/src/main/res/font/ibm_plex_sans_regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5387ad48ccb9dd751aef3f1ee7122b5c6dd56946 GIT binary patch literal 218236 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
Wb2hTQ5EP@lT!aID6U0GG2(= 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/font/ibm_plex_sans_semi_bold.ttf b/app/src/main/res/font/ibm_plex_sans_semi_bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a63f1c5629736481295aa89d20e38a0d4286b6eb GIT binary patch literal 218248 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

tqQ97l zoOh7(u(wC%TF9EsH5dO8S{a@%j?;r(PhLF{~ z!alr8rgzZ9>atAlCmpeq?FiB_f?OX%LXIKVBS^?-^cK0eM(jRSi>GCl?ThU1tmJg9 z-J!LwYVH2?OQd9`8s?W>zsk4WrtTH?_y?pQ%m3JxxuTaxtQ-iMzl_$cv@`b@(SxS4 zjeZQRpVsQgK7!UgF{`Q;?X>T_9++jQ7x_s=jd~C<>#%-32rm*nhEy9^>^J2JAYrLG|zdAzkJi&qzW?`f^fv$8E(+@!@#TH8pjTiE2t$abRl zJgt6-O%8kfq?R{oxtU(H?}O@(G3(3vl(Ie9uH}t1vq8(rIB)V%=&{vTup=J}n@tBY z|EKk*C0CL7Pl6r2$}0yOl2|$Td6>n{e9LEd!tAKmvwpYm$X|h5<==O>&W3NJ{deFl zw7=Wm_u$*}t}9?Atb#SL7Q%9F_1m3ZzXrQt4>b6FBQ!xXw7_22=UyGqN#dMhSF9qL zgWxc)!|IAoNsql-^<<}>?9_|cDXu=Nm(5Zy{Bo>i_x_zQn-Ba9+Go`Tn)_w(##dF! zZ_~5y`a5!~ABcx@3py&Z^-<$kpemWyr90H6m*ZVW`UmeXfu+#yxBc_1aePA5KPJ=e zQ+Xk)w_c}i-Jx#Xp>EwF##<%ETSfM9lNR^wkRMgQ;6r(r{7fgl;OV(u)RyzyLAmwJ zY|*P~tzB8H61DzEi~!)z9{kypoIwXFWC;gk2?t~e2V@8bvay9(S)B|5(I09%?)oMZ>FhS;Kx=!+u%A zep$nQt>2;bI}WLQ+nv7XbUBjNOwyY5WQU&YkWK8DP3%vmr!#r8Sz60a(Bd{DYz^fM zcDJ4dO&eqqLDvR7+mO>$9<)gOp2g|3{srG#4KKo0_h8Lvj{f3XdrIAc>#n8FP;~vg{Gpu+(caOPxo4wRC8FZnatKAL!v+E8%{ow)6-I zdXyyf>Ck>X+Mq{myyOUaw1FNK@TP<}G1~Aaty`;QF?tf7asyr3&T_|!ZvVW01J zK&Kwppm%Lp5g4sHXkQzA>sI$o)qPWS-&EZ8n_OSHbEPbq~$Scy2#Yv0{#?Y~S4vj|hmzpJ-l>3>2Z?{|F=6~oHUg9UufLc9&jp_)y~*Rmen{jEn9 z%eDKgzs0Yix3$n``PY)(y`*<9>D^#tW`mKL4Mt`*#F(NU_p5;W&IQK5->PSgde+Dr zui?jb8~a(qmqotULRvTLS)-mc>RBVN+d*GD=xayjaqo3qz&9;a34L4~y~yg^I`1_= zBQ!xXw7_2I)5(qjUN-XU$ufddd4SVkn)u^%I0Mdvye_?xRoTU=>|#}R(YfV%5Rq(* zgGO{!J_k}SKLj+9q(^RESB|cBByUTuk~4l1t~T<2jY#!c*XvwApG>B!ri}Z;R>AjVJ!X?1TlZ*h0I=KW^+`kyWExNNFh>8y!H$JcV?QC!OQ*>KM{_4Cy?k_%46H z8zMtK-)}B}_a~>yIHt)>&yaDvLywP=b(|qzI=VO`c~9{pKEGI`_;%7bDE+L~#kj&u zvG-S4np=%le>@V*i68}Ys|%e~AjLzNmCWCdARLKc?rFeM(Ql)Qr- z{;$^se$Fc`psNe{$MByPD;b8#}qn7>OUt@T;_~(u5|9Sk=w-0xpHOu$iX3cuzoUgK8k!^m*dp*|c2VVb# zN%l-TLf>pX(U(d1SBZ3D#c7FkO6Y5W->o1ESsYyY9{;_G&)!8Y?7L1LK0rqD9VBb{Yn2;+JI9Ys zPoUE=hFVl_`Zv{t->5hJM!o4bstP|*Rrrmn!cS$nPpK;Wn^^eYtYiNSo15vqo{4A0 zTbudr6Y+FZruX;o=lA;ieiWFiM=@h1uj0PIe=nsCHFC#6w4sfq8%-l>^s*ye0!!fq z_goDxLY@0;b^iv}MriVkW@v%E(CYWr7G?HepXYW!r$`37L^Mb8>r46drTqHRgQC#9 z3OoUICe!yRYAC0=o(5-&hRzYKoC|M-clpk{!A^g)tcEPqpu$W~y491z;(f=uvfO($ zvU(fvHLM<+?wVV^7M714!0(0RAjbV47lkhJ_j0|j^P4T~!dCa|v2soB*$geP7g{0s z-i|{1$W;e)vRWzr6=5`+(No)=z+z1{&m^~qEi7USi`c>2L;|3DarE zS((3It4C{D&8S?d5tEyqJy!D_Y~y^T4$t^Eptvp^X8#_fc zyUE2S7H(wO8y+o28_6SflZ%)K7;>?iT(pvlO?tT~n+os*-i? zvBht;x_^V$jnL$`&CmjSq0d$nM7$H&iV1AR1k@RnWj`sqQG^;9O)U(D38a3q_om3P zPjx*Frm>dJOA=ibMOWsM`p#M4)S&@(BS!e%<^6X%DsLl4F=x1jwpFu1QSTRpd%YIwdbMi=?HWP5YH3$3 z?W(0+wY2MSp7`+B(X473wSq>iK%EtAPl+eqCC=R?&fP^`+Eq*1RZAMlOIzlN4~^p6 zSn)P;)JTpR$x$OYY9vQH$x#cftLCk%dFyJFZsoHY`K*}xG*1-Y#=^JtM)4o)r+p)6 zU#&`TO-?=6J76|^TkoTWbQkTq+u!$keV^Aq4ocG6sMP1)y@m!>u;8mvZ*4}sn9=<> z+qB61sqj^O`AvU~97Q8*Xk-nItf7%LeU$dBt^T%Rhc?#G#v0mKLmS&@;~UnbXk!g+ ztf7q+w6TIVR`hD)WHqKKK08(Ja~e$J^G=5|;7rKJpk?&9V@Gb(ETCoqHTR?7Y7|_Z ze26t~qiq}14fp36pVxPIJsZA_3Nf$mZm;vvTM<3&n@jtCPBVWY{&~pv=XtNs?`=Z0 z?JRs$;i9(NmU(t7BSnL4tb53y*+K5P0#?E*=*bMXy5CNJzXrQt4>V{;BgDvB%pp7s zYGmuRFxZ~8;rouDtz%#;j3Yne!9GdkZzuWN@H+l*6RK@Owe6_39o4p@+ICcnQM*m3 z_Db>XsQoVYcsHEyy$itke&Gj27fs1UpFzoi zwV0S6cn&Q+7v2iJev{0e@B0^&o=Ilp(FEJ|Iog-YVS70PsUwH&>2jt0!Vk|1Y%kA+P6oFQSY*6H(tTR}p(Mk!Sq=S;!&`*XLmctb|oCFiSb5 z9DUT0$9D4AP9EFIV>@{~g*={eNanIn+d80AJeFrGBgFD~1X9T!9tJfsj#?NDN6^fk z^#K2`)`|NY+RB&(C-L{Am6*RN*TOCEt-Ocq6|Fq4Ikk+56EOMRnY5qa#& zM!@o@2$l@ZhSdLy@pM{8C!=oHLqE=^w zbgSndI+E5Cee5ECyU5=z^0$lp?cjfRmLrftHiFjQ=8Z;;fz--#y*%1Il6H5Bb~{D8 zouXZo>y36_KT0_prO%NG*>#v~np46qp6@q#Ce%s8JCjSuW+#e9q?^m;EE@V19^+Q_ zF3*m~h2Ic9#|Pt)h3UR2+5 zKRt-XN9{2(t&r1Ba@v~7Y3`$YWVNRT8M691Q8P}hh8JOt=d6Xu$PTrgFY(nciJZ5R z-K}JIE7{#jc6VplSiato{~Nx1(w&S#2e&tz@;8 z|8C}$T6v|`9+^!p>(%}|{}_U@mAN-UpTezE5V=XEXsA*&R4E#& z?3e!@OyQW@EI+}Seb51&vU;m+Sqf{UMC7$F7Unk&Wow&Jvxu5S)GVTAHEN3NQ8q@42E%CDeS`>V42*?wWNti6 z=IfneU@Wa*EUjQHtzaxob-OnfT_dVmBdS^>s#?QB#44#*$g-L|tCEdSBPI7T`)$r(@2}V^PoZI;_cZx%vx! zyBc1ER`0jLKELgNPO+&SfY{T0G(Tp5b%;xwQSSii9YDPUy|OtOWu2R*7K1kPP|Y&WmCT%^PIf4vtD%7A-d`iU3G}Aj0yUz5t_848Cqa3 zv?fQO_z~s0a9^YqquhN_R);970~a30g~xH>@hm&-wF+$MWUF7N7zIBhBlZ4iFim`V zI@rO0cdL=_7v%d^TOQ)wI@#b(vit=&caY%@vrA%5ddx_!%i`j1lf{_N^j)(^ z?h%#U>+k!?VNXRqtjYqB+CsH}$5@-kaUmkNOoq)F7!c$7ZSQ<*_v}Bnsonkexqkk~`Vlb{?&rM{7sHSRK1a^tDJ{ z6*Kxf%|pm%Oy?uBF$W=bL5_KEmBq`*a?J3JxdvD8e1&p6(G&Ytlw;otwz-0B-i~5D z`Bz0=)kmd!y?4K=-9S$_sBg_!c}(*$+WxpmE+5w{$i)i%#x;%n@np|?&I(uwtDw%k z^Z2)dO|D>*E7;@;)ZWe}Z)cMa&c7mtFa}Eg2YR>)Hn{@T2eHY6*yKU^8a8poc*sWu zVw_YAOw&(-lVK{n@i=LCz0J6=9~b)avw%MmN(*OJf3(_-HL+J06eD#8VFsz#p0!~LqkW$V#X4L;O@yt!;aHouMq zc{2<0=GUskGCvof_&BCi~;eI4u3Q%OE3Htw|^tpj4?ypo)# zk0#{*DHbHl<9aQ~C;Cy_czj0fh&h7VJz4P-)E>iDxA(KvQ`qUJP&~%yx==ha+WO+JKKA&}V4cq)2+uS$${YIxxf7%`gH$rZs?WbvMH%7r`qPo)xRj=FB)Vj^> z8H97zL5dT;Elc@MaLicnyRwmwtNN3#tN*}D7$;0Ehq2i`~C%xuQF&UW~;Ms?jrspAA##xofUJ+ zjKX<;;L5CsS7LohoVpkLZuHEmx|-+APh58Lme;Z7WZ;ad3LG#C5@zZBSKwBZxx?SN zFNhj&mpHvbEhK!wK3lvBwO8Mr|%E+2|YF7E}ZJZsV%2$9ej^(wfge>4{upCd%{fzXDdmDu|gW>)n5+*RR1Y*aJiu^lO>S zDfi6Ri8ebDnw88@VR_?oR+r*Vei}@i1aq~W&95=D?^@UET(9@uryx$TGrrG??WaQ> zbSQEJqX8nsnA3NU-rwu>T<`r{&vSk0VzKH`w3U9u%;K1fZmk?@Mg0GQzgNSH(6h?4 z&OLHV)ib;P;5mRTEL95~=tRX%RE!$nKJvbgyzlFk_sQ)06c(&!$De8P($nD#I1{F; z+Q+5M^9`}K5Xe_|DCaxq*2mx9v`lgr>L6~<4(p%yL9{upF_VTJjH z6@1GedeTWxI_XI#JxN)(H2plE;(MyShtrdi+@MMott$On?|mJ<0k^7KI=d(Rd$_}Q zzUgY`Zn{&#&F=Icyw0i?y#L+a`>wyg2VoJv@A}X1L-<#i1Ap+`C9o8p^Y`R%!?YS+gf*}hUM3B%`tCZ|02^TwY=*7cy3KVv?0}u_@fz%cdVlY6ZP4aM zIJlx=@238iGVSvB0Vs)<6R2d-sz}cuI80vlY1ID{>i-G#e?|u$q60sp0}uJ6nn$l@ zp$6<7fCGQRfj{BEpHMt1YjlEK=eb2QKVoEpF5D}gy5DE9YB;Y^TA%ChhhaV}u(S0- z6>TyNIVn{}+ux^k_29t$*2 z%+#S0;apkP>VJRFgj%{YaLoQ}1Av0`Dj%JP0yjTj;B z$;V@_gxFOnR&JG7e#*VGdJ_BeS-vOMQ8px3^;F|j-m+7uT;mj~PowaSaI4R6$JPGT zIJ-vk`c3A3ly?Y2ftje5d;ca}*hkM|y_ywWzULG^HL6%o+`?it(YgIbUaX6P`*0!F zW!}#^h5q$;{fFq#Jn!Z6&335lb(nh^WBKdTKY0EUc*eb+g{59Er%%s&y#iLkDp;c( zYa#X_sPn9?u+#gm!7kVX4c=>neyhT=s!3%;+9H5KaG2Njkd@1)^fPADtj~0^Z%*3| zoY{dhJ8&jeJ*~%?^=9Q4WQkGl@0r`S%bd0$`K(WVXNJ$6hG^DjQoMvd=DP{R`C_eR ze3s7>$3c}QRX{7~_@;Wksh)4D=bP&Jrh2}qo^PsGi9JK4FhLwQ!KpO0Vz~*)CtUvq zt|~oB*B+&3i|N>6UT%V@!Mu1n_r+uye|30b_8;APlx{srw;s)7JCykxM0|G(xzAU( z9i4v7-?5WO>;-p+_hVf|%p|_sHH+)KzDHj5Pp9pFKu;@)&P9A6Aa>T%UzJ#_PuIZrtw1?e2W164%#Y7wm!8osFzr z9nfi|dZj4(FsPBo*TQHOmLqXv9E!)@8L`^#MDLvhC&N_e)5n3k#+@xE8W`{8x_F`A zyjL6@-1~Et#r3RXiFGWojwM#Hkv^uZVk3P_S;Z2o7+x@85hLE)PdCl!1gFoaJCx{T zR~}X9`B(fM(L)wBu#OQiWYGfabFaT+)TpQWxS;e${%vLE+hQ%^AAGh1o^iitVX4=7 zJ@}w#!E;u_i_kL@q|UwjM*&#`;Jug$a&QFD>b`Bzu1(oE9FNb_7prmL^{bSz_VJJW z-XHnBm2_?;om)xgR?@l1Y@hyH~ae*bHHcm$yekJUrnZ# z^Bp^TdjH$zoPUR;;?_s~4 z4-3qsTgW#(Qu@cTZj7QECzhj-7xOu)+GmGxTw9K7%W-Wpt7zSnQqmq6p_i5zdK5sFoT7EUL}LI*b*h;Mb(!*P@-D+C$_X zdx+da4}U5~k3HG!@F3?Jkz5Q`Whd5^C)SlGmqF|{afQ_dAA>8Q@ATPb7PLesn_1Bk zom@dDSJ26kbkd%Ve5&|TMX8=8?LC1uv!pZSSuu+B6}oz>*D;?XR*cVK6H<+?YvZw@2W{7#IuVd^R4AvdhH;J}G8pIjdOSw*7T7;5yu@!>x_DwGp>A z;?_podX8Sk7~(6v(b?+a2O)I!!!U#7e8l_V zD=+ujS>1GVWO56=Tt_F{)6cVFUxb-v7UcT4mOd^^|JHk7hi|~GKD*uZ@8J$I{!Q0! z!JUxnYF+vdUVjJ0?{W=&{jPJmzUTEl&eHk5>p#Q2KL4TXzruaqpX2&t*ZYmx#5}t^ zyM7KQ7t!G@ba)Hhjd^wZac(aQyN<4|qoeE6=lu4Mund;VGXCUxsLrlsY1gu}YgyW5 zbaq+#s_(6X4X_b5!Dgt_wk`6gt@^sn-`ima^w;ltfA99JT+i$1c^y69NY6LY^NsX; zBRzkOp4X9{m+AWRbp3g{{(Rcyx82sk9B?hMvI(R(Q_OO<#hKn$lbRZ_Xe|sbJy;yh z$BwqQO;5FJ3aL2J-zUMzFco6n-i5C3Rmr%64n9c-`_^(_!_Qp@J!`mU8F9PK=eMf_ zeTg-Sx<{5#)2lC&edp1bgWR2d4gL=DN^VC#pP1lsd)X(pszi0;aF`=2#hc%o{kB9XJi9d2ispplj)Pj7{xgk@vI6`&s1utZ*AW-$u{3 zvA|s{a2NfKJ%F6p>)wA2AA}Eq9Z^-8yXkqSnoX?rXyuoy=y<+6;J4^`Bmdh#&pYXP z?Blo=#~bK(C;jfE-%&MQPrp0qcPCCa(C<$A-ATV=Zft`rWIX+r6Pi(U7b@NDy@*%8 z=e=0z{C(GdhI@VQhpzt$bKu9al>5cR`3OzVm{^R^JW9XY>36$o^YDDGnAeZtYCbkL zoUS+0b$gq8*0ZqG>*w6_kFX3PbNQ3&^FCVvD`6G9>b-Ta0XD)W*bH^r)-wvf&EMN$ z2ki8l*I*aa`+JXTgYPy%lm0eC3+#oy6&Nu$r+4)=-Hu3XH{I@}+jez=fg|+|^gCAE zKT3KYB|VSQ>vj_KI^%BMn{20?eB`H{uD8?mcDmlKqCMQG{cxl9Z#3>Ua0SP^+$&rA zr1pBg-(3I~y3c!g^4a`(oTgn$J_2?Tk{Oj`MkSe1NoEwgNBxQ|d5%ASjz51+&O6Qw zlyS+`GNWtkA9k(lb*}$kZ|4FYMUn0Cs_ISx(HImWpaO!3il~T)h+b4+5d}ffRok>(r^Sd^Qex1Ree;GzFjQMf_jpCB(*#!3RE1y$Z!sF=ir` z&|~CvRe`oxP$o6ss;sV`$Ny3hd?B)85gOqGBH3PUQ5kw) zGO~Arrci&MWMuCJNyW&KLQqr=ipoLJVNi4!6qSRVYEV-JYN|j@6{x8~J5(b>szFIC z8lV_dRDp^rP*DXUsz5|6h=>jEujY*hkP%h9*(%=bZr&_a$lzzMPcJ-=s0@3c3|l}V z6Ig9FL%U(0UMNF*FEU~;cEDcj0I9aO4H>Zw8By$w@8uj4vFL^6csxtn_T?cX7z1X< zXEeqRh`|ns!w!%cCgZRL;_#cJu?1uvUg`lMbMSy2JYejCJp5*v1!jv^4+t$J^F|6n zN`C_(M?gq62+0N^*{48AHVDZMLr4IGMEnXuDuM_hIsz{qM@Y$OB1Eb!lr=yIRToY| z$ble2DnLj@7(%E9^qUAN`5z!8RH32Z{|F%mP6HtaPa7e>$6~z~x(~TEg!ND&GsD;( z4jM;d(Mn`xCg|9V{Md~A*o^$xjQrS){Md~A*i2;QIwC8f`F>-GtjK)7u|!swN$FUR zKqbC`^vhJ@8%V#5H{b7gsz^+Lyjq19FiN=wn`J-#L3r+ENGW-&hRndRs3HKNv(jx+(!*m3mw6h z_i8ZK;58QDH5MR)$XH@O^RM7JM&LO{fHFqm*XIYl#D=42^RY?tu}K<^qw%U$cgGvN zo^yu!k9zTcZ;tN+1xL>!Z;G)sVu%4qUEnw}m0Ht3B(=rjh;cVTmedeAJzLE}j(Bwk z22**C+$PXc2U_YtOC4yb11)uE8}S|&AWIe?OBNtY+MsRPplzB2wM~CkT%Le8|9#lzQ)EV z!!s?zGcCi92xXUuS1Of#{8*|W$R^yb(; zkmqqWtOeN-ZSzaDATyCAJCP-M$dWu{$v4Q7Ok_zWD5*rAWFk*?sy8fBPMsCI7?dmp zB}+lcQc%(gl(YgRXM>Vv*d%9zl4jT>OF_v}P*RB;sbr>;dQg%Rv`boGmq?~;D^Su3 zl(Y(>{GTs zW8X4({7YyBBi|CyQY$&u#_Mf9U~5oOfGtvhW+?;}g`lDUpC^FN6Ts&QV3$_@r0Dh35C<;HQ9Wp16I7a|KD1aXn z09CojpIj{7T>Kyz`<08;8->*yg&!1+42nhuMI(cv@stmuk&b2S;Qs`WKR@CB1n_?X z_&-vOwI%V5cEmT@fwo*wmW!2~2+9&cSt8o0$_XE37wWlfMbxT2nxup6L#V?4slxxM z!vDdOX8+Yt7p&ZCpsvuhP&c&Db&%~#K>LI$U)YLdobMK>7c!~4q(>1d|yXr}FGrtN5^?btERuw%STpAp0`CEI5d>-(Y6$NB;3cfhN% z{SK@{*+1j4peI0&6AOPr`W=u%o=@Z;dmLns19};G#T%1(h9<$=lR>fcyLcF%W2-cnev<33ZNG_JEAN@rUTxsh!@ zlm%r&dED=2$cx965?RX*_95;EVf#VYe$cg_NO?99v}_`14adh76G1zG-9w!Nen$;d z3yHtQBLrC@zxE@)l8|3XAZtIdnSutkkH{`>RM*9L!5y$)IwH?5hdM!5LE-j|)b;Fz z#_P-eTZxGGgKlHHKl=yZZ{2~s9EeOC#C4?Z`e0%#cXNKJts(QCds<9p?9YRYT!rI+MKjJQWr;0#HF(@g*+AT&)9YRYTA`-5NglkYzhn6ZuOGzI5J}lmS z>J`5CDilvlQTh{)N9?MD5j(G9Zzy8-M~?BLcGbwXU{4lauZ#xwda@3k9JS*u9A3L5)|BKOebcqj;QKGNw+7;&JXW=;X?V!EsZdwP6&`_Kv~x(byViKvLP&i`pNL zzjzTm4>4W@Zx<1~O5{-OFGTG_)esxbZnPZ@ScC>F1zqJ>&*jbyP)`u+jRLY25xwX= z=;;S}(fhq1EmTpqn&@6NNUH#8`-$#Jg=)#jl8Ul2CV-irLE;DyNJVP(A@XA<@l^lY^ShMT`ibj!9;r|o&tyH6&h`(SZv*6mGO*$^S#RXN{ZJN^4drkjxzHx) zNA53=``ZkO9NWtA+n@sWZ)d#&+6fgxyZCKIJhx)DOQ1c_Pn>Trv=1uf{{yTKa$Ffy z&hM&#DxpJA75l280MGC+&#nflh3fd;5$^RU>w1uAX98gDBF`eQi6XJHqM$}>N3%Wy zIunWmec>6-98t7xex}-g@I;#6afBXo+n{)*EQ}lu?YIvAqng`4U67jn>poi$JzTVi!e0jo5BX&to*2@(f67(#K(K zpUZZ0s0DN$a_oGlJ+jowM#edJv;8AWmXBP+%Gl4rCzJl2;YWW3?LUvkc*P9)dIQLoJd4- zH1cIcA}%Hp(UM5S`N&EKS$RI0sxfLAHeVs=lv?)WN0=8TPzGMWxWMh2E z#`uzr@g*Chr4!K72}Caq@ohs!N(5SZ8PUr~Y&psCiolkOz?O?Z7EAPUzj>TDi@oRB za%3=gww&~3OOA0JnXAZMXd3h)Z;yGK$X-=suS&*uDcP%v>{Xd9sRC4%dL9Y?zs5CW zrouPaC!;FfWS{hh{~4MKiAN&+Z}XvdAd#~Pki^daie~hBT9c5mUm#;^(B?%!Ih%r< zm63Ghiy^C|{>%4#Zyn$BqN5?3uYzn?MK-J=8`hgiCzJI??#B;hLD|rWInbg0IlK~% z-3D!kc0fC!Ldf$lDVed%qs02SR}z6&5`k9|fmb54 zNCx9&JeR|4*Fd#U9dv}>ag=pE=oK5%&_Cut5y-7Z(D7c^_vzD@*)ePIfot%AYl4|g zA^Ew7@dg_CnF7LVKzI!ZuL0pTAp8K@{{Y&5mvdqbni^zfGGhxI`s*DcuxH`_I{3XZ zn?p3Q`DpCP2x9Zm#O5O%Bqe@t7JhFQes2zb@2B{^S@^vxuro{XdwtlMS!y{*-UX7k zBWJUavsuX5EaYq!ayAP&n}wXs0_96Vc_JuJ1m%gKJQkG4g7O$p9s|l_KzR%(PXy(O z$ksgaN4Fqf^VFlPAGbX^AA<5&P#z1)V?p^UQ2q_FG&qIl=}>M zaUeYnOQRUiWe1+i4v_veNcVy8m7sbhvbG3WEAxSU1EN=g=*`%sJFLw83+uO`c^u=_ zoXo~zNCU|!AUP$7RB8mxU*S!xCg)n_-jOW*6ncWz z@f%X1G_JiKN@qI*4ZM;2@IzTpHk8Bt=0cmGJg&bP%7=RjxHqZnx*OSC#P9lvWA{S) zpaalBJ}ZOD`F#~oC3Fa?!kVat0{qs)$l_x%nd^J#>}EZj;|N`ejGl#zo&{1@BBOVQ zp>-KDdQT9c-nc!RBSep}%niiMv_U_54>EcWGI|d(dJmdDG=8t)=wGiA-1S6sdq6ip zJsBNvGv~Vn3abK#tlopH_9LtP$ZDC}P-eB1Sv;fhl$g~Lj__vjRG_!E0q3I!9C@xmc_b*01m%&SJQtNlck z{Gj}E5WX6O=YZ}MY-m6Bvme{p54x9QH~X=h{UCfbcC#P5*^dnOgZ9;+eG_)GAH++R z%xVz78pIc1H~T?+8aA^Zd)W`-H(@9Hv6KBEJ_Q@u59+@F@oTYtj@t%phju_ap+aaE_g%y@C}z6^+5`Q>Irc*Ppi=%n!1^G^ zl|d(G&TNA-w!s+%a7G%Ok%qOBh8^rjey3vx`>}(Ikl)Pc%G$+CiXfZ25!Be)z-zIA z*J1-Nfh%&5;o;*dJ^9_QD!mK-=D2ad>rBcyh!i|y-T`<_@!w;TUo2VD>KfNp?# z5+n6SvAWp4l6{i{2jqbM$Y9Q76zFF@5cGr{(Txr5&GMND`j>+Ke}VW!5TB@$!Vq78 z3@<>27a+q6kl_W$@B(Cb0Wv%s@j1wGL3|E~&p8dm?*#GLAbux^&;AX>`#^jSh~E{4 z_+${D5k&lk28d4%LwrU9#Ak#dz7WLcf%uFt#Ak*f{>L!HZwewl2gIj=_^cq}%R&4` z5T6F(^Fe%m7~;1C5r0M);(Z|A2jX);d=7~BH9)*Ci1-W;p8?`CKzv36#BTuc8%}|E z>~T2hM8s!+_zV!A5k!1O7~%`j1%>E>LUaK$*MjzH(C#5V6U1kN_{<>U#q;|m#Akr` z3=m(09!LZ6X(0YH5HFGYaKx9BbwEuxWO#@AjUYZB#OH(fd=Q`iA0oaG#FHBe+C9YQ zgZTUghz~SC`%cha0NM+X^#xcl>B##6UOmpYk^2&lZHC-$irjCC+;589PlXGlWPlcRWWNvDpA07?!wJc7f)ClB3?~#K`wNl%4XYk` zRlx&1m%}`h8mJbk<9l8V#E0xJL-tFp(lX@!Mz|muE)Z*I6fnMp za&M#-N*tV!3Mc%UHFV-EilN%4-HEqck5$tHx&iVmqEJ1Q^>9U~n!%o+C3LzqQhjiU z4-WCcA-Qmf^osi6kgtLq@&g>=!{cORwoJTr;4HEqcvGmPey?`ZoShnNsKjP{!jaiRO!9u1cpxcotU z?T1(*;q)@r@?-jK-eJ*t2MR7O@Z?;s`m5Scwm_ zEoU*r#z2zFKG&>aE78qwaJk((SI&&87MRwOjWv1NACriXP%D#|v-E znQ6(kk?mNX&mZcav3u6o_Dg>Cl=}P3g?R35(eEx%vo%D`)(|yYqaKD_HI=vW4E|4B zWH0pzux;DI2U4kEAbc^%Rx6Mk(j)Q-*2=wnGK5ct^2soIfSD!Ee&SUx7y>^G#}1OY z`eg3TD9)D5*(5$A8L9Q0sSJCcQ6gmQMDa`PcpECZK|Kys(IKsPbfKPuWK6Niuh=$O&HdH_~_(3a(4&h2t4n5xp(RmaqZAAqjy=(!TmSp=|%JOqV2f` zaHj+L#EwUkejx7c9`3X;pRVRARXhV`gX0K$HP&P^1g};lN8us;o;~-H+c%V_EWdU* z@@WM3#P}tyDAmlsEk{&wPe*ws$~%hn2=;kLRdG+l>Sv-4XJQS`1kaKs(*z_-mP`|L z-%NDhOzx^koyn1@9GS|IseF>kC#igr5kx?}eP?&sdzB30I-&uCK{IcVaUP0s9*S`u zig6yw^7Lrd4?x7H(3##mU~R!=%r9Msrx(T36O5#DJ(-)jo`{D$mjKuL8LoevnHl=y z4Gsj8gSe|Z*}jYQV9-kRn4{8o8s0cRnVEG2@_Q6H9kE=mkl$6v@1ouUG>+^_@9F-G zRIT$cMW*90kjk7zV1v0_d4{9FvwZt_MXF#0D(HG;x<7_K2nmYYCOEX3f4r5f|aA>5A zE`-KGQ;A?dL%ixjqAP9D1>T&xAzrNw!*M;&hd0JuH04ZboGFbnrE#V-&XmTPsyI^> zXDa7Ri9t?~-b|@EC9_5D<7~A&?F0DeE@zWjP>&#u8_s@5UL8^OHAL0FR0(+Nr<##& zFuM5HW~K9H){TabBj7M^b~>%75W;V03EE`o65;W>xSG+X13=Cl=q1C`j{t$xPo!TVMLht$0=)_`c7?seIBGaF5*iDQ zgJkc?Zw6V$XAO@Hoxjnqd>YHuV|mux8^2LB;z+B79)w#(-%RE6XF|vI-BnN3N8L^VG%k<^C zlOCqi^#<*e?-8%kW`ML>@<6n{#9-A1;lYsYvZ`cP7MYL4@v^ErIF(n&!o=Qumb z;J%dqm;67`GOqKV)3?r6r_gQh9CBAV2b^==<<0=Nquav$#BJ?d;EZxVbC&gXoPIcEg@otto!yW6yJ3ZVv?gpO5 zR=EP#SS(ku*SXob+3Cw$8{oEZ2FtbB`w8t3dp)kmHODw(xMDAsB(6BYnc&{TvfG*D zOyR0|a#fZTd);+hdz~}gUOUT~E!Ph&8=SeE>s@D&^AYD?;w-bjU?BIuQtsYad+g3< zxEr|NUd~1*-JM0d$=>xIp2;DnmR}ypU7f>SwqR-Pw&xjj=9zSJZw#H$9p;YaoMYXI zwDK&baUZid=R7xo-_GyjSuW>0N!-8O@dln0&(9SceG3u4#HymkCQ^{GjOe7ZL2y%~ zUL5vc3pn9CB0IQ{h%JF zC+La#IsK}BO~0cT=)dX3`tSN*dbv*2U+Hi4_j0mmVPUcF})$}ku%}wTJbBpP1`k3FDTTMT6yXkN4FoVopX0W-( zJY>e0hs{_s-aKL^n#ar&<|*^EnPR4zXU%hFnweo?nIjIp7|xkaE9Y{jlhe)V2^xEm zVIaJIfo&Q8ug{Tf-P*R1wtd&OJ?W#=`Wo9xf2CHl?EV|1Wt+EYZnS%{?Vjy+yPa)& z+iyK=+lltObEP$1?4Fx!dx>q&v&T2HZC7d49J_t7ZJ)R8752#CwjF2NFKqjgZNIi{ zls&Suw5r^0x3_I8+rDr2*V*l>YHp7!*JX?119WZIyH(8Ji)4s`~VY7|fFILn_WD+14x(@M1eY>A(^N-*thHQ`81{IYaG&i;Gk_9Qw14P}k}x zeWtnz?rWufr`zbZs=vNSU!(@=k$S8eq{r(=)KEQ1KdFZ6>3WvBU%!s$GhV;1m#C-p zr}_)^NBy-FQ|XPON-Q}@X|->Geh)SEyW|F_skTK z&5>y8c{D4XXtdxe=NzY*S`8<)Qs2Nuw-BBEE^1WNn5YR+Q=%qCJs&kaDn6<&drp5D z!?#a&nZR{UwM^kI8ZMK#uTw40bJwT4Oy~EVYKiC9pS<+tiJWQ~5PWX39vn4sgNjvofcjlgBJj!_fz zxuE$E7R^&Enx7HPqMpT)>ZD%KSL&1Wjv{k(oftD8}&l{iTY9h18ymVTRu}o`g6TPmFSf^N$uC)!8z5Ib82*&PE)nmc|WK+ z?ZehPqBHeIbyR1uD4nD8wAT5$5M8-jm*`milRluE>M~ufTk1-d^U-kueSxmi_2>z0 zTzwII*jQg;&M?jO<))=+qq_??>YLDdUG>eP_4F<9L(dRy*Ds64)UU$xXX=^4^ZIq+dHtr-(dne;phLUqzo18Z>bXdPUixjUyS{q9 zen)H}XS&-Nn`|1^*(^)2Ck^S~E6`QTIw>Yy|=3>G9`tk|CL4ME4 z3%^hn`}tyL5x=y-;(UZP+F+mj?<}!rn}@|X&sk=l%?y5hg9XbsxP(3tE7)4XbFemp zi<2%3PxN$_<=Caeyv16+n|K4izT{bpUc3f*Lnkj{|I30EZ{Hi%`spl=*xK@jW$Eb7 z5MSZ6mRiRy)-o6CTo%+a%VeIaU}_cHa<7pgBw?v1fgtbm*4Xte_*AU=Bx}7-;|^w6 zn#G+g1{2+Qt~UnH)sJ(5Mr-ejwJ-MmWNYsWTIBBKyWaZ^y$|sLJTE}rhj;<9YzRJ= zB#xKoh(CbTmOrh(mDcpKt<>Q`7TN8yZF`p8gMGp=VwGqlxok6XkG8e6da`ZlgXPl? z?Y6hSgWZEy%8@&#&PVe~McAIz~dnQV2y4Y=^cZPFo7g=W`-6>GIT-+5K0263^gQ_gpy{OMq|V@b=S78 zW$k4nvBs!tS=Y9bf-B-rF{Y62kVNe{)@ZLH(+G=Pg7z8Rey|J+5{4p7`osLj3j;;{8$UhC#C*BSygA ziuS~gb)7v+&J8pXlGH{>;I2;Bz&heXqR=kJ8#}uLo( z(e*@6PY@$Jiu5j0fZ)y8H)A;AF^^Gw(6(-onp2S(aIF%D4WKSq3kS2ofkq&!mlfFsU#F|KxiSYZSFulN?gQPxb!4bn) z?Sc{Snq?z&&q#coxH=at9ntR@Aq`8HH6EsPf74m}_K}#v1tSOR8gB!;VhWoMGgh>y z@vx5XZz?27?*B>RpJyQw*hZ5bH-c{b~z3=n>%*W(2+o#iKyU!gy$9-db zSNh)I`;}jbUyI)Xze9c>7(XL@L%sg5)ctk8gMY+y+D27#=xgcKBncS z5!3TQ{z2_QzX^IHI4^iv@Vy~ZLaqr-49yEI3SAId7up`WG4!0!OGEDteJu2a(C@=^ zVWu!^SXx+p*ygaa!p;l3J?w$77sEab`!<}0r-UyJzdHQ0h~S8 zjSP*9j=X$I-IUfTTc-L>wNL#+RAAJis6$b2N5@9nqUT0;MxPUXUyLaxF{U}@w3vM{ zcg4II8yuS)n;qK`yEFFU*n47Mi+v|{Y?}A9>C-Z%EuPjjZSS-{nuE>D&G%ShErXUf z;*#Tb#64yWwVr0ZdwRk2o8$HIYvLbHn4NIfjF=g#W;`^L&diwk+nL|Y+A!;{v%X54 zlei)A{-ha6JxQCB&P+OxbZOGHNh3-3B|Vn(LeiVboyq;l+miPr|0enBIZKDYg7H`s&ivG!T^ zO#4~(^X$L3-(`Q;{*3(xhnK_Th<40$taNla1|2&c=Q=KOJm+}L@xJ3r$4{At%#h63 z%*4#hOlRh8nfGTto)wm5&PvY8&ML~P%37M$l{J)gde**d|Ln+YYj$dOZgz3@gV}%0 zemVPxoYtIMaz4*Fk*m*b&pniTPwpeR&*uIk_r2UNbAOucJv(G}?Cg!R&zQY$_S3Up znf>nU&u9Obr_T${i_J^S%gQUrtIS)H*OJ$hw<&K|-hsSJ^RCM~oOfT|V|mZ#y^;6N zysz^{^L_He^3D0l`PupV@-NQ6I{#4q(flX!|DOL={-^mr%<-NRI>$UGdCuURopa8e zbK#sH=j!JM&5fShJ$G>Kj=95ge>?Zexi`dTrOxY|hn@F3A1??hh%TrpSXR(kFi^0) zV7TDIf+q@IEI3y1alv?$N^dXyQ&~h=Tvq3V$8n(BSkpH_cceX_=@#=j=4CZ;C7 zW@F8cnzL(etT|kBPt993AJ%+X^TVRJMTv`Si>_OAXwip@zFhQEt)Vu!Hl}t~ZDwsj zZDs9}+Lqd$+D)}*)*h_AtoDZ5+iM@F{cG(@wQtvcRQpw3aoss}$LszDXJJGA_WIrR z-!;r{xUk{V#Zwkr7AG&xUVPf(LyKQud~%6n$gmk zicKqat{7WcxAMA`&#!!ARm!TCRp+g`WYtxxZd`SE)ibMJTJ`3t_nSkS2b-U5e!2Na zSCXs7wbgZ->&uquEuAfgTTZqXw^p|B{fg z(KXz4bJxpVZ+Cs#_5B*YX6BkDYxbquws%VJ^xm}I*}Xe^_x4`g7t^<aCNbyL<^ z)+MjYURSto;kv8Wll67$Z(9FTe`f!l{y+6UF_1g3XW-_6&j(Hn#thCMtRGx8xMpx@ zaNFQbgU1Fx8nO(n99lDU%g`M|FAcpp^x@E#8*(=cZn$B?$VQ)yog0sBGHlA(v~1G_ zn?Bwgwt4a9%Qqj{61HXKmIGT3Z~5>v=V@K1-E`VlTm80nZoPHu16!ZndTi_GTgSEq zZkx6(ZQHzU)!SBW>)Wy>k1y?dNa5WBbe7f7lVVqj*R6 zj`Mchwc{T<#&*u!xoGFgoojbqzVn6CeNQhuebecOPXFnQiZc$L@xmFO?DE=`uxs(I z-Mens_3*COca5DHcV^w0XP$Zgnctn2c-ES;4xRPFS?}+jzPoXE@9smp@8133?k9FX zzx%b_@9zF|_jkL;&h|b#=dGOAIC(cVculu}_^Ns)J|CsZg=RbKt&IS9i^TYW;a{E`pKMEx} z@0V~tPIkhZY9{FE2}dW^lnb==5$3I2>ON;h4Xrdy?J)veVH=^oa-s{2s)gI9dOyx6m1FOU7f z>~9V;Pc_GyS>|-J-8|b|Y+h&HY(B?)mH8U;b>>6n+st>GkDBi{KVS*5gj?b) z36@mLBFj?CO3Njdn=H3m?zY@(dBpN)9E;P(1;z!(g~d&ci;YW)%Ze+HYmRG=e{x31 zjLM{-PmX{7)Q@a*Z0scbYT>J8klCbwEF-JQY2->t;g$4O`ZRpGNJ-(n>{0d#CtN>H zVFD;T6BO>}=kcrgP5d_gq>kvKb@94%U5jpwu3vXh_pI)9-Dh6YLE%nNc%_+`P3A~* zwAl;_XPVQ@Hgm3|aL~L{QFw#-u=x)2kx3NRSn4dxEC($&T1G5)S&n*87z7HZcu?4; zC=8Gk(s2rX;p4x7bTz0YWX9MOd6$>bFGlYo?~j+SB3Ix{@f$*ZdW(?JH<3n0aatMO zD0+-uIC{}|&+*Jx>u?rm62;?1TIKP~cb-P6{&?DP$J=k<|I5b%kNY3Tnc%qZai8Oc z<6g&g$Id@?@L2O(WO{ zo0)Gq{_*$MSG^A3KVoWVir1fY-||sHp{YO(p0_trES)aku{YUq_BJF2%EdqK3+)W& zv04e`I3)Dssj?MUKARWH{2+gxzlhVv>pG{dUe~KT69)y6_Ik}F#A~tFQm>VwpLP|w ziGN;I6ZwgpSE*My`qv}1P1K5<*K#eLT8p|$&l>(N=^-w1F8L!?U=3E}I9wkqZ=gE`gIr0tpo_di{N-3ij8U+bXBPXey=F=>iOAG02az1s^cDjnT&{n#I zuB2P(Uh)h*i#$g6k!R`e$#?Wh@&mn!oS>JJf6+gXAL-TPCwhn)=yha_-b6XpvNydR zXR0GKh~ABJ&QTgd@1eo;K01ZoOC#yyG@d?6t@KYcnm$IS(}(F)oJ$kvlXNEiE1g9X z=~Fa`K0{Mr6O!q(G?hL_)9Bx5I(>oK=<_s#I_TeNCOt;y(U)m9eUr|mpV2D%IjyE& z(na(OT0_60we(xsK)<2&^lMs2f21qu4|Ey*o-SoRbS=}<)pV3LGjF?011y9Nv0yq# z50Jmn%gDF%Em}aoql@VYx}0CkFXfl<^Z6D08d$I2@;~xh_#vFRZ{Q=a)xwe;<~Q?O z`4N5>zXxZ)>sULvjCHV1wwkSFJ!}>0V%@O%%h+x_wd^`}1G|yk%x+t*ZMdN#m@*haRA zZDCv4cD9q9!Omo7vEA%!b`Be6=i*elpB-f9u?yI5*oEw3b}9QE`#rmyUCEwjFK``u zn*E)PampFz>;v{84)1TXW9&Ovfq86{N3mCV3j2gtazAcj&+uUO91mfC<5OYTW7una zI(vu5vv>In_C8Nw@9|mepF9cY;B@vmUjX}&!M@-&_9f3@|Khpqdp?`}!0qfSp3i>d zbJ$P34751+=Tu$QqX`m-mvkv+}>*i$^5y~xYCfk(2Jcr^P5k7cj(IQAAd zvp0D%`Cm*tLD=Vd_h7 zr$%}Q^{02z0D2qsqko}s^v~2xU!!^S4LXN@Naxd!=>qx*t)!pQh4dp@LEpvGf%j=C z{eYIyf6{XL9xY*vwlN*;V1BfR`O`iYK-aNAx}F(nFN>zz*;KlX#n2rrmhR;Lt`bj|IG*|9^sYMngR9aWA*>d zSe@7@FeCO#(C5bSzs4}qu7pgZ(k2h?C5v3(zx!fP8W^t?j7o(;dqkS zO-=IZE3Z0K_mj~++{pKR{cXMEtNsoBz2uVtKqK!DboF+S;{yZf8RR8gZR9Cj?c`xx z9pnhEndA_zS>&35p_T!1`M}V+0dnz{_WnL{zQjF9Uco=m5rF-Qf}4aU$Q&eq=Z2yV zbYh1WxlrV+G8ckeoXo+CpcVNXT+!#JdQEkqQ6OhroILLqxH<|aj%_T{a#M5SeatIOuDb&`E~0`am~?9 z*GFURf5+C4i%CAl3z*)3k_@f!#Xd8G-vMvqcK$Mdg}=)G!C&LA^EddL{1`vZ-{NoM zDJTQ(-uN$`s`}&k=&k%#JRiM{-$rz>(np9FKZ+-&dP$)-_Pv9&7q)&b`2*HfIOwC$ zP)aVBGmB?^ltjT23p?z#!iU&x>~?ksyNlh;j<9>+(f^4(%mZM@Qg|xQk=DGJmyg4$ z^?((|3Rod4VkNAUm9hD(f>pAGteP!ib*!E(X6b6>e~(#!buh{7(3iLLPyV+DO^%rWOz(F9BCP)28I-t+%39_-ldC z{#i;xy-~LX{To5K5p~g!stHfy?+5R$=l4kt-izxW`B7YN!RYDWVI=S}@`q6~0&GOj zM{vE3{~6am@`rG}#RC?e&BFtDP_{jQ>#h7xvIo`&e1b!K!~+*WufR!%XZqrID}o*a zl3TOSB=b=3gL7jEd4s%3j=@8Ji@Z(VA@7p+aMt*M{F8i0J|Z8JPspd_Gx9n4f_zE7 zB45)`8b-ru1Z`q7*;3ZW`q?1cz&5kf*fzFOk^G&! zL|!JZkXOk+$ZOa^P4Ezd;T<-@uW5o`qIo5rKFQheME1iA(R`5KN&n+Icr(I}If`@Q zn9(Z(7(45(x^M$P`eColoEm8|TJK;H_CZ!9$N){C)^)7InqIzl>C)ZKAb8YJ;1u zeCX&B-pHHyQof8Y=PUS1zKS=G_h;B|efdIOCC?g*crCBv^}K;EmNVo)dIZ*>=#&}e zVwV(_oWUyi$~7dkQJmrg7Cxw_n6nvqvA%?@!=B*Lwh+)onUYPiRUd+Pr{gC?|xVJFnVmM@33Isy1PoE=uc zcKryfGz_T3K&*9vfzWt{bvGMV;R8(IxgC4Yf2cifjr?C&jbh*X|HnFHY-a z?@huD&#Al*=`gHOc|T$^+v{?b z4(D^|4M%}1ZPoXC|1(QNg++!)9z?teusP4Gx??sYzcc{D`V{cM< z1Buh^QF(8YpleZiAL6Z3{G`6btedUs{eVNN%7aFo8#jMq;)=I4fXw92t3H9mn?I@Y zCSvC9d4ota->>R}iH$E;`4EhCsC+1y%f3_jFcQmNQTcG^c zC%gF{hrH4UYK0wh(>NXVyH)>qcs8{vp8#(sPUUBK$aJQM9A|mRF403?NfSCulRadV z;vtt*4_Tyn@IT!{XEHqaW`mWNekJ&0N8VTA=0J`B>puCss+Y{i^ClObGFx+Y6!KRXzNFti}VsRto&wK>Q?>DI1g$g1|*C@oDKWY(*>CA=--Xjjk2y4bpx`l z9rrEB4dQ-1ckG>M*hg*tp03eB|UF{|WSk z60a`F&7VW|Z2eE5)&uG$$m-`1-7WtKw4X!ydCjkJuM(W=gg*QdE)#A42{t8?vVKT= zV*JnX`K4a}$t?B2xeI#pbI9(N{{)&_cii`1l_m|}IOLa@Y{WfULYO(}4xOM24p-$Mxa;)l&uueidwjkdR z3*~~XTnnqPMy|1SQmUQk(}C7LP&a_Quz12|3QMv9sT+A=fi~eTMy$tJ&F*!=s`j9- zuyTV)7UI?i4L9?+Ju;75B%%F-fHNDX>@fCR?ZA;HM`f3R>4Ejw+`~F#Jw6bi@u(ah1@0} zB%^IH`t(cO#O&htd8sm)Juo|UUN<%_aL^@ba)JArjo*l}z{89dF>e8Wry}x$;E5Ua z|2cn79kUTU*$51~Fk=tyt>9G8B)INAEoc+FLyzQZ8?e|sK4Kvttd-m<0HhX_dQleq zs6jum$C@Q|f+J#I5&W%0i_jjeR~KprRg2(*=qdDb0P~5RTX5cO1Zk$XDPZG^A6G*6`8vS5Rb@xb$L9vs@KI z8wUVa=)fSZ0wIxtgA=il!f_A~Z0i=Fu586nov*MDAFS_vT z-DjP->x|QP?%2L<>uFmyZ`!zFXmFr^{kp#1p6<14x>k2~w70dkxSCh3T(NxF(x%2G ziyP|e7S&W&Ev#HnF~7X5bmlaZuTL^P?B`o#Eo%2oNhXJV{gCxbNv0$Eq7j3v9H~w+ zms zppeXM%v<)4y2nY#PT8uH6|&q4DrBA333ZgT9${LYN%lLOASZI-T-X z*6Ma@y=SW4-e@t27CfA!cyJ?d*8YJ@5Tw)B%jxa(aT=LFgDgbVZKyelzBt0(Zp5#t zq7DNlC_wcQy7RD)GwL1*Nvk?accQ1L+X;ZG8zZ8d2OvzT5#E5CqM%`Ef|>5npS2;fSBLaJ*$6 znWwerMT@~&I6}iUu9sL#%#mHgt=1N3ptGj2GpeJ>1=u4_t7}AOEsQ#>BZXL9krX7A z941vspltzkusW$`85XHvhIx3n*nHTjOK`QiM7h|4bw8|{ti{D*(Yi;Jn1@H4uGVJs zC~1Q<3Nam!tq@q_K3rif zX+sZ@Tx}y98fP)L;caW7GNeY@jbH5q5aXT9kf{VdY|0aQBT8tOB^2;8Jkoh;arJny z6wOcuU3{vhDL<`FO4%^fbGT*BcNkV{1q`k(p>=UHwgtSwRce-^c0rQ`6XuIj z698!)eXwHXcz_Vt^duc#VThloL1p|%Uy|0@TS5h9wT&Y+Vp8#AkUz+*Pa0tnIcO9D zqP4IeunG{AV4hd}e6ZIE)r%6N%_9t3nKT;O`1xXJl&Vp~P$TWG*fp`QXejt;_-d2t z1^f}C{PBq&@s5X}M|8kJYc>dS+%RPxNNZz&642EMKps#jX&WOY+g zn+8m;-R7HNQDM1T7fEkp8CHYUVt^e32Vl_5BXvpGL?mrz%Ml4sabZG)R?<={DTNNH z3?8|S5NkOV7lNf_EgxYhj_0hm;WrT8)*Ny3vF03R)BtM_8*DZC8)4{&TbtXk^)I^G91-^(5nA!Wt!b3&ehXD*WP82&h6#fE&}us1T%h zfzepg!^5pEcvvd}#0oVg1ff0{H06S{TtyprvlVpLh}nSy2$seAMnS$Glt3zv9~w;H z<3pNi`=QYU!XJV`Q+VHlmo&gY)mvj7_zQSa&sDQr7y_6Ww=t;+xl)mu(W_J>wUYeQ zDm6~B`U<=zQ=d~Ct>eJNMsFR5C`yN^5zeqK$_q0lm`z~UY$>_~P=fOC?8DTMpgKS! zO(1jj@UWj%+fuB;{NDoylt|~2G{HKbS~0Q>q8}di_W$J;@5%lBISWl?u5s7D62r0TCCb887X)VMq>y#-Y1Qj=;-EK zhg{McxXHEkjoUDZ;M8Bh4ATh3-7CQ&Qj}nw)VUF?jJ~8M&E?uAbmI)Uq|Qh(o4ep= z6;XIw*eH=V!y2HscY-u>!*F=IT-cgnhlJf}ii9s!E4*Wz0IVi6%_sTVvB;`vTpjiR zU3_DHRBjW_6-UNCj289^tYO&Xk?M!dW>XNFhRwk^XpEdCmZDCzS!Eq|aead7B`7#6 zX?R%cCwy`v8(vTcCWsT8Z%&jia2h{NfP~VIkpGc% z@jlWe>RGflUi766fb$H=pjjB7OjhCdQB&C8iIu)Y;zS;A!A7x0%-c!2Sqmv;=i{D% z6oGUp%6E`%I!KD?b0nPQBmWxd=FwnC6O7Jr_3YOAio5u6e$gT(UXHX}-9=s`(Z30)0?DrOV!TMAZ8^J^l=5|? z6mL4#xf6azH(ex--zAD@RF;c3UA`bI*mGnB)!`Y+7sQVH9Fg#zLmM5!lb|n16H*>M zNScuHkaytjpwq##>FECo?yuloqMt~sNQg?cBE?fYXG997Dd1BIDWQ4bZytD;iz8z$ zo_1X@)+`e5Cku41kOg>~rCTKCAd6WwXnKTL=<~$Nwv!0zA~R_(NkzE~c$EXMa=He* zMdX1@k4wH4gYE*PxgM#@Bkyi&K;3wviDZjRpr6)|TEPdj&sO82X)E;Wb;#`wl1Tqb zlK5A^(Mc*<1qr8LLbsqN^q*rVSrKp$GA}0SYz6uV{V5{F>=I&<=~?K?nPiqoY!vM_ zQUd;)&_9Z;!u?G2Uqe#lxTPe4wW8cgB3J|30FRDBeCdE71w+x&l!pqES}x%R}m^-N+9_$}7INMbMepQY0Aablkkdx>W{D(#E5 zw+xa@>@g`S70dlb>^T!DN9Cupjj+)Zd(mRCAC0FsNr2p!#NOnY#QgtdM3FKi@o@llGvZ!DGTeN5#>i<=ii1cK1vp_)3Ao; zA?0HI{2gCH5Nj_0d&e!J2c%A2cdfcFXe9tJrI5f;F-t$kRq#eZj6uEfHMA#Q0lR41IRN#grdK!F>bp-T?WzeE_wu$-PzZ*`59j9SZ;*9{Z{ER|MZh`p|>_LI$7V_tDr3C6C=Q z5O>IdnUJE9mSApgj2nf{SA&m2z9(ec#GVG8a}T+&zrr8 zcRrFs$xz4{WXqfW^gx+!HX z_GdG8`I(q=*j1THec&T}2~Apo#?)O=sV*F@q?(5Ei&Z6|#9 zA?)={WENcpe|0I&L-iyHzH&ar`|pVSn}dATzuS)k7X0%Jz8HRM9q!;i@4&qRQy zk#}v(9mtC$#<-8LVqg!4}76!Y%S6bqz{qyBVC1b3<+@}V}mMf#r-;@yO7XN{FC`3T6ydh z+(lo}&z%HZ0Z-KLR`)fyN2&a|xUU5c9yE^A_e-=*rpJu&0w4E$;{I>ViL)6INt_!+ zqTi^r5cMaJuE%+@5%({UHmH<``!D_*`xoZDLKjYU>MkKpz!PtR%YS3#@Uws6AHLm0 zuo4)eB1%aaDaY^kD=5clZ2{iOSV*c!HQw7;1V6rx;Cn!Lr)3Gj2^kT-%gA!X`u>}d zFn9x8y#Jkt_r2$k5b8zsrJ zL@VPn%^_=HpK{3> zIvbIX`G{uEn7K;-Ta-9R@Y(sMJSQw9S-zBi%}d=r$_8!myK`j!58L zh{HaM?nW&39>j#cgShN-VIemm7HU7)jPDp6L=@##dLEt+oKG)6MCetB2;D|6q!-bP z=_T}1L`+>qe@`z*+|-riFuv;W2N6F--b3{Cwe&iAJvm24b>D=Ds$0ls`1->i=^?U{ zoK9~gI}l5H7_pU=|6B9I7nY7 zC&?I23U45?`WW`g4@o;>n%_oT&y$GgdKb~K?;$qz1H`3%h*;H+5x4p&yn*i#fBgkw zy}qJflcx|h@vV&hIYGZe)cC&;{q+Olp?^d?`borHk1=ez!X35dU$$!4)cmc)`-3QJ{aES+UA8?!S9%Vb&j>O>BF z^N-nVmPhVo`D_lGi+%ll=0uGD4Tx*Kgj}KG?uu39UAc_CTOgzFst|uyLw?5=v0530 z*MK-YJXd2)h^o@!wpSvKyBRUtEv%KbjmPM9F+}Mhy1NH4L48cbWcMQ~dyoww3QI(0 zZ$@nPX>2Q^v9==~YbPSI&Ol6-J4$tbcob1y_p$pCpZEZKkUhj6W`Aanu)iSg z>M{<34`^=5ABF6v8K4c%UkJ%^eQ^Z?;&c0w@vai_J>>Kti;y3@rzGpwM6YNL!6FbR95ou1e zSaW>�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%0DZc>n{eq#3sOi6`MOx4Y$y=Zf zl<%(_A<8{j9>2fPW`mb-ArntrIbdE5q;bnV+CTR=&} zdk#eB=z9QXJ$mTlz-9?}tq*5?g?*l!9BbH$E*fSUQD8EG4DugscALkUs-wfor@` z15PNGbnFS6A>utr=`+ba2=-J^9hp_))Ah|E@gpaB%-nWGXrP}!+rHbJ>=Q81Q{Wzj zBk>17RHlu=ZrFvTnK=Qy)Z?;RbiK4x6KaVo%!j5s1v6Kr^$=i8ZQIGhJ9O_=y`Fjm z=Cs;^twVV*v`&`4Q$Y<_*!N29%rlFs7jal@t88-s+FNJqUR~ zouv7E`64ivr&VAsCXyer+O-OA1y)*GP01|br=g}|Xhc_bPJm@}Ld++}-8RZh_ao)N z5xcFqy%dJxufL_-IK%~Nl19067_&5SpAK`bihBaD8S{Xn1v4aO5^(x6t()V6e@wp& z#V!o(n*AGimp#y%%$ON_4hKn1<#}beOtA9=&Fk_kkc0pOy)Pd;Jul?5YWd!LnV)a* z=~#4bnC8g|#_Vf6XmJxMTLqVrT>THtaM-InGu zcq2w)0IaA6L!2oaKOVMR-0oh&GvZ9X(r zM{X4>nwWRTNAtwkk?>`>YURq%BaaO5FE|-^?X|#nQ#?5UlR7NJHqsR@`iTM!%xIRT2`u2SQ?8=z+MyRr)^Uxg0s&gcJVgJZP%7!0+VK z5x-=d1Q^6x5tS~3%dUn@PbW?m!~3Q%)0G}}W5KV-m!6~LcykJKU`F7x;d1mopE2#; zgx#@dL{;Jr!IpeRToR6yE{?^dC1Ra%R$S7#lPTxL$)w{a)tPZ5hXF3^eGO?`wIfcg z!*5`TX&kyX`@IVf>LJnlKb1k~PzBJ1p+yyXTxDsYP+3`)CktbvCrOJU2E}yEHZv&W zB%v{^smE05?0Cn!42YT7S7frs9h_m=ydvdPs@XV#lumPXjoZ1@<5{|P=atDvP>Fsz zhcpd`RWXD+7{VgV*H%S?#XfgMdL&X&k>ktJC15mmr+_6`iQWd3ssmum{(InD6zbhH z6r9WFn{e*gqu+4tKuE_=7k^EHbUgM2y#}~!)Fx?7(aZ^zjk0c(WmIKBWyEW-6ck9C z(>Qt*z>c{RyP)tKoB|sJ!HWS{&M=4XxT!-eDQ%^-Ic%xHEG8rmfiXQ2H|EG|GV5kn z=T6F-^Don|Qra1?N^8)zbaixFXJ%_4I&1Ol*^6hll}@RO9h)<0(wvTI9n)NaK-l4$ zc=@75JH|=Oqsg5YHngo9W4D%HGjILH7q6eUw*sc5=7!1JOG>s+ZkXQ7{=77ZlXp4q zD&Tg~kO2m0j2B7KwprlopT7N*Pn|AWgI@?D9L=kp zz*{hW8Rt-NEba5AV&CLF)M4?Xa|J-#*vB95!nQ7s(%w+CiWTp^eww&~itS3V=NWc= z=0?h%w@J(jlgGoshcMqpZ}nfy9ug_`JaamL$9%SvfvVV5q6cR8;JM8Y9i(@&@$o*a zycsky!Jenv^f%;t5`T$Z?^%onZj>aA-mdI!82R_CTSv|pKmR#xEjSiC3kG5seh8xF zJfl~D6&nQsyZu1qP(*$l5uS)Bh+xYRHu8~)4^Yys%iKS)rWR9h;4{o$;-q2a$UUpSIJ)e@mqu&s z6FWL?-sDINT0&pBXXa$v)CEL8wVzSu;^=&ae-1g>*J*VI34!E6^lN33dz!Ag=N`yT|rD`Na3|^<36Va2I*$r~OCH zT`%T%-9n1d5Vc>H!sCGl!phiJ`05i4@VQ2tk}WyLZThgH#XnNZjYsb$ACg8IK^jD* z&!1Ba1zb$x87y5SJh2g=bF&!YHb-Yt1ho$PF+xB=@OG3A9!5jR*amotRC1U zL-@co^qq|DuPbcV8hlypVs7}X98HSFKA1-AEAiOz%)=k$9A3x70CQvZrYXc~yh_s| zIOs5ogn=-P_m+(NVr}D%1<;|0=7Zj z_U8+HzQ;Go2F19uf#P2Su*`E+Lt$6J>%)}!Fs?+HI3I-Cgf9_}-;t;c@H;7549g-6 zi==SCdonG}X@QMVv%shb^#il1Y9j+poSZh=@F1{W-^^a&E9ngFnVC!E`gPCf0}rn z|KCd!xF`2zL$OxQ7725V+2qux$Yw!XWg3=?n|g4x2OaDIhYRw};{GxR4w!@$$O8K7 zC@~0mk9H!rT0@qQPv0L9_++vPP+O(g4I*Yt1B=o&XS}4 zFMu)wI$berl4?lDCx?Fkbl+$WMLErFHoj1SXJNnns@7mmT379>6g?zQZ;22QGW zmnWGC(gw*)G^CpTV`!NQ=n&AyDs2UgS*@*&jfSN!$)y5CA*9MmLyINY4?Uf`n zg#)aYS(D9{n4or86>nW3zdiE~!S9n+LeAp6q(Sjb*&nI%U} zd{6!&`=eiH|3v;I`&TEXfuGKeeM4LT)^P;RJP*enW6xm7Vp6c|bwqKHGt@FuQT`H? zpGnjgmb%qyS}Ef)5>Iu+OCPv)kG%X~h;Hjiar7gmp6crd#-8vcq%}=pvQpw~;}bsY z+rb7(94DdZot0m>jwkGsB)%luC+P?Y_AV@3HYT`bV|dM~;JD?=zYtc*zOBzcfANKu zXP-5^3_%kZQRJ&!`|qOmq`P6mH;gnSElflGX{4!$1`3@ajb81xLdNlO+vR z;&uXHU}>Ae@h(9n9ge+WI=@mmXrs9IxA-R0Vgqa)--gynd&$7_qcpdsCMaxPAqugJ zU?C58=owTL{)z7@^9Ii-M&O;DY-m;9iDf*78^fOb_PI}76Z>W@+=(;hIxd*F@XEGs z*jktA(VaA;$NqqE+b;SY<2H*G(wdF&&Ny)H&`z)CqQ1V{;j{P-hH0B6!%G7odQStm z2SHq}HB;}YC}?Pih=8A9E&=heuYZqmE&x^zh3C9r=&F9z%*wJBtMjaHA8jbkihstc>h`dV1X)>kEC{A1Qv zV~<6!sDx39mXQoH!0N@tEf?08%_+O^u4UM$E+Y??z+4wvVeyxiluyoG*4xw@oxGxH z^|Gp-hS;^MdX}u*Fn8_-S1^+6^(?&avPT3~-RR_`Wl3S$+u{o3bisv7F+S~GmEXzQ4~F)c;rQy60e>N_bY>Qrmn5!{jbonBJ`X~`Wy4cjh#HcVI1n# zP}9;<*HT>T_v2&<-+%am6PsElag}i5PgP^cCtpUb#sh+pfPmJvf{Qz~+}s16L!QSy zy2k@2Ly)R@m;oT+11U|49o5>5`A|%g(AY7MbiX-jYU9-0yfL!^(%VurdP>`v+HvD* zaf!AGZDUt=2FrTeL{8R(mX-;=+IqNr@&_pp1IPUjC}jCH7b+ zwxeh#wFgGxL`KVpUz*z9P*GJldF48QTK(_wsr2))DdJPWaW&vE_!RnxfeAP? z4&YNJmqHEZGR+!XsvcabsHn0sJ0lw^az>nViQ%(--PkdZ6uS8A^iW)?HKp?p;!*~8 z8e?#)^r4xQFTt6fOYke=QK)Gh;2w@gnY}KVN3H!I@u)uy&!V6WfPd&%5u8@8&w(~j zq3sga;oGV&k?_8v=l!4QqlS3CR7UuD6`p6y7x4aEx3qsJU3hXA4lwu-}#RC72f~6R;XL#moYxM zp40_)d924Dj%Kk6Q6WUD5D}qU+_4|Ve&`l;u{YhKUevo|Z`OP07d}M22ZuY+2SMZ4 z?v=-7CS*q2H|*&enc3&JMy%FIE3DZS)=0$a|F&n#C|DOpo_lSR7`4SCRv@BDilC59 zTi{G2w8Ib;8lZu>v9f?1Ls@q~eIizPR!3miY^}gaEaKAS_vA||+jFnUk(@2%1HBou zjGPZ9JC$GuLt;g1B+^=e{tKvDBdPhg20%BkPFM#>b(#zb6i~pI7&%q6%Hsn{A5bZQ zGtxF-Z;Ew{7tm!r3C*xYpgx#`!e^-DdSSb3x|l8YyJOpCNjRvi3+ZxJY@1u`pDm`} zh5D>V9&3#}GTaIdm^1(fS_+>fEplzjJ91s@&y*);LU~ecuGiKAk_#9Tmx5#`1b5&9 zEsf9S(DjrF!$AeF9RL^Qu^xG>HS&;Hm;#Kfg%AT=fMD?1(k#~wD4HRQXNo-FF^BV3 zU&2ar@3)-k*yKQPJ10{N*|3>rmMip%&R|RtjdUUgM04&#DdKdq9PN#s#yO@tVP{aY zWR&Ahg9g#)sX2}e#-3q%c}!(US*i?)mj4~JydC-3zF~DJS~h49#H^_B^#QNR?F!V` zYeCVe2oZG+AgBLh-&w!|3hEg($BaLX`DYWCwMmt(*rxkC! z9nD@s?Wp?6%>%I$Z%DHY$`S2&v(b(YD;;0K+9B0-ttpr zSW+wW9pIUdV)WPv-rAk=1Tp*sDf+t^LyD7Sq4k5QoQz9G`?V4aU;;Imnz)yn{M$w? zd-<2i3mAp;2z0AR45cU@^%5j|tfDfH`A+aCrVP+7Gd^wO5!Kzaba&OXsc#j9G!getg2AkuCA_KZCrG{s^fiA zw|3RkbZwow@ak#Pu3mVbDvtIRO_b&gc~xm^6@}4U8x{|whf2&t{D}LsMr4;NPL&cu zsgoyfm{pZhoGQjF)F_TyYq5M=u7Wko_Kox`)mM!^Pxf~zvBfmWr#9JDjh&U)m!);y zh!OKzW7n!CqxM8Il~1j!n_3>MnLV<3PEEYc{92-{Ow|WXN;mz@LR39+wlt`e5Q#xA zcI~L{5hJ=ssUpQyDTUR{X&yPdCaB6(h0#3Br}De#3w2~mE7Ub`HFcH*+g&EBA%sqJ zBRel2O~!|UP|;j(I`@r67tA2j@G`Nab9`BC_hmC@Ue;Z^aISOuyy-VATYmlYqSlV` zi8SaO2Jdezm^gjK#7TXNo0=AHo3!-y3Sa5Xi@L7w>bid3m__ZAidtzn0?t!l8&T)M zSxt4^Q`u@bSq)8Yz-9u&W~v0Jv^zYFT4DW*!04wdm$jU&ZZ9Cv77@`zB3XF@0h|t1-&mCU=PM$Rp@iEzvwoT4w|@ z((U%H^i}CHJ-tg4TQyOri36yGMt(CZaPBb9a8`=!m2~<_e34ECTYQWKI$6kO&??-I*c6d<{WY~_ft4Kz)B(t6BHS-5;-)d z{Q9Ah-Gf79n^eI6e*Uk^nc`#lF|ceUJX;P3EZK#~EIdL$P=ZtK3b0*b7c_o|x!XNk zp2Q`8dAs8d7cTTG;Y1!^;5;JHj3F{m?~5;(?@?cT74OW7zr&4NufaE;=^KUO9TX`h zY!7UaGjDfMIoct)SUe+7Vhugk*`#50k#@i$9=8aOMZAIY%?)U&Q{e4pzzd;q(P~ za8lPLpEnRModZp_w8^cVIMP_D& zr^N5_waDJq(k$B)oZlFlV#_L})f#Wg+2RIl=Ig;sd`UDI@!D*_-7!YuTup$s8IPds zrg~Z(1ojg5^oDhNz|4}U&8Z59t8#KGBazCS!t(M$Tyk~?Gs{toqQeb^Z;v1fs&YjR~% zQ)N|SW0e7izV|}=MX@6|E262Xsa}sLD z4N>EAWC#4=kn}knax+NExEP!3};C=r#Pp$EaVSJtJj)W9xQz|kb&b6bFu>2LN1<#UDyh90);{5Bq)0< zG@FQ){e(}WQ=6i8o3E30ywBiOd4@rr8oCukm3(ad$KldYV}}LvGA%hp#u@dmdh)}0 zQ!DKjZ&p=RR&J)(?##e=EDFIZFK1qfITtV$aA#)C24fbNPxnrhC+|$Z8+bU3w09#d zPP~SHD`u^%p^)Zw7ZiB%M17vfqs|QbrLoUS>LAB+*YP2*mH7SVjPdDv#`l#}RMHTb z7^~Kze4N*_QSQ)gl}FO7`pvPo$R5;xwY){UM&5^*14hj6sa+WjhOr8Y;7sFj0jj1x~7uqqq_{1*u*hRfvc`sIDeLHH!$%#KvyY$hjPB6 zN`?S2Qmeu$HLHGae?XNieye56jj&t0pT_1myj62k69l~Z$eWf#v}C(I)4Jrwbso2W z8{zkv{!!X8jiCRk0sZg#uh1g>4}%75-@vd=deg!b>BDHu8xpODIv?+^#al)5Fc@GD^(cpkzRb-f!C-7;&uJ@A=oe5ScKOix-6?Ka*IXGwTS(s%oJGaE&3h{R(3(BN#b}Y8mbLSRxQ=03T_?9 z`COSdxo*12b#M@Y%kONy9>cc~^Pm32ZEY%}}(DF~HhAE|1UU>hi7f$vr;N0M}Y-lKnoh z#V5S@mC_)<2epav<0RE_eiHYxDp)E^p7ny!NE70`s#k%f_kSJ~da0gk^kB%))Pn)h za5PF(K)o14f9QNvdg%wp2GFSP@cR!W2s3fVd~+`N=3H2U3bhr{QC<0~^5uzqk)NGc z5DsTxL2P<@h8BQOifvE|L|4J80@+X?3YcUI#Qp-Y2ftGA!vq6RY3a4%m!MvtsSO*g zDK!peB67-7yS%`F6j4Z_~d0_>SI(noNk6#O+93 zq+>>DG$$7S27O}dHPiC4qHo)_e~N8OuZ%+!hY^J)V1j3G9Hw+yeFvBr6i7S}Fq-O9 zMixlQ3G`rWOd#$&_O)SPcv$ZckLW$1Gn}kVg3U4Q1XM`k#|fL3-a$4k5zn8dAC`luulBde9(Ebi9Vu$F*xd&q3X zRo}vSVQ>XyqZ_4UmO3&GG+^n?i4qcb;JDiBvR{0xe-*XG#&1tq4CMvc4>Bt0x0yyI zvMKe8FYsHACyiIs8*E16lz{bBq?%=>Qg}cra3Ezk>L>XL79ZUyp3%Py4h%a-7wf{z zevesBSmY{;s8<50Mgk=pW|~%PLpG`pm=+}c%W=9s1SRYl{T}2uCR#?epDtazp~C{S ziVQxm{A?8xFrN^g2zd-&%J4%rlx9$t;u!<%KDsBK`vbaPJg(mi&NwMr!&aF|>2uSi zCtZA;-cQ!xLk7W|&_2;*y(T8Hbr>{2wk5U<_mOyn8Vs=1$U&AGf5`~lpKPcpZGn@9 z&>jQ~j{ycqobaS1tH}v22c>cESYdEJ>J`AYX$uG_&oX=)LP^7hiGRbBF?@GgFQjk`kCRZ|@+>?;m{s$J5 zv{C1=m?X4&*He0G??}?@Nhdw0Ez)nrm`V0et4HI+B2{ z)YG-=(tK#!kX9YdWG&2MIY!v_GCf7HO)haGq9!s{{i7O|o}MaUm>O1UxvXLRcgh`B zdm31-sXcMIup*(2qtWs#pU@sdWw+R`hG1t8`9dzAFY4-YVJ9xHOV+!@F)Vo`jBeY; zMp`9WzMujLw>5x8CUz;2FYIf>3AD_n2H@5@d4qj`d=_k)?k%rNku_PcJjzn zP;e|8n{9ZrWqq~)1Iw1!97(Y%_*^HAQVK+H?O{f$K>$xn9@0~0hL#Vm!DEBR(+3As z1ycUadYyJ9s7q-<=u?Ikv?@&;N)z>I;#k^=H2KfagVHSL)q?=XKAbVH^q}TwZi*hX z$|??7MZHxVv!1|^%KeAL$A69{r0-y6KD;Ib*!q%jWN1R?$I*XB7t${|uPy|8^{*KY zht?3yJz*23CUnd$qV_JkthWmdhhIPeG6?Q(=|0>j$-2*=rd7Y7uKKoygpg)6URu6G1yF;$Drnar~Z;)C<*-qbaknI z%;Xt~=h0w*iCcjQ(qLvrs|M>W`PtdfXpR+N6!R9y`T`Lx=qivH z^;v*XQ)9%;5E44eKSN(h)8o28oSVh#bdmaa(hOOSuuL_iZLU5awmDm6qk%Gj@{ZR>L)yOqjkcnf9Y6qTjQjX%R5J{ znOk2!cg?8I%S$FT-nOLUUsg@9iWOz!i;J>GR5sxCF}U~#?RCxVRkJRdH0h#QRqf4n?OlzFFKq)(qWzzyje%EIp*9gxdSqNnS&bF@T;MPb zACQ1UKrMYO?59O|;8iz79wg&pwFQ>(P;FX6gaC3X;njDMP`QOMGdP~SdD4R8*H6p% z;SV#Wtsfuor-z)=_pTW|dd=SH&QQAluh+KkXde_CK%`tga@m;8W0tn)8-+mfnKSX4 z5F7RWjveg--2ZAXB*8@Rbg%}knOYta&k&aa&tw%>BPAheLAe{+?>2d z2_`05Q#4%nE-bqHzb{!YC0b>sd4?Q!iHP8|fR! zqeN<=q)+`0{8fF|-)=lVuD&a1tsK%fzOBAT8tKuu`Ta+G)c1pg1LXG~i`YwA;y%r| zBRI+Hk7{Aw5lk}UIQ{m1*S!l~^`%t7!GHblr^faF2(5R%KidCL>pz7L-1Wn!UHxJH z=XC!`^B11{sQ*m=QCN|YrXQa7My^>#>ce^u}NRi=hA0{I&)81gTW~ zm8i#@GeePp#CURAebc8(mH3^w8|n$yEuN(R9o$lxu(#45YIznl`jPP~UVr?ix}HpZ zo8REtpk8OG7ABniPa~K26~>Swg31w}lF~f^P$`a!0)>UOw7|pBo&*NTS+I z!9(|1oDVnz%2X|B*5eE)$Dm-wGx0(T*Fn|7%t>XOkDP}8i`Usm;u*4D3Il|tA^t$E zr_B}ww>g7;LHv-RHt>-27GhH2OL}J1AvuOkLfijE!D`xS5kT- zh0#yXqQ{-3-5Bw0P%QfBDU+*nTcBT{ujCUPsBb<3jXl)b)E8bM3hjR$xOg5t9xHhI zU%^FfoQ3{R_tYmI$CG@#Q__Dw;|9-B4)tF2Q=~hE*23sV+@G;Xbfo$ck2hvLm_Jaf z5Z@rmwU}5nQy6>$d<1C|BP$_*OTf3;o+U{XLbc=8Hd~Zl01WSdQ@ulP;LhME3U1>$ z+8Z_Ea)8m3;4IWj=r5@yR9bwRC36HYM%Xtf8YP@G-=Ugo9{yA#E`F+Xj1wCBlm5^O z4(4doKGY(V4}!rp6%A27)T0QS@wW-nNf{;Gay~yo+I-|}=D;F^Ql+w=#5|U|XWB`}vba99nKa>~#n3heBuA+=j14~?Uq*FbRpP5gn-UBGX z0{DpL2_L2eh2F_^1MlY8A={5@N+}gACBP5uVdVi|Ji~QP^zrf3PpJf4ag0;WNU7S3 zi^1=A@TN(dX6Xs~@ld}={ZnwGx3L^$K4baklu4yD%JLJc2U7;&cc?$6oumh5OC?1O zx~^>Uh{|Cz$j5GpwTP?J2)`o{Dxsyf;z_sGgIR;6+D1I-Lzt@V zKxo%)&~DT^pevu%rfcWK2<;kpjV{uj5KF~j?Wf{Daelx!aSUO$cw3wibHty;S+PZ& zlSN`X^w8CS59V3ikxoj%3pk-ABhG?f1h;@DZ3V101RwNsJK~Aw`d|TdBE1X2ff?ou z)WJ=jfWWJVzbUmJ0h@y&=$MBJAtsFAM}84tgMyVYk_C+9BBwlr9N-}zP!u9a#txm> zR*v#35EPCia71UTHz0VRH8;Y$y$Kf(r|i%gNFc}2F! z*6bojlxq$woUPRIM3tyQe6^@Xe2u8rus%jK;~sk-<8zdlgM8+SdARRJtNX=b(W6Dg z60rm+mx>iyrdTO1)vV$&ak-Wyt`K`Pm$*h;tL2F6#GP82xJ!Hmo9ulPv?4((FKagO zig-m!7q5y}wR}*_M~MFe*28;B4Aho14K!Ris;0d zG_(g%kA>+bh<3L#)zAn+bc0ph2zI6$+8@IWN+-I>2mKIb5#6LCj{w@8sK>$7Q;N2r zK-5#fbW_N5L$sHtl`-82rW+4hhe9!e&NP&nL_<|5tr90fz)A;xMtv@g=?U{y2*pfQ zKBlT{rYb8_RSr{?i>a!Fsmje%mB&<7!BmyUR8_%LmCICB&s5dGR8`MZ)xcDh$5b_f zsj7~tY6Mdi=8O<(xPR9$Rpo-JUIebbkC4x_C6lNs0IE8R8k|E&2W`1EIG2IK(wV}7 zOkobDFeg)(0~A&UiYW($IYbp`s}i(TgZ8c!z=Rk9E|L!}QjgCD(3ul-HU+u0iB2tq zeR5{wehw%Pj%=X3Ql`8xQ(J-P6}?)y*o6H!B206IOmi7bb7i18cxm8d&^tl#M0p-@ zueeVu5?>QfBj%gfRW40@3$&P-M2l9Y#VYXw@dNBs^_n;eItD+(=iB0ar2i%SsJ%Eh z=l8h(2=uCpkHu-Nn5ovsRGST|wQE+K2kX)N(hCZz7Ded=fuPmA#nQpYtVmdn)xP%i_lYGh>(ECtZuAe9}0{cEf*&BiQ&?$~{^8jC#h?LYFqnz&GiZkR^d7 zk_|X-`lb|!Pfm&20d8u`)Ob2$NBya~oP>1zB1s}9JoJ#|Qu;P%g7ZS|@zzi@0T~8y z@!H}?33ygMS}%yZq(9EbXlE4-s}!d}Tab=$){t}$2HN9cJf(Wv&%cRQ2m-<- z-_vjYt3(b=2YB)#+Cja~t)1MyW^$x5Brk4?FxFapyq$z6A zv+4;`$%|Z*GX{MU9gy{l+Uzjeh5Akt>V+7@sXqB4o+)af7Cx$Sra0h$v`wWkFny?W zRH6Y{K6*BD3A8uSTbvSrujKkU&__p545vzdLU8bJ!ZvV!KT{a@(0FO;xq)ewirzBn z81E6N;hm@)P~NC@F4!EA={Ew1SzO}@JUt_q8r#N)o;Wd$GiN8@`>6( zRlv(Ts2lYHl8X(=+<+Ui3r2d%kF_n zj$4Ib<5Wf;#xKG%;i9tt76bRp5f$}u8T2OMnl5@Th_s{&65SXOB}!7z;YpmYnlbck z)-5>>7&9p@B^o8fp-g#T+5%KN#%Uxq&Cq30O;lazGx3-DOU0{ni8P5j<}+lKpA5$^SR`8$EA5~sPj%H%U1o1v|gf{ZwdSl$? zeB*edw@mCZTq&iRc@FiBT2Wf6or1s^RaAcFXUdxf9?dvFWXL>RGUY-eJ=;0WH0oRR zhSWIvm5RZE&oO>*I}eN>`Zu?C%A@4m(e}sDLyTTwwoM9LG(PjJ0o8^w8j6c>JHk?{ za!~b8DKzPak&DreNe_%$=F?=^X8aHFJl>WV1DXHC=_mfgeCr>eucLt4q%ZnT%FCz~ zVnAod4Z2XcFesPGGodivC7FZhfbufwn`Ek*VeGln%nLbEiWmFuZh`kfPl3FER z`Yn_Oqb-lMge?R9lr~PKo8)|`B=gV2yNNS19(kHQGO1+{n*>i%+N7}nu?}eVHLUS! zY=fdb9%;P?*`TsnN6nF&aIJ6DxLKkl(>xH{X-r*Othax$ZNDh?5?&~D?&?LkC+?e4anhhXcfV& zBIW1h=e01}20O~jFQA1S+(J?wkO$DBUzA@&{4H4HZING+U(&qt->_$skhjWP5pz%; z#QkmZHr(GXZ%5nTft~w=yj$Ll&wJ!ODE(fvv{OEaGv{0q=hJEdoXzyOmd7pa!1Ju3iu&D-;_T_ zy@(DxOa~#*!Fz~5Ax{7{I>BAYU&~(u!r#c>V0HRQ>@!j%e=9#g{D<=Qc=scTb1vj3 z5{oY6Y551>Xy#3Z6ybsS`lgAwgoneNchUqELW znp2PHu9|8>#&4s~T9tAUa3_K>EDbL50XJyJOV4BNd9+M6p^8)fAnsb5E zd=H;5g5Ow~{vu3yHc;MC(D56fziOtxa?syfsQcUUCt4bIb~_HvN8HFS-}II@!1=1c`2wKPAo!mXbeRQ8$_5v#VCoDr zb%yA~7Q~n8rHC)nD{xPg>e8$9DxAeptykl|Mz2AhM7vhKUav=dgWiCgiH-|E$4w{; zC(0n6s5ygqYC7{&7gKWxJarnVpQzc&)Lf%UODS35(%-gx9ivNjd_3Z@mL+kL1W6k3 z&y&9bXlB-A?2DQWzsuj)u1_YXol)3#_^*VH&4b#>SP`E zBw#S|B5hdxp-i?(AdipYaY`4)PdsDUmY<}|oT3b4%vB>YBpulI;&~>?NoKALC5_&L z>Tae;jO|HxrneF&>i@Hu7P)a5CKUM1@F*)(qAq59;yv@uEW>z@=2r*IS{f-ZFUwW| zylA$8dIGG|J2n%mz=@&n0Bi86V9Uchkl)@{?~^o$JXlI1eBu2c!LDC|6co>zh=PXO zG>%`TCz)^?-)2h=h>pYZelo6-6QNYHU3`iX(Hcp2e+EQ`ti@0MoTN)8XYhC48`vWY z*I!a!0iMWzM_B?@Ey+5g+ApEMro04P;<32}UXI7^G*LMj zF3_4~k6Z`&eZ9OyBVYbThC{H-p|i|kW0^x| znZw31hh&)}%(8HVW#KT(!V#8*b(T5&EDHx%7WT6&9ANoZ%3@ipWl5?}ChAj;F}MP? zO52G`k*I`^R5C2}dsT_%@doL(-ML(W(sS3;s(C08Nm)$&5f3TxyV z9@ggee;^ zRe?HG0$F9+kx z27E0+=}Un%=OC=5G1fwiH49@ch+Ui4LM~ee`br0VZ9uDBEH6f$8-YQGyaW_y(}ZIN zNe5c3?K;~_9B#7RWIJFxXrE)d(>~tzw*3R!Yqopsg^o;no$Z8ujlB@xG5d@5`|URS zc)Q>B0MZoNPT*M`;_kO!VSCi}luC{NpK&Y*p&W3OYMV-dnZ zl=4YNt+U&4$a%ZtA@`NeC!Fh@uQ`@Gj$r$xUasZd%v0_e?lZ}uW|XJPgEg{rxupA$ z`;f20_W)fKpHXbxO_y_z>)%|Zu2Zfft|Qew&MTb1b-qby-G`hvWh{56Wfw+Xp7cQ8 zCr!DTOFPbZ9%^1xc;~q88QqbW^FEpLXsCSTzg6w7d|>oVV@`R~>W|NIRlFOn&WRO# z)U`Dy=6AHb@Bb+L)Z}uy_kT40g(;6uy)O5@hTlwVYHd(?XD;rlIsW?Vs?9%ZL@7h&%|kO%}$&4R@>IuY3)z6b=!8}JHNfR{l!_&O#5J7 zX{XlS)ETxHwvTVWVt!qFN9Vh3J?)!jSEnEE&Q3qxe&f9E1znxBv)-Lv+X}8 zJIxFzHy$XiZC3jeRA;L7aG^bz2+3)HBMQA{nD=ORPy34;D%;~>+6O9hV%bb0v^P=c z3=a%;_rRFM@AfO&uR#Ac0$PIt;syrW3&}BPp$-)~-yI^nV7BJ$Y6|JchYM}JiI7Nx zl5XU1a9+0x)3wf86{Z&_hxYp@bpL$o9c^nC-aNajb6@9_wu?LOpZ~$a((XI@8fIU% z@UOEkTXe&`U(MUojul61xyOnZ))X$>xB9tNqc8a2-+Nb9FS>VS^^)g$3VU{~c=Lkm zmOQuQxmAB&{oJB^*W9$MXZ6yB`worjt^C~KmDjBsweG&l?p->1+5JoQzWv=L{-sy+ zJao}@E8kt-ab(o;j^4M{e0tHDMX&zurA-Y-CtiGb;}c(SZ+~>rf#mSSDmaQDL9i%;~-po`+8uPxY1SI^Jye7SG=h2Q*H=cXqX$0*gp-93dDT(_ohU|9R| zz?j7Eh5P=IaKQ%`e6VV?87}g#Ur#aT53ByXvRZ{j_o_g+TXb(v;re%b3O6iRbr3j3 zSmvN#J-Zg&dqMt+Hwnj=EV$sh4X;vaGpzdaaADb}iI7Nh!3S$@qOh#T4DWq*Y3Ays z+lp5&MR;!bx-aQW1T$4{r3x#rOAcsn3ik~R7e@!iBz`a1yJYXu(Pmh7KLv^#6h2Fi zS>Cb4ufozRh6pb#y<*X;iqe}A^lR8S*mjRA6PPr{9wFPQxd<|UuUrY~bsfp5 zkWe9=>T~pY`a*rN-lH$km+8H*zqyG9^eAvGP%F?0w<%(X5&$u1K()7qHUvD>qEV9u zOzc5hSPwj2j7!Sr`cLa)L3dLA3HARoy#c$p1NLFuQLC#Kmj^&Ae*tYwMIF=RX5i>$ zTv#C^Un3gO=b=>=_rI?%L7Jt2EDg4O2l5Oe&mipE4x|C)>C2G!a$GAYAIe|5MzbK+ z!Z8+kZ~xQs8~sn~E?gP7+|X$)+7{H9DC`RfyiF0r#PYD2yI z6nZ!H^LqTGIM4Yg9{Ha_{-==tDdc|&`JY0K&Z0(VQ6t#QE1=k|<3Y0HFYtXlXawD!wP&XUiJ%e}8KsWZ_{WH+; zJO;P$AP)~L)r8-jxNg986R!QZo&#?%a4z4(Z+J$)BJRMfj03x{q;2Z>uEU|_fv6oq82mpJr~~#`kzPNJq?^a4}B7=&twa(R$Sw7O~loU zYbCDrxGu)E5f|~s4B3P`PKi1Yk1|uPMf^I{_99#ZYwzYVsBP$NRh9!~IZ#$mb|WXk zvBFzwd2U&QHwZ%YwkrWC=xPGuC-#4Yb8^6W`+p=C_Mc>!7We;D%KApxr;siqb=2G7PJM}`-)K=5|p>hAvxaDPP9#Z()T)qsm|G?H=S zKxR1)kXsxxl*5mob=nWf@o@fj?qiv~2)#IBf2B})n z6UN~8IMD6{d{0E&B*f8J*^QFt_umhgk21`Q(QDTto^wX-oHP1)Si1(jdoQT|PP|D} zm7qtoQ2%e4_7yd~0{Bj0v_1`va|W`4rejppX>9059L8;M_V+PPoY5Bn$6;*#rD;oW zcNxC-66{9qqrnj-f_G4RCtB|nv*mQeK?>2pmmSFQG;%wIkwL=?Yth1`;d;TAHcLFU}S>_9W?{g@I zQYnUFI3Oi*6plz#0we?if+B)AGRdTbK~WrVKpa2>WQen(Z9BwieZ9_gwf%i7>suFx ztSfPd!?C-oZ+F>R4i#aG6k>@~3}v9ye7|S!sxu`)pgG+8-IevvuIW_m{l3rpy#MF_ zJny@6A2MUH6YOfjIGAw76ZtQ+{6f9>1r|_@hp?@#U%ADv+~QZ-e&v?J62iXp-^{P* zHwx-2S@8KVe@r|PbL!`F_I0dnmGjNLg5x41J+A49&6}pZ=P@21>)XTL&hU6}-fYe+ zr&V%$a}0J`SVnL3EbpCbmU0HHBTJshW7I|tan3Pbp26nhnhy6`G0v;Tch$Aj%s*4+ zpDEXqSPg5vdHx<3a+db7iq;sT5%BzEG&I>a+x{t z3M}ec=O5P@^Jj3&%Cng4MQPUGO z?J=PzGCdK!z^6Or^PjT|MsbF}4OSt>&>J!3oyR*o(VozKET?nBBij zeqKB?dYb3qgT+r+f5pzQ<%r^DvF(Hn^+%0VzOJlpA|ES$;TdL|!ozfnvEsF*UMt4R zm>%lrp-vtdo#JRTPWynr8$8pyas5M9HEe?y^9cnv+EzQ1AG96Bz}sw#IFn8ui3IaDw({P{ zN3ruB_Q(+)7hIvwH}>^Vmv1zmvCe#!bk=9+wHeRVHKO}w$&A!i#GUZE=RHW6r7^8iaXLL>}!mZ%#SVYdO<&y#>=uFr@pPSu6J`@ryBrUgFp29`nYLGxOe= z&aODKBp*xXcrBt=J)ED>fwEvFIk1wk6nwWd@OHsk^_bT}!&vHZ!2%0CBcHjw9+rKa z-1b!jIF%)=nOu~ijA*a3y}{j8E5@DJ^4EQ^LjJktTXf1#hH~y zp5ZZ%&6coU7@k$ZO`Vay&dI(>}#ukEv zC^J@R8GQS7o4=%&*Es7TH;VRr$PujGZHhhGgV>{>8|ZjkBC|mXjiv z8C#6ruJA6yF(4qL1k&lSC19oS-JdM-U3yN|hHXpd&2kr{ie zY{MRJ(c`z|HhJ)X0oV0(N&D5rUnOx@xtJ%kO+IpbYuM#dwG9yi=JSQKDLnJux$hf} z=R!3q^UhW6R?%)X9=d8=FEw{eXt$bntMSk^Z5NtjN82@vvF-7>9-rs<3P*ak_H1d- zju`MDXD|W5e8LV7(aRBEJ;T|~jue*UXBu9+m_v?oJX-q|XIs;z39sGcwVOFVJ6X@4 z;&JH4`51R)!CQG7qbK-lHt^bs5tM8ts_0Jh*oZ3POov{`eCu(+2!_2MUZ_wQmUyr5 zCgg>-hA(%_d}~PdRR<8_xPL8g@V%+XVe{x^UyGcTqhfF zogq7~@=%po9;#+8s?l((IkPz5afS0cgcX$8Yk9yf%GzvGK0`jkuNI>!qT87``beKG zw5H%Zp(iFI$2ksTtcZ5=IbEAZtQBpX&+8uNp5OCgZYs0evbNsDZo_8FgV<}frq(X3 z!TW{xk25|P?>j_K<)g~+neZ&1C}z&OHqF>86~k*sn{SqTe5}`=?Km@IVzZtXwpwVk z#mpHh-_7hcEMbka>x>xZd3NcQzVCdXV~<=27ePLoviD2iHSk)v)a$RyS?@? zj$g37;Gp%~DvIpgOcXxj&9uAUTH$XCZ&r8Kvtm83&%}D_tHgS7)&pC1?V*)!+oP2S zZC%*1EYzT_Lpu$R7WO=3%wZ|vd&7>+zS=S(kJEGYGjfSV+#?Py?Ae(W^ILgf({tH# z(bkjNdNOb8GdY!HzMZ~>qD##*=%h{sv6&Vkf_5~gye$nVNRLLJXx@`2gsDvLqK@I$iE7#OcV$CP#UM6@^3Z-m` zvstQbhMqki4W1X?ePS>g+RnVK-8%#C9wVYX@a)cB+Yj?|qFL=e^zOrUAC88$vtO*; z7i;&$g}-#PD^%q5w0rD_n?`CBl0-( zR5j>5Mm;Xh z6mP))<7{7I-hXK_hBr*$xm7&3lB>aIIOa+Oj&T-7bGA4(l;LwdXMK2XaNKSl*(`BY zg|2vx25e?ThS-M*BY+!zou6%Re#Y?f6>TevtW=6hokOrBBVnlh$tO2(kqj5faFJ}}V$Wy$v}u3lyTYF>b9L)n-8u|vohw`C$|5#d zXI76Zs}ESz7@xKdi(2D~))iM|tSs~RC^*`@wVaPS#^WL{WWMzHcoFFdaH34+N!ZWH zJjf}Yzrejish+SMA3|ZC+uV3JIE`*EVV$WaY`*412 ztCMFMU+a4>_5H8&9z_b<>L$zP@b493#S5UY%HF^#d%6B9|CYQBra5|8rgpl~=Whag zj^y0uVexfmbUIIehASCx_NX<$+atqN9*n<;GlRDqe+0mDs zT$?;tyF|wM5EihASB_lBvsmY$5HaUrj)(h9WT=*SzSR4}Z1ho{AML&6J~NY*?(0)* z+4mJz%ImwLB7f2tC^|T&?+YbjCXZ6qryYIT(Wec4T4S;O5wX#T*oeh;^l4w8_VsCB zpJLFt)y|#~f{)If5th5!rmJlh#(~1}%^t_%cZnmDEH@$szl1c=!n=NFErcpfuC&MzEKGjHbO)8jMswH&l7 zZo1;BocZyFuDIojTduh2ircQZ?TXv3xH*W-x5Z^+tS(QEc}P|q8v2{z(YEB62jhzK z2y`nJozE%@VAanxv-BUdjwmuYkLIj1WC&Z!2u;ti?5I#zwTj0@1hAGj+j1s~9Ms&I z=#giPUi3FwVp2=g&A)Z?Z+#X&YMXyMJYC!T+cE#vlS|+Ve5sgw+jBV*s~pCsPt)fI z%O^*STEtF~xr_N&zRZ;$?!AKRM#dp(PKs# zZmaq-&jvnn8_Kp|E<+m%zA$7kF{2imM4>)Kt1X2gqj_-KYHiiFLY107OFo+Rre1|F zdGMC2&l!Ce`n>3T3yv3DJlJX|-70e^wMoue57f6a(I6XhMT@*Q9DRp-zp$^OwU&7= z)P&_Qw6Vy77WtzY27D5`44*aR?l1BDRQ5*w=BZ^&eQ&Vgg2R_)MTO=iudjd$!1Y)M z7m7ovV9q(8EHaAP#;hHqITZCGZ^vGXx{2J{!grb1Rb966{WiYe#`oL!ejDF!KP)NqE$;q?QTV@dVi@kYDYRQgQMVR&yT^PkM)`39E*8xM_uy3SN?X<`lo=2|X zEXT9`-8m4E(0P7mg~u2B+t+K2f`QL&v0C0@DxnK~GFlEo%RCF{J$bGyYOh`iMU2rg zc4@6zvaTiTTC%Ps>sqp|CF@$Ut|hD1Bu-eBIAJ~FgqEyedKD`Xqa~~CGFq}~mF7eu z%1>US1C+MZpuA?$H)7<6CjxBDUL63WM}Mks3(^47C+l( z&w--esyr{scwp|x_qk|&IScmL5(j7E;LI$uRvg?i+SjqusFI3&Po|nbe5U%Czu`B7 zwan5o*y9CoAzYL!W~&oyb+J}1w2aq^K3)ffA06WXCbV?e=>$8SV5bv#j^jXAI^$3G z$)lB_Pc2$H=I!AA`;08nI!on3=c;Qv6p*g-p{kPj)f<{ z^*t_fPcbt^#lT!YT6l!WuvKS8KA}9+iVT~UJi~i=c9JIuf6DR(J~bKjea87q`OTLF zFEr}6=?$!JKZi}?;OusaH%PQ_qJ=|GDG&6NvKF3V$5Yr)HkhI05_8|0XxT)|h8?%r zv6;$lR z%3iBUWaq=DUISaR*}3)_%H)7C<(^?rty&)V*j=>jP@N3B-E*GZ?#XV4)!k2IyTLt+ ztXWk1=av3B$Lz4#in%{3$EsR&zRm7A*Bkhb3w+mwa1mVWd7cNPn9YseXW6h;E^N3W zdLP!rRn2Nu_8k7W${$w-S+~mQiX`D(^I9;ib@t|~+3hNJyNcbeVz=X3c%0pivD;|j zF`i)&yIsX@S83^rmaZh1g?BJ6W?Ffi{f@KW@qsUH6~5RNOhDm_7qR31z>a(Dcub2I zJhkw};%3hemr0pnVPo@Jo>Jg5MV5NJ@Wq}VFV-z|`B1g#@m`C3TExlG`k~Uzc#E*- zv8}ZHYzC&~wcd;JmY=}97P0MNUVePg;^XYQ$-W!>bc=nr`04i!{B*3=3O*6`-NX=z zilD#6DQY-H)o7@y@a+4ms+C@SE4})9rmAPEdM5bAn4SrKF_u_?fnQXU*XUO|yq+1X zA>vi8^ZJc&6Rd=&Y#Y}a2O7l(!35+zqgS5p@gZizqE;X{@vI2K`-PG*SV`c$Wj=e9 zzbO>PsMF?YycR18a&O~zid87Fjv+FfJ=$BuTV_R%DZIQ(R3V2#Kh)leDr@yCREr+f zqDQq*ca?ja&{o5b4{F)8?x}hw=OW$@A0CQvQ4P_{Tm5{k9`SsF&m~sEC04=(8%eB$ zOY$8+qB?b$*>@JkKxdkBL_I~U8OjxZt(hzSj?-CxpT8#RL87I7?nW4_Ez;7hVjQ@# zU~|J+vKR-&x{*B7?Y)TAhOM2C1J8?b5VdthBoeb`p4a55a;41kW8v9)<~YaW;RGo7 zb0}q-WU&0g{G(%Ucv*3J21nj zcZ`*Ed4$YT3!877Ij78=Q+V_g9zBIePvOy1c(l3-b{X~_wmxIyrNOLOV&i5_@8veG zrA3?thjz^QvnXXt8?UnQJ{#|{@h;V_M{`!|21Vwc_wjz->fT$-KBsHme5R<#izua7 zQI)H8uKXCRFkgk@vHP%U^`eIGM90W1M-5?kp0M?(ea|b0bDNjD@q6kz*?gDHM^?X2 zo9vCu=*``EOpx}Vl4`j6E$Zf@%9i?5)PJz|Gd#DZZdU!~u<|eJpd(|_HxA@N3V+WJ zor*)B1}dWT#4UQ_7Cmu`p18$0=$Qw4JWs@iJ)Wn_^K{vNM$rlT&nP-!|2=a-^h7Ip z9Yl@6HEjP{2$q=Jes~&oav+X!5M_S?Vzoz9{>FNYLtqik@eG`#&`vwF(@tJ3bC_dP z0v|!4S>kg`eWp;0>pV`K$7vV?k<+N_jn*KiQ8x!{G6!su(|AB{{IZD1J%5SEa$q^X zIb-vWXCiUuX8h}sx*n;bT$+q&-!!r2B}vn9>?Y0i)HKFX{hYYVGvvq<)>$r<3#M_u627uj$iCeL9)EhK*SNVT3jHZO3eaQ5mH- zn%k%6ckMq82jYPT$qP+D(YI}V+t#Y%sza`nFNTT8@YNOhm6s{9UZ^I?{0& z90f(+PU+jVgT9?I($?zRK_GX5Oz4;x@3HdxWcFMYBA5^oACkP87q=w zHM0C(ejXwxuMD(&b8OBhy)vf%_XX;#yV;bmi^#hcy2u({WDPH}h8J1Gi>%>A*6<>0 zoO^|pm2s7_86cvc(C8wYoUp8nRb|e&HY;bK&fTx%vnVUO(cj$!DXKi=#B$14@EN(rE zyN$(dVsRU1d6V@lZas@z&*Ijzxb*{zi@q$@f5l9i>wIh?biTaKFZc6aKIE zGw=A_;99OTtk?JV^6%}1-^s^F)TFKu1H`XIMf%*8@v#p=sO59l!k5w~x?4^So(dC2 z1_tdLc5n{s;Cs$Nq?D>|PPS)(y=0%wy;SZXeLK7Z-s!dN6LW=M?WCLFes}=-UW>a{ zSM%%K^4s<*-bpcz6yr!mMrp8)9h_6uIaSjq!8kk>q9x3s$&PUyf8!Ip1BO|{Fl!iQ z4a2Nqm^BQui0$uUr<*p8I%*W@;^wO!;s#*tSY^^o6)*4%DjjgrD)>>RC z!IdI@!&G6Yj;*lo^#yR@=J%SZ-)p9RubKM2cvH+1G49&NUAq|L+V8D?=WUS3%530T zyJugw`DP4uB?h}vO~guL?`C6f;~-wxVC>y(?A<*WdktgnZeuU<_wv2g(LR&MEymtP zV{d0;Z=00?e7yPH^I?V8FYwxha1lhV*M1IghPgx4$dqk#s>LmkQ+7CKU_AHApOsZi;7hh_dI?qbK>@lc1<5YZn!_o)@}OK)oCLe02L(OR_M)V*iZzMZ~-_nv1 zWe`?p1`VG}tqG;3>{H>xR1D1bi2Qbs-|q3-J)hgb|9i!!;Cnpd z%fZZ_;_<1OAyqe(29JMJc&q~*` z(x@TH_!R4>^ZC5XO1p!|K-Hkn9kKa0gZW&&GQYCS-xc%u29|o;U_Rf#r`*O;=g;S= zu36)Bu8w7eQj|x>j=>;{`Fzu?`CKiD^N}TDrCnCqWu-Bn-^NOBW2Lvvn$KmSSVgXk zhNS}UFo+IXd`w@DN8NtpkTaILwQ9Haz)~|lrj_?#T@S9|V^-_I)p~HX9$c*lSL?ym zdT=$ydAS~3sRvi;!N|(5)Pr?BC_6u`oYwSU_?X(j$E-{)@wwOd?$`R;O76-i>vsWRc3}C>&3cWw7PTiNA+S$FRmNR3~Th_8os7! zW>}*aqfS2JyH#d}b$W4?URf~{`uX!+SJMxLVI$u=w>D`UUf-_X7 z8I$;M7HgWl*Hd@_^;Yvoe!9VHe}s*2AN0)iPr&Cx_pRgf!92rKBaSUrnDE)TPcsTw zXzWXoE6D!pKn&}fa4WbAZ2B$uHhc%Z3+{iDehYXSOTs!50OSv!*Y7 z7MOQZ6&)!LoXTIM6qD3QNn@l86h8N{e4_IWCM#OPd&)RZXhCJ1CgP)V`YzXWC0qsX zhO6N{aE&o${P~8xoW(xA;czVT2!FxD@r@n6vBNiZQhAv4?eGqGC$CdwOMAecu$RB7 z+O4^o$KLxm?&}-&H3I}++z*DFaet4W3C%hATHW;3a0$EysCDV3@H%)syaC<_m%*Fh&F~g@D_jn5^Zone z*D>J!BG6b#8!=;yk7)mBor%G9O$@H9JZPDTLCZ|!*ETP17>wLaMHqy6Ud0?z-x(tM0n$uB-04>aMHqy6Ud0?z-x(tM0n$uB-04>aMG9 ze}kH_xMcI1^m=`B17M`7_&pWBr*;QR-wz*v55kAw!|)NXZ(8~>xEVeUpMbxEPr~2B zr{L4@8Tc&3YRkQO?=jd1_Jt?Heh_zQf2tPlh#0ecyw{8+9tkh%;6)w0Xp6D#j7!eA zy?kFewzJEdfKlCo)xk_}8Ii=FZJJ^umx5T@Wq@Xzos@UKvZe}n%C z{|^5F4frwqC;S9{3QhPK{2YD(zl4o&9}h8$wWd?N-KNcx>}Zl5O|qlO^eI?)paAD-3OAe+Br}_89-N(1ro+JEdMJy3_f_@zD zxtHf-+H@B!9ruBb`=#%zwV#eBSMt8eJJS7l>UX94rw1fg zrcdFWuXf+$rzh{p?~;6jJ0qW&+?bw4llgDydDNJH%GaO_+<~+6ZV1!`8|IX(eDxdGE|^zF{X%K^Qgr!-*Lxlr}_P; zc%?71$$ql4HqLoaa8>;tvGas;UyQX)h@m4>9<>RJMpdb6x8Vx*34a+a5&2lTQoQq_ z?|9{25z(i{O01M{roLgVZ+K|?wDCEE-;L<>;r{k6uD6u8Qq)=Li8u$pjbG-rGSq9; z#(9m3I#kp#|9;*(yZVM?5P|oMEDYb7YX>pKL*FxJxB1@^eCQE<)9%K=gmFB9=}lmI z6PVrvrZ<7~k_7?Bs-AT{$KLNg%;Cl(am;4nr<9+Vflcq2Nqu@Kz z68N5U2iOsI0(YoQ9|wM__(&OPd z@LV_n>>HcfH#U7foCGJs3*Z!ZA-o9atEnhkl+Y3-v_uIlQ9?_U&=MuIL zc}`8%TwhRl__F9-J0^G>xmnpN)~7nk=OUM}N3pMqUM?z|RJa*u#qJz6zHL|q6uvD~ zfY_bGiYfL|^m1s2*}xiQeA!RvXM3=l{wy!DI=5}s7`8oak%gu?d!)qPQN{Vv^#;EX z`{1(3!MAo@d8p4(*&VfSu?96W<_7sB$FRi0ix;*XmCs>~=R(0oTCP4amyyk>;{~(N zHR>MEP8RVtW4^tnRbuax7)2%C-aaq#rJ;+cdDR+Yxq@0$1Jg67$7Re@E#F*JorNFG zXE@)sc<^m8_m&28NT|9of5Z+b!!{1~)GgZ9^%d2FQC-#a%{|{7ygx>bbyt2x9enr@ z-yXa3MC5pdYmnt&59_o@DE>{h&}0jf?4ZUD=^a6d-=w8G1|=oS7-%1 z+SL!wH+F5Ay_z*zLT1(bXKG)WEZ<(_5W>o2TJ>J+trgkdzKH!$JvQ*i=_dAYKRf{a zn7#Sp|Eho9Tg&tdw&H4X&lN4BpL2hxCGuI{`8?7+_WT0NE5_hp&nxYn*A2vMo%41q zfh`Pl9lsQHqE$T{T3Qi}$GjNrA67}18StBa-UnM=L(YEnM{x~p-)^52?LPM!*t^$? z(O%R=(vSvyFx#)!T)|;%x<>)%H`(D<>t!e z=E~*f%H>*cv0q>0`o>wq_~80Zbba9^Ug|6&|G(U?L|+u6tHL^CMCB_hru$%vIZ2D; z%*%1cV+F_9+CG0tZc~1RP30_@S1A{(NvxeW7VK=Bx0Ze6S*rTq zoXyO%7^~HXdDcsRM~hYTI%cCEqCeiO1*0M~G9$y8FuX*;D2tlC!c)YUj_P3bs>XET zJBN9f+4XyJznFVD|MvubhZ3cas(!Vc?gG2QZeZ3-pJ>cH2|^b;h%QDC6B|~=hE=g) zRcu%l8&<`JRk2}J|5o*HRsUA?Z`Cga$K2O%e>pw zI^0Lk4ozO4_I@nkJXT$d_uvqf(G}XuFZsPt=tyde&IFXTxQMueN zEoV#1*;26S#agY{6*jmJJ=2)!_$8jj^PH{d%g9{q<5!}8Vz06xcl9gUyja^2vt!H; zn5gT@E4Mul){@UUxy^+o40E7GhDznEYmyuHi^VQJ5ozu!=G@M&xQC`=M3&7n`k^k!^!q53McG#25yMBvUpR$9c0fN{SVYUH>p3B^A8EEr{xMSNLu zqSlNR28*<2So=6@FBw=v`d#jGUe`k0x+Z!dRU!G0Fa*rPVc zeYp1vJ|4Rkhvg@uE3{kuVt6L8f@A!0@RqzKH+R!eyq_eR9%MQAjbhjT;4hD~?$Iw& zQ1(^7c38BgF(KQ}TdgVPr_ED-aRLWhE6x^C>YtgFBF3IGc(`?6`{h19yswJ4q8~jT z?pHCGbEyvv+FOJ6)}X!3_Q;QHpWFSCA&;;;bow}@Yz(6STB z%&$&hFcTQe1O_v~%Pz#P&YwkNwQ;O89?YhxJu>F?W$bq_i*vB3GuUXs(1vlqgU_ls zf_}^u%x#R#@I!B9*KdQurt|$E|I6dFM%ill^=>hz8>z3;C^@j`tWD?3;Y!}>*EAc zaNg-CIQP`Kr_Mdy0r26}HKbT^`Z#zzJOOrw3b?Lx57-m-g0P#Va3m~)qu^**4#&W; z@N75^j)&*KbKwMd9-Iizhm+uBcmb%&OJ4}aTS^5@uYkA1JK&wLiEe#AJOKSXmMXES z5}PWqsaVmmo&UFo-5_cgXySQJlpc%VuvvC3ffPny6nv+a zDru>bmMUqfl9noIsgjl|X{nNyDru>bmMUqPl9nlHnUa<%X_=CiDQTIKmMLkOl9nlH znUa<%X_=CiDQTIKmMLkOl9nlHnUa<%X_=CiDQTIKmMLkO(iZg?SIE}P&gH(#^DE&h zcsE=P?}2OJdXdTvU~P-+WL0*uDmz(~ovg}ER%IuvvXfQW$*SyRRd%u}J6V;TtjbPS zWhbk$lU3Qts_bM{cCsovS(TlPTvC-%SshXDI-+)AMD2ooD@KjZ9n3S2bIfZL9CwBa z?B#WSfG-LjH52F0)D^{womllA{TnMWLv@WRjhGe7X2tN|(|Q2*KfRJzp0+Db+fDZt zyJ3j3Mv>v4sa%M-Zhv?(9021`)ISsz43P(%fTw{Ko#`R42%Z7Y1W~5^Z#O;LW2Ssou6b0qr-ox?s$=`LzWc7@$wcbM;+-o*y4gsb4)a5cOKt^t{)^g4JiT<`e} zpnB2hON_q6=u3>g#OOg#OOH_!QcH6Ho|?-gH1BX_rn9w zS1(spowx_=3C67~U~@zqBinQPVzrbVZ;=#&bEXRpncBhc2D@V)(MyN`J?B948u zT11migqru=pOMYCvGFd?61lP>yZmr=s9xtgzNcm9j}E^zuDmPhiP1;D;~; zKZ1XTe}R96I{X{_PxyEE4`{%T;XmOg@Kb2Q&*10q3-~4Q3`ux~UCeO1!fvoTVDDzt za%xvhWJKtVLcVrQyF=Zx~2W$$@=Vi zJ)Y@txgfp1uhtEgsv^>ipP2Cn^AT&nI})5@FfXl17W-UO??jc~67|`3J=80iUdi-I zrdP80e8kw=HX~GVp=GODwrZwN)HWq*o09a4@Fn;vd=0)1-+(pnaOapQzaJiug{g^3 z)I=p}q7pSxiJGWHO;n;LDp3=asEJC{L?vpX5;akYny5rgRH7y-Q4^J@iAvN&C2FD) zHBpJ0s6+vs^-91wZ44DYF>Rc zufCdBU(Ktp=G9m8>Z>v38m3&slxxZR_<|~{=&_0(KcJ?UN8QUiQRSwZf|XSGgT<^Q zqIh?z@wwb{`|M#p6?)kbEJbw27gYIzDqm3L3#xoUl`p9B1y#PF$`@4mf+}B7zM#q%R9Rh*)%93ikJa_~f`?bb9KJw( zOKLt#tzSsxq*65!W{R4bqGqP3nJH>!iV1#Vf}fb+Cnorb#r(u#equ2{v6!D&%ug)l zCl>P)6RdfHHBayp89$Nn6B$2|@e>(8k?|85Kaueh89$Nn6B$2|@e>(8k?|85Kaueh z89$Nn6B$2|@e>(8k?|85Kaueh*~1cUYvEh)ZTJp+7uLb|;QR0c_#ym=CH%zS{S=z;Gx$0D z0)7cCSP#E~+u(M{;MZ^m{08oXHrxfjg}dQ*(1G8>J+MK<_eaADp7)C*bj|uAu)ha4!!-9fuR9R7n^#n6)vl@yP9Ok{lA)<9U2i{S}y~Ed(`I<6c zQ|4>Rd`+3JDf2aDzNXCAl=+%6UsL95%6v_kuPO62Wxl4&*Od91GG9~XYs!30nXf7H zHD$i0%-6`w@(Z&gut(-=wqmKi8-M0=$}F|a=al)JP@l&6oN+#9oX;8m8{A}O2EE>_ zas%85c5UHvI($xt&*|_v9X_YS=XCg-4xiKEb2@xZhtKKoIUPQy!{>DPoDQGU;d45C zPKVFw@Hu%^F6->G&OYnxv(7&2?6b~3>+G}6KI`nW&OYnxv(8|)ZI)AJIc1hpW;tb+ zBOZbK;Q{DVU-de^Qo~nj_)2YLZ}G_(>;q!A5#D8FKZyA46S*~Q$DeEuIfLbc%CMW~ z7|*~bMP^#8;hiTs?q~MOt%`*m$}b%zn{_xpv@}^Xi^VRuHBkU76u=4vutEW>Pyj0w zzzPMhl2WE9fE5a0B^?FVNCB)+04o&0O1dNL1Z8*}sD`EhRw#fK3ScGOh0og+c7xqv ziPx6Gk+2Mof}>$M90SL~v*9>69-afwg%jX;a3VY(>;Og)tWX3i6u}BbutE{6Py{RK zsURDW+O;T^4M@*~AUHp5c-U5FcH6`+-VYBz zAM>r!ZTA3k77d|?|183P7U4gOlFzazAr?!aOy`OrMVg(Ia~@>8v!1b;na%6LeP(91 zP~D@hJ(QcwEVpK;04``;)N&pRrS1=6uGxxysy*f?@mu3hLuFDPN$-v6y|MHm&wRfB zR#*$)f^Wlj;Jd)zr~G}&->3Y&D*AFBH9s~p-&XvWnCpIc0Qy*Wm4)pAd%|AuVC#DR zTQb7$YzHOS9(DpuHesW=#f4&c5JZ;paF&+Odfv-*YL>dfdl$fk9v5q0O%VZ%>79FMR^+3>DBesqvc{zp3$?E`g=%^JsYK4wkp`%vls1-VDg^pUGqgLpsR(HTE_z}#@HnXrk3+uD6J`3x! zu%6hiC${T}?RsLnp4hG@wo_e_XKAAzF|xGf(KD!XXVU!n<$>-Wl~2R!O=~Z_em<;V zPye^ITzx(;%PnzCv`<~l{U42m5A0y~!Oyw_AK1a}V|i# z1?yW2*0&a{Z!K8gTCl#gV0~-B`qqN=tp)2_3)Z(5tZyw?-&(M~wP1Z~!TQ#M^{oZ# zTMO1tn(#CDIs5{C2^--)JY#D;^>UtHUYY{Yr0zATdrj(Ile*WW?lq}vhi||d_$GbpR#*$)f^Wlj;JYBZglBc}tS+9_#k0EBzqJPbup<)ahy*$! zfsRO^BNFI{1Ue#tj!2**66lBoIwFCNNT4GU=!gV5B7u%bpd%9Khy*$!fsRO^BNFI{ z1Ue#tjz}QZYtB*UDH<(`MvJ1+qG+@z8ZC-Oi=xq@XtXFAEs92qqS2ygv?v-aibji~ z(V}RyC>kw_MvJ1+qG+@z8ZC-Oi=xqDN5S~-`3gjt z(>xO^Yno?cWlQsnY}GO1RAWSR(I4np>sV`BR1unUPh z^9Vn?oo6M-?H$zth@smULumGG)}3Gt-8_zdV$M^oujj7||6J(xMeJPYb7oA@PRX~I z7BqHlIj8mTE4U4AhYWrVcffDpPH4kj@LRYWeg_@+J=_C-fP0|}8{m(yQM-sES$e|K z6OmLRl1fBU3FgtoJi3@im!&5xJ*W1fszg*}>p{?-qN+qxm58bmQB@+UN<>wOs45Xv zC8DZCRF#OTBJa>ncZJw$3cL_r1TTh{8)d54x6ljTCEB?Xu7Y`0;pVp* z9$v%4YeqzqKG38OH0c9P`aqLD(4-GE=>tvrK$AYuqz^Rd15NrslRnU-4>aimP5MBS zKG38OH0c9P`aqLD(4-GE=>tugWb~T6JelqO^B_{I7!_(>Ky0iA zs*=b4RmXkx`Y@kiEDT0MPxK$Vx<%e%4L@I5;K;1P&sX^Q3O`@r=PUetg`cnR^A&!+ z!p~Ru`3gT@;pZ#-e1)H{@beXZzQWH}`1uMyU*YE~{CtIRn87+Vcvt6^+4jID;T z)iAai##Y1FY8YD$W2<3oHH@u>vDGj(6_BtB9ySv*LUD%FT$`F}Q*$lHQyNj(HG-dv zsO%cq4setam0cq|`iRP|5nN@2{xG7lYeZ$&h{~=Jm0csOd}J5c6;zjv><$kSU7ABG z=8%dxq(c2n{ZCDrGg?Gi`G^r|O^+Ip#6T@8SW>RT`ny6gs|*;^+I$2R8pkb0QPn7_ z&|fR`*9!f$LVv9oqZRsVh5j06P@%t8=&u#}YlZ$=p}$t>uNC@hh5lNhzgFn475Zz1 z{#v2GR_L!4)r$)`iYn%i%40T)=I5*aSB$DH)HhbTE%r1!Gy7OXyboXDtI(CVRynkm zF0+;{vz9Kib}PEfE!fvB*w-!C*DcuBE!fvB*w-ya&P?s#&oQq)jRtdu?EzEBvllyg zTm~$GW+R6Nd2I_u5_)q{)6z9!=r^>*qGB#~Z^(BrGHPN4Q{2<2tLmtmoDOGzwciQ# zEK%2&*n2-YM?7NXZ4!HH6n8ZlSBn^TH5pHacQtu~-@MHC7He6fdV6A8%WgTZ_3$gW z4Q_`FehqiPZ{SX7!(H%OxEp>49r!)m1Al;fp$i+}kI;iZ!6vvL9)Ldl8U6x)h0UV! z1gHr#pFYi}PxI;1eEO;Or1|t|K7E=`pXSr2`SfW%eVR|7=F_M7Y+28vtue1Y=GDi% z`h&X4;l5I_+i4};pH)1W-#x%_W?!jd_ayb*bfZ4qs82WQ(~bIcqdwiJPdDn*jrw$> zKHaEKH|o=k`gEf{-KbAD>eG$-bfZ4qs82WQ(~bIcqdwiJPdDn*jrw$>{w)3b!RwB$ z_t_iZMz{%9!u#O;@B#QBdadFDH49vI; z%(x89Hh0aM9jA;IYm8!-k+IQYg+Q^Q{B+OHh&3rdiLpAMX>~w7UmfsD&x=(79o{~V zaaesG<2Xia^90Nd_cp@1MSNp^+S}uzt~#p6qON*Ik2=V6`{3tVRH4InF}=0PLdGFI z=kq7n1oy)OFem=-e6#odm4d} zp_h3zuc_&9JjiR2?K;9|SX(iddF?bf9nOF=;pK1^#7gROeEwXp%Rw@8Kc3jPGw#O| z`*z0tc$aE0Hv4rcAoKa=fu4hyEuxt@iZFQ>IRzwy}2n{%t9=Fgjt#Tf{Lx58TZ7JM7N1K$Pem`r0yrm-Z`SdwXs zdj&*I`rM44*~lpC8f9IhtZS5Yjk2y$7CXUJ%!jdBZt3XEJ(h+$N5#$`O?jBu-zV-F z7W+51=m5e*aa!b{W7YX!M0y+}GU{b^^IFyO7?F0-z&3|Y7}rAVAzLZwKk6bY3g zp;9DNiiAp$P$?2BMM9-Ws1ym6A`w?@ZFN{eok*w?33cMpSsk`zT$NBO5^6<4t%#L3 z55F#O2`gO+N5V2V3XX>5a10y^|J4;{Th{!{uQOak(_2K-TSU`aq*`rJ`X0Cj=GG&( zF~~Ls*~TE-7-SoRY-5mZ46=RiialB~~fvRZ4o5l3t~xS51QqrrG z^eQF2N=dI$(yNs8YPut63rc#Gl3t~xSJNlJ&QO8*^-0>wXssHpRim{^TdW#+RU@xz zfE(c^SPAcg_rnL^gYY5vFnk0)3J-TJ)#v=q z=iv+RMfehY6}|>vhi||dkfWqGw$h(?{8MPc&*10q3-~3d6iU~_ui!Sg9jpLQ-(F7d zfZxEK(1yFTBd`R z>7cQ8nduJZS6Zyc+rtjtQDJZNCg#|VIkqhBj8V+af!b{Zj~TsV=GV&1-0Ho9jMU-W zI#Z(>Yh$8DwWxz%=lj$wEpVn`;pXs-uH!!F!JlAGp3U=_x%|<}vvuUzI`V8CdA3ff z59ZC~4{yECLH>RMmcUY2*xcNZ*;ZtzD{6TwYI!SadB=E_FLgWUwWZ#c{uJBZI&1rBtoB?OT%juq#=_&&;0i}F;b^VZcD8o5*-v%eW~k$Lxc zW7xdwy?pd~Jm&E}Mr|?w#>&*F!CtNYa5W{WN{K3&gICjhS0~T%J?_S$2C;5r7b_Hx z@E1i@*SK25!N_(FKY$;CnmN^7E!ABu)m<&sT`kpJE!ABu)m<&sT`kpJE!ABu)m<&s zT`kpJE!ABuwTLaXh%L2M|~M8JD_@OI^mLF5^;{ zajDC=)MZ@iGA?x)m%5BgUB;y@<5HJ#smr+3WnAhqE_E4~y6Uc$>aG@jxh~66mu0DA z(~DI5FH-HlNVWeWI&ocgq@L~xd%;1;@#eqdx4MJGgN+)>gc_5%l~!Bq^I^W)_B=Mb zrg98Z9>bK!Fy%2!c??q?!<5G` zACsXUlc67zp&yf>ACsXUlcA6L^3`f8SF5R9t)_Cdn#$E`Dp#wiT&<>ZwVKM+YARQ! z-^BiJg|+Z4_%?h8z6d*cF|l}HQM5iG9@wUYBB0+HI=K?RIXN2xjOv?{1RHQ z9)1P4!R?U2ui*~(4crNBxC?#@cf;?X1HXrRU<1$eN1zm@s`%0#Y_eK(?#j_RW?jdu z>zH*Nv#w*-bpEs#$E@p^bse*=W7c)d zI(Ar?zjE}!s?^3Y>v7C_96#I|vkpc*WYJ?DM_#mugChnm))*h;D0?9W9;`2RJj^J~ z<6nC0vMa+$td9_Y(G`f}WZ&OK8Q3+%dEV0VEz!2da{eLhQnEZDYw!>S+J zI-<|{+~?s7@J09%d=;yHUj#QmE)qo>=k!wzPnXM!;^*s)`H2gvH^ zdDaHJ0$vH{!wO>~?#>*0pw6wPF6xF#1Ex*)@&1-|Ls4@#Gs+J%;g(4--UJXJ+K{Hbyy{bCo#qRkMZ9KM&VNULgnjc6bN86W(RLuOi=T5opNB8N7vW3rRrnfw9lil;V2T&ZcX;ynr_h9-!O!6r@Jmn! zC{FK+)4SsIt~k9bPVb7-yW;e&IK3-Q?~2pA;`FXKy(>=diqpH|^sYF)D^Bk|#!6em zirB*QG1e7I4} zNAU!)%hPbzx0YDFBwt;koyT52P4Rk3ydD~Q?06p)CH7Cv_48skxP{ft|Idk;?c0?; zc&6)-RIM!h{Cy4&a4v`$&Cziu;77WP-a^jNEpv3sesU#oe@Wb568D$H{UvdKN!(u& z_m{-|C2@br`ksfo-%?W)P@)r*=maG?L5WUKq7#(p1SL8_iB3?GYcHj@!R?TNHNJA~ zCAs!eYK^a4dr7XnB-dV&YcI*Qm*m<@a_uF#_R#dZ)W5Ek3|%W3y0}GIeRg?dPuL3{ zWc@#GF}>TL`V18tTU4$@#mX*5@2(J4E4w>J<%(ax_$$fYj=}jO|Glq~UTE-@oF7Cy zpDT4fS5&G*6==nsM5>tn&6xgLOn)t=zZTO^k_#Z;LltKz)VLlsZY`$2mKwJh+b>h( z7GwOeyRv%?;2?2Vt{XkR2~<~L`3twFT+4T_hhM>Ma63F&l{FiE*L@(Cl0#qk3Y+;A zH7bzOgF%f#dMGRgky?5LJQme9FY!Asg_psp^4fN!n6p#R`CeZE7r=#Z5nK$ff>*;O z@ETwv>7~F%($|BPFX@JMs-3%e?#*t?I~XhhH5qjPVgd<<}M z^ZVS2(&ElFao@hUBiHP^f7sz86h5z=>G*QTv*2vir{_@n&Q)bvD132`wi<=6G8*mu z1lhQ*Y}|wFLu1tMW#sJ*v`3Lb?4oQhEytSUu+lX4sTo$nywvx-jMjdt4Ap6HI-CJ# z!pkA8bGQ^PgYXd7`km{% z{(aZ*1Nb3Kfr>)eysm6sS2nLJo7a`i>&oVJW%IhSd0pAOu54acHm@t2*Okrd%I0-t z^SZKmUD>>@Y+hG3ZvkU}-+v#-@~8*@KXmULbJ%HcI-CJ#!a3r97KuL;J7b^kxB|=& zMt@@TCq{o_^e0AtV)Q3Qe`53}Mt@@TCq{o_^e0AtV)Q3Qe`53}Mt@@TCq{o_^l!QA z_Pf*rTnSgfyWwhh4_pJ+8xc3ajc^kz%+4kGTjsE0;*t{ysC!AxJs2I^s!*Q(nyF|lW&l_VY9 zLZrdUt=t>r_9K%&R1>W?_PEd<8X}HaI}rQMVTSNfe{ndNw{m4sl|J<^_OMt$&0!%u zfb-64>$K0GU=!RA4?y4VPOE>OZx$^ikb<3pts(1JL)Ni|tYZyXC$&?sHDn!Y$U4@L zb*v%lq;?9nhOA=^S;rc(jy){q?$SJ8{o~yqQLX&J{_a_DC@coNFtswsI<$^;XdUa& zI_WYv3XX>5a10y^&xYgRcz6yx7fyiZ!HMvEI0;UM7r-g-LU<9#bfquxJ1>Qo!B*=T zc${LtjQM-|K2l||L0N2278{hs24%59S!_@i8(l*I;Ru|ZjEP!=1M z#Rg@uL0N2278{hs24%59S!_@i8gm%b;~*Ih(y`7uyh+D8Yu<#HuuBwgqVm{Lwu>i;HEBGFW7Uyv&65=CuJ`tQ znxA+a{A53)tLAU__xLGL>_gnAWX9dRGaM!EA-YneGAUA-6sb%OxJP-wJ<1}KNfF9q zzP?)Z3%-%esv^qpjtuX}@Qw`c$ncH~@5u0u4DZPBjtuX}@Qw`c$ncH~@5u0u4DZPB zjtuX}@Qw`c$ncH~?{Lp1zh##$Ifss%Lr2b`Bj?bObLhx9bmSa5at<9ihmM>>N6w)m z=g^UJ=*T&A zE7f=D9 zS|gfWsu)hJn_EatrO11H&Ut+vz5ri@FTq#gYw&gW2CRW%PwGAn)2GJvsj+=(Y@Zt2 zr^fcFv3+W6pBmez#`dYPeQIo<8r!GF_NlRbYHXhx+o#6%sj+=(Y@Zt2r^fcFv3+W6 zf52g4?RjzUZn-7=CBa?nb(rT&I&vm)PuaLT_>`PU+>5zBTyuxhbgZCGshcBm8dfOq zL=B#(!4oxRd7?({iL6ja9&hwK0jy9+%&WXp#ye%aQ)A$r8oX2NotRm#o{5^=W6|gK z!&_=TGo4!rHB|%5d7CzG z)8=j3yiJ?8Y4bL1-lomlw0WC0Z`0;&+PqDhw`ub>ZQiEM+q8L`HgD75Z5q5ygSTn$ zHVxjU!P_)=n+9*w;B6YbO@p^-@HP$Jror1Zc$)@q)8K6yyiJ3*Y4A1;-loCZGe=5G)7_~~Iaun3+3&xB`r-LBF+SjK~8 zJXpqqHE^H?4%EPb8aPk`2WsFz4IHR}12u4<1`gD~ff_ha0|#p0Kn)zIfde&gpau@q zz=0Y#Py+{Q;6M!=sDT4DaG;C_%XqL12g+1JXDXpHmC%_==xn+Y`fTTTzUS@$&ueA8 zR>o^(yjI3*WxQ6#Yh}Dv#%pD~R>o^(yjI3*WxQ6#Yh}Dv#%pD~R>o^(yjI3*Wm{BM zUn`2b4&DpbJI@>7Mp!W3L?wMFxuV!_Ow`XaEo`1>1CRVikmZ*h9^BQ6T7Ew~05p^> zxY6ET6BlhGTRgo7TDq)=!g!6mhQo1tC@QLBEuz&-Fq7Yzt>47%PNCl1_LsnBsbRPD0Cxy@`j4Z*&l!vEOwcCbnh;tu5ZCsK|g4Xhu?kFS5UFET|wWg2v5=~ z>;YESH*Z&#duf6cvr=ESH*Z&#duf6 zcvr=ESH*Z&#duf6cvr=ESH*Z&#dvpQSFj_GigEcUwWkyv+3CNzAGPfC^uDHarl?7s zU5gs`sV=KQ4TZW)p)QYxLe0yG;70JI?VtqP!wyExj@EbVY@t&Laaj+H+*2KYN zZXEaUd{4){c(1*2km=RfJ|C;GiwJR&-ZaQ?dp+(qGR$xnoGk7G9_u;XxyCWP;5x9T zj`F;a>qwe7SraE~;$%&ntcjB~ak3^(*2Kx0I9U@XYvN>0oUDnHHF2^gPS(W9nmAb# zCu`zlO`NQWlQnU&=JYy}p2vRzyISC6O`NQWlQnU&CQjDG$(lG>6DLzu1o{CdYvN>0 zoUDnHHF2^gPS(W9nmAb#Cu`zlO`NQWlQnU&xO?R~5#Txz;5rfDIuT$KCu`zlO`NQW zi?s&3cs=yHqfYP+2m8Bc!J)7i4ud0LiSJwrN5V2V3XX>5a10y^&xYgRcz6yx7fyiZ z!HMvEI0;UM7r-g-LU<9p7+&IcUJ5S*_m0H5nmAVz=W60y&6ySEyvOX-XXnc_uYe2S zLbwPnhF8I>;SzWaycRBn*TL)I4e&;=VgdhZ<6mw3tBrrP@vk=i)t2je=&RS~MvarW z*(7c@iJMK*v?gg#gw6*Rr-BlT7^9x!eRUH-XDd;BphV+{38+oAHKr zFeo&zjF(d-0NaB|hljI5-!WFCs~6$nIy_v)!`aQjk&eQ{wRyKLPS;DU2M}RqcwMnW zf9}mZ7NLkRhj&p*c(hoZUgFJ42`k3y+R15fI-CJ#!pq?-IGcw(2hIhtGo5UmTwPDD z&N>_Uw+rAxtAH+oi=o(?a2?%j9iCT`*^j(kNoGHCcVja9Ejn5m$E(WhS7r7ihqsVg zTE>%RJZZ+0W;|)elV&_=#*=0|X~vUgJZZ+0W;|)elV&_=#*=0|X~vUgJZZ+0W;|)e zlV&_=HcLy(c+!j~&3Mv`C(U@$j3>=_(u^m~c+!j~&3Mv`C(U@$j3>=_(u^m~c+!j~ z&3Mv`C(U@$j3>=_(u^m~c+!j~ZSbTGp0vS}Hh9vEC(U@$j3>=_(vB#0!m7Vm^*+Hv zMpWA2Av-)|hllL&kR2W};~_I1GUFjL9x~%0GafSIAu}E_;~_I1GUFjL9x~%0GafSI zAu}E_;~_I1GUFjL9x~%0GafSIAu}E_;~_gdWQT|B@Q`gDvdu%bdB`>o*6Rd>y!TaF@@Im+xd>B3gABB&>&G2#f1pFO*68;`O1)qk` zz_3pEbFTmM@CEoHdbQ@`<%kIpAE2EB1d}ONU!ahpW@!*3jXa zYL{2j;nvuO{g8-f)AF;PQ`_fpOJ@H&{od`*+WxGOC4rG8r4N=qSpKKS-xkPUzh`vs zk-$rLJ@85YvFpE#Tsm^;n@$~>*zUaT?j8AIe7f|(J$4(t{AnL9ZFuSx)r#oMy4N8uxpnVV zd#@@!8;^G0W%R_+%j5sO4vBy9&c0uM!yV_ma?zc&jW4@=$1m@G>vnrSZe9Gp@0WM} z$G2U#(}C}J;el73x#o#iyzaxbjkS$q=Zu}R^FQwVk9+JE=QnzJC97Wil&eNoUc7Pl zy(?M#J8kh!|FF|P?Dm!?Tv6Ik+VBGBSNx0D;+>uTVdq`qOsW?b=dkyx-S^&O-N?$l zSM7O4@$Z%IU-3^D)<-Wd&V1)xj{WiI<=g-0fKTl3|2}!LbZqI^y$*@r*=O%VuiE#^ z`+j-HFE6@t(Ve4{*Y38<^*egD;KJant9=Gnq+78R(S-iIUtz+lJ zH7vR_u3_hYtZm%o`kf9Oovdv<@T%h9m9?vPdCOh#nUkNh!}1-LS5A20TONPv<4@iB zA4eufCigq(td)oT`I);s{r@@s%S%3W%p0G(=W9Ae?1aT@jyrZ@ z|=JiR>tk@Z~&(J8pHoDB`wjVLV zMtQzbp3keDQF+BtdBtQ0e^d4?Wq()w|EfC|C@ZQn-|wpGruC?_F+C&gqnSv8okW-j zJ^>R%V0;B%_y9DbC@MONFGPGHDk3TpF-Ej?kjXUhaWhSZL}(cuGCf9=bkO#3qP8(d zO=~!2Y{ete=5l}kZ&%ehrypo$-F4Tx-RobwPSvieU3-7~d+l%U3Yps%g&=}nUB6?vnEX6DT+50zSYv4!Mo_|} z44IIqCGK9}?uD=se9G@Fl);xjAC0C=W4Yf>SOQTUciop~R9lJAPk9d)UIwm!W6YvN zRx*Cy zW!tzq8$QMT*AaP5J%+!db_Q>2q@~-Swl=QHa#fbAvRsvo82OGE`HmR*h6384LPiUy zxg6!H3zswhx{>`yxYJ7Z*YfV29A}0J<*HM;BIa*L%-@cfzfJk_lrK;Dplc{*1aJ6N zsI?kjn!f$@boeQ6w}le#v~3G5+!h^5`H;`i_q8@5$E}4)8TX1#OhemOXT%)H5h+EhVXivY}Nd zqZV3fHCpvPKxm08iTV%m$M6JezwjAKK|EISPT@A*nzf>NuU05G7mcRO+>Q5ZL;g7A z4iw9A-Xp^QFwdZN@|81yOlinpXOezBW0H=MuvdGQSvFflersc+6lh3=9Vca25I( zG?Ir#Jcm*{sV9yD*jHPz-K&%oBWHL-&ZbA`UC$xqeT^^7 zqwVayd5Yeh3<@X`%TWj;1ugw|dG7@dndlI!Wk$OLc-=_i9 zyF6oz-RSAO^(5+m{%*ZgPrivdx8BIUT3Sy=t|hJQpU$27b0_#=+#7ufShJj`YYf$M zeWGdL30<_h_sgA5dM3Z8VrTwcOlNsYP@s;9#Dw1G@g(u~E9p0jc>04peHp(c71eh< zKgg$aSH=7J9!%@APfQP#P6Qf!;UvPTq5Oq{2omUj>Wbg1YNAh%2)ipGrG8pyO}H@ z6_qX{wR#}+6kC9|qK$x!@MJGHj7LT4Fa47zlI{x*p$@Fyu+NJ7#vv!NZ=8YjRPX~p zWT{F6pST2hHkb59w6}TGk+@&@1!E%6y5e%+oIla7Xpd ztZ_%lm}10rZ)+;3BsCHKZ1)Y*meTr&Y36E5V{}7$8>L&scPN&!-vAyU^U&x&m zXj;;Xn#osexprT79P{#tenx9Eo*o6%gXqV%-U8!2o_^|MsoBmtN+(iNXnBrWbkw3d z1yGCbG*H@~)Wg-1qOq%hN_`!;0n7&r!Cl~Pumt=F{206l+Q3WTW$+f*1oGem@FCa= zy1?g@xC&%=_F!lUO&gwfBi7+O-d`;zik1$%4EVkynvq=Y;JrKGE1PM>CR#BoSqzP| z(2`kNG8Y{Oj%WV_Gza{)v}D#a1^l+~+E$|--Wty57?E(%6mU8?1H?2HO|_C8&vp_s zVK0FTGJ{goo>KYMXg=zD(lmWvleVsY)+zg?jKWjuhTEG|kT%ZKMk8^h2Z+LtgXSa| zXdjaZlgKM+oJeB)aq#C(__J2p@E*GkJa!#;>pF;H>%bewN;f=N^*0BIUoYpkN+|Bw zL}^#DzlMGB>es;Qpo1r}A}4yMBu63TnDz9412}geI0zgJR9f1LlI7!itMv88Z@h&j zJ?bf))_2c%?f_Sm4J4XU$*u;Xshhx3AgW&h9;I~Bu{XjMjYCquTc{T=LC|e^g6X!D zKyu9c9b~yw`qm}&{j{2y5tSy_rjSo^&BmO#7u+IJAFYqM1to;;7?qCY8g_&9K}sX8 zA$}!Z^(pBVuIvXGF-y6}XnuRz>xA}lo{LaQbTrei7)g(5Ph3QrYA)s?8A{h17tyF# zjg|15;Z@KP>lB3x!JX90U8Kt?%}TI}-}siWQ5r+$I)u!12$|~;GS?wwCTqw{){vR3 zAz#!BKPKO1@ChhTq6jO4alnZ2zlfDkqg_CMK%8Dgv`a*^ON1{u!k>tp(}k#f31sHmnPa#^a=I`vNZ-%UyKv=pwkh&(NUE0 zXq6IeMzNr1GqgQAgSTthpUXadx@_@{#&``|Xbh0!GC`zG`1;5NXx4e4CqEv9Trp9x=-Cq$(ywE&A=kz7od z*_bZH6GfNeiLwNx`(dpYcq?cMZW0GqpO6099dKmR}C>RYA{%G1W`A;y8PU$%( z%VjdDIJoyQiUVccw`uXLx08@5vl7h!OUCQ4HRy7=Vks%D?DCDIrV;s8w$k-St|X-y zOT8US33^&rWpye*pC}7A+Ew7L?$v57DMs zfYkem@Ja6z$VVr0{1oz^#&PCu*;xG)t}V_gla5mzO?6t&4O@{?*FvLcT=b-Q)ZJy2 zOkDozZJ$xMy?CNHCw}@nQq%tu4$qT4?RFTK_fk7=F3E|Mj7vT&?fWL5D77T0$tUR5zeRPi-Z{5| zuD`={up>47{>4rj(@g@|BB9hEVc4N?t>K*J1hS8xfsQMh?ozK^gi^ zgx2}UQtE=0x|0&)J)z{rsqh<>NmG>;NScZ_ETv@Xd7_dPq$;V&GWHYc>gyj*3wcB} zTxYjs<=3hf_GWeIAVFLLPZK{vNuPC6SLML^=O8 z3c+V~HT9NgFuu+^ydKZ-qSS~j^O(l{8*GW`Jh47R-_mCK@chsllU`|Wz}rqDZ^H2s zoz?U%YM9bvn@N*4%M7k3ZCZRer4IIq?T&5c$RtR)RfdL5o`fp;^R(2H5qprWzPG(V zeamjb#|VyxX1!!d?55V(Zjxk?{PPr3EV*+hj=Fb>jMnxna5k6*&H?f^iS}m! ztPe($ZJs#X(OV~TNX64RXO_wBqgVfwcJ5aDX+)1Min^F{|)d?z0|j0H2X(E9e5BQ?k9l-e542 zj8${d=UVYe=I}}8@JZ(IN#?rwty|IYSX~znR0f@dRlVTzqN=19-^kf{+a5N`N=h%u zPaBo>jivCM2B4n3f|4-;iZ4X`s0;3ycpo~^1mwY%)T%a}&U+lxN2JHpdN}|`oPZQN zjyE};H<16*>oKCV^~iu`C=G53MS1B}=WRLKN}Tk7?b^TesxJesJ+(mdma2uwjuGYw3nm3WO?PWyz(XOl%<_I zX{XK}?KFb?<2XK^G98fifrR!&?~edIc@=m9_@@^bqw11JtVdr^ALvH^J!pG(o;m>3 zf;~V&Q3+@0;aN*dUpA%^ji4M5_O1y0c*&EHK&g5IZlai?)EC;e+HEQx0 z_1MJzN{%J{U@gDb(I>nIvL<|me6NBm=-}MPPrX55|PaV<|w+Upc%Ht(lRW<=K2S^hE3nNl#csthKonSFoLW%Dq zT}towUWk0^fmp>GJ^@z4^VX0)MIKp&EnM?!-tJwl>jWQxkHKc}2`GS1!4^PN7JM!P zpUc4KGG!hNzUbjCL*8OP_J@F>V1FuRKSd z(`Qmn&kQT0^heZG3zhBpqQ z4TpmRsF4G~LEvB@j#4&i$?x%$d8Cs*bQU-pJwkHq98$@$8#y}nI`f8L{^BSo`@NlJ!%r#n;p0O{AF)rbNl;e)rNJ!W$fFZ;)f$ zHOIJXjy`9j|4=&CFXz65cI8IVj-%lCqtHEup?eHN_ZUWd4ny~-v%Y#cZ;j63-=2K) z!L49{8-*OKN%^j)=o;g-qUb+DJprW%v0M0xQp9Syz4Fq5W>z zF?+OSt7%V*DgAxOE9r}k^tC2_uY%&90INB^2G6#q%3LbXSe-3=9w66{@HHWG0Yl~j z()L+2tqkqoO8d9Q{8ytNUHF{}jKgK%vpGCDHTa+k_@D~-pbGe)#CNmE!Yq{A0_C}(yRaZadIe^eB(jNqd8~#4yne>P9!y3jPzu13iz@< zhQl3K_v!zi#JN(gHjUq9+>EzQ^c>H*(6Tv}^!KIgKMW+RC8ZvPM#{Jt$Bc`SuET>b zOSD7>GA`C#PJc$;t)L5h&YSk+Y8^$c#`)6PHLk|7QNT0}QgOAz zObaden_BQUwcu4~!mH4NSD_{Ljy0nTH@m~FEoV|XI9fOx$bz~Z+zB60zhA=sePH>v z^}Ja&*1hoJvcHmJ;&RQLm+qCw?$Y*rg>$chEO-}mfKKocU@cYTc^&e+4tbtNzQFtO z`f@&L?~u2Tz|Ls*yMX?nTu1X>;DOYbIA=YznQ%|(Vx@9?40(x@9!4aF_h)r&V2+u!h4t$b#NBotIo*#PUO9}ePr|82=MSB^K;1j z95P?pYRQ-mbnr!9sMSR0$PV(lI-@IG)0am|ZEvz4{h3)Gyls0ATPX2wj^o^TP~@8b zbI;Y-@M5GDx*N1n2W`}tG`th4UjifzH3H+MVSTre7+K|tjFZNbV-ukJ4 zZYn`yQ}?IO4>TRJ4*rmXKhzyXCXwJYiVim=O+@eR`_xc&$*mYzC}YsaGz9%&qu zo)K$L@3xPB#@s&m7yNloAFP?_#%%1bS1uubW3cm7G+&dCZ`W*S62VR@X zV7pf{!d}e?do?5M)nOTzg+^3!n>bD^CL`|EjJQ{q&{)|hAoSHKK7_4bjsL0|=~{;+ zTxYi9UMUX}ePR8Q?*Mqlf#4u;Ffi?le5JgmNJj;CG<>C%5twEq?G?o_H&%_D3;z(; zok`7HMh#uTn_Fbfwg#ka3w)#nY1@djZN@j;h_r1++BPC>n~=86Az%G5nPgEC^b#Mv zr|~64?@8jmPOodA*EJw@n;9EzU~IGj>Dz?#ZD4$~fgXkq3bw&9nX7>WM%Iujp0z(? zoqO`z`q;V6{xCv?8fHZDG8aE(~ zo8r-*CU>l-Axb}o(rYZ*OX5nS8{fNpEW~ood1;(8?aE8zT!~h$cvl}YEMLz$YR9y2 z_Fo4kiMdBn5?3OLE0M&NNa9K?>q<29%3gcc&eRUGRH&VtY3u_?Yr!61FKSC3#)0&Z z!O(;xaZfG202f!BZMpq<2zd|X+L0j9)<#2*W4PB5Kx1y>xNba1wD<{d=>j|{>3ucy zzDi$v@QnHFF9f%fM>?wSeU{|E2tBfr9$A@2RA^*d_6}>k(i?iP{W1!VQH@(WzO6PoLYHNY;odk3}ES)vcg5>yQQXVg{)wbg}W?@DWI zgKCO%FLJC6yaZkbuf;Uk!L^(Cod+L)4?#kovJP48fJlWdYNV4I!M6py?9LmNYl28$ndq_qcDOE2Wkr$BqGL7w&kIgKF?&m z9sHZB#SA@L+9$qF%FvVh$NmT=ay0d!5iMMuN`wKtbuHKfm<)xs>X8t`=#j(0 z0Z4`e!9n0)V7(aH8wCynV`veRoA5&BlR$tv zmgFw>y%(_tI?Tqr56hD4JnzdEEfMk-Es;dSNaUw#vZwF6On&k_(>^H2Ci3RN2jD}H z%pLfcJY_K|#hUXHgqlh;kSg{wfO*o;t)xn}Y`(!>)aKs6bU13L%zELva_c40&x+Q| z#8d;(80uA&M82E(U?K3DM~)iw9!AqTpcnBx&5B4h500&(H$MTqKfT%WK4?CJU$#dT=Kb=I3rvnip=QaN7Q z!;=~|yVK~A=r2<5DbL_t$>6)n;JYH)33zR}JDnyYA9&ulc06P0s@25LSnYWxzg4S6 zekm=P`B5B`mMmKJH7g4|1HGc{Sj{r-Lt3QMWNwaRG!lpFHKtaqRUd8AgMX4I@lB+) z%rkrP&cuo@K)VHKw*c*y#7je0srJnNE}%as(~S7-t$BPDaDaM#Zv6VUP2Y1*&6t(yaGA6K_;eI#_OR! z)6}WeWgK75+iG6ZBhZzXR&WK5t>WAh!0VdXSl872GL2t)pNQ8hYv8Xn@YfpnD`T2m zo6xMudh%}KI4cCeYir=O@+Rc)I_0pLGf1fnT73qsUeT+XZ& zq<+=@)ZFg$>;ceUE!YDjQp%5kYAh{-Cn|#{DuXAgR2MCu2WMKn>7w!cM*K6e4vOa~ zgGQyOg5&WjG4ALXcXW(9I>sFx43X~d`3fn;p8wAMf6_!h90>r3NOQ>mre zLy`;ttnE(ib*8jAm~%ZO7RQEz?TrhJqb^4ilC|l1ul&9pMN1P~W(|3ZlC3i33|?pLrXO%m zFU4}uZ8sf(b02|^DaU5;2`GS1!4~itT&F}wHJ@-%%Sv>I4)|{e{I|ob(;`>Eg8~2S z)gtBiaBu+h_~oQqqJ?!L-70CB%G4sAjJKok1+?4=Eq6i7tb`BFCjT^ID9<51mvlPE z&I84$`BtOd+o88Rq0Pm>^KEDuI`q*HNhHL2cy$)d&Bu5oR;yZ~l!j%MrWPpo+YDHp z9;t>e2yErPUEp&dkD5HN$*7CCL%Gf6C7Yz$F!=6p(0w+nk3En@S|0Z?mV1pO|9Idd zQ#&Jgfgj)Exr#OPGgLKKLvs?ljJ6fWIT^{9_#-ub;cb7f`zCgOsXkHZz52Y7>A0l1Roi6HB7p?l0=U-R=GD=n$0UGf-0N@Z{M3r#5y0o+lG= zlj;$QN6|QGFZ0=GiQdOaA2X>pf_snTKBIu_Gx-G)YuC3(JXXqaEM7My*4$*PX$E@^ zN$CAk^GUs(CNFSpiJcZ(x8zN&4EEDeV_K`6Yt)ozZHZptM~+|Q8ExPt@G?lf!`!c@ zeU^BOYvCZZaFAL!NG%-1=2UNodw3g7BhbBB8_AfwJjXr!S%0N&>_?{K@p_(@jMpbV ztsj)sHgw%0%?yeW9i9>W!#RgQHicmiLRmeGtGk6cpW-3wX%+5 zMSZ!n=6hPniPx}attZw`-XIV!3B5^rK^8Oxj4>3KJKh5)`v zhTc&L$4TPj$|KAUp=RZWFdZ6SMH0tT^d@3Kb1m_6=pmKRc_my}@zs-=JC)3(>OKON z%&j^ftz`z7#Z`Vpti$&WYIZg?dNt`Ba1EFTZUVQ{A{H4#3&;bs6v(<+1|9~9b+elJ zfbu@BC7<`*de5V@LDn%vr|v|j?zEBe*SPL=@CJFk=La7J_uXz}4Kv+7x41(2vI-U7F*KP@F;K?@Rsy1sL@}*%eC?V^Ps5N^4ReLUUALNQcRhTAD@EM z^)s_7<2iSkXeuKsYK=UaUf+?xa38cg9|e3dwJ;NiGo{u#`zeRA+D~jt`VA6NQq=Tw z(v(ZF@AdO!l(&o4=<nB z+t+ExF`1}1=3BTkfaYzV1*Tb~SeCE)RJ-$l;vHwXdPa|189i=w3$S+7a`NC`2Ce|J zfLc*~Nd4zJX!{1BK9sbk`jO{;HR0WyTe9u_@JFOS21~d7o>3wnL$`u!9tGtss?|JN zi9e=);px}7ebS;uo3>}m{*L>+#Wmeqv3qQ|MK4gEF7Wxb_j_$UMPTno4G#fB!TzAQ zl1RBXbtHL5fx|$&l8CjAZBJx4V{O*Mqr0t#&iG1ya(O~e*&AhM;?3t{><+WNmEMU`K9wPKI8mW&;>pRf1#DAvN+CCGc%EO z%n#oYWU#N!hcjj2OxZY=H5TQxa(%t5es{hdUylvA% zbMURbjPr@@o%l$lv&rW6p1X3prBru&jcZ>AZ-7K^>n>M{dR)17@F~yO0zQMbt7xGN z*a`GzlbhXQc6ncZP|c?Iy4)DOI#)_($_}oIq<$MY5j-&Srla zn%g;~=aQa}l|BP#X6QU>8$UnXtlBNWW-+O6wO^F{vf)ko<6oM?Ikkf3yw2zMLU233 zJ;&v9Y}n?CWFm7XFrwrT>CuOK>m$@FKNKd zI^bp{f5@|m<9YA__z-k*>?2UhiTsFlM>CZrT}zuw1ql{WOK~tOgZN?q6f|e(>Zq@5XZa}olbfkeW;9M`d0R9CS4{= zmYTnsn!1Kox{m!D0N;zCh4ZwqA1%L&RPyLizVrh`Drd9Cf>VwiAyw>2Y zSJM{Yl9G4ocjX+=uVkk&j5JP$`#ldfkXQO(4{d?_yb7`)>1*PMrCNa30KUko?X<{9 zNqi)|c`SS5h#J2rjtZ66zPD_1W)l^;AoJyE&EvrF0DkAalceH~CxfK#oyPtoFd0k% zrvvnD>wi0;hH&gwj3?lO24Yb>aE2CT8l@&iGJm0hi|Tle%3@kYoebumGraj(ExF*51e!)F^r?YVPG_rGlqK}0mkB|NMoeA*HJv@ zXmAXx0A21!tZ37d0Ca%ORlbgrW)%>5PhV`IFEWo5%l9l`-hTR^dHYF|`J|~wiDPr& zwm!zX6D_3^Ev3`sC00SI?MpU_OG;z6cw5rq7^6nE@+G>bpC{Z*p0ylLMg^Xs6%#oq z`S%KV6=cC{z%&%{NJBTSN7@C@w4)usj-WKYb~j|v?i}lF+)y!;NtE)w>}&kHr#_m* zZglrJ#ri0%T#PK$x|(r>GS55;91XCF{TcwIrG1umD(kQ6pT2Kq+?Di8qS$%UOQF@v z!IjYCRrHP7=yG#NujSbFU@n-)xtmFE0rNR`E9nBDDAk2P5jS`6`%dn;h~IaC#T@$~ z$Ci-ZLwYaJD8&7w4}b@mN%0WrGSXyi(8p+XA3@zpANH&K_?7+?SEoqC9DOxMAI*io z;o4U4TdRQ&us%QftSH6JnvPI1+Ve@b?_$neh>Zta^P+74$vsZA8F|h-t|3x zzYqQdHgQcJd;tE;@BaoLvfp=fk6+#8Gs?6Tbb-&oU$|}?t>>^z0uX`Pny$MwmIL^tF2SWh3!(+BhPK`#rv9LysJSx*t& zG+Arq3f@-z3k}Bln6wl{P+UWL9k>B_eYC_f;F#i7%o9a=H@}x~&5uZb4DJIA zGL!cQ;7rRj0$#fUUb_NbJ7(+St!CvWcu6z7q#2vH z4x5+taItNtVfmaxdM@d7&YcG?K!#rkW^rG?GLo%0g$-PX4P3_)>tcO7_CV0rijmk| zP+n;yw!CzHyh1$XL9h(?h-~qZWV}y2q_>FdF8Byz*ihhl@EkCkm(*)_y+>pl@8G$8 zMP+ZL3|#gei`8<+zPs(}#QN0m=Av_XzFSCZ<1^kD_X3K-rkJ z*~xx>hV%ff7^UwM$Zpp63AFB#?B- zQ7THCzA3~@pOiwNzqwGvjQ|N#P9fB+=Ag|aHR(ia%wb=W=*v-v)_m+vA%!Bpf&a)e zqIeOb5bnDkq!hyb7g7j${(1_Dqa>k%{~sviRHP1Ez*~2uQz-Z804o~`DMV9gx7(nO zcKAm-{G%QI(GLG;hkvxgKiY|LtHZNWk7uPG&q_U>m3llY^>|k5;U&HM&!%(kJdpU& zF4gyR+z_Zm_Cas{w9c4PhQ)eJ4U{sh=*gs|?gVB=gPOeZ|0v*<_Tc)5;JgKbfRZJ{+ii4*612W9J1FX8-V z@Chh@Pr(-8N7vHGJL5Z&E>&O$`s$7#)lcZ(ekNO;QJM4*&0FZnZxSC|ce^9;!IiJJ zFc#}D@yEpy1b&mOl2TlC2rn8`QdcrQROc4LNBnw(+Z!YD)?@KYt#JrHsYl|}BXR1HIC=OE|r#4D@y%(t_`2+Up4IT2mrBrp-23|QR?p3)3Y(R@mMtE&l}qzRp*2|kiU#VUG2E0@%vlMF*A zX+kGyf{)~&5?1emQhHKJF;dp3gqog7U$vPzw3w$7%@FgR+S@sAyoBG02E2r0MJkcD ztC>2zQHi9ER-%$GLV8I|C0uXXEx*0gDfiAMRPqMW%IhXQy|sTerO+Z(v}(#b*iR{j zbG=iHX2TMDXB3m@D!s%XAsIw5rmG-9{LJd2u5v8LiaJW-U+imjk5;Ir6{=~4YFeS1 zR;WhbRMNN2TcMg(sHW8|ihYcJ4XI11-OGWubF%m|)RI~J89DqJIs6$p`hFIFMh<@l z(ZK98s~>-c*0dKt$olbO_ASbt-*Am1S_W2SP{tT^$k;R{pgI8ps z0>1nMpLm389wSc^`ztw?My0`*)<9{^q6n;8Z}Zec6^So0hh&kTqa8m-4nIc@KZn+6 z&EeS6;pZsCevT}DjvRiD z9DWY@F|+WWEc_>npF=z-TO5N%dTj0gYbNHpHd zsM#xk#@%O;YFt9v?=>J9J@T4x`4~kpsv*;36zM*Cz*1VXfqSKP6s_r3CX6W*YV;#Y zevPAMu6dGY${*7Lo&nENPQLqF)RfuxJgYn!;x+QV4&LB-8eK|9d-Y0P5>up>yuK9bQWtpK+>#}kU$m;Al0tu&J3iO)rpqA|xKx$Y?V z*U{h@_PvDDeD@6Y6l-h1zfQ!8o=9FFBg2Z(_@1f!e@4yqT z)x>gf1V*l8bjrt8Caaf9+r5!|_+=Pd?7$=5;TE80h&s$BBGtIb)ubtPurH6@jX)G~ z6DW@7!^_BD=C$MekHC+Cr;yF*xXM3qY#A``9cd%dX9cNzINp0Fp6284Q$NnOSG-+C zzNes!b^KPOhbZUQP=Sqvv0tVkbN*G31!Yu2zLaX%&w~%ZhoBRR_z3j$;weUeRn)lG zR`PWLtaQ_oi`sE{WcdJEt`_V8_9SmYG2VmsO6YYqL<6=k*3x7I38R+KGWm(Z_O{sZoDCLHBokbWKT z556-%txNieN+bcVpwCMRdOp$y#jv6i=jM=JLoG=nUI(rRH-JPk-o$=UI<}QaNAa9C z)0XcbkJp9Tk&bP6`|~Cp@8I1SBPY45TA11&Oq5VE;jmKLnNmqcrX#-Dw4> zNlx@89QS!1Y+%24DcXhzqW;!~WG(S5LQSQT)hHWk*&Eb>!Q4lBT+dlq$@(yL zSORre0(DpdtfdYlT}x+W8$~10<27Mymex_+`)Hu~#EoA-wl7Xph}=a`QXl(#^7UJ|!1 zkAc3EF$@YN>WzF&?5|`$8LwK+u{A&v)W)0HUk9FnYM&+T)pNje+dwg%FoWkHgXbVq z7H?E9#pPrIJ)qv?i9K9Z1oRSc+mha(oxipS2V<_B4R~TCfM$ zi`Eqt4F)#4L7x4{GXx9;`-5Se8x9Ttz1ovTNkz#!mfz#ZJ02X#^?Z*U>6?X$^hJq8 z0+)zXi;vb#EnI0B&R7sFM9V zfQ`VAdg{#dh+s|mEO{OP;k8Lp?`zXhailL5`SQ~zZl15?tTC_!q zEyj%fhHF~EZ-Ml`7eJ2~7mmFOvfwrFI*<+fCh70NA3zSg4c-B=ZT|>5z3(#E$XJel1bVKem-x%Hu1Bf?C_>hJW;9hgI#a>Ew@keLxHGYyeojscqpszvl$P;N zcgBrp-M9yr#^daRfASTF0Laz$m7 z`qfIQT#<{S@;azI@vCLs1@P7xJmEs)u^Q1?UryzWe_z5J`I*$Lw2dpEo-46&XL0N* zV44QhHU}!ZhU3?fN4n`e_HRNW&L_`8a6445_2m|^e-~Jcq`sScOSrD6oAQl0@-%SW zgB)K59tM6~Q7eu&V`FP=9*qQb*A%qwy5>D}LebUm;Y3rYL`!H!OK3(*cp5F?X|#l9 ziz9fE{WkCtco~#x1+Vek*TEau@^4YjV$47*l=?J0`DrBn)7Z{Wqo-!kQ?ux)y{&JT zMNjR3C$}K&TafmO4QP(3ll3s6k|KpZjikRD9(^}F`sp}EAd&V@!=pQ6-PNxHBndwd zNXmOk)t8OBtr)_&;h-l4`_;ZiV%>}ahXKtT7{mRJ041xyd5I4%_LfrO)k#(clcgj+ zt&t~1p=j-0QFm?RJvuokTi=6`4^W<*X7l8%g`(Th9J1TD$FYj=2f?>nvBwn^-HJV) z!yea6gIaiaEj+v)9zF=_u7|n@LEWwJ@K$#|c`g9*30?>;fuGOfID8m>t`)0m;pMgP z@>=xjR9j{V*tRuI_UM2Y!8QG#d-m4^v&!Ty>qZ_x!BkBIj zc~6mN9q-UW`V4rMcUcdLI&mvHaXX%+c05Z&ynz?Micga$>`vYRP+l$A10kV0uP(O2%;OoUNBAtl`Y$_c0KVoe}vzfLR zSyxK&igXpl7ohmU7gId?vGH?K&(B5i8lmrv;#paa77$;*loq%gNPD@8)Kk2y#yk|C zhvNO03T`I71z6k&=>l*Yu(%QKbqD+2Qq+h(an2n3A?XtCdk^WoKw8WFqz`}x*?)+1 z8R>GUNs&WF@%%QQ1IJde{{--{BVO0;N%1{L{(r-LTfuLEX)dJQ<40cMSoi4MH#zou z@CT3sZ-aM$w3ZIa_a6K2gFk^yAP*Ev{b%qYNGYEDo53fb0F2^EyZJ1z{8%3uN^($p zKpMh3B@_AqdG0g7Q+%>6VZ1IJ=TnMje{bL^z84?HUq$hX$j5)dH6<}5B^2+Ygv+U& z@A`7hBrq8ekrt016J@~fWDNOPdVto-6wlA1#bnW9vS=|`w3sYfOcpIBixzVQJbwW^ ze?iRi7nJb)WTa4IK#EJz7?9#p7Qpit!1MF5Mw5?wK>Q6n`rll7&^+_UmW~)oyCGtk zRwzbCw$KZj=mm<7Y@rvFMn|@kL`OE2L`SyJ3!2b!TH@$PX*x~xf+l)FmR_Lf$mWvh z$d;1m$d))dGSPI1pn_7orV~d{!9R;W5otPc^naPABi^5AI!T0cbGPWpmN+*LRieAoTa?Z|)G zA9iT`2Q}Lty~(Hcds`DDrZxV^|8&bZs=p&X4d?LgIPRL&A<}lX9Xyj~Y(v*ZpMp%? z4#+clKOUYbu8I+pGbr~|iw@IQ%>UNDV!k`t)&e&m925?6dvZ;GyC$$}A|ggk=dE>R zMAXQc>`z6r3(@TST;6G}A3fdA=RKGG>5R8TcE>Q>C)~&FVE3)!ie2rFq1`LAy99QZ zesGIvlumc)2gf*_5Or-Fe7@#@dQSh*m8GmYhB_G6E4OhMUxHgF{ri{8$&IfE82PM)kpb2|GP z|I!)1o`FU{Sl35Kqp6g%in~c4(%tZ4+nrbifwQMTJyq0_A5GIpT0Bz5z2v{i=vs6o zeZzJ#@Ln8NNzk2nrtaKDuZh17%$@ynHS*Hsc8IT&w9z*OyEvOj8(%W0f-~ONPOl_~ z`H?8Cjpjhjdo&eCckXR~1CzM>QJ-^udBR&Jt@GKdqo#rWx|(NlMBrrnuA^QEK-xk}@fmBS#^wlge0b7JEaVvT*jQnD z3OECtjTH1V6D190-`|Ziyqi)L+|K08k~2$ARw@AJ!FLD2bD)K^&3svT8(MT1q;uc1 zu%@Cw=edp6R}r5&7p_v}F2>r_ z`YE%h|Jm*uYUf6DkFOXH`D*li?o#7+qYTC9mL!UWIl9zXCw*MC)@D7+k4U0-Q6BZM zZvIgBRqj;u`Xt^Rw0Q26=T7b1sgYXl@^>S(o=@HQUeRHc>|@G1;m?eI@^)Ie&VLV2 zU$ndt?!ve5T!Xb&-`}Vsl81Kd{X2D~YoYiaR)EL-$@poln`r-Iod4IaQT&TP`ydO3 zP{@3I5euM<3DI%U@zDv%NxkI49L)>@WSk|BauKjCI z{{d$z=^eYfZwB8Eh6F={(}N8`Yw%lLhyOJQzpgD3NZW#K|7hEt!y`GekCPS>MJu9z zgVLIjOS?p`L~px2ka#Y7{QnVt&U5~Htc#wDUa7b_dL#N<%Dh*_;^^3l-75N3++49U zzkg7%FxnjL6V+GLRSbxRR!rxAs|lMps-^u{>(z{yc$aTyIZ#qvGCZd^Dc@V|h})=tMm$+RXEAj!uhy5S?RB+{{xq zR}8S{HB?NEW<)b=znLe@toT_pOHbvw6YaSi<@h{%Hcz+bFQN>KDwcECSGd zdd0VrJ60T2F{)xr#gXY9r|N#-vWnSycm5YvEUvh>qJdgdiI-DT)L%t26toV6^yz+R zhC9MVc7hsrbzgykzX~7u8#KZJ^n^X&GkdwckyZoU-?^_rcZ1y5-8bA|w=b0TP4_ML zZN9!d#0_a9(ZLbHxL`tXLNGBnB{(OzAh;;FIJhpjEx0pyAo!=?pM#$Sj|Kl4{4!V*JQ@6F z@ay3D;5YP>w&3O9_28}G?cm+u&p~IfIVc2Mf~{c~R)v{x=Wvg3->^R1FB}?vCp;(| z6^;%M566T@gyX{T;Xi~&g-3_ShTjj53r`473MYoAgy)9S!}G%P!x`a);l<%4;pO41 z@TzcjI48U|ye^y@&JS-57lgNk3&T6YJHy4{lJNd;dH9p?U&5b;kA#nfkB2`Ce;)o@ zxGMZ*_(ZrmTobMhp9+5!ZV2%^gxjKiQB~AG8W;_UhDL`(qoXm=*hu}@g?rhS772FH zeo$pca<+e=?Z06AgNb|&g1v0JQd@VqoxNOKA$Z^NylzL@ZTq$z8EW~@u>8!r<*KW+ zg}dl(-?8mD+YYv?uC=SquZ4~`7dLmklE#P*Tog$=F3VyYqv834Z3T44Q&pxEq3h51w(i1kVP~ zy1RnEg#Fy&aEEY5cYnBR_*K_H|EYJ&=r@PEhv_%t+;aNOQSP6qp~>zi>M=yRoF87` zR;b6gN9ZqCxyR@&*SW{T8yH>sU-XdW?q~FnpSphypCzicDSVOnf~&%}7^`_A3Zl@h zj&^2jyE&?f{?@Ife++a_(>IR53;V08bE;-k&8)h%YF5>}ss&Yxs*dHzm;ax^)nE31 zCePX4|Fx8&`~NJ;wY~rGRbT#p0q?iH|3$og&;Mhok?sAT7}uN9)2e>J9ej-{C>Y`91*3wo?$%&@aFkmd91|Sx z?g>r|PIC7LCkH3HhG23q#XU%WnCAW|IG0}W6MDrzx}OG@1lPL913Un(Iao;F_%Hg# z58boDlHgvqA-FGi$ZZUk;SYEEO;(> z&TU0|`;F@gev1b8m*9oqMf&JV{JY?l;I$wK-U!|a`UQUs-bV^<3O)?J8hjLd9MlG% z@V_UL>$6}ldSDRLg;Cfq7(_qZDcCpMC9Dm;9qt)^EjUEIG58*`?4ZD8S#UUg@*jdD zB+G*Fl4ik?$g|^uqmgMR1jk6O;kP&?JSCW*9vd7NP7S99$J1{w3Qkau4JN6_22+r5 zHw336;TFKt7lsRiX_9flIY_z1!F2WE;5;PVPlEH+lY8#Yo0Of+a}D(ZM~Ekin0lBcmf}kEQ516VbKm&|oH_W8I8?Gab$9>!z>GuDC2( zT`?Jr>nU`ji=q~Eo(A-y2L4B(^&Dh6k3%2)4*Sg&qoN#o(9P&q_nQ{D94+g}FZD0o z?~DH@ppVtX|H~=y^zB}=kaxHlZLQ}&Z>WFH^N;o@O}PBu-@W`8ztAyf^M9HCrCp*W z_x8UK?a=?nXQQY5zx3JUAFY&sYV^ze-;1s}CjM`b7H(~zcIfTjbZGS6jn+axqm|14 zS4oGb)ef@%IJfDs+ub+qSuL!8>G*%{_5VFIZ2zB}HwyrYP_4%Q(N_J_e$$Pn8rT;# zxrCCqKl*-rURwIMINOY-zFZW`|5R#Tm~O2o?foM1h&~(AdyG*jjsA3n>>7Wizt*>I z(jJLsFTLJt_PUeT?i2k!(ePo~=rhb5LTmb|?SIYo8OP$tG~0e`+YPqGZ^H5a)D{b# zZFqF0_53lGq<=TReE|e_h+q zws3YGInuV{ZA%msM;I$+i^res;kIQgl>M`8yQgjC;SPee+9GANzsRvw*882chlApZOHaN J?8rpt{tvIz(p>-m literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 14b960e3..bd8a0e6b 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -2,13 +2,11 @@ diff --git a/app/src/main/res/layout/activity_bread.xml b/app/src/main/res/layout/activity_bread.xml index e17e37f7..829da68c 100644 --- a/app/src/main/res/layout/activity_bread.xml +++ b/app/src/main/res/layout/activity_bread.xml @@ -43,7 +43,6 @@ android:clipToPadding="false"> - - - + android:layout_gravity="start"/> diff --git a/app/src/main/res/layout/activity_camera.xml b/app/src/main/res/layout/activity_camera.xml index 2f3edafd..0ddb386f 100644 --- a/app/src/main/res/layout/activity_camera.xml +++ b/app/src/main/res/layout/activity_camera.xml @@ -22,7 +22,6 @@ android:layout_alignParentTop="true" /> diff --git a/app/src/main/res/layout/activity_fingerprint.xml b/app/src/main/res/layout/activity_fingerprint.xml deleted file mode 100644 index 9adc907b..00000000 --- a/app/src/main/res/layout/activity_fingerprint.xml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_intro.xml b/app/src/main/res/layout/activity_intro.xml deleted file mode 100644 index 8858c324..00000000 --- a/app/src/main/res/layout/activity_intro.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/activity_intro_recover.xml b/app/src/main/res/layout/activity_intro_recover.xml index 802e5b8d..d2c89037 100644 --- a/app/src/main/res/layout/activity_intro_recover.xml +++ b/app/src/main/res/layout/activity_intro_recover.xml @@ -2,7 +2,6 @@ @@ -38,7 +37,6 @@ diff --git a/app/src/main/res/layout/activity_notification.xml b/app/src/main/res/layout/activity_notification.xml index 15901e71..78b07885 100644 --- a/app/src/main/res/layout/activity_notification.xml +++ b/app/src/main/res/layout/activity_notification.xml @@ -2,7 +2,6 @@ diff --git a/app/src/main/res/layout/activity_paper_key_prove.xml b/app/src/main/res/layout/activity_paper_key_prove.xml index 6e66fe62..0c241db2 100644 --- a/app/src/main/res/layout/activity_paper_key_prove.xml +++ b/app/src/main/res/layout/activity_paper_key_prove.xml @@ -1,7 +1,6 @@ diff --git a/app/src/main/res/layout/activity_pin.xml b/app/src/main/res/layout/activity_pin.xml index 6ad60422..a26b47da 100644 --- a/app/src/main/res/layout/activity_pin.xml +++ b/app/src/main/res/layout/activity_pin.xml @@ -2,7 +2,6 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_qr.xml b/app/src/main/res/layout/activity_qr.xml index a9160692..b3e2b4c5 100644 --- a/app/src/main/res/layout/activity_qr.xml +++ b/app/src/main/res/layout/activity_qr.xml @@ -1,7 +1,6 @@ diff --git a/app/src/main/res/layout/activity_security_center.xml b/app/src/main/res/layout/activity_security_center.xml index ed9f4965..5ddef0ff 100644 --- a/app/src/main/res/layout/activity_security_center.xml +++ b/app/src/main/res/layout/activity_security_center.xml @@ -15,7 +15,6 @@ diff --git a/app/src/main/res/layout/activity_share_data.xml b/app/src/main/res/layout/activity_share_data.xml index b6cad1bc..cf571e30 100644 --- a/app/src/main/res/layout/activity_share_data.xml +++ b/app/src/main/res/layout/activity_share_data.xml @@ -2,7 +2,6 @@ diff --git a/app/src/main/res/layout/activity_spend_limit.xml b/app/src/main/res/layout/activity_spend_limit.xml index 5e619f23..3616618f 100644 --- a/app/src/main/res/layout/activity_spend_limit.xml +++ b/app/src/main/res/layout/activity_spend_limit.xml @@ -2,7 +2,6 @@ diff --git a/app/src/main/res/layout/activity_web_view.xml b/app/src/main/res/layout/activity_web_view.xml deleted file mode 100644 index 28c6ee68..00000000 --- a/app/src/main/res/layout/activity_web_view.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - diff --git a/app/src/main/res/layout/activity_write_down.xml b/app/src/main/res/layout/activity_write_down.xml index a4974a83..9195aa3b 100644 --- a/app/src/main/res/layout/activity_write_down.xml +++ b/app/src/main/res/layout/activity_write_down.xml @@ -2,7 +2,6 @@ - diff --git a/app/src/main/res/layout/buy_partner_item.xml b/app/src/main/res/layout/buy_partner_item.xml deleted file mode 100644 index cd58e3e1..00000000 --- a/app/src/main/res/layout/buy_partner_item.xml +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_authentication.xml b/app/src/main/res/layout/fragment_authentication.xml deleted file mode 100644 index a9ee9c50..00000000 --- a/app/src/main/res/layout/fragment_authentication.xml +++ /dev/null @@ -1,5 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_balance_seed_reminder.xml b/app/src/main/res/layout/fragment_balance_seed_reminder.xml index 3426b358..073301c5 100644 --- a/app/src/main/res/layout/fragment_balance_seed_reminder.xml +++ b/app/src/main/res/layout/fragment_balance_seed_reminder.xml @@ -22,7 +22,6 @@ android:padding="0dp"> @@ -109,7 +106,6 @@ android:orientation="vertical"> @@ -122,7 +118,6 @@ android:orientation="vertical" /> diff --git a/app/src/main/res/layout/fragment_bread_pin.xml b/app/src/main/res/layout/fragment_bread_pin.xml deleted file mode 100644 index d338850a..00000000 --- a/app/src/main/res/layout/fragment_bread_pin.xml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_manage.xml b/app/src/main/res/layout/fragment_manage.xml deleted file mode 100644 index 0fee48bd..00000000 --- a/app/src/main/res/layout/fragment_manage.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_menu.xml b/app/src/main/res/layout/fragment_menu.xml index 25ae9c32..93136915 100644 --- a/app/src/main/res/layout/fragment_menu.xml +++ b/app/src/main/res/layout/fragment_menu.xml @@ -20,7 +20,6 @@ android:padding="0dp"> @@ -208,7 +204,6 @@ @@ -245,14 +243,12 @@ android:background="@color/white" /> @@ -278,7 +274,6 @@ diff --git a/app/src/main/res/layout/fragment_word_item.xml b/app/src/main/res/layout/fragment_word_item.xml deleted file mode 100644 index 57154d43..00000000 --- a/app/src/main/res/layout/fragment_word_item.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/app/src/main/res/layout/notification_bar.xml b/app/src/main/res/layout/notification_bar.xml index 4632fdd2..a6b9445e 100644 --- a/app/src/main/res/layout/notification_bar.xml +++ b/app/src/main/res/layout/notification_bar.xml @@ -5,7 +5,6 @@ android:layout_height="wrap_content"> diff --git a/app/src/main/res/layout/pop_up_language_intro.xml b/app/src/main/res/layout/pop_up_language_intro.xml deleted file mode 100644 index 5e7a390b..00000000 --- a/app/src/main/res/layout/pop_up_language_intro.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - -

lq3k*XJLTkQC}g)aqX~= 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