Skip to content

Commit

Permalink
Merge 1.0.3 to Main (#119)
Browse files Browse the repository at this point in the history
* Update .gitignore to ignore all .idea files and all build directories. (#20)

* Turn on Gradle parallel execution and caching.

* Add "app_deployment" key (#21)

* Add "app_deployment" key

* Lint

* Initial setup of StrictMode - only logging in debug. (#22)

* Initial setup of StrictMode - only logging in debug.

* Revert injection changes

* Use limitedParallelism and MainScope() in AbacusThreadingImp. (#25)

* Handle exception with invalid URLs (#26)

* MOB-348 Show Squid routing error on deposit/withdrawal (#28)

* Update AppModule.kt and used dependencies to follow Dagger Best Practices guide (in Notion). (#27)

* Correlate x-request-id to correlate route requests from Squid transactions (#23)

* Fix build (#29)

* MOB-362: Some url links don't work with the deployment build (#31)

* Test

* Check for deeplink path during routing

* Clean up

* Clean up

* Update rest of Dagger modules to follow best practices. (#30)

* Remove network selector from settings for release build (#33)

* MOB-363: Android: "System" theme setting not working (#32)

* Observe system theme

* Recompose when theme changes

* Fix a crash on url tapping (#34)

* Remove hardcoded scheme in the setting links. (#35)

* Add Firebase Performance monitoring. (#37)

* Bump Abacus and update the system link. (#36)

* Fix the release build issue of wallet amount not showing up on deposit (#38)

* Fix Subaccount transfer for France (#39)

* Fix Subaccount transfer for France

* Lint

* Update function name to be consistent with iOS

* Clean up the start-up sequence (#41)

* Clean up the start-up sequence

* Lint

* Update Cartera and WalletConnnect to the latest version (#40)

* Update Cartera

* Lint

* Add comments

* MOB-285: Call startTrade() after setMarket() (#43)

* Update the v4-native-client.js to replace # with ___ (#42)

* Add script

* Update v4-client.js

* Safer replacement

* Safer replacement

* Move startWorkers back to Activity.onCreate() (#44)

* Move startWorkers back to Activity.start()

* Comment

* MOB-410 Add tracking for onboarding, transfer, wallet connection (#46)

* Adding Onboarding/Transfer/Wallet events

* Add userID and userProperties

* Optimiazation

* Add link to send logcat messages via email (#45)

* Add link to send logcat messages via email

* Clean up

* Error handling

* Make file provider depending on applicationId

* MOB-432 previous branch was based on a wrong branch (#48)

* MOB-432 previous branch was based on a wrong branch

* PR

* Bump Abacus (#50)

* Bump Abacus

* Revert

* MOB-421 add settings control to turn in-app notifications on/off completely  (#49)

* MOB-421 add settings control to turn in-app notifications on/off completely

* MOB-421 add settings control to turn in-app notifications on/off completely

* Clean up

* Feature/mob 396 position cell with margin type (#51)

* MOB-432 previous branch was based on a wrong branch

* PR

* MOB-396 skeleton for position cell

* Better layout for place holder views (when there is no position, fill or transfers)

* Convert AbacusState flows into StateFlows. (#52)

* MOB-422 Withdrawal gating (#53)

* Withdrawal Gating

* Clean up

* Doing the paddings better. (#56)

* Update Android Gradle Plugin (#55)

* MOB-446  create new add price triggers panel screen  (#58)

* SL/TP Routing and  price triggers panel screen

* Update deeplink to match iOS

* Renaming

* MOB-443 add limit price to price triggers screen (#60)

* Feature/mob 356 trade input (#57)

* Margin type and leverage screens skeleton

* MOB-356 MOB-358 Margin mode screen

* Change bg color

* move modifier to param

* Feature/mob 257 weekly dates (#61)

* Added end time to rewards date range

* lint

* Update SharingStarted usages from Lazily to WhileSubscribed(). (#62)

* Fix issue of text input losing calculated value when not focused (#64)

* Inject coroutine scopes and dispatchers instead of hardcoding. (#65)

* Revert "Update SharingStarted usages from Lazily to WhileSubscribed(). (#62)" (#66)

This reverts commit de98092.

* Fix margin issues with portfolio position items (#67)

* Fix threading issue (#68)

* Bump Abacus and v4-client (#69)

* MOB-440 TP/SL order submission and data binding (#63)

* Wire up input data

* Submission

* WIP

* Bump Abacus and toggle size section

* Update PlatformInfoScaffold

* submissionStatus = _submissionStatus

* Simplify TriggerOrderStream

* Fix an issue of order/fill status display (#72)

* Fix dollar() formatting crash in FR locale. (#74)

* Add formatting functions for size specified in double (1000.0, 0.001,… (#73)

* Add formatting functions for size specified in double (1000.0, 0.001, etc)

* Clean up

* Clean up

* Clean up BigDecimals

* Remove rounded(bigDecimal:

* Fix rounding issue on leverage slider when locale is French (#75)

* MOB-441 add TP/SL display to market screen (Android) (#71)

* Wire up input data

* Submission

* WIP

* Bump Abacus and toggle size section

* MarketInfo buttons

* Clean up

* Clean up TriggerOrderStream

* MOB-442 Support error states for TP/SL inputs  (#77)

* Wire up input data

* Submission

* WIP

* Bump Abacus and toggle size section

* MarketInfo buttons

* Validation

* Show validation error at sections

* Highlighting error/warning field

* Slide size formatting

* Clean up

* Clean up TriggerOrderStream

* Clean up

* Clean up

* Made localizer a computed property (#78)

* MOB-455 Add retry to trade and close order submission (#76)

* Add retry to trade and close order submission.

* _submissionStatus.asStateFlow()

* Turn on Kotlin incremental classpath snapshots. (#80)

* Fixing threading issues (#79)

* Fixing threading issues.

* Clean up

* Feature/mob 360 target leverage (#59)

* Margin type and leverage screens skeleton

* MOB-356 MOB-358 Margin mode screen

* Change bg color

* MOB-360 rough UX for target leverage screen

* Fixed PR

* move modifier to param

* lint

* There is no longer InputFieldScarfold

* Put back InputFieldScaffold

* Fix market info's stats/about tab animation issue (#83)

* MOB-14 Disable sparkline touching on market list (#84)

* Disable sparkline touching on market list

* Clean up

* Bump version (#81)

* Bump Abacus and add script to use locally built Abacus (#86)

* Bump Abacus and add script to use locally built Abacus

* Usage

* Update

* Feature/mob 400 adjust margin screen (#85)

* Margin type and leverage screens skeleton

* MOB-356 MOB-358 Margin mode screen

* Change bg color

* MOB-360 rough UX for target leverage screen

* Fixed PR

* move modifier to param

* In the middle of coding

* lint

* There is no longer InputFieldScarfold

* Put back InputFieldScaffold

* More placeholder code and it compiles

* rough amount input

* Formatting "Add Margin" and "Remove Margin"

* MOB-466 Integrate Abacus changes for trigger order status notification (#89)

* MOB-466 Integrate Abacus changes for trigger order status notification

* Clean up PlatformInfoScaffold

* Update FF logic to SL/TP trigger (#91)

* MOB-445 Add TP | SL button to market info page when there are open positions for the market  (#82)

* MOB-469: Add basic order lines to market chart (#90)

* MOB-469: Add basic order lines to market chart

* Only display open orders.

* MOB-468: Clean up market prices chart (#92)

* Clean up SL/TP (#93)

* Clean up SL/TP

* Cleanup

* MOB-470 MOB-471 Add order line annotations. (#94)

* Add Portfolio header selector (#95)

* Features/mob 400 adjust margin screen bottom (#87)

* Margin type and leverage screens skeleton

* MOB-356 MOB-358 Margin mode screen

* Change bg color

* MOB-360 rough UX for target leverage screen

* Fixed PR

* move modifier to param

* In the middle of coding

* lint

* There is no longer InputFieldScarfold

* Put back InputFieldScaffold

* More placeholder code and it compiles

* rough amount input

* Formatting "Add Margin" and "Remove Margin"

* MOB-400 placeholder for bottom

* Adjust margin receipt area

* MOB-400 rearranging receipt data

* MOB-400 liquidation price

* Fix copy and modified code

* PR review

* spotless

* fix build

* Update abacus to 1.7.6 (#97)

* MOB-480 MOB-484: Order-lines formatting, localization, rendering clean-up. (#96)

* Update Abacus (#98)

* Bump v4-client and AGP (#101)

* MOB-495: Add entry and liquidation lines. (#99)

* Feature/mob 497 integration margin type (#102)

* Set margin type into tradeInput

* Layout changes

* Update Abacus

* Fine tuning Isolated margin trade input

* Margin dialog fine tuning

* MOB-487 Android: Log error into Crashlytics (#100)

* WIP

* Timber

* Use Logging with consistency

* Cleanup

* Clean up

* Clean up

* Lint

* Feature/mob 498 integration target leverage (#103)

* UX working

* Sync up text formatting

* Update Abacus

* compile issue

* Feature/fix trigger (#104)

* Turn on V2 abacus manager in debug. (#106)

* Bump Cartera and add log message (#108)

* Reduct params of v4-client calls from logs (#107)

* Stop app from exiting at region restriction (#110)

* Stop app from exiting at region restriction

* Not showing the button

* Lint

* MOB-511 Fix JS runner in webview of older devices (#109)

* Fix deployment issues with mainnet test users (#111)

* Stop app from exiting at region restriction

* Not showing the button

* Lint

* Force TESTNET when user debugging is enabled.

* Force deployment web host

* Fix URL

* Clean up

* Made ethereumAddress null instead empty string

* Update version to 1.0.2

* Increase heap size

* Update from TESTNET to TESTFLIGHT

* MOB-513 Clean up force update logic (#113)

* MOB-516 Add NavigatePage event (#114)

* Bump app version to 1.0.3 (#115)

---------

Co-authored-by: prashanDYDX <163016611+prashanDYDX@users.noreply.github.com>
Co-authored-by: Prashan Dharmasena <prashan@dydx.exchange>
Co-authored-by: John Huang <johnqh@yahoo.com>
  • Loading branch information
4 people authored May 23, 2024
1 parent 25c810c commit c998fb3
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 27 deletions.
2 changes: 1 addition & 1 deletion v4/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ android {
minSdkVersion parent.minSdkVersion
targetSdkVersion parent.targetSdkVersion
versionCode 9
versionName "1.0.2"
versionName "1.0.3"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ interface DydxRouter {
Default,
}

val initialized: StateFlow<Boolean>

fun presentation(route: String): Presentation
fun isParentChild(parent: String, child: String): Boolean

Expand All @@ -31,6 +33,7 @@ interface DydxRouter {
fun tabTo(route: String, restoreState: Boolean = true)

fun navigateBack()
fun navigateToRoot(excludeRoot: Boolean)
fun requireNavController(): NavHostController
fun initialize(navHostController: NavHostController)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import exchange.dydx.trading.core.DydxNavGraph
import exchange.dydx.trading.core.biometric.DydxBiometricPrompt
import exchange.dydx.trading.core.biometric.DydxBiometricView
import exchange.dydx.trading.feature.shared.PreferenceKeys
import exchange.dydx.trading.feature.shared.analytics.AnalyticsEvent
import exchange.dydx.utilities.utils.SharedPreferencesStore
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand Down Expand Up @@ -61,6 +62,11 @@ class TradingActivity : FragmentActivity() {
CarteraSetup.run(this, viewModel.logger)
AnalyticsSetup.run(viewModel.compositeTracking, this, viewModel.logger)

viewModel.compositeTracking.log(
event = AnalyticsEvent.APP_START.rawValue,
data = null,
)

WindowCompat.setDecorFitsSystemWindows(window, false)

lifecycleScope.launch {
Expand Down
39 changes: 17 additions & 22 deletions v4/core/src/main/java/exchange/dydx/trading/core/DydxRouterImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ import exchange.dydx.trading.common.AppConfig
import exchange.dydx.trading.common.navigation.DydxRouter
import exchange.dydx.trading.common.navigation.DydxRouter.Destination
import exchange.dydx.trading.common.navigation.MarketRoutes
import exchange.dydx.trading.feature.shared.analytics.RoutingAnalytics
import exchange.dydx.trading.integration.analytics.tracking.Tracking
import exchange.dydx.utilities.utils.Logging
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject

private const val TAG = "DydxRouterImpl"
Expand All @@ -35,6 +37,7 @@ class DydxRouterImpl @Inject constructor(
private val tracker: Tracking,
appConfig: AppConfig,
private val logger: Logging,
private val routingAnalytics: RoutingAnalytics,
) : DydxRouter {

private lateinit var navHostController: NavHostController
Expand Down Expand Up @@ -85,7 +88,7 @@ class DydxRouterImpl @Inject constructor(

val destinationRoute = destination.route
if (destinationRoute != null) {
trackRoute(destinationRoute, destination, arguments)
routingAnalytics.logRoute(destinationRoute, arguments)

if (tabRoutes.contains(destinationRoute)) {
routeQueue.clear()
Expand Down Expand Up @@ -115,8 +118,12 @@ class DydxRouterImpl @Inject constructor(
logger.d(TAG, "DydxRouter initialized")
this.navHostController = navHostController
navHostController.addOnDestinationChangedListener(destinationChangedListener)
_initialized.value = true
}

private val _initialized = MutableStateFlow(false)
override val initialized: StateFlow<Boolean> = _initialized

override val destinationFlow: MutableStateFlow<Destination?> = MutableStateFlow(null)

override fun handleIntent(intent: Intent) {
Expand Down Expand Up @@ -166,7 +173,15 @@ class DydxRouterImpl @Inject constructor(

override fun navigateBack() {
routeQueue.removeLast()
navHostController?.popBackStack()
navHostController.popBackStack()
}

override fun navigateToRoot(excludeRoot: Boolean) {
routeQueue.clear()
navHostController.popBackStack(
destinationId = navHostController.graph.findStartDestination().id,
inclusive = excludeRoot,
)
}

override fun requireNavController(): NavHostController {
Expand Down Expand Up @@ -220,24 +235,4 @@ class DydxRouterImpl @Inject constructor(
}
return route
}

private fun trackRoute(destinationRoute: String, destination: NavDestination, arguments: Bundle?) {
val trackingData: MutableMap<String, String> = mutableMapOf()
destination.arguments.keys.forEach { key ->
trackingData[key] = arguments?.getString(key) ?: ""
}
// Remove query parameters from the route and remove the last component if it's a dynamic route
var sanitizedRoute = destinationRoute.split("?").first()
val components = sanitizedRoute.split("/")
val lastComponent = components.last()
if (lastComponent.startsWith("{") && lastComponent.endsWith("}")) {
sanitizedRoute = components.dropLast(1).joinToString("_")
} else {
sanitizedRoute = components.joinToString("_")
}
tracker.log(
event = sanitizedRoute,
data = trackingData,
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package exchange.dydx.trading.feature.shared.analytics

import android.os.Bundle
import exchange.dydx.trading.integration.analytics.tracking.Tracking
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class RoutingAnalytics @Inject constructor(
private val tracker: Tracking,
) {
fun logRoute(
destinationRoute: String,
arguments: Bundle?
) {
var pathWithArguments = destinationRoute
if (pathWithArguments.startsWith("market/{marketId}")) {
// web does not have a /market/<MARKET> path
pathWithArguments = pathWithArguments.replace("market/{marketId}", "trade/{marketId}")
}
arguments?.keySet()?.forEach { key ->
pathWithArguments = pathWithArguments.replace("{$key}", arguments.getString(key) ?: "")
}
if (!pathWithArguments.startsWith("/")) {
// Android routes don't start with "/"
pathWithArguments = "/$pathWithArguments"
}

tracker.view(
screenName = pathWithArguments,
screenClass = "TradingActivity",
)

tracker.log(
event = AnalyticsEvent.NAVIGATE_PAGE.rawValue,
data = mapOf(
"path" to pathWithArguments,
),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class DydxGlobalWorkers(
) : WorkerProtocol {

private val workers = listOf(
DydxUpdateWorker(scope, abacusStateManager, router, context),
DydxUpdateWorker(scope, abacusStateManager, router, context, logger),
DydxAlertsWorker(scope, abacusStateManager, localizer, router, platformInfo, preferencesStore),
DydxApiStatusWorker(scope, abacusStateManager, localizer, platformInfo),
DydxRestrictionsWorker(scope, abacusStateManager, localizer, platformInfo),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,49 @@ import exchange.dydx.abacus.state.manager.V4Environment
import exchange.dydx.dydxstatemanager.AbacusStateManagerProtocol
import exchange.dydx.trading.common.navigation.DydxRouter
import exchange.dydx.trading.common.navigation.ProfileRoutes
import exchange.dydx.utilities.utils.Logging
import exchange.dydx.utilities.utils.VersionUtils
import exchange.dydx.utilities.utils.WorkerProtocol
import exchange.dydx.utilities.utils.delayFlow
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.onEach
import kotlin.time.Duration.Companion.seconds

private const val TAG = "DydxUpdateWorker"

class DydxUpdateWorker(
override val scope: CoroutineScope,
private val abacusStateManager: AbacusStateManagerProtocol,
private val router: DydxRouter,
private val context: Context,
private val logger: Logging,
) : WorkerProtocol {
override var isStarted = false

override fun start() {
if (!isStarted) {
isStarted = true

abacusStateManager.currentEnvironmentId
router.initialized
.filter { it }
.flatMapLatest {
// Wait 2 seconds for the root view to load first. Otherwise, "/portfolio/" would take
// place after "/update"
delayFlow(duration = 2.seconds)
}
.flatMapLatest { abacusStateManager.currentEnvironmentId }
.mapNotNull { it }
.distinctUntilChanged()
.onEach {
abacusStateManager.environment?.let {
update(it)
} ?: run {
logger.e(TAG, "Environment is null")
}
}
.launchIn(scope)
Expand All @@ -43,10 +60,11 @@ class DydxUpdateWorker(
}
}

private fun update(environment: V4Environment?) {
val desired = environment?.apps?.android?.build ?: return
private fun update(environment: V4Environment) {
val desired = environment.apps?.android?.build ?: return
val mine = VersionUtils.versionCode(context) ?: return
if (desired > mine) {
router.navigateToRoot(excludeRoot = true)
router.navigateTo(ProfileRoutes.update)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ class AmplitudeTracker(
val jsonMap = data?.jsonStringToMap()
amplitude.track(event, jsonMap)
}

override fun view(screenName: String, screenClass: String) {
// No op
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ class CompositeTracker @Inject constructor() : CompositeTracking {
override fun log(event: String, data: String?) {
trackers.forEach { it.log(event, data) }
}

override fun view(screenName: String, screenClass: String) {
trackers.forEach { it.view(screenName, screenClass) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import exchange.dydx.utilities.utils.jsonStringToMap
class FirebaseTracker(
private val firebaseAnalytics: FirebaseAnalytics
) : Tracking {

override fun setUserId(userId: String?) {
firebaseAnalytics.setUserId(userId)
}
Expand All @@ -25,4 +26,11 @@ class FirebaseTracker(
}
}
}

override fun view(screenName: String, screenClass: String) {
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW) {
param(FirebaseAnalytics.Param.SCREEN_NAME, screenName)
param(FirebaseAnalytics.Param.SCREEN_CLASS, screenClass)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package exchange.dydx.trading.integration.analytics.tracking

import exchange.dydx.abacus.protocols.TrackingProtocol
import exchange.dydx.abacus.utils.toJson
import exchange.dydx.trading.common.AsyncResult.Waiting.data

interface Tracking : TrackingProtocol {

Expand All @@ -14,6 +15,8 @@ interface Tracking : TrackingProtocol {
fun log(event: String, data: Map<String, Any?>) {
log(event, data.toJson())
}

fun view(screenName: String, screenClass: String)
}

interface CompositeTracking : Tracking {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ fun timerFlow(period: Duration, initialDelay: Duration = Duration.ZERO) = flow {
delay(period)
}
}

fun delayFlow(duration: Duration) = flow {
delay(duration)
emit(Unit)
}

0 comments on commit c998fb3

Please sign in to comment.