diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 9cda6cddb0..cc387e59e5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -375,7 +375,7 @@ android:name=".ui.tip.wc.WalletConnectActivity" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" android:launchMode="singleTop" - android:theme="@style/AppTheme.Music" /> + android:theme="@style/AppTheme.Transparent" /> - navBackStackEntry.arguments?.getString("connectionId")?.toIntOrNull().let { connectionId -> - ConnectionDetailsPage(connectionId) { - navigateUp(navController) - } - } - } - } - } - } - } - } - - private fun navigateUp(navController: NavHostController) { - if (!navController.safeNavigateUp()) { - activity?.onBackPressedDispatcher?.onBackPressed() - } - } -} diff --git a/app/src/main/java/one/mixin/android/ui/wallet/InputFragment.kt b/app/src/main/java/one/mixin/android/ui/wallet/InputFragment.kt index 5611a04e2e..36d7f5e62a 100644 --- a/app/src/main/java/one/mixin/android/ui/wallet/InputFragment.kt +++ b/app/src/main/java/one/mixin/android/ui/wallet/InputFragment.kt @@ -214,7 +214,19 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC override fun onResume() { super.onResume() - binding.root.hideKeyboard() + bindingOrNull()?.root?.hideKeyboard() + } + + override fun onDestroyView() { + btcFeeRecalculateJob?.cancel() + btcFeeRecalculateJob = null + if (dialog.isShowing) { + dialog.dismiss() + } + if (alertDialog.isShowing) { + alertDialog.dismiss() + } + super.onDestroyView() } @SuppressLint("SetTextI18n") @@ -224,7 +236,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC ) { super.onViewCreated(view, savedInstanceState) jobManager.addJobInBackground(SyncOutputJob()) - lifecycleScope.launch { + viewLifecycleOwner.lifecycleScope.launch { binding.apply { if (requireActivity() !is WalletActivity){ root.fitsSystemWindows = false @@ -518,7 +530,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } else { v } - lifecycleScope.launch( + viewLifecycleOwner.lifecycleScope.launch( CoroutineExceptionHandler { _, error -> ErrorHandler.handleError(error) alertDialog.dismiss() @@ -586,7 +598,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC val fromAddress = requireNotNull(fromAddress) val toAddress = requireNotNull(toAddress) val amount = currentInputAmount() - lifecycleScope.launch( + viewLifecycleOwner.lifecycleScope.launch( CoroutineExceptionHandler { _, error -> Timber.e("Error: ${error.message}") ErrorHandler.handleError(error) @@ -719,6 +731,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } private fun applyFeeUi() { + val binding = bindingOrNull() ?: return val hasFeeText: Boolean = binding.contentTextView.text.toString().isNotEmpty() val showFee: Boolean = isFeeWaived && hasFeeText binding.contentTextView.paintFlags = @@ -934,6 +947,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } private fun updateWeb3AvailableBalance() { + val binding = bindingOrNull() ?: return val transferToken = web3Token ?: return val displayBalance = when { @@ -959,6 +973,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } private fun updateWeb3FeeDisplay() { + val binding = bindingOrNull() ?: return val token = web3Token ?: return if (binding.loadingProgressBar.isVisible) return val feeOptions = web3FeeOptions() @@ -1030,7 +1045,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC private var isFeeWaived = false private fun renderTitle(toAddress: String, tag: String? = null) { - lifecycleScope.launch { + viewLifecycleOwner.lifecycleScope.launch { val (label, index, _) = web3ViewModel.checkAddressAndGetDisplayName(requireNotNull(toAddress), tag, requireNotNull(token?.chainId ?: web3Token?.chainId)) ?: Triple(null, 0, null) isFeeWaived = index == 1 || index == 2 || index == 4 // Privacy(1), Safe(2), Fee-free(4) binding.titleView.setLabel( @@ -1218,7 +1233,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC if (lastBtcFeeAmount == amount) return lastBtcFeeAmount = amount btcFeeRecalculateJob?.cancel() - btcFeeRecalculateJob = lifecycleScope.launch { + btcFeeRecalculateJob = viewLifecycleOwner.lifecycleScope.launch { delay(300L) val currentAmount: String = lastBtcFeeAmount ?: return@launch refreshBtcFeeForAmount(currentAmount) @@ -1275,6 +1290,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } private fun updateAvailableBalanceForBtcFee() { + val binding = bindingOrNull() ?: return val token: Web3TokenItem = web3Token ?: return if (token.chainId != Constants.ChainId.BITCOIN_CHAIN_ID) return val reservedFee: BigDecimal = gas ?: return @@ -1308,6 +1324,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } private fun updateAddText() { + val binding = bindingOrNull() ?: return if (transferType == TransferType.WEB3 && shouldUseGaslessFlow()) { if (!isGaslessFeeEnough(currentInputAmount())) { binding.addTv.text = "${getString(R.string.Add)} ${currentGaslessFee?.token?.symbol ?: ""}" @@ -1432,7 +1449,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC web3Token != null && web3Token?.assetId == chainToken?.assetId -> { if (gas == null) { if (!dialog.isShowing) { - lifecycleScope.launch { + viewLifecycleOwner.lifecycleScope.launch { dialog.show() refreshFee() } @@ -1501,22 +1518,25 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC get() = field set(value) { field = value + val binding = bindingOrNull() if (value != null) { - if (value.token.assetId == token?.assetId || value.token.assetId == web3Token?.assetId) { + if (binding != null && (value.token.assetId == token?.assetId || value.token.assetId == web3Token?.assetId)) { val balance = runCatching { tokenBalance.toBigDecimalOrNull()?.subtract(value.fee.toBigDecimalOrNull() ?: BigDecimal.ZERO)?.max(BigDecimal.ZERO)?.let { if (web3Token == null) { it.numberFormat8() } else { it.numberFormat12() } } }.getOrDefault("0") binding.balanceTv.text = getString(R.string.available_balance, "$balance $tokenSymbol") - } else { + } else if (binding != null) { binding.balanceTv.text = getString(R.string.available_balance, "${tokenBalance.let { if (web3Token == null) { it.numberFormat8() } else { it.numberFormat12() } } } $tokenSymbol") } - binding.insufficientFeeBalance.text = getString(R.string.insufficient_gas, value.token.symbol) + binding?.insufficientFeeBalance?.text = getString(R.string.insufficient_gas, value.token.symbol) + } + if (binding != null) { + refreshFeeTokenExtra(value?.token?.assetId) } - refreshFeeTokenExtra(value?.token?.assetId) } private var feeTokensExtra: TokensExtra? = null @@ -1529,13 +1549,13 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC private var gaslessFeeToken: Web3TokenItem? = null private var hasManuallySelectedWeb3Fee = false - private fun refreshFeeTokenExtra(tokenId: String?) = lifecycleScope.launch { + private fun refreshFeeTokenExtra(tokenId: String?) = viewLifecycleOwner.lifecycleScope.launch { feeTokensExtra = if (tokenId == null) null else web3ViewModel.findTokensExtra(tokenId) updateUI() } - private fun refreshGaslessFeeToken(tokenId: String?) = lifecycleScope.launch { + private fun refreshGaslessFeeToken(tokenId: String?) = viewLifecycleOwner.lifecycleScope.launch { gaslessFeeToken = if (tokenId == null || web3Token == null) { null } else { @@ -1554,11 +1574,13 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC private var isAdjustingBtcAmount: Boolean = false private fun setFeeLoading(isLoading: Boolean) { + val binding = bindingOrNull() ?: return binding.loadingProgressBar.isVisible = isLoading binding.contentTextView.isVisible = !isLoading } private suspend fun refreshFee(t: TokenItem) { + val binding = bindingOrNull() ?: return val toAddress = toAddress?: return setFeeLoading(true) val feeResponse = runCatching { web3ViewModel.getFees(t.assetId, toAddress) }.getOrNull() @@ -1613,7 +1635,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } private fun prepareCheck(item: BiometricItem) { - lifecycleScope.launch { + viewLifecycleOwner.lifecycleScope.launch { val amount = item.amount val rawTransaction = web3ViewModel.firstUnspentTransaction() if (rawTransaction != null) { @@ -1629,7 +1651,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC private fun checkUtxo(amount: String, callback: () -> Unit) { val token = token ?: return - lifecycleScope.launch { + viewLifecycleOwner.lifecycleScope.launch { val consolidationAmount = web3ViewModel.checkUtxoSufficiency(token.assetId, amount) if (consolidationAmount != null) { UtxoConsolidationBottomSheetDialogFragment.newInstance(buildTransferBiometricItem(Session.getAccount()!!.toUser(), token, consolidationAmount, UUID.randomUUID().toString(), null, null)) @@ -1641,7 +1663,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } private fun prepareTransferBottom(amount: String, item: BiometricItem) = - lifecycleScope.launch { + viewLifecycleOwner.lifecycleScope.launch { val t = item if (t !is TransferBiometricItem && t !is AddressTransferBiometricItem && t !is WithdrawBiometricItem) { return@launch @@ -1744,6 +1766,7 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } private suspend fun refreshGas(t: Web3TokenItem) { + val binding = bindingOrNull() ?: return val toAddress = toAddress?: return val fromAddress = fromAddress ?: return if (t.chainId == Constants.ChainId.BITCOIN_CHAIN_ID) { @@ -1819,6 +1842,14 @@ class InputFragment : BaseFragment(R.layout.fragment_input), OnReceiveSelectionC } } + private fun bindingOrNull(): FragmentInputBinding? { + return if (view == null) { + null + } else { + binding + } + } + private suspend fun refreshGaslessFees(t: Web3TokenItem) { val fromAddress = fromAddress ?: return val toAddress = toAddress ?: return