Updated on 2026-08-14
This commit is contained in:
commit
39d212a493
12 changed files with 89 additions and 73 deletions
|
|
@ -138,9 +138,12 @@
|
|||
|
||||
<activity android:name="com.tangem.tap.common.qrCodeScan.ScanQrCodeActivity" />
|
||||
|
||||
<activity android:name="zendesk.messaging.MessagingActivity"
|
||||
<activity
|
||||
android:name="zendesk.messaging.MessagingActivity"
|
||||
android:theme="@style/ZendeskTheme" />
|
||||
|
||||
<activity android:name="com.tangem.tap.features.sprinklr.ui.SprinklrActivity" />
|
||||
|
||||
<provider
|
||||
android:name="androidx.core.content.FileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class ChatManager(
|
|||
fun open(config: ChatConfig, feedbackDataBuilder: (Context) -> String) {
|
||||
val opener = openers.getOrPut(config) {
|
||||
when (config) {
|
||||
is SprinklrConfig -> SprinklrChatOpener(getSprinklrUserId(), config, store)
|
||||
is SprinklrConfig -> SprinklrChatOpener(getSprinklrUserId(), config, store, foregroundActivityObserver)
|
||||
is ZendeskConfig -> ZendeskChatOpener(getZendeskUserId(), config, foregroundActivityObserver)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +1,27 @@
|
|||
package com.tangem.tap.common.chat.opener.implementation
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.tangem.tap.ForegroundActivityObserver
|
||||
import com.tangem.tap.common.chat.SprinklrConfig
|
||||
import com.tangem.tap.common.chat.opener.ChatOpener
|
||||
import com.tangem.tap.common.extensions.dispatchOnMain
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
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
|
||||
|
||||
internal class SprinklrChatOpener(
|
||||
private val userId: String,
|
||||
private val config: SprinklrConfig,
|
||||
private val store: Store<AppState>,
|
||||
private val foregroundActivityObserver: ForegroundActivityObserver,
|
||||
) : ChatOpener {
|
||||
override fun open(feedbackDataBuilder: (Context) -> String) {
|
||||
store.dispatch(SprinklrAction.Init(userId, config))
|
||||
store.dispatchOnMain(NavigationAction.NavigateTo(AppScreen.Sprinklr))
|
||||
foregroundActivityObserver.withForegroundActivity { activity ->
|
||||
val intent = Intent(activity, SprinklrActivity::class.java)
|
||||
activity.startActivity(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,6 @@ import com.tangem.tap.features.onboarding.products.wallet.ui.OnboardingWalletFra
|
|||
import com.tangem.tap.features.saveWallet.ui.SaveWalletBottomSheetFragment
|
||||
import com.tangem.tap.features.send.ui.SendFragment
|
||||
import com.tangem.tap.features.shop.ui.ShopFragment
|
||||
import com.tangem.tap.features.sprinklr.ui.SprinklrFragment
|
||||
import com.tangem.tap.features.tokens.addCustomToken.AddCustomTokenFragment
|
||||
import com.tangem.tap.features.tokens.ui.AddTokensFragment
|
||||
import com.tangem.tap.features.wallet.ui.WalletDetailsFragment
|
||||
|
|
@ -121,6 +120,5 @@ private fun fragmentFactory(screen: AppScreen): Fragment {
|
|||
AppScreen.Welcome -> WelcomeFragment()
|
||||
AppScreen.SaveWallet -> SaveWalletBottomSheetFragment()
|
||||
AppScreen.WalletSelector -> WalletSelectorBottomSheetFragment()
|
||||
AppScreen.Sprinklr -> SprinklrFragment()
|
||||
}
|
||||
}
|
||||
|
|
@ -26,5 +26,4 @@ enum class AppScreen(
|
|||
Welcome,
|
||||
SaveWallet(isDialogFragment = true),
|
||||
WalletSelector(isDialogFragment = true),
|
||||
Sprinklr,
|
||||
}
|
||||
|
|
@ -6,8 +6,8 @@ internal sealed class SprinklrUrl {
|
|||
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" +
|
||||
override val url: String = "$baseUrl/page" +
|
||||
"?appId=$appId" +
|
||||
"&device=$Device" +
|
||||
"&enableClose=$CloseEnabled" +
|
||||
"&zoom=$ZoomEnabled" +
|
||||
|
|
|
|||
|
|
@ -2,23 +2,26 @@ 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.State
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.ui.fragments.ComposeFragment
|
||||
import com.tangem.core.ui.fragments.ComposeActivity
|
||||
import com.tangem.tap.common.analytics.events.Chat
|
||||
|
||||
internal class SprinklrFragment : ComposeFragment<SprinklrScreenState>() {
|
||||
internal class SprinklrActivity : ComposeActivity<SprinklrScreenState>() {
|
||||
private val viewModel by viewModels<SprinklrViewModel>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Analytics.send(Chat.ScreenOpened())
|
||||
viewModel.setNavigateBackCallback {
|
||||
this.finish()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -24,7 +24,6 @@ internal class SprinklrViewModel : ViewModel(), StoreSubscriber<SprinklrState> {
|
|||
prevState.copy(
|
||||
initialUrl = state.url,
|
||||
sprinklrDomains = state.sprinklrDomains,
|
||||
onNavigateBack = this::navigateBack,
|
||||
onNewUrl = { updateWebContentOrOpenExternalUrl(it) },
|
||||
)
|
||||
}
|
||||
|
|
@ -34,6 +33,14 @@ internal class SprinklrViewModel : ViewModel(), StoreSubscriber<SprinklrState> {
|
|||
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 }
|
||||
|
|
@ -41,10 +48,6 @@ internal class SprinklrViewModel : ViewModel(), StoreSubscriber<SprinklrState> {
|
|||
}
|
||||
}
|
||||
|
||||
private fun navigateBack() {
|
||||
store.dispatchOnMain(NavigationAction.PopBackTo())
|
||||
}
|
||||
|
||||
private fun WebContent.updateWebContentOrOpenExternalUrl(url: String): WebContent {
|
||||
return if (isExternalUrl(url)) {
|
||||
store.dispatchOnMain(NavigationAction.OpenUrl(url))
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.core.ui.fragments
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
||||
abstract class ComposeActivity<ScreenState> : AppCompatActivity(), ComposeScreen<ScreenState> {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(createComposeView(context = this))
|
||||
}
|
||||
}
|
||||
|
|
@ -10,8 +10,6 @@ import androidx.annotation.FloatRange
|
|||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
|
|
@ -20,7 +18,7 @@ import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
|||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
abstract class ComposeBottomSheetFragment<ScreenState> : BottomSheetDialogFragment() {
|
||||
abstract class ComposeBottomSheetFragment<ScreenState> : BottomSheetDialogFragment(), ComposeScreen<ScreenState> {
|
||||
open val initialBottomSheetState = BottomSheetBehavior.STATE_EXPANDED
|
||||
|
||||
@FloatRange(from = 0.0, to = 1.0)
|
||||
|
|
@ -47,7 +45,7 @@ abstract class ComposeBottomSheetFragment<ScreenState> : BottomSheetDialogFragme
|
|||
return dialog
|
||||
}
|
||||
|
||||
private fun createComposeView(context: Context): View {
|
||||
override fun createComposeView(context: Context): View {
|
||||
return ComposeView(context).apply {
|
||||
setContent {
|
||||
TangemTheme {
|
||||
|
|
@ -67,13 +65,4 @@ abstract class ComposeBottomSheetFragment<ScreenState> : BottomSheetDialogFragme
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
protected abstract fun provideState(): State<ScreenState>
|
||||
|
||||
@Composable
|
||||
protected abstract fun ScreenContent(
|
||||
modifier: Modifier,
|
||||
state: ScreenState,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,21 +1,12 @@
|
|||
package com.tangem.core.ui.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
abstract class ComposeFragment<ScreenState> : Fragment() {
|
||||
abstract class ComposeFragment<ScreenState> : Fragment(), ComposeScreen<ScreenState> {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
|
|
@ -23,35 +14,4 @@ abstract class ComposeFragment<ScreenState> : Fragment() {
|
|||
): View {
|
||||
return createComposeView(inflater.context)
|
||||
}
|
||||
|
||||
private fun createComposeView(context: Context): View {
|
||||
return ComposeView(context).apply {
|
||||
setContent {
|
||||
TangemTheme {
|
||||
val backgroundColor = TangemTheme.colors.background.primary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(
|
||||
color = backgroundColor,
|
||||
)
|
||||
}
|
||||
|
||||
ScreenContent(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(color = backgroundColor),
|
||||
state = provideState().value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
protected abstract fun provideState(): State<ScreenState>
|
||||
|
||||
@Composable
|
||||
protected abstract fun ScreenContent(
|
||||
modifier: Modifier,
|
||||
state: ScreenState,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package com.tangem.core.ui.fragments
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import com.tangem.core.ui.components.SystemBarsEffect
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
internal interface ComposeScreen<ScreenState> {
|
||||
fun createComposeView(context: Context): View {
|
||||
return ComposeView(context).apply {
|
||||
setContent {
|
||||
TangemTheme {
|
||||
val backgroundColor = TangemTheme.colors.background.primary
|
||||
SystemBarsEffect {
|
||||
setSystemBarsColor(
|
||||
color = backgroundColor,
|
||||
)
|
||||
}
|
||||
|
||||
ScreenContent(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(color = backgroundColor),
|
||||
state = provideState().value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun provideState(): State<ScreenState>
|
||||
|
||||
@Composable
|
||||
fun ScreenContent(
|
||||
modifier: Modifier,
|
||||
state: ScreenState,
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue