diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 570f9e96e3..e6e2daa7a3 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -9,14 +9,34 @@ plugins { id("configuration") } -//conflict of dependencies when adding WalletConnectV2.0 library configurations { all { exclude(group = "org.bouncycastle", module = "bcprov-jdk15to18") - resolutionStrategy { - force("org.bouncycastle:bcpkix-jdk15on:1.70") - } exclude(group = "com.github.komputing.kethereum") + + resolutionStrategy { + dependencySubstitution { + substitute(module("com.facebook.react:react-native")) + .using(module("com.facebook.react:react-android:0.72.4")) + .because( + "The current version of SPR Client (3.6.2) is not compatible with the latest " + + "React Native version" + ) + + substitute(module("com.facebook.react:hermes-engine")) + .using(module("com.facebook.react:hermes-android:0.72.4")) + .because( + "The current version of SPR Client (3.6.2) is not compatible with the latest " + + "Hermes Engine version" + ) + } + + force( + "org.bouncycastle:bcpkix-jdk15on:1.70", + "com.facebook.react:react-android:0.72.4", + "com.facebook.react:hermes-android:0.72.4", + ) + } } } @@ -159,6 +179,9 @@ dependencies { implementation(deps.walletConnectCore) implementation(deps.walletConnectWeb3) implementation(deps.prettyLogger) + implementation(deps.sprClient) { + exclude(group = "com.github.stephenc.jcip") + } /** Testing libraries */ testImplementation(deps.test.junit) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 53d4be3c7f..c1b1d65718 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -12,6 +12,16 @@ + + + + + @@ -39,7 +49,7 @@ android:extractNativeLibs="true" android:supportsRtl="true" tools:ignore="GoogleAppIndexingWarning" - tools:replace="android:allowBackup, android:fullBackupContent"> + tools:replace="android:allowBackup, android:fullBackupContent, android:label"> - - diff --git a/app/src/main/java/com/tangem/tap/TapApplication.kt b/app/src/main/java/com/tangem/tap/TapApplication.kt index cfd38560ca..8c4091a21f 100644 --- a/app/src/main/java/com/tangem/tap/TapApplication.kt +++ b/app/src/main/java/com/tangem/tap/TapApplication.kt @@ -336,7 +336,7 @@ class TapApplication : Application(), ImageLoaderFactory { val feedbackManager = FeedbackManager( infoHolder = additionalFeedbackInfo, logCollector = tangemLogCollector, - chatManager = ChatManager(preferencesStorage, foregroundActivityObserver, store), + chatManager = ChatManager(preferencesStorage, foregroundActivityObserver), ) store.dispatch(GlobalAction.SetFeedbackManager(feedbackManager)) } diff --git a/app/src/main/java/com/tangem/tap/common/chat/ChatManager.kt b/app/src/main/java/com/tangem/tap/common/chat/ChatManager.kt index 56ded693ad..693113b27a 100644 --- a/app/src/main/java/com/tangem/tap/common/chat/ChatManager.kt +++ b/app/src/main/java/com/tangem/tap/common/chat/ChatManager.kt @@ -2,37 +2,31 @@ package com.tangem.tap.common.chat import android.content.Context import android.os.Build +import com.tangem.data.source.preferences.PreferencesDataSource import com.tangem.datasource.config.models.ChatConfig import com.tangem.datasource.config.models.SprinklrConfig import com.tangem.datasource.config.models.ZendeskConfig -import com.tangem.data.source.preferences.PreferencesDataSource import com.tangem.tap.ForegroundActivityObserver import com.tangem.tap.common.chat.opener.ChatOpener import com.tangem.tap.common.chat.opener.implementation.SprinklrChatOpener import com.tangem.tap.common.chat.opener.implementation.ZendeskChatOpener -import com.tangem.tap.common.redux.AppState -import org.rekotlin.Store import java.io.File class ChatManager( private val preferencesStorage: PreferencesDataSource, private val foregroundActivityObserver: ForegroundActivityObserver, - private val store: Store, ) { private val openers = mutableMapOf() fun open(config: ChatConfig, createLogsFile: (Context) -> File?, createFeedbackFile: (Context) -> File?) { val opener = openers.getOrPut(config) { when (config) { - is SprinklrConfig -> SprinklrChatOpener(getSprinklrUserId(), config, store, foregroundActivityObserver) + is SprinklrConfig -> SprinklrChatOpener(config, foregroundActivityObserver) is ZendeskConfig -> ZendeskChatOpener(getZendeskUserId(), config, foregroundActivityObserver) } } - opener.open( - createFeedbackFile = createFeedbackFile, - createLogsFile = createLogsFile, - ) + opener.open(createFeedbackFile, createLogsFile) } private fun getZendeskUserId(): String { @@ -40,18 +34,6 @@ class ChatManager( preferencesStorage.zendeskFirstLaunchTime = System.currentTimeMillis() } - return getChatUserId(preferencesStorage.zendeskFirstLaunchTime!!) - } - - private fun getSprinklrUserId(): String { - if (preferencesStorage.sprinklrFirstLaunchTime == null) { - preferencesStorage.sprinklrFirstLaunchTime = System.currentTimeMillis() - } - - return getChatUserId(preferencesStorage.sprinklrFirstLaunchTime!!) - } - - private fun getChatUserId(firstLaunchTimeMillis: Long): String { - return "${firstLaunchTimeMillis}${Build.MODEL}".hashCode().toString() + return "${preferencesStorage.zendeskFirstLaunchTime}${Build.MODEL}".hashCode().toString() } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/SprinklrChatOpener.kt b/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/SprinklrChatOpener.kt index f8936d6abd..0fcb2a4cf2 100644 --- a/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/SprinklrChatOpener.kt +++ b/app/src/main/java/com/tangem/tap/common/chat/opener/implementation/SprinklrChatOpener.kt @@ -1,28 +1,57 @@ package com.tangem.tap.common.chat.opener.implementation +import android.annotation.SuppressLint +import android.app.Application import android.content.Context -import android.content.Intent +import android.provider.Settings +import com.spr.messengerclient.config.SPRMessenger +import com.spr.messengerclient.config.bean.SPRMessengerConfig +import com.tangem.common.extensions.guard import com.tangem.datasource.config.models.SprinklrConfig import com.tangem.tap.ForegroundActivityObserver import com.tangem.tap.common.chat.opener.ChatOpener -import com.tangem.tap.common.redux.AppState -import com.tangem.tap.features.sprinklr.redux.SprinklrAction -import com.tangem.tap.features.sprinklr.ui.SprinklrActivity -import com.tangem.tap.withForegroundActivity -import org.rekotlin.Store +import timber.log.Timber import java.io.File +import java.util.Locale internal class SprinklrChatOpener( - private val userId: String, private val config: SprinklrConfig, - private val store: Store, private val foregroundActivityObserver: ForegroundActivityObserver, ) : ChatOpener { + override fun open(createFeedbackFile: (Context) -> File?, createLogsFile: (Context) -> File?) { - store.dispatch(SprinklrAction.Init(userId, config)) - foregroundActivityObserver.withForegroundActivity { activity -> - val intent = Intent(activity, SprinklrActivity::class.java) - activity.startActivity(intent) + val messenger = SPRMessenger.shared() + + if (messenger.config == null) { + initSprConfig(messenger) + } + + messenger.startApplication() + } + + private fun initSprConfig(messenger: SPRMessenger) { + val application = foregroundActivityObserver.foregroundActivity?.application.guard { + Timber.e("The SPR chat cannot be opened because there are no activities in foreground") + return + } + + messenger.takeOff(application, createSprConfig(application, config)) + } + + @SuppressLint("HardwareIds") + private fun createSprConfig(application: Application, config: SprinklrConfig): SPRMessengerConfig { + return SPRMessengerConfig().apply { + appId = config.appId + appKey = CHAT_APP_KEY + deviceId = Settings.Secure.getString(application.contentResolver, Settings.Secure.ANDROID_ID) + environment = config.environment + skin = CHAT_SKIN + locale = Locale.getDefault().language } } + + private companion object { + const val CHAT_APP_KEY = "com.sprinklr.messenger.release" + const val CHAT_SKIN = "MODERN" + } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt index 7210599e41..8175888c08 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppReducer.kt @@ -14,7 +14,6 @@ import com.tangem.tap.features.saveWallet.redux.SaveWalletReducer import com.tangem.tap.features.send.redux.reducers.SendScreenReducer import com.tangem.tap.features.shop.redux.ShopReducer import com.tangem.tap.features.signin.redux.SignInReducer -import com.tangem.tap.features.sprinklr.redux.SprinklrReducer import com.tangem.tap.features.tokens.legacy.redux.TokensReducer import com.tangem.tap.features.wallet.redux.reducers.WalletReducer import com.tangem.tap.features.walletSelector.redux.WalletSelectorReducer @@ -45,7 +44,6 @@ fun appReducer(action: Action, state: AppState?, appStateHolder: AppStateHolder) welcomeState = WelcomeReducer.reduce(action, state), saveWalletState = SaveWalletReducer.reduce(action, state), walletSelectorState = WalletSelectorReducer.reduce(action, state), - sprinklrState = SprinklrReducer.reduce(action, state), signInState = SignInReducer.reduce(action, state), daggerGraphState = DaggerGraphReducer.reduce(action, state), ) diff --git a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt index 71be2aa020..19248b08b9 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/AppState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/AppState.kt @@ -32,8 +32,6 @@ import com.tangem.tap.features.shop.redux.ShopMiddleware import com.tangem.tap.features.shop.redux.ShopState import com.tangem.tap.features.signin.redux.SignInMiddleware import com.tangem.tap.features.signin.redux.SignInState -import com.tangem.tap.features.sprinklr.redux.SprinklrMiddleware -import com.tangem.tap.features.sprinklr.redux.SprinklrState import com.tangem.tap.features.tokens.legacy.redux.TokensMiddleware import com.tangem.tap.features.tokens.legacy.redux.TokensState import com.tangem.tap.features.wallet.redux.WalletState @@ -66,7 +64,6 @@ data class AppState( val welcomeState: WelcomeState = WelcomeState(), val saveWalletState: SaveWalletState = SaveWalletState(), val walletSelectorState: WalletSelectorState = WalletSelectorState(), - val sprinklrState: SprinklrState = SprinklrState(), val signInState: SignInState = SignInState(), val daggerGraphState: DaggerGraphState = DaggerGraphState(), ) : StateType { @@ -108,7 +105,6 @@ data class AppState( WalletSelectorMiddleware().middleware, LockUserWalletsTimerMiddleware().middleware, AccessCodeRequestPolicyMiddleware().middleware, - SprinklrMiddleware().middleware, SignInMiddleware.middleware, DaggerGraphMiddleware.daggerGraphMiddleware, ) diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt index 287b5d35f1..176841c442 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalMiddleware.kt @@ -100,10 +100,10 @@ private fun handleAction(action: Action, appState: () -> AppState?, dispatch: Di } // if config not set -> try to get it based on a scanResponse.productType - val unsafeChatConfig = action.chatConfig ?: config.zendesk + val unsafeChatConfig = action.chatConfig ?: config.sprinklr val chatConfig = unsafeChatConfig.guard { - store.dispatchDebugErrorNotification("ZendeskConfig not initialized") + store.dispatchDebugErrorNotification("The chat config is not initialized") return } feedbackManager.openChat(chatConfig, action.feedbackData) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt index baf5ed2fcf..68a4bb6df8 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt @@ -52,7 +52,9 @@ object OnboardingHelper { fun whereToNavigate(scanResponse: ScanResponse): AppScreen { return when (scanResponse.productType) { ProductType.Note -> AppScreen.OnboardingNote - ProductType.Wallet -> if (scanResponse.card.settings.isBackupAllowed) { + ProductType.Wallet, + ProductType.Wallet2, + -> if (scanResponse.card.settings.isBackupAllowed) { AppScreen.OnboardingWallet } else { AppScreen.OnboardingOther diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrAction.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrAction.kt deleted file mode 100644 index b781ee102f..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrAction.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.tap.features.sprinklr.redux - -import com.tangem.datasource.config.models.SprinklrConfig -import org.rekotlin.Action - -sealed interface SprinklrAction : Action { - data class Init(val userId: String, val config: SprinklrConfig) : SprinklrAction - data class UpdateUrl(val url: String) : SprinklrAction - data class UpdateSprinklrDomains(val domains: List) : SprinklrAction -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrMiddleware.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrMiddleware.kt deleted file mode 100644 index 922e3a2e67..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrMiddleware.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.tangem.tap.features.sprinklr.redux - -import com.tangem.datasource.config.models.SprinklrConfig -import com.tangem.tap.common.extensions.dispatchOnMain -import com.tangem.tap.common.redux.AppState -import com.tangem.tap.features.sprinklr.redux.model.SprinklrUrl -import com.tangem.tap.store -import org.rekotlin.Middleware - -internal class SprinklrMiddleware { - val middleware: Middleware = { _, appStateProvider -> - { next -> - { action -> - val appState = appStateProvider() - if (action is SprinklrAction && appState != null) { - handleAction(action) - } - next(action) - } - } - } - - private fun handleAction(action: SprinklrAction) { - when (action) { - is SprinklrAction.Init -> updateUrl(action.userId, action.config) - is SprinklrAction.UpdateUrl, - is SprinklrAction.UpdateSprinklrDomains, - -> Unit - } - } - - private fun updateUrl(userId: String, config: SprinklrConfig) { - updateSprinklrDomains(config.baseUrl) - val url = SprinklrUrl.Prod(userId, config.baseUrl, config.appId).url - store.dispatchOnMain(SprinklrAction.UpdateUrl(url)) - } - - private fun updateSprinklrDomains(baseUrl: String) { - val domains = listOf(baseUrl, SprinklrUrl.Static.url) - store.dispatchOnMain(SprinklrAction.UpdateSprinklrDomains(domains)) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrReducer.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrReducer.kt deleted file mode 100644 index a27d16d2db..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrReducer.kt +++ /dev/null @@ -1,22 +0,0 @@ -package com.tangem.tap.features.sprinklr.redux - -import com.tangem.tap.common.redux.AppState -import org.rekotlin.Action - -internal object SprinklrReducer { - fun reduce(action: Action, state: AppState): SprinklrState { - return if (action is SprinklrAction) { - internalReduce(action, state.sprinklrState) - } else { - state.sprinklrState - } - } - - private fun internalReduce(action: SprinklrAction, state: SprinklrState): SprinklrState { - return when (action) { - is SprinklrAction.Init -> state - is SprinklrAction.UpdateUrl -> state.copy(url = action.url) - is SprinklrAction.UpdateSprinklrDomains -> state.copy(sprinklrDomains = action.domains) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrState.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrState.kt deleted file mode 100644 index 12ba5b8672..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/SprinklrState.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.tangem.tap.features.sprinklr.redux - -data class SprinklrState( - val url: String = "", - val sprinklrDomains: List = emptyList(), -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/model/SprinklrUrl.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/redux/model/SprinklrUrl.kt deleted file mode 100644 index 2d1eb1be87..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/redux/model/SprinklrUrl.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.tangem.tap.features.sprinklr.redux.model - -internal sealed class SprinklrUrl { - abstract val url: String - - class Prod(userId: String, baseUrl: String, appId: String) : SprinklrUrl() { - private val locale = java.util.Locale.getDefault().language - - override val url: String = "$baseUrl/page" + - "?appId=$appId" + - "&device=$Device" + - "&enableClose=$CloseEnabled" + - "&zoom=$ZoomEnabled" + - "&locale=$locale" + - "&user_id=$userId" - - companion object { - private const val Device = "MOBILE" - private const val CloseEnabled = true - private const val ZoomEnabled = false - } - } - - object Static : SprinklrUrl() { - override val url: String = "live-chat-static.sprinklr.com" - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrActivity.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrActivity.kt deleted file mode 100644 index 7ddbf49c68..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrActivity.kt +++ /dev/null @@ -1,54 +0,0 @@ -package com.tangem.tap.features.sprinklr.ui - -import android.os.Bundle -import androidx.activity.compose.BackHandler -import androidx.activity.viewModels -import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.systemBarsPadding -import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.tangem.core.analytics.Analytics -import com.tangem.core.ui.components.SystemBarsEffect -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.screen.ComposeActivity -import com.tangem.core.ui.theme.AppThemeModeHolder -import com.tangem.tap.common.analytics.events.Chat -import dagger.hilt.android.AndroidEntryPoint -import javax.inject.Inject - -@AndroidEntryPoint -internal class SprinklrActivity : ComposeActivity() { - - @Inject - override lateinit var appThemeModeHolder: AppThemeModeHolder - - private val viewModel by viewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - Analytics.send(Chat.ScreenOpened()) - viewModel.setNavigateBackCallback { - this.finish() - } - } - - @Composable - override fun ScreenContent(modifier: Modifier) { - val state by viewModel.state.collectAsStateWithLifecycle() - - val systemBarsColor = TangemTheme.colors.background.primary - SystemBarsEffect { - setSystemBarsColor(systemBarsColor) - } - - BackHandler(onBack = state.onNavigateBack) - SprinklrScreenContent( - modifier = modifier - .systemBarsPadding() - .imePadding(), - state = state, - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrScreenContent.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrScreenContent.kt deleted file mode 100644 index 5277ba0cea..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrScreenContent.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.tangem.tap.features.sprinklr.ui - -import android.annotation.SuppressLint -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import com.google.accompanist.web.WebView -import com.google.accompanist.web.rememberWebViewState -import com.tangem.tap.features.sprinklr.ui.webview.SprinklrWebViewClient - -@SuppressLint("SetJavaScriptEnabled") -@Composable -internal fun SprinklrScreenContent(state: SprinklrScreenState, modifier: Modifier = Modifier) { - WebView( - modifier = modifier, - state = rememberWebViewState(url = state.initialUrl), - onCreated = { webView -> - with(webView.settings) { - javaScriptEnabled = true - domStorageEnabled = true - } - }, - client = remember { SprinklrWebViewClient(state.onNewUrl) }, - ) -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrScreenState.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrScreenState.kt deleted file mode 100644 index 8757f6e167..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrScreenState.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.tap.features.sprinklr.ui - -import com.google.accompanist.web.WebContent - -internal data class SprinklrScreenState( - val initialUrl: String = "", - val sprinklrDomains: List = emptyList(), - val onNavigateBack: () -> Unit = {}, - val onNewUrl: WebContent.(String) -> WebContent = { this }, -) \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrViewModel.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrViewModel.kt deleted file mode 100644 index a6cf3abe13..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/SprinklrViewModel.kt +++ /dev/null @@ -1,66 +0,0 @@ -package com.tangem.tap.features.sprinklr.ui - -import androidx.lifecycle.ViewModel -import com.google.accompanist.web.WebContent -import com.tangem.core.navigation.NavigationAction -import com.tangem.tap.common.extensions.dispatchOnMain -import com.tangem.tap.features.sprinklr.redux.SprinklrState -import com.tangem.tap.store -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.update -import org.rekotlin.StoreSubscriber - -internal class SprinklrViewModel : ViewModel(), StoreSubscriber { - private val stateInternal = MutableStateFlow(SprinklrScreenState()) - val state = stateInternal.asStateFlow() - - init { - subscribeToStoreChanges() - } - - override fun newState(state: SprinklrState) { - stateInternal.update { prevState -> - prevState.copy( - initialUrl = state.url, - sprinklrDomains = state.sprinklrDomains, - onNewUrl = { updateWebContentOrOpenExternalUrl(it) }, - ) - } - } - - override fun onCleared() { - store.unsubscribe(this) - } - - fun setNavigateBackCallback(callback: () -> Unit) { - stateInternal.update { prevState -> - prevState.copy( - onNavigateBack = callback, - ) - } - } - - private fun subscribeToStoreChanges() { - store.subscribe(this) { appState -> - appState.skip { old, new -> old.sprinklrState == new.sprinklrState } - .select { it.sprinklrState } - } - } - - private fun WebContent.updateWebContentOrOpenExternalUrl(url: String): WebContent { - return if (isExternalUrl(url)) { - store.dispatchOnMain(NavigationAction.OpenUrl(url)) - this - } else { - when (this) { - is WebContent.Url -> copy(url = url) - else -> WebContent.Url(url) - } - } - } - - private fun isExternalUrl(url: String): Boolean { - return state.value.sprinklrDomains.none { url.contains(it) } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/webview/SprinklrWebViewClient.kt b/app/src/main/java/com/tangem/tap/features/sprinklr/ui/webview/SprinklrWebViewClient.kt deleted file mode 100644 index 2f2487c88a..0000000000 --- a/app/src/main/java/com/tangem/tap/features/sprinklr/ui/webview/SprinklrWebViewClient.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.tangem.tap.features.sprinklr.ui.webview - -import android.webkit.WebResourceRequest -import android.webkit.WebView -import com.google.accompanist.web.AccompanistWebViewClient -import com.google.accompanist.web.WebContent - -internal class SprinklrWebViewClient( - private val onNewUrl: WebContent.(String) -> WebContent, -) : AccompanistWebViewClient() { - - override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean { - // If the url hasn't changed, this is probably an internal event like - // a javascript reload. We should let it happen. - if (view?.url == request?.url.toString()) { - return false - } - - request?.let { - state.content = onNewUrl(state.content, it.url.toString()) - } - return true - } -} \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt index 493d6b2e9e..2a1e34d105 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/ConfigManagerImpl.kt @@ -103,6 +103,7 @@ internal class ConfigManagerImpl @Inject constructor() : ConfigManager { amplitudeApiKey = configValues.amplitudeApiKey, shopify = configValues.shopifyShop, zendesk = configValues.zendesk, + sprinklr = configValues.sprinklr, swapReferrerAccount = configValues.swapReferrerAccount, walletConnectProjectId = configValues.walletConnectProjectId, tangemComAuthorization = configValues.tangemComAuthorization, diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/models/ChatConfig.kt b/core/datasource/src/main/java/com/tangem/datasource/config/models/ChatConfig.kt index d34275da0f..2ab45d66bc 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/models/ChatConfig.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/models/ChatConfig.kt @@ -23,6 +23,8 @@ data class ZendeskConfig( data class SprinklrConfig( @Json(name = "appID") val appId: String, - @Json(name = "baseURL") - val baseUrl: String, + @Json(name = "apiKey") + val apiKey: String, + @Json(name = "environment") + val environment: String, ) : ChatConfig \ No newline at end of file diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt b/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt index 3d0bf5be7f..f8fe099745 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/models/Config.kt @@ -16,6 +16,7 @@ data class Config( val isCreatingTwinCardsAllowed: Boolean = false, val shopify: ShopifyShop? = null, val zendesk: ZendeskConfig? = null, + val sprinklr: SprinklrConfig? = null, val swapReferrerAccount: SwapReferrerAccount? = null, val walletConnectProjectId: String = "", val tangemComAuthorization: String? = null, diff --git a/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt b/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt index 83ffe5d09a..93210485ef 100644 --- a/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt +++ b/core/datasource/src/main/java/com/tangem/datasource/config/models/JsonModels.kt @@ -32,6 +32,7 @@ class ConfigValueModel( val appsFlyer: AppsFlyer, val shopifyShop: ShopifyShop?, val zendesk: ZendeskConfig?, + val sprinklr: SprinklrConfig?, val tronGridApiKey: String, val amplitudeApiKey: String, val swapReferrerAccount: SwapReferrerAccount?, diff --git a/data/card/src/main/java/com/tangem/data/card/DefaultCardSdkConfigRepository.kt b/data/card/src/main/java/com/tangem/data/card/DefaultCardSdkConfigRepository.kt index 321a48b0bf..4e3b7acdef 100644 --- a/data/card/src/main/java/com/tangem/data/card/DefaultCardSdkConfigRepository.kt +++ b/data/card/src/main/java/com/tangem/data/card/DefaultCardSdkConfigRepository.kt @@ -49,6 +49,7 @@ internal class DefaultCardSdkConfigRepository( ProductType.Twins -> CardIdDisplayFormat.LastLuhn(numbers = 4) ProductType.Note, ProductType.Wallet, + ProductType.Wallet2, ProductType.Start2Coin, -> CardIdDisplayFormat.Full } diff --git a/domain/legacy/src/main/java/com/tangem/domain/userwallets/UserWalletBuilder.kt b/domain/legacy/src/main/java/com/tangem/domain/userwallets/UserWalletBuilder.kt index 565930ae9d..b843a98ee2 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/userwallets/UserWalletBuilder.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/userwallets/UserWalletBuilder.kt @@ -20,7 +20,9 @@ class UserWalletBuilder( ProductType.Note -> "Note" ProductType.Twins -> "Twin" ProductType.Start2Coin -> "Start2Coin" - ProductType.Wallet -> when { + ProductType.Wallet, + ProductType.Wallet2, + -> when { card.isBackupNotAllowed -> "Tangem card" cardTypesResolver.isStart2Coin() -> "Start2Coin" else -> "Wallet" diff --git a/domain/legacy/src/main/java/com/tangem/domain/userwallets/UserWalletIdBuilder.kt b/domain/legacy/src/main/java/com/tangem/domain/userwallets/UserWalletIdBuilder.kt index cad0957152..40ac39de3c 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/userwallets/UserWalletIdBuilder.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/userwallets/UserWalletIdBuilder.kt @@ -60,6 +60,7 @@ class UserWalletIdBuilder private constructor( ProductType.Twins -> scanResponse.secondTwinPublicKey?.hexToBytes() ProductType.Note, ProductType.Wallet, + ProductType.Wallet2, ProductType.Start2Coin, -> null }, diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index d4c76f2594..a239eb22ab 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -78,6 +78,7 @@ walletConnectCore = "1.18.0" walletConnectWeb3 = "1.11.0" prettyLogger = "2.2.0" okHttp-prettyLogging = "3.1.0" +spr-client = "3.6.2" # endregion Other libraries # region Tangem @@ -227,4 +228,5 @@ reactive-network = { module = "com.github.pwittchen:reactivenetwork-rx2", versio walletConnectCore = { module = "com.walletconnect:android-core", version.ref = "walletConnectCore" } walletConnectWeb3 = { module = "com.walletconnect:web3wallet", version.ref = "walletConnectWeb3" } prettyLogger = { module = "com.orhanobut:logger", version.ref = "prettyLogger" } +sprClient = { module = "com.spr:messengerclient", version.ref = "spr-client" } # endregion Other diff --git a/settings.gradle.kts b/settings.gradle.kts index b2c3126321..7e4c66d7d8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,6 +40,7 @@ dependencyResolutionManagement { } maven("https://jitpack.io") maven("https://zendesk.jfrog.io/zendesk/repo") + maven("https://clients-nexus.sprinklr.com/") } versionCatalogs {