diff --git a/app/build.gradle b/app/build.gradle index 105d4d8323..ce5b525f66 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -144,7 +144,7 @@ dependencies { implementation("com.squareup.okhttp3:logging-interceptor") // Support - implementation("com.zendesk:support:5.0.9") + implementation("com.zendesk:chat:3.3.5") implementation("com.zendesk:messaging:5.2.4") //Crypto diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d180642a75..b460cf581a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -47,7 +47,7 @@ diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index 518ad410c4..adcd569b7f 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -8,6 +8,7 @@ import com.google.firebase.ktx.Firebase import com.google.firebase.remoteconfig.ktx.remoteConfig import com.google.firebase.remoteconfig.ktx.remoteConfigSettings import com.tangem.Log +import com.tangem.LogFormat import com.tangem.blockchain.network.BlockchainSdkRetrofitBuilder import com.tangem.domain.DomainLayer import com.tangem.network.common.MoshiConverter @@ -108,7 +109,21 @@ class TapApplication : Application(), ImageLoaderFactory { val infoHolder = AdditionalFeedbackInfo() infoHolder.setAppVersion(this) - val logWriter = TangemLogCollector() + val logLevels = listOf( + Log.Level.ApduCommand, + Log.Level.Apdu, + Log.Level.Tlv, + Log.Level.Nfc, + Log.Level.Command, + Log.Level.Session, + Log.Level.View, + Log.Level.Network, + Log.Level.Error, + ) + val logWriter = TangemLogCollector( + levels = logLevels, + messageFormatter = LogFormat.StairsFormatter() + ) Log.addLogger(logWriter) store.dispatch(GlobalAction.SetFeedbackManager(FeedbackManager(infoHolder, logWriter))) @@ -126,4 +141,5 @@ class TapApplication : Application(), ImageLoaderFactory { data class LogConfig( val coil: Boolean = BuildConfig.DEBUG, val storeAction: Boolean = BuildConfig.DEBUG, + val zendesk: Boolean = BuildConfig.DEBUG, ) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt index 3cb5aa96c8..e2490e7886 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Blockchain.kt @@ -27,6 +27,7 @@ fun Blockchain.getRoundIconRes(): Int { Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_bsc_round Blockchain.Dogecoin -> R.drawable.ic_dogecoin_round Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.ic_tron_round + Blockchain.Gnosis -> R.drawable.ic_gnosis_round else -> R.drawable.ic_tangem_logo } } @@ -53,6 +54,7 @@ fun Blockchain.getGreyedOutIconRes(): Int { Blockchain.BSC, Blockchain.BSCTestnet, Blockchain.Binance, Blockchain.BinanceTestnet -> R.drawable.ic_bsc_no_color Blockchain.Dogecoin -> R.drawable.ic_dogecoin_no_color Blockchain.Tron, Blockchain.TronTestnet -> R.drawable.ic_tron_no_color + Blockchain.Gnosis -> R.drawable.ic_gnosis_no_color else -> R.drawable.ic_tangem_logo } } diff --git a/app/src/main/java/com/tangem/tap/common/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/common/feedback/FeedbackManager.kt index 4e551608e5..c2bb70a931 100644 --- a/app/src/main/java/com/tangem/tap/common/feedback/FeedbackManager.kt +++ b/app/src/main/java/com/tangem/tap/common/feedback/FeedbackManager.kt @@ -6,18 +6,19 @@ import com.tangem.tap.common.extensions.sendEmail import com.tangem.tap.common.log.TangemLogCollector import com.tangem.tap.common.zendesk.ZendeskConfig import com.tangem.tap.foregroundActivityObserver +import com.tangem.tap.logConfig import com.tangem.tap.withForegroundActivity +import com.tangem.wallet.R +import com.zendesk.logger.Logger +import timber.log.Timber +import zendesk.chat.Chat +import zendesk.chat.ChatConfiguration +import zendesk.chat.ChatEngine +import zendesk.configurations.Configuration +import zendesk.messaging.MessagingActivity import java.io.File import java.io.FileWriter import java.io.StringWriter -import timber.log.Timber -import zendesk.configurations.Configuration -import zendesk.core.AnonymousIdentity -import zendesk.core.Zendesk -import zendesk.support.Support -import zendesk.support.request.RequestConfiguration -import zendesk.support.requestlist.RequestListActivity -import zendesk.support.requestlist.RequestListConfiguration /** [REDACTED_AUTHOR] @@ -30,14 +31,14 @@ class FeedbackManager( context: Context, zendeskConfig: ZendeskConfig, ) { - Zendesk.INSTANCE.init( - /* context = */ context, - /* zendeskUrl = */ zendeskConfig.url, - /* applicationId = */ zendeskConfig.appId, - /* oauthClientId = */ zendeskConfig.clientId, + Chat.INSTANCE.init( + context, + zendeskConfig.accountKey, + zendeskConfig.appId ) - Support.INSTANCE.init(Zendesk.INSTANCE) - Zendesk.INSTANCE.setIdentity(AnonymousIdentity()) + + // Zendesk logs + Logger.setLoggable(logConfig.zendesk) } fun sendEmail(feedbackData: FeedbackData, onFail: ((Exception) -> Unit)? = null) { @@ -57,11 +58,8 @@ class FeedbackManager( fun openChat(feedbackData: FeedbackData) { feedbackData.prepare(infoHolder) foregroundActivityObserver.withForegroundActivity { activity -> - RequestListActivity.builder() - .show( - /* context = */ activity, - /* configurations = */ buildConfigs(activity, feedbackData) - ) + setChatVisitorNote(activity, feedbackData) + showMessagingActivity(activity) } } @@ -84,20 +82,30 @@ class FeedbackManager( } } - private fun buildConfigs( + private fun setChatVisitorNote( context: Context, feedbackData: FeedbackData, - ): List { - return listOf( - // Request configuration - RequestConfiguration.Builder() - .withRequestSubject(context.getString(feedbackData.subjectResId)) - .config(), - // Request list configuration - RequestListConfiguration.Builder() - .withContactUsButtonVisible(true) - .config(), - ) + ) { + Chat.INSTANCE.providers() + ?.profileProvider() + ?.setVisitorNote(feedbackData.joinTogether(context, infoHolder)) + } + + private fun showMessagingActivity(context: Context) { + MessagingActivity.builder() + .withMultilineResponseOptionsEnabled(false) + .withBotLabelStringRes(R.string.chat_bot_name) + .withBotAvatarDrawable(R.mipmap.ic_launcher) + .withEngines(ChatEngine.engine()) + .show(context, buildChatConfig()) + } + + private fun buildChatConfig(): Configuration { + return ChatConfiguration.builder() + .withOfflineFormEnabled(true) + .withAgentAvailabilityEnabled(true) + .withPreChatFormEnabled(false) + .build() } private fun getSupportEmail(): String { diff --git a/app/src/main/java/com/tangem/tap/common/log/TangemLogCollector.kt b/app/src/main/java/com/tangem/tap/common/log/TangemLogCollector.kt index c1ae08ebc2..54a56e17c3 100644 --- a/app/src/main/java/com/tangem/tap/common/log/TangemLogCollector.kt +++ b/app/src/main/java/com/tangem/tap/common/log/TangemLogCollector.kt @@ -1,25 +1,31 @@ package com.tangem.tap.common.log import com.tangem.Log +import com.tangem.LogFormat import com.tangem.TangemSdkLogger import java.text.SimpleDateFormat -import java.util.Date +import java.util.* + +class TangemLogCollector( + private val levels: List, + private val messageFormatter: LogFormat, +) : TangemSdkLogger { -class TangemLogCollector : TangemSdkLogger { private val dateFormatter = SimpleDateFormat("HH:mm:ss.SSS") private val logs = mutableListOf() private val mutex = Object() override fun log(message: () -> String, level: Log.Level) { - val time = dateFormatter.format(Date()) + if (!levels.contains(level)) return + synchronized(mutex) { - logs.add("$time: ${message()}\n") + val formattedMessage = messageFormatter.format(message, level) + val logMessage = "${dateFormatter.format(Date())}: $formattedMessage" + logs.add("$logMessage\n") } } fun getLogs(): List = synchronized(mutex) { logs.toList() } - fun clearLogs() { - synchronized(mutex) { logs.clear() } - } + fun clearLogs() = synchronized(mutex) { logs.clear() } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/zendesk/ZendeskConfig.kt b/app/src/main/java/com/tangem/tap/common/zendesk/ZendeskConfig.kt index aad872b7df..66569ee1b7 100644 --- a/app/src/main/java/com/tangem/tap/common/zendesk/ZendeskConfig.kt +++ b/app/src/main/java/com/tangem/tap/common/zendesk/ZendeskConfig.kt @@ -11,6 +11,8 @@ data class ZendeskConfig( val appId: String, @Json(name = "zendeskClientId") val clientId: String, + @Json(name = "zendeskAccountKey") + val accountKey: String, @Json(name = "zendeskUrl") val url: String, ) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectNetworkUtils.kt b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectNetworkUtils.kt index aba7726098..3da00c517b 100644 --- a/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectNetworkUtils.kt +++ b/app/src/main/java/com/tangem/tap/domain/walletconnect/WalletConnectNetworkUtils.kt @@ -28,11 +28,15 @@ class WalletConnectNetworkUtils { peer.name.contains("BSC") -> { Blockchain.BSC } + peer.url.contains("honeyswap.1hive.eth.limo") -> { + // Check if something's changed after this bug report: + // https://github.com/1Hive/honeyswap-interface/issues/83 + Blockchain.Gnosis + } else -> { - Blockchain.Ethereum + Blockchain.Ethereum } } } - } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt b/app/src/main/java/com/tangem/tap/features/feedback/FeedbackManager.kt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ExpandedCurrencyItem.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ExpandedCurrencyItem.kt index cecf873bf9..ca702054eb 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ExpandedCurrencyItem.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ExpandedCurrencyItem.kt @@ -2,7 +2,16 @@ package com.tangem.tap.features.tokens.ui.compose import androidx.compose.foundation.Image import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Divider import androidx.compose.material.Text @@ -132,7 +141,9 @@ fun ExpandedCurrencyItem( val contract = currency.contracts.firstOrNull { it.blockchain == blockchain } ?: return@map val added = if (contract.address != null) { - addedTokens.map { it.token.contractAddress }.contains(contract.address) + addedTokens.any { + it.token.contractAddress == contract.address && it.blockchain == contract.blockchain + } } else { addedBlockchains.contains(blockchain) } diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt index b4f5f84a1f..78bbb4c3ed 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/adapters/WalletAdapter.kt @@ -9,7 +9,7 @@ import androidx.recyclerview.widget.RecyclerView import com.tangem.blockchain.common.Blockchain import com.tangem.blockchain.common.Token import com.tangem.domain.common.TapWorkarounds.derivationStyle -import com.tangem.tap.common.extensions.getGreyedOutIconRes +import com.tangem.tap.common.extensions.getRoundIconRes import com.tangem.tap.common.extensions.getString import com.tangem.tap.common.extensions.hide import com.tangem.tap.common.extensions.show @@ -118,7 +118,7 @@ class WalletAdapter badgeCustomBalance.isVisible = isCustomCurrency ivBlockchain.isVisible = wallet.currency.isToken() - ivBlockchain.setImageResource(wallet.currency.blockchain.getGreyedOutIconRes()) + ivBlockchain.setImageResource(wallet.currency.blockchain.getRoundIconRes()) cardWallet.setOnClickListener { store.dispatch(WalletAction.MultiWallet.SelectWallet(wallet)) diff --git a/app/src/main/java/com/tangem/tap/features/wallet/ui/images/CurrencyIconView.kt b/app/src/main/java/com/tangem/tap/features/wallet/ui/images/CurrencyIconView.kt index 35d89aaa27..b973c9cc52 100644 --- a/app/src/main/java/com/tangem/tap/features/wallet/ui/images/CurrencyIconView.kt +++ b/app/src/main/java/com/tangem/tap/features/wallet/ui/images/CurrencyIconView.kt @@ -24,7 +24,6 @@ class CurrencyIconView @JvmOverloads constructor( init { elevation = 0f cardElevation = 0f - radius = dpToPx(8f) - background = null + radius = dpToPx(6f) } } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_gnosis_no_color.xml b/app/src/main/res/drawable/ic_gnosis_no_color.xml new file mode 100644 index 0000000000..a8d4069093 --- /dev/null +++ b/app/src/main/res/drawable/ic_gnosis_no_color.xml @@ -0,0 +1,21 @@ + + + + + + + diff --git a/app/src/main/res/drawable/ic_gnosis_round.xml b/app/src/main/res/drawable/ic_gnosis_round.xml new file mode 100644 index 0000000000..8734b7177b --- /dev/null +++ b/app/src/main/res/drawable/ic_gnosis_round.xml @@ -0,0 +1,8 @@ + + + + + + + diff --git a/app/src/main/res/layout/item_currency_wallet.xml b/app/src/main/res/layout/item_currency_wallet.xml index 9ac49b1ad9..01860acfb1 100644 --- a/app/src/main/res/layout/item_currency_wallet.xml +++ b/app/src/main/res/layout/item_currency_wallet.xml @@ -6,14 +6,14 @@ android:layout_height="wrap_content"> + android:id="@+id/card_wallet" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="8dp" + android:background="@android:color/white" + android:elevation="3dp"> + app:layout_constraintEnd_toEndOf="@id/iv_currency" + app:layout_constraintStart_toStartOf="@id/iv_currency" + app:layout_constraintTop_toTopOf="@id/iv_currency" + tools:text="J" /> + layout="@layout/item_currency_wallet_content" + android:id="@+id/l_content" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_marginStart="8dp" + android:visibility="gone" + app:layout_constraintStart_toEndOf="@id/iv_currency" + app:layout_constraintEnd_toEndOf="parent" + tools:visibility="visible" /> + layout="@layout/item_currency_wallet_shimmer" + android:id="@+id/l_shimmer" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_marginStart="8dp" + app:layout_constraintStart_toEndOf="@id/iv_currency" + app:layout_constraintEnd_toEndOf="parent" /> diff --git a/app/src/main/res/values-ru/strings_final.xml b/app/src/main/res/values-ru/strings_final.xml index fe80b7139f..3e221ac924 100644 --- a/app/src/main/res/values-ru/strings_final.xml +++ b/app/src/main/res/values-ru/strings_final.xml @@ -77,6 +77,7 @@ Да Чат + Tangem Bot Настройки карты Тип безопасности diff --git a/app/src/main/res/values/strings_final.xml b/app/src/main/res/values/strings_final.xml index 4a732df7a2..6d4137103f 100644 --- a/app/src/main/res/values/strings_final.xml +++ b/app/src/main/res/values/strings_final.xml @@ -78,6 +78,7 @@ No Chat + Tangem Bot Card Settings diff --git a/app/src/main/res/values/zendesk_styles.xml b/app/src/main/res/values/zendesk_styles.xml index 0022b241b1..ebb4fcab6b 100644 --- a/app/src/main/res/values/zendesk_styles.xml +++ b/app/src/main/res/values/zendesk_styles.xml @@ -4,15 +4,4 @@ @color/darkGray6 @color/darkGray6 - - // Contact us FAB style - diff --git a/dependencies.gradle b/dependencies.gradle index b4a597ff72..cbd16111f5 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -1,12 +1,12 @@ ext.versions = [ - kotlin : '1.6.10', - build_gradle : '7.1.3', - tamgem_card_sdk : 'develop-156', - tamgem_blockchain_sdk: 'develop-96', + kotlin : '1.6.10', + build_gradle : '7.1.3', + tamgem_card_sdk : 'develop-157', + tamgem_blockchain_sdk: 'develop-99', ] ext.environmentConfig = [ environment : "ENVIRONMENT", testActionEnabled: "TEST_ACTION_ENABLED", logEnabled : "LOG_ENABLED", -] +] \ No newline at end of file diff --git a/domain/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt b/domain/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt index b69ffb1c49..8708f1a0a8 100644 --- a/domain/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt +++ b/domain/src/main/java/com/tangem/domain/common/extensions/Blockchain.kt @@ -37,6 +37,7 @@ fun Blockchain.Companion.fromNetworkId(networkId: String): Blockchain? { "tron" -> Blockchain.Tron "tron/test" -> Blockchain.TronTestnet "xrp", "ripple" -> Blockchain.XRP + "xdai" -> Blockchain.Gnosis else -> null } } @@ -78,6 +79,7 @@ fun Blockchain.toNetworkId(): String { Blockchain.XRP -> "xrp" Blockchain.Tron -> "tron" Blockchain.TronTestnet -> "tron/test" + Blockchain.Gnosis -> "xdai" } } @@ -102,6 +104,7 @@ fun Blockchain.toCoinId(): String { Blockchain.XRP -> "ripple" Blockchain.Dogecoin -> "dogecoin" Blockchain.Tron, Blockchain.TronTestnet -> "tron" - else -> "unknown" + Blockchain.Gnosis -> "xdai" + Blockchain.Unknown -> "unknown" } } \ No newline at end of file