Updated on 2026-08-14

This commit is contained in:
Tangem 2025-06-09 12:42:30 +03:00
parent 904d4bb006
commit b352bb6235
39 changed files with 353 additions and 5 deletions

View file

@ -32,6 +32,7 @@ dependencies {
/* Project - Domain */
implementation(projects.domain.models)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
implementation(projects.domain.wallets)
implementation(projects.domain.wallets.models)
implementation(projects.domain.card)
@ -52,6 +53,7 @@ dependencies {
/* AndroidX */
implementation(deps.androidx.activity.compose)
implementation(deps.androidx.appCompat)
implementation(deps.lifecycle.compose)
/* Compose */

View file

@ -28,6 +28,7 @@ dependencies {
implementation(projects.domain.card)
implementation(projects.domain.demo)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
implementation(projects.domain.manageTokens)
implementation(projects.domain.markets)
implementation(projects.domain.onramp.models)

View file

@ -36,6 +36,7 @@ dependencies {
/** Domain */
implementation(projects.domain.models)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
implementation(projects.domain.core)
implementation(projects.domain.card)
implementation(projects.domain.wallets)

View file

@ -54,6 +54,7 @@ dependencies {
implementation(projects.domain.qrScanning)
implementation(projects.domain.settings)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
implementation(projects.domain.txhistory)
implementation(projects.domain.balanceHiding.models)
implementation(projects.domain.balanceHiding)

View file

@ -0,0 +1,95 @@
plugins {
alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.kapt)
alias(deps.plugins.hilt.android)
id("configuration")
}
android {
namespace = "com.tangem.features.send.impl"
}
dependencies {
/** AndroidX */
implementation(deps.androidx.fragment.ktx)
implementation(deps.androidx.appCompat)
implementation(deps.androidx.paging.runtime)
/** Other dependencies */
implementation(deps.kotlin.immutable.collections)
implementation(deps.material)
implementation(deps.arrow.core)
implementation(deps.lifecycle.compose)
implementation(deps.jodatime)
implementation(deps.timber)
implementation(deps.reKotlin)
implementation(deps.kotlin.serialization)
/** Compose */
implementation(deps.compose.accompanist.systemUiController)
implementation(deps.compose.material3)
implementation(deps.compose.material)
implementation(deps.compose.foundation)
implementation(deps.compose.ui)
implementation(deps.compose.ui.tooling)
implementation(deps.compose.navigation)
implementation(deps.compose.navigation.hilt)
implementation(deps.compose.paging)
implementation(deps.compose.constraintLayout)
/** Tangem SDKs */
implementation(tangemDeps.card.core)
implementation(tangemDeps.blockchain)
/** Core modules */
implementation(projects.core.configToggles)
implementation(projects.core.ui)
implementation(projects.core.utils)
implementation(projects.core.navigation)
implementation(projects.core.analytics)
implementation(projects.core.analytics.models)
implementation(projects.core.datasource)
implementation(projects.core.decompose)
/** Common */
implementation(projects.common.ui)
implementation(projects.common.routing)
/** Libs */
implementation(projects.libs.crypto)
/** Domain modules */
implementation(projects.domain.models)
implementation(projects.domain.legacy)
implementation(projects.libs.blockchainSdk)
implementation(projects.domain.tokens)
implementation(projects.domain.tokens.models)
implementation(projects.domain.wallets)
implementation(projects.domain.wallets.models)
implementation(projects.domain.appCurrency)
implementation(projects.domain.appCurrency.models)
implementation(projects.domain.txhistory)
implementation(projects.domain.txhistory.models)
implementation(projects.domain.transaction)
implementation(projects.domain.transaction.models)
implementation(projects.domain.card)
implementation(projects.domain.balanceHiding)
implementation(projects.domain.balanceHiding.models)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
implementation(projects.domain.qrScanning)
implementation(projects.domain.qrScanning.models)
implementation(projects.domain.settings)
implementation(projects.domain.notifications)
/** Feature modules */
implementation(projects.features.send.api)
implementation(projects.features.tokendetails.api)
implementation(projects.features.txhistory.api)
implementation(projects.features.qrScanning.api)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
}

View file

@ -65,6 +65,7 @@ dependencies {
implementation(projects.domain.transaction.models)
implementation(projects.domain.txhistory)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
/** Common */
implementation(projects.common.ui)

View file

@ -38,6 +38,7 @@ dependencies {
implementation(projects.domain.settings)
implementation(projects.domain.staking)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
implementation(projects.domain.promo)
implementation(projects.domain.promo.models)
implementation(projects.domain.txhistory)

1
features/usedesk/api/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,17 @@
plugins {
alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android)
id("configuration")
}
android {
namespace = "com.tangem.feature.usedesk.api"
}
dependencies {
/** Core */
implementation(projects.core.decompose)
implementation(projects.core.ui)
}

View file

@ -0,0 +1,13 @@
package com.tangem.feature.usedesk.api
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
interface UsedeskComponent : ComposableContentComponent {
data class Params(
val feedback: String? = null, // TODO [REDACTED_TASK_KEY]
)
interface Factory : ComponentFactory<Params, UsedeskComponent>
}

1
features/usedesk/impl/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,36 @@
plugins {
alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.kapt)
alias(deps.plugins.hilt.android)
id("configuration")
}
android {
namespace = "com.tangem.feature.usedesk.impl"
}
dependencies {
/** Core */
implementation(projects.core.ui)
implementation(projects.core.decompose)
implementation(projects.core.utils)
implementation(projects.core.navigation)
implementation(projects.common.routing)
implementation(projects.features.usedesk.api)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
/** Compose */
implementation(deps.compose.foundation)
implementation(deps.compose.ui)
/** Usedesk */
implementation(deps.usedesk.chat.sdk)
implementation(deps.usedesk.chat.gui)
}

View file

@ -0,0 +1,60 @@
package com.tangem.feature.usedesk
import android.view.View
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentContainerView
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.feature.usedesk.api.UsedeskComponent
import com.tangem.feature.usedesk.model.UsedeskModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import ru.usedesk.chat_gui.chat.UsedeskChatScreen
internal class DefaultUsedeskComponent @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted params: UsedeskComponent.Params,
) : UsedeskComponent, AppComponentContext by appComponentContext {
private val model: UsedeskModel = getOrCreateModel(params)
@Composable
override fun Content(modifier: Modifier) {
val state by model.state.collectAsStateWithLifecycle()
Box(
modifier = Modifier
.fillMaxSize()
.systemBarsPadding()
.imePadding(),
) {
AndroidView(
factory = { context ->
FragmentContainerView(context).apply {
id = View.generateViewId()
val fragment = UsedeskChatScreen.newInstance(
state.usedeskChatConfiguration,
)
(context as FragmentActivity).supportFragmentManager.beginTransaction()
.replace(id, fragment)
.commit()
}
},
modifier = Modifier.fillMaxSize(),
)
}
}
@AssistedFactory
interface Factory : UsedeskComponent.Factory {
override fun create(context: AppComponentContext, params: UsedeskComponent.Params): DefaultUsedeskComponent
}
}

View file

@ -0,0 +1,25 @@
package com.tangem.feature.usedesk.di
import com.tangem.core.decompose.model.Model
import com.tangem.feature.usedesk.DefaultUsedeskComponent
import com.tangem.feature.usedesk.api.UsedeskComponent
import com.tangem.feature.usedesk.model.UsedeskModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(SingletonComponent::class)
internal interface UsedeskFeatureModule {
@Binds
fun bindComponentFactory(impl: DefaultUsedeskComponent.Factory): UsedeskComponent.Factory
@Binds
@IntoMap
@ClassKey(UsedeskModel::class)
fun bindModel(model: UsedeskModel): Model
}

View file

@ -0,0 +1,35 @@
package com.tangem.feature.usedesk.model
import androidx.compose.runtime.Stable
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import ru.usedesk.chat_sdk.entity.UsedeskChatConfiguration
import javax.inject.Inject
@Stable
@ModelScoped
internal class UsedeskModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
private val _state = MutableStateFlow(getInitialState())
val state: StateFlow<UsedeskState> = _state
private fun getInitialState(): UsedeskState {
return UsedeskState(
UsedeskChatConfiguration(
companyId = COMPANY_ID,
channelId = CHANNEL_ID,
),
)
}
private companion object {
const val COMPANY_ID = "170509"
const val CHANNEL_ID = "65637"
}
}

View file

@ -0,0 +1,9 @@
package com.tangem.feature.usedesk.model
import androidx.compose.runtime.Stable
import ru.usedesk.chat_sdk.entity.UsedeskChatConfiguration
@Stable
internal data class UsedeskState(
val usedeskChatConfiguration: UsedeskChatConfiguration,
)

View file

@ -74,6 +74,7 @@ dependencies {
implementation(projects.domain.card)
implementation(projects.domain.demo)
implementation(projects.domain.feedback)
implementation(projects.domain.feedback.models)
implementation(projects.domain.legacy)
implementation(projects.domain.markets.models)
implementation(projects.domain.models)