Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ val kotlinVersion = rootProject.extra["kotlinVersion"] as String
val tinkVersion = rootProject.extra["tinkVersion"] as String
val securityCryptoVersion = rootProject.extra["securityCryptoVersion"] as String
val webkitVersion = rootProject.extra["webkitVersion"] as String
val lightweightChartsVersion = rootProject.extra["lightweightChartsVersion"] as String
val mixinJwtVersion = rootProject.extra["mixinJwtVersion"] as String
val alphabetIndexVersion = rootProject.extra["alphabetIndexVersion"] as String
val web3jVersion = rootProject.extra["web3jVersion"] as String
Expand Down Expand Up @@ -358,6 +359,7 @@ dependencies {
implementation("androidx.biometric:biometric:$biometricVersion")
implementation("androidx.security:security-crypto:$securityCryptoVersion")
implementation("androidx.webkit:webkit:$webkitVersion")
implementation("com.tradingview:lightweightcharts:$lightweightChartsVersion")

implementation("org.sol4k:tweetnacl:$tweetnaclVersion")
implementation("org.sol4k:utilities:$sol4kUtilitiesVersion")
Expand Down
32 changes: 32 additions & 0 deletions app/src/main/assets/trading_view_local_time_tick_mark_formatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
window.localTimeTickMarkFormatter = () => {
return (time, tickMarkType, locale) => {
if (typeof time !== "number") {
return null
}

const formatOptions = {}
switch (tickMarkType) {
case 0:
formatOptions.year = "numeric"
break
case 1:
formatOptions.month = "short"
break
case 2:
formatOptions.day = "numeric"
break
case 3:
formatOptions.hour12 = false
formatOptions.hour = "2-digit"
formatOptions.minute = "2-digit"
break
case 4:
formatOptions.hour12 = false
formatOptions.hour = "2-digit"
formatOptions.minute = "2-digit"
formatOptions.second = "2-digit"
break
}
return new Date(time * 1000).toLocaleString(locale, formatOptions)
}
}
1 change: 1 addition & 0 deletions app/src/main/java/one/mixin/android/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ object Constants {
const val PREF_PERPS_ACCEPTED_ASSET_IDS_ORDERED = "pref_perps_accepted_asset_ids_ordered"
const val PREF_PERPS_ACCEPTED_ASSET_IDS_V2 = "pref_perps_accepted_asset_ids_v2"
const val PREF_LAST_SELECTED_PERPS_ASSET_ID = "pref_last_selected_perps_asset_id"
const val PREF_USE_TRADING_VIEW_CANDLES = "pref_use_trading_view_candles"

const val PREF_USED_WALLET = "pref_used_wallet"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package one.mixin.android.ui.home.web3.trade

import android.content.SharedPreferences
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.border
Expand All @@ -23,6 +24,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.CircularProgressIndicator
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand Down Expand Up @@ -130,15 +132,33 @@ private fun PointerEvent.compatCalculateZoom(): Float {
fun CandleChart(
marketId: String,
timeFrame: String,
priceScale: Int,
marketPrice: String? = null,
) {
val context = LocalContext.current
val preferences = context.defaultSharedPreferences
val dataError = stringResource(R.string.Data_error)
val viewModel = hiltViewModel<PerpetualViewModel>()
val lifecycleOwner = LocalLifecycleOwner.current
var candles by remember { mutableStateOf<List<CandleView>>(emptyList()) }
var isLoading by remember { mutableStateOf(true) }
var errorMessage by remember { mutableStateOf<String?>(null) }
var useTradingView by remember {
mutableStateOf(preferences.getBoolean(Constants.Account.PREF_USE_TRADING_VIEW_CANDLES, false))
}

DisposableEffect(preferences) {
val listener =
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
if (key == Constants.Account.PREF_USE_TRADING_VIEW_CANDLES) {
useTradingView = sharedPreferences.getBoolean(key, false)
}
}
preferences.registerOnSharedPreferenceChangeListener(listener)
onDispose {
preferences.unregisterOnSharedPreferenceChangeListener(listener)
}
}

LaunchedEffect(marketId, timeFrame, lifecycleOwner) {
candles = emptyList()
Expand Down Expand Up @@ -194,12 +214,21 @@ fun CandleChart(
)
}
else -> {
ScrollableCandleChart(
candles = candles,
context = context,
marketPrice = marketPrice?.toBigDecimalOrNull(),
marketPriceText = marketPrice,
)
if (useTradingView) {
TradingViewCandleChart(
candles = candles,
marketPrice = marketPrice,
priceScale = priceScale,
timeFrame = timeFrame,
)
} else {
ScrollableCandleChart(
candles = candles,
context = context,
marketPrice = marketPrice?.toBigDecimalOrNull(),
marketPriceText = marketPrice,
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import one.mixin.android.ui.common.BaseFragment
import one.mixin.android.ui.home.web3.Web3ViewModel
import one.mixin.android.ui.home.web3.trade.perps.AllPositionsFragment
import one.mixin.android.ui.home.web3.trade.perps.PerpetualGuideBottomSheetDialogFragment
import one.mixin.android.ui.home.web3.trade.perps.PerpetualViewModel
import one.mixin.android.ui.home.web3.trade.perps.PerpsActivity
import one.mixin.android.ui.home.web3.trade.perps.PerpsMarketListBottomSheetDialogFragment
import one.mixin.android.ui.home.web3.trade.perps.PositionDetailFragment
Expand Down Expand Up @@ -224,6 +225,7 @@ class TradeFragment : BaseFragment() {

private val swapViewModel by viewModels<SwapViewModel>()
private val web3ViewModel by viewModels<Web3ViewModel>()
private val perpetualViewModel by viewModels<PerpetualViewModel>()
private val coroutineErrorHandler = CoroutineExceptionHandler { _, error ->
Timber.e(error)
ErrorHandler.handleError(error)
Expand Down Expand Up @@ -593,14 +595,18 @@ class TradeFragment : BaseFragment() {
)
},
onOpenPositionClick = { position ->
requireActivity().supportFragmentManager.navigateToPerpsRoute(
PositionDetailFragment.newInstance(
position,
lifecycleScope.launch {
val market = perpetualViewModel.getMarketFromDb(position.marketId)
val activity = activity ?: return@launch
PerpsActivity.showDetail(
activity,
position.marketId,
market?.displaySymbol ?: position.displaySymbol.orEmpty(),
market?.displaySymbol ?: position.displaySymbol.orEmpty(),
market?.tokenSymbol ?: position.tokenSymbol.orEmpty(),
AnalyticsTracker.PerpsSource.PERPS_HOME_LIST,
),
PositionDetailFragment.TAG,
R.id.container,
)
)
}
},
onMarketItemClick = { market ->
PerpsActivity.showDetail(
Expand Down
Loading