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
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ fun String.checkUserOrApp(
val userDao = db.userDao()
val appDao = db.appDao()
scope.launch {
val isOpenApp = isAppScheme && uri.getQueryParameter("action") == "open"
val isOpenApp = uri.shouldOpenAppHome()
if (isOpenApp) {
val localApp = appDao.findAppById(userId)
if (localApp != null) {
Expand All @@ -299,6 +299,9 @@ fun String.checkUserOrApp(
}
}

internal fun Uri.shouldOpenAppHome(): Boolean =
toString().isAppScheme() && (getQueryParameter("action") == "open" || !getQueryParameter("page").isNullOrBlank())

internal fun App.homeUriWithSchemeParameters(uri: Uri): String =
runCatching {
homeUri.appendQueryParamsFromOtherUri(uri)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import one.mixin.android.extension.isNightMode
import one.mixin.android.extension.isUUID
import one.mixin.android.extension.isValidStartParam
import one.mixin.android.extension.putInt
import one.mixin.android.extension.shouldOpenAppHome
import one.mixin.android.extension.stripAmountZero
import one.mixin.android.extension.toPerpsTradeAction
import one.mixin.android.extension.toast
Expand Down Expand Up @@ -249,7 +250,7 @@ class LinkBottomSheetDialogFragment : SchemeBottomSheet() {
dismiss()
} else {
lifecycleScope.launch(errorHandler) {
val isOpenApp = isAppScheme && uri.getQueryParameter("action") == "open"
val isOpenApp = uri.shouldOpenAppHome()
if (isOpenApp) {
val localApp = oldLinkViewModel.findAppById(userId)
if (localApp != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package one.mixin.android.ui.wallet

import android.annotation.SuppressLint
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
Expand All @@ -24,7 +23,6 @@ import one.mixin.android.api.response.perps.PerpsPositionItem
import one.mixin.android.databinding.FragmentWalletHomeAllTokensBinding
import one.mixin.android.databinding.ViewClassicWalletBottomBinding
import one.mixin.android.databinding.ViewPrivacyWalletBottomBinding
import one.mixin.android.db.property.PropertyHelper
import one.mixin.android.db.web3.vo.WalletItem
import one.mixin.android.db.web3.vo.Web3TokenItem
import one.mixin.android.db.web3.vo.Web3TransactionItem
Expand Down Expand Up @@ -58,7 +56,6 @@ import one.mixin.android.ui.wallet.home.positionMarginUsdTotal
import one.mixin.android.ui.wallet.home.toWalletHomePendingIndicator
import one.mixin.android.ui.wallet.home.walletHomeImportKeyAction
import one.mixin.android.ui.wallet.home.walletHomePendingTransactionIndicator
import one.mixin.android.ui.web.WebActivity
import one.mixin.android.util.analytics.AnalyticsTracker
import one.mixin.android.util.analytics.AnalyticsTracker.TradeSource
import one.mixin.android.util.analytics.AnalyticsTracker.TradeWallet
Expand Down Expand Up @@ -503,49 +500,6 @@ class WalletHomeAllTokensFragment : BaseFragment() {
return true
}

private fun showBuyOptionsBottomSheet() {
viewLifecycleOwner.lifecycleScope.launch {
val cashRewardApy = PropertyHelper.findCashAccount()?.rewardApy
WalletBuyOptionsBottomSheetDialogFragment.newInstance(
walletName = getString(R.string.Privacy_Wallet),
walletIconRes = R.drawable.ic_wallet_privacy,
cashRewardApy = cashRewardApy,
)
.setOnGooglePayOrCard {
WalletActivity.showBuy(requireActivity(), false, null, null, source = TradeSource.TOKEN_LIST)
}
.setOnBankTransfer { openCashHome(addBank = true) }
.showNow(parentFragmentManager, WalletBuyOptionsBottomSheetDialogFragment.TAG)
}
}

private fun openCashHome(addBank: Boolean = false) {
lifecycleScope.launch {
val app = walletViewModel.findOrSyncApp(Constants.MIXIN_CASH_USER_ID)
val url = cashHomeUrl(app?.homeUri, addBank)
if (app == null) {
WebActivity.show(requireActivity(), url = url, app = null, conversationId = null)
} else {
WebActivity.show(requireActivity(), url = url, app = app, conversationId = null)
}
}
}

private fun cashHomeUrl(
homeUri: String?,
addBank: Boolean,
): String {
val url = homeUri.takeUnless { it.isNullOrBlank() } ?: Constants.API.CASH_HOME_URL
return if (addBank) {
Uri.parse(url).buildUpon()
.appendQueryParameter("action", "add-cash-bank")
.build()
.toString()
} else {
url
}
}

private val callbacks = object : WalletHomeCallbacks {
override fun onAddWalletClicked() = Unit
override fun onBannerClosed() = Unit
Expand All @@ -566,7 +520,7 @@ class WalletHomeAllTokensFragment : BaseFragment() {
source = TradeSource.TOKEN_LIST,
)
} else {
showBuyOptionsBottomSheet()
WalletActivity.showBuy(requireActivity(), false, null, null, source = TradeSource.TOKEN_LIST)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package one.mixin.android.ui.wallet

import android.annotation.SuppressLint
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
Expand Down Expand Up @@ -237,7 +236,7 @@ class WalletHomePrivacyFragment : BaseFragment(R.layout.fragment_privacy_wallet)
sendReceiveView.isVisible = true
sendReceiveView.enableBuy()
sendReceiveView.buy.setOnClickListener {
showBuyOptionsBottomSheet()
showBuy()
}
sendReceiveView.send.setOnClickListener {
if (
Expand Down Expand Up @@ -766,7 +765,7 @@ class WalletHomePrivacyFragment : BaseFragment(R.layout.fragment_privacy_wallet)
}

override fun onBuyClicked() {
showBuyOptionsBottomSheet()
showBuy()
}

override fun onReceiveClicked() {
Expand Down Expand Up @@ -910,60 +909,24 @@ class WalletHomePrivacyFragment : BaseFragment(R.layout.fragment_privacy_wallet)
AddWalletBottomSheetDialogFragment.newInstance().showNow(parentFragmentManager, AddWalletBottomSheetDialogFragment.TAG)
}

private fun showBuyOptionsBottomSheet() {
private fun showBuy() {
defaultSharedPreferences.putBoolean(PREF_HAS_USED_BUY, false)
RxBus.publish(BadgeEvent(PREF_HAS_USED_BUY))
_headBinding?.sendReceiveView?.buyBadge?.isVisible = false
renderHome()
WalletBuyOptionsBottomSheetDialogFragment.newInstance(
walletName = getString(R.string.Privacy_Wallet),
walletIconRes = R.drawable.ic_wallet_privacy,
cashRewardApy = cashAccount?.rewardApy,
)
.setOnGooglePayOrCard {
WalletActivity.showBuy(requireActivity(), false, null, null)
}
.setOnBankTransfer { openCashHome(addBank = true) }
.showNow(parentFragmentManager, WalletBuyOptionsBottomSheetDialogFragment.TAG)
WalletActivity.showBuy(requireActivity(), false, null, null)
}

private fun openCashHome(addBank: Boolean = false) {
if (!addBank) {
"${Constants.Scheme.APPS}/${Constants.MIXIN_CASH_USER_ID}?action=open"
.openAsUrlOrWeb(requireActivity(), null, parentFragmentManager, lifecycleScope)
return
}
lifecycleScope.launch {
val app = walletViewModel.findOrSyncApp(Constants.MIXIN_CASH_USER_ID)
val url = cashHomeUrl(app?.homeUri, addBank)
if (app == null) {
WebActivity.show(requireActivity(), url = url, app = null, conversationId = null)
} else {
WebActivity.show(requireActivity(), url = url, app = app, conversationId = null)
}
}
private fun openCashHome() {
"${Constants.Scheme.APPS}/${Constants.MIXIN_CASH_USER_ID}?page=add-cash-ban"
.openAsUrlOrWeb(requireActivity(), null, parentFragmentManager, lifecycleScope)
}

private fun openEarnHome() {
"${Constants.Scheme.APPS}/${Constants.MIXIN_EARN_USER_ID}?action=open"
.openAsUrlOrWeb(requireActivity(), null, parentFragmentManager, lifecycleScope)
}

private fun cashHomeUrl(
homeUri: String?,
addBank: Boolean,
): String {
val url = homeUri.takeUnless { it.isNullOrBlank() } ?: Constants.API.CASH_HOME_URL
return if (addBank) {
Uri.parse(url).buildUpon()
.appendQueryParameter("action", "add-cash-bank")
.build()
.toString()
} else {
url
}
}

override fun onResume() {
super.onResume()
renderHome()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package one.mixin.android.ui.wallet.fiatmoney

import android.annotation.SuppressLint
import android.net.Uri
import android.os.Bundle
import android.util.TypedValue
import android.view.View
Expand All @@ -21,6 +22,7 @@ import one.mixin.android.R
import one.mixin.android.api.MixinResponseException
import one.mixin.android.api.request.RouteTickerRequest
import one.mixin.android.databinding.FragmentCalculateBinding
import one.mixin.android.db.property.PropertyHelper
import one.mixin.android.extension.clickVibrate
import one.mixin.android.extension.colorFromAttribute
import one.mixin.android.extension.defaultSharedPreferences
Expand All @@ -45,6 +47,8 @@ import one.mixin.android.ui.wallet.AssetListFixedBottomSheetDialogFragment
import one.mixin.android.ui.wallet.FiatListBottomSheetDialogFragment
import one.mixin.android.ui.wallet.LoadingProgressDialogFragment
import one.mixin.android.ui.wallet.WalletActivity
import one.mixin.android.ui.wallet.WalletBuyOptionsBottomSheetDialogFragment
import one.mixin.android.ui.web.WebActivity
import one.mixin.android.util.ErrorHandler
import one.mixin.android.util.analytics.AnalyticsTracker
import one.mixin.android.util.viewBinding
Expand Down Expand Up @@ -438,7 +442,22 @@ class CalculateFragment : BaseFragment(R.layout.fragment_calculate) {
}
}
}
proceedToBuy()
if (isWeb3) {
proceedToBuy()
} else {
viewLifecycleScope.launch {
val cashRewardApy = PropertyHelper.findCashAccount()?.rewardApy
if (parentFragmentManager.findFragmentByTag(WalletBuyOptionsBottomSheetDialogFragment.TAG) != null) return@launch
WalletBuyOptionsBottomSheetDialogFragment.newInstance(
walletName = getString(R.string.Privacy_Wallet),
walletIconRes = R.drawable.ic_wallet_privacy,
cashRewardApy = cashRewardApy,
)
.setOnGooglePayOrCard(proceedToBuy)
.setOnBankTransfer { openBankTransfer() }
.showNow(parentFragmentManager, WalletBuyOptionsBottomSheetDialogFragment.TAG)
}
}
}
switchIv.setOnClickListener {
fiatMoneyViewModel.isReverse = !fiatMoneyViewModel.isReverse
Expand All @@ -455,6 +474,18 @@ class CalculateFragment : BaseFragment(R.layout.fragment_calculate) {
}
}

private fun openBankTransfer() {
viewLifecycleOwner.lifecycleScope.launch {
val app = fiatMoneyViewModel.findOrSyncApp(Constants.MIXIN_CASH_USER_ID)
val homeUri = app?.homeUri.takeUnless { it.isNullOrBlank() } ?: Constants.API.CASH_HOME_URL
val url = Uri.parse(homeUri).buildUpon()
.appendQueryParameter("action", "add-cash-bank")
.build()
.toString()
WebActivity.show(requireActivity(), url = url, app = app, conversationId = null)
}
}

private fun isTwoDecimal(string: String): Boolean {
return string.matches(Regex("\\d+\\.\\d{2}"))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class FiatMoneyViewModel

suspend fun findAssetsById(id: String) = tokenRepository.findAssetItemById(id)

suspend fun findOrSyncApp(id: String) = userRepository.findOrSyncApp(id)

suspend fun fetchSessionsSuspend(ids: List<String>) = userRepository.fetchSessionsSuspend(ids)

suspend fun ticker(tickerRequest: RouteTickerRequest): MixinResponse<RouteTickerResponse> =
Expand Down
36 changes: 36 additions & 0 deletions app/src/test/java/one/mixin/android/extension/AppSchemeTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package one.mixin.android.extension

import android.app.Application
import android.net.Uri
import one.mixin.android.Constants
import org.junit.Test
import org.junit.runner.RunWith
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertTrue

@RunWith(RobolectricTestRunner::class)
@Config(application = Application::class)
class AppSchemeTest {
@Test
fun appPageLinksOpenHomeAndForwardPage() {
for (scheme in listOf(Constants.Scheme.APPS, Constants.Scheme.HTTPS_APPS)) {
val base = "$scheme/${Constants.MIXIN_CASH_USER_ID}"
val uri = Uri.parse("$base?page=add-cash-ban")
assertTrue(uri.shouldOpenAppHome())
assertEquals(
"https://example.com?existing=1&page=add-cash-ban",
"https://example.com?existing=1".appendQueryParamsFromOtherUri(uri),
)
assertTrue(Uri.parse("$base?action=open").shouldOpenAppHome())
for (query in listOf("", "?page=", "?page=%20", "?action=other")) {
assertFalse(Uri.parse("$base$query").shouldOpenAppHome())
}
}
for (scheme in listOf(Constants.Scheme.USERS, Constants.Scheme.HTTPS_USERS)) {
assertFalse(Uri.parse("$scheme/${Constants.MIXIN_CASH_USER_ID}?page=add-cash-ban").shouldOpenAppHome())
}
}
}
Loading