From 03ccecc843734d2e6af67f95c4962a907f258664 Mon Sep 17 00:00:00 2001 From: SeniorZhai Date: Thu, 25 Jun 2026 14:06:25 +0800 Subject: [PATCH 1/2] fix(wallet): refresh perps positions on home --- .../mixin/android/ui/wallet/WalletFragment.kt | 15 ++++++ .../ui/wallet/WalletHomePrivacyFragment.kt | 46 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt b/app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt index 4a962a9194..31245ee0b5 100644 --- a/app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt @@ -466,6 +466,11 @@ class WalletFragment : BaseFragment(R.layout.fragment_wallet) { fun update() { val destination = selectedWalletDestination when (destination) { + is WalletDestination.Privacy -> { + privacyWalletFragment.update() + null + } + is WalletDestination.Classic -> { destination.walletId } @@ -486,9 +491,19 @@ class WalletFragment : BaseFragment(R.layout.fragment_wallet) { } } + override fun onHiddenChanged(hidden: Boolean) { + super.onHiddenChanged(hidden) + if (hidden) { + privacyWalletFragment.stopUpdate() + } else { + update() + } + } + override fun onResume() { super.onResume() jobManager.addJobInBackground(RefreshSafeAccountsJob()) + if (privacyWalletFragment.isVisible) privacyWalletFragment.update() if (classicWalletFragment.isVisible) classicWalletFragment.update() } diff --git a/app/src/main/java/one/mixin/android/ui/wallet/WalletHomePrivacyFragment.kt b/app/src/main/java/one/mixin/android/ui/wallet/WalletHomePrivacyFragment.kt index 64d4656637..834ce96212 100644 --- a/app/src/main/java/one/mixin/android/ui/wallet/WalletHomePrivacyFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/wallet/WalletHomePrivacyFragment.kt @@ -23,7 +23,10 @@ import com.uber.autodispose.autoDispose import dagger.hilt.android.AndroidEntryPoint import io.reactivex.android.schedulers.AndroidSchedulers import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import one.mixin.android.Constants @@ -48,6 +51,7 @@ import one.mixin.android.extension.openUrl import one.mixin.android.extension.toast import one.mixin.android.extension.putBoolean import one.mixin.android.job.MixinJobManager +import one.mixin.android.job.RefreshPerpsPositionsJob import one.mixin.android.job.RefreshSnapshotsJob import one.mixin.android.job.RefreshTokensJob import one.mixin.android.job.SyncOutputJob @@ -113,6 +117,7 @@ import kotlin.math.abs class WalletHomePrivacyFragment : BaseFragment(R.layout.fragment_privacy_wallet), HeaderAdapter.OnItemListener { companion object { const val TAG = "WalletHomePrivacyFragment" + private const val PERPS_POSITION_REFRESH_INTERVAL_MS = 3_000L fun newInstance(): WalletHomePrivacyFragment = WalletHomePrivacyFragment() } @@ -131,6 +136,7 @@ class WalletHomePrivacyFragment : BaseFragment(R.layout.fragment_privacy_wallet) private var positions: List = emptyList() private var topMovers: List = emptyList() private var pendingDisplays: List = emptyList() + private var perpsPositionsRefreshJob: Job? = null private val assetsAdapter by lazy { WalletAssetAdapter(false) } private val perpetualViewModel by viewModels() private var walletHomeDataState = WalletHomeDataState.EMPTY @@ -669,6 +675,7 @@ class WalletHomePrivacyFragment : BaseFragment(R.layout.fragment_privacy_wallet) override fun onResume() { super.onResume() _walletId.value = Session.getAccountId().orEmpty() + startPerpsPositionsRefresh() jobManager.addJobInBackground(RefreshTokensJob()) jobManager.addJobInBackground(RefreshSnapshotsJob()) jobManager.addJobInBackground(SyncOutputJob()) @@ -680,15 +687,48 @@ class WalletHomePrivacyFragment : BaseFragment(R.layout.fragment_privacy_wallet) } override fun onHiddenChanged(hidden: Boolean) { + super.onHiddenChanged(hidden) if (!hidden) { _walletId.value = Session.getAccountId().orEmpty() + startPerpsPositionsRefresh() jobManager.addJobInBackground(RefreshTokensJob()) jobManager.addJobInBackground(RefreshSnapshotsJob()) jobManager.addJobInBackground(SyncOutputJob()) refreshAllPendingDeposit() + } else { + stopPerpsPositionsRefresh() } } + fun update() { + _walletId.value = Session.getAccountId().orEmpty() + startPerpsPositionsRefresh() + } + + fun stopUpdate() { + stopPerpsPositionsRefresh() + } + + private fun startPerpsPositionsRefresh() { + val walletId = Session.getAccountId().orEmpty() + if (walletId.isBlank() || !isResumed || isHidden) { + stopPerpsPositionsRefresh() + return + } + if (perpsPositionsRefreshJob?.isActive == true) return + perpsPositionsRefreshJob = lifecycleScope.launch { + while (isActive) { + jobManager.addJobInBackground(RefreshPerpsPositionsJob(walletId)) + delay(PERPS_POSITION_REFRESH_INTERVAL_MS) + } + } + } + + private fun stopPerpsPositionsRefresh() { + perpsPositionsRefreshJob?.cancel() + perpsPositionsRefreshJob = null + } + private fun refreshAllPendingDeposit() = lifecycleScope.launch { handleMixinResponse( @@ -730,7 +770,13 @@ class WalletHomePrivacyFragment : BaseFragment(R.layout.fragment_privacy_wallet) snackBar?.dismiss() } + override fun onPause() { + stopPerpsPositionsRefresh() + super.onPause() + } + override fun onDestroyView() { + stopPerpsPositionsRefresh() assetsAdapter.headerView = null assetsAdapter.onItemListener = null _binding = null From cb2c7cb8ab967d0b636c070f4cf06db2c4bbe3b5 Mon Sep 17 00:00:00 2001 From: SeniorZhai Date: Thu, 25 Jun 2026 16:05:10 +0800 Subject: [PATCH 2/2] fix(wallet): avoid persisted perps refresh polling --- .../android/job/RefreshPerpsPositionsJob.kt | 2 +- .../mixin/android/ui/wallet/WalletFragment.kt | 16 +++++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/one/mixin/android/job/RefreshPerpsPositionsJob.kt b/app/src/main/java/one/mixin/android/job/RefreshPerpsPositionsJob.kt index 8b761795ae..791337ba8b 100644 --- a/app/src/main/java/one/mixin/android/job/RefreshPerpsPositionsJob.kt +++ b/app/src/main/java/one/mixin/android/job/RefreshPerpsPositionsJob.kt @@ -10,7 +10,7 @@ import timber.log.Timber class RefreshPerpsPositionsJob( private val walletId: String? = null -) : BaseJob(Params(PRIORITY_BACKGROUND).singleInstanceBy(GROUP).requireNetwork().persist()) { +) : BaseJob(Params(PRIORITY_BACKGROUND).singleInstanceBy(GROUP).requireNetwork()) { companion object { private const val serialVersionUID = 1L const val GROUP = "RefreshPerpsPositionsJob" diff --git a/app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt b/app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt index 31245ee0b5..7ee8ba1583 100644 --- a/app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/wallet/WalletFragment.kt @@ -464,30 +464,24 @@ class WalletFragment : BaseFragment(R.layout.fragment_wallet) { } fun update() { - val destination = selectedWalletDestination - when (destination) { + when (val destination = selectedWalletDestination) { is WalletDestination.Privacy -> { privacyWalletFragment.update() - null } is WalletDestination.Classic -> { - destination.walletId + jobManager.addJobInBackground(RefreshSingleWalletJob(destination.walletId)) } is WalletDestination.Import -> { - destination.walletId + jobManager.addJobInBackground(RefreshSingleWalletJob(destination.walletId)) } is WalletDestination.Watch -> { - destination.walletId + jobManager.addJobInBackground(RefreshSingleWalletJob(destination.walletId)) } - else -> { - null - } - }?.let { wallet -> - jobManager.addJobInBackground(RefreshSingleWalletJob(wallet)) + else -> Unit } }