Skip to content

Commit

Permalink
Migrate test app to Jetpack Compose (#222)
Browse files Browse the repository at this point in the history
* Test app fully refactored and migrated to Jetpack Compose

* Turn off dataBinding (not used)

* Fixed log view

* Fixed button state for market update pairs

* Fixed currency in ticker view

* Updated CapeCrypto exchange
  • Loading branch information
aneonex authored Nov 14, 2022
1 parent 2837c9d commit 0be2c8b
Show file tree
Hide file tree
Showing 93 changed files with 2,927 additions and 1,284 deletions.
13 changes: 13 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ buildscript {

kotlin_version = '1.7.20'
core_ktx_version = '1.9.0'
coroutine_version = '1.6.4'

compose_bom_version = '2022.11.00'
compose_compiler_version = '1.3.2'

hilt_version = '2.44.1'
roomVersion = '2.4.3'

okhttp_version = '5.0.0-alpha.10'
}

repositories {
Expand All @@ -17,13 +26,17 @@ buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

// DI support
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
}
}

allprojects {
repositories {
google()
mavenCentral()
// maven { url 'https://jitpack.io' }
}
}

Expand Down
6 changes: 3 additions & 3 deletions dataModule/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ android {
kotlinOptions {
jvmTarget = '11'
}

lintOptions {
lint {
abortOnError true
checkReleaseBuilds true
checkDependencies true
checkReleaseBuilds true
}

}
Original file line number Diff line number Diff line change
@@ -1,66 +1,96 @@
package com.aneonex.bitcoinchecker.datamodule.model.market

import com.aneonex.bitcoinchecker.datamodule.model.CheckerInfo
import com.aneonex.bitcoinchecker.datamodule.model.CurrencyPairInfo
import com.aneonex.bitcoinchecker.datamodule.model.Market
import com.aneonex.bitcoinchecker.datamodule.model.Ticker
import com.aneonex.bitcoinchecker.datamodule.model.currency.Currency
import com.aneonex.bitcoinchecker.datamodule.model.currency.CurrencyPairsMap
import com.aneonex.bitcoinchecker.datamodule.model.currency.VirtualCurrency
import com.aneonex.bitcoinchecker.datamodule.util.forEachJSONObject
import org.json.JSONArray
import org.json.JSONObject


class CapeCrypto : Market(NAME, TTS_NAME, CURRENCY_PAIRS) {
class CapeCrypto : Market(NAME, TTS_NAME) {
companion object {
private const val NAME = "Cape Crypto"
private const val TTS_NAME = NAME
// private const val URL_TICKER = "https://trade.capecrypto.com/api/v2/peatio/public/markets/btczar/tickers"
private const val URL_TICKER = "https://trade.capecrypto.com/api/v2/peatio/public/markets/%1\$s%2\$s/tickers"
private const val URL_ORDERS = "https://trade.capecrypto.com/api/v2/peatio/public/markets/%1\$s%2\$s/order-book?asks_limit=1&bids_limit=1"
private val CURRENCY_PAIRS: CurrencyPairsMap = CurrencyPairsMap()
private const val URL_PAIRS = "https://trade.capecrypto.com/api/v2/peatio/public/markets"
private const val URL_TICKER = "https://trade.capecrypto.com/api/v2/peatio/public/markets/%1\$s/tickers"
private const val URL_ORDERS = "https://trade.capecrypto.com/api/v2/peatio/public/markets/%1\$s/order-book?asks_limit=1&bids_limit=1"
}

init {
CURRENCY_PAIRS[VirtualCurrency.BTC] = arrayOf(
Currency.ZAR
)
}
override fun getCurrencyPairsUrl(requestId: Int): String {
return URL_PAIRS
}

override fun parseCurrencyPairs(
requestId: Int,
responseString: String,
pairs: MutableList<CurrencyPairInfo>
) {
JSONArray(responseString)
.forEachJSONObject { market ->
pairs.add(
CurrencyPairInfo(
market.getString("base_unit").uppercase(),
market.getString("quote_unit").uppercase(),
market.getString("id")
)
)
}
}

override fun getNumOfRequests(checkerInfo: CheckerInfo?): Int {
return 2
}

override fun getUrl(requestId: Int, checkerInfo: CheckerInfo): String {
val pairId = checkerInfo.currencyPairId ?: with(checkerInfo){"$currencyBaseLowerCase$currencyCounterLowerCase"}
return if (requestId == 0) {
String.format(URL_TICKER, checkerInfo.currencyBaseLowerCase, checkerInfo.currencyCounterLowerCase)
String.format(URL_TICKER, pairId)
} else {
String.format(URL_ORDERS, checkerInfo.currencyBaseLowerCase, checkerInfo.currencyCounterLowerCase)
String.format(URL_ORDERS, pairId)
}
}

@Throws(Exception::class)
override fun parseTickerFromJsonObject(requestId: Int, jsonObject: JSONObject, ticker: Ticker,
checkerInfo: CheckerInfo) {
override fun parseTickerFromJsonObject(
requestId: Int,
jsonObject: JSONObject,
ticker: Ticker,
checkerInfo: CheckerInfo
) {

if (requestId == 0) {
ticker.vol = jsonObject.getJSONObject("ticker").getDouble("vol")
ticker.high = jsonObject.getJSONObject("ticker").getDouble("high")
ticker.low = jsonObject.getJSONObject("ticker").getDouble("low")
ticker.last = jsonObject.getJSONObject("ticker").getDouble("last")
ticker.timestamp = jsonObject.getLong("at")

jsonObject.getJSONObject("ticker").also {
ticker.last = it.getDouble("last")

ticker.vol = it.getDouble("amount")
ticker.volQuote = it.getDouble("vol")

ticker.high = it.getDouble("high")
ticker.low = it.getDouble("low")
}
} else {
val jArrayBids: JSONArray = jsonObject.getJSONArray("bids")
val jArrayAsks: JSONArray = jsonObject.getJSONArray("asks")
val jResultBids = jArrayBids.getJSONObject(0)
val jResultAsks = jArrayAsks.getJSONObject(0)
ticker.bid = jResultBids.getDouble("price")
ticker.ask = jResultAsks.getDouble("price")
jsonObject
.getJSONArray("bids")
.getJSONObject(0)
.also { ticker.bid = it.getDouble("price") }

jsonObject
.getJSONArray("asks")
.getJSONObject(0)
.also { ticker.ask = it.getDouble("price") }
}
}

@Throws(Exception::class)
override fun parseErrorFromJsonObject(requestId: Int, jsonObject: JSONObject,
checkerInfo: CheckerInfo?): String? {
return jsonObject.getString("message")
override fun parseErrorFromJsonObject(
requestId: Int,
jsonObject: JSONObject,
checkerInfo: CheckerInfo?
): String? {
return jsonObject.getJSONArray("errors").getString(0)
}
}
59 changes: 51 additions & 8 deletions dataModuleTester/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}

android {
Expand All @@ -10,7 +12,7 @@ android {
buildToolsVersion build_tools_version

buildFeatures {
viewBinding true
compose = true
}

defaultConfig {
Expand All @@ -20,6 +22,12 @@ android {

versionCode 1
versionName "1.0"

javaCompileOptions {
annotationProcessorOptions {
arguments += ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}

buildTypes {
Expand All @@ -34,24 +42,59 @@ android {
targetCompatibility JavaVersion.VERSION_11
}

composeOptions {
kotlinCompilerExtensionVersion = "$compose_compiler_version"
}

kotlinOptions {
jvmTarget = '11'
}

lintOptions {
lint {
abortOnError true
disable 'MissingTranslation'
enable 'LogNotTimber'
}
}

dependencies {
implementation project(':dataModule')
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'com.android.volley:volley:1.2.1'

// AndroidX
implementation "androidx.core:core-ktx:$core_ktx_version"

implementation "androidx.appcompat:appcompat:1.5.1"
implementation 'com.google.android.material:material:1.7.0'
}

implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutine_version")

// DI: Hilt dependencies
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"

// Jetpack Compose
def composeBom = platform("androidx.compose:compose-bom:$compose_bom_version")
implementation composeBom
androidTestImplementation composeBom

implementation "androidx.compose.material3:material3"

// Compose Android Studio preview support
implementation "androidx.compose.ui:ui-tooling-preview"
implementation "androidx.compose.ui:ui-util"
debugImplementation "androidx.compose.ui:ui-tooling"

// Compose dependencies
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation "androidx.navigation:navigation-compose:2.5.3"
// implementation "androidx.compose.material:material-icons-extended:$compose_version"
implementation "androidx.hilt:hilt-navigation-compose:1.0.0"

implementation "androidx.room:room-ktx:$roomVersion"
kapt "androidx.room:room-compiler:$roomVersion"

implementation("com.squareup.okhttp3:okhttp:$okhttp_version")
implementation("com.squareup.okhttp3:logging-interceptor:$okhttp_version")

implementation("androidx.constraintlayout:constraintlayout-compose:1.0.1")

// Logging
implementation 'com.jakewharton.timber:timber:5.0.1'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "3114016120a0732454bcf8c5b9ed35d2",
"entities": [
{
"tableName": "markets",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `marketKey` TEXT NOT NULL COLLATE NOCASE, `updateDate` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "marketKey",
"columnName": "marketKey",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "updateDate",
"columnName": "updateDate",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [
{
"name": "index_markets_marketKey",
"unique": false,
"columnNames": [
"marketKey"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_markets_marketKey` ON `${TABLE_NAME}` (`marketKey`)"
}
],
"foreignKeys": []
},
{
"tableName": "market_pairs",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`marketId` INTEGER NOT NULL, `baseAsset` TEXT NOT NULL, `quoteAsset` TEXT NOT NULL, `contractType` TEXT NOT NULL, `marketPairId` TEXT, PRIMARY KEY(`marketId`, `baseAsset`, `quoteAsset`, `contractType`), FOREIGN KEY(`marketId`) REFERENCES `markets`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "marketId",
"columnName": "marketId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "baseAsset",
"columnName": "baseAsset",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "quoteAsset",
"columnName": "quoteAsset",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "contractType",
"columnName": "contractType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "marketPairId",
"columnName": "marketPairId",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
"columnNames": [
"marketId",
"baseAsset",
"quoteAsset",
"contractType"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": [
{
"table": "markets",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"marketId"
],
"referencedColumns": [
"id"
]
}
]
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '3114016120a0732454bcf8c5b9ed35d2')"
]
}
}
Loading

0 comments on commit 0be2c8b

Please sign in to comment.