Updated on 2026-08-14
This commit is contained in:
parent
c55274f40f
commit
efcb0dea79
20 changed files with 477 additions and 17 deletions
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.feature.walletsettings.component
|
||||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
|
||||
interface NetworksAvailableForNotificationsComponent : ComposableBottomSheetComponent {
|
||||
|
||||
data class Params(
|
||||
val onDismiss: () -> Unit,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, NetworksAvailableForNotificationsComponent>
|
||||
}
|
||||
|
|
@ -37,6 +37,8 @@ dependencies {
|
|||
implementation(projects.domain.demo)
|
||||
implementation(projects.domain.nft)
|
||||
implementation(projects.domain.notifications.toggles)
|
||||
implementation(projects.domain.notifications.models)
|
||||
implementation(projects.domain.notifications)
|
||||
|
||||
/* AndroidX */
|
||||
implementation(deps.androidx.fragment.ktx)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.feature.walletsettings.component.impl
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.feature.walletsettings.component.NetworksAvailableForNotificationsComponent
|
||||
import com.tangem.feature.walletsettings.component.impl.model.NetworksAvailableForNotificationsModel
|
||||
import com.tangem.feature.walletsettings.ui.NetworksAvailableForNotificationsListBS
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class DefaultNetworksAvailableForNotificationsComponent @AssistedInject constructor(
|
||||
@Assisted context: AppComponentContext,
|
||||
@Assisted private val params: NetworksAvailableForNotificationsComponent.Params,
|
||||
) : NetworksAvailableForNotificationsComponent, AppComponentContext by context {
|
||||
|
||||
private val model: NetworksAvailableForNotificationsModel = getOrCreateModel(params)
|
||||
|
||||
override fun dismiss() {
|
||||
params.onDismiss()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun BottomSheet() {
|
||||
val state by model.state.collectAsStateWithLifecycle()
|
||||
|
||||
NetworksAvailableForNotificationsListBS(state = state, onBack = ::dismiss, onDismiss = ::dismiss)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : NetworksAvailableForNotificationsComponent.Factory {
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: NetworksAvailableForNotificationsComponent.Params,
|
||||
): DefaultNetworksAvailableForNotificationsComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -11,10 +11,13 @@ import com.arkivanov.decompose.router.slot.dismiss
|
|||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.context.childByContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.core.ui.decompose.ComposableDialogComponent
|
||||
import com.tangem.feature.walletsettings.component.NetworksAvailableForNotificationsComponent
|
||||
import com.tangem.feature.walletsettings.component.RenameWalletComponent
|
||||
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
|
||||
import com.tangem.feature.walletsettings.entity.DialogConfig
|
||||
import com.tangem.feature.walletsettings.entity.NetworksAvailableForNotificationBSConfig
|
||||
import com.tangem.feature.walletsettings.model.WalletSettingsModel
|
||||
import com.tangem.feature.walletsettings.ui.WalletSettingsScreen
|
||||
import dagger.assisted.Assisted
|
||||
|
|
@ -25,14 +28,24 @@ internal class DefaultWalletSettingsComponent @AssistedInject constructor(
|
|||
@Assisted context: AppComponentContext,
|
||||
@Assisted params: WalletSettingsComponent.Params,
|
||||
private val renameWalletComponentFactory: RenameWalletComponent.Factory,
|
||||
private val networksAvailableForNotificationsComponent: NetworksAvailableForNotificationsComponent.Factory,
|
||||
) : WalletSettingsComponent, AppComponentContext by context {
|
||||
|
||||
private val model: WalletSettingsModel = getOrCreateModel(params)
|
||||
|
||||
private val bottomSheetSlot = childSlot(
|
||||
source = model.bottomSheetNavigation,
|
||||
serializer = null,
|
||||
handleBackButton = false,
|
||||
key = "bottomSheetSlot",
|
||||
childFactory = ::bottomSheetChild,
|
||||
)
|
||||
|
||||
private val dialog = childSlot(
|
||||
source = model.dialogNavigation,
|
||||
serializer = DialogConfig.serializer(),
|
||||
handleBackButton = true,
|
||||
key = "dialogSlot",
|
||||
childFactory = ::dialogChild,
|
||||
)
|
||||
|
||||
|
|
@ -40,12 +53,15 @@ internal class DefaultWalletSettingsComponent @AssistedInject constructor(
|
|||
override fun Content(modifier: Modifier) {
|
||||
val state by model.state.collectAsStateWithLifecycle()
|
||||
val dialog by dialog.subscribeAsState()
|
||||
val bottomSheet by bottomSheetSlot.subscribeAsState()
|
||||
|
||||
WalletSettingsScreen(
|
||||
modifier = modifier,
|
||||
state = state,
|
||||
dialog = { dialog.child?.instance?.Dialog() },
|
||||
)
|
||||
|
||||
bottomSheet.child?.instance?.BottomSheet()
|
||||
}
|
||||
|
||||
private fun dialogChild(
|
||||
|
|
@ -64,6 +80,18 @@ internal class DefaultWalletSettingsComponent @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private fun bottomSheetChild(
|
||||
config: NetworksAvailableForNotificationBSConfig,
|
||||
componentContext: ComponentContext,
|
||||
): ComposableBottomSheetComponent = networksAvailableForNotificationsComponent.create(
|
||||
context = childByContext(componentContext),
|
||||
params = NetworksAvailableForNotificationsComponent.Params(
|
||||
onDismiss = model
|
||||
.bottomSheetNavigation::dismiss,
|
||||
),
|
||||
)
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : WalletSettingsComponent.Factory {
|
||||
override fun create(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.feature.walletsettings.component.impl.model
|
||||
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.domain.notifications.GetNetworksAvailableForNotificationsUseCase
|
||||
import com.tangem.feature.walletsettings.ui.state.NetworksAvailableForNotificationsUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@ModelScoped
|
||||
internal class NetworksAvailableForNotificationsModel @Inject constructor(
|
||||
private val getNetworksAvailableForNotificationsUseCase: GetNetworksAvailableForNotificationsUseCase,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
||||
val state: StateFlow<NetworksAvailableForNotificationsUM> get() = _state
|
||||
|
||||
private val _state = MutableStateFlow(
|
||||
value = NetworksAvailableForNotificationsUM(
|
||||
networks = persistentListOf(),
|
||||
isLoading = true,
|
||||
),
|
||||
)
|
||||
|
||||
init {
|
||||
modelScope.launch {
|
||||
getNetworksAvailableForNotificationsUseCase().onRight { networks ->
|
||||
_state.update {
|
||||
it.copy(networks = networks.toImmutableList(), isLoading = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2,8 +2,10 @@ package com.tangem.feature.walletsettings.di
|
|||
|
||||
import com.tangem.feature.walletsettings.component.RenameWalletComponent
|
||||
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
|
||||
import com.tangem.feature.walletsettings.component.impl.DefaultNetworksAvailableForNotificationsComponent
|
||||
import com.tangem.feature.walletsettings.component.impl.DefaultRenameWalletComponent
|
||||
import com.tangem.feature.walletsettings.component.impl.DefaultWalletSettingsComponent
|
||||
import com.tangem.feature.walletsettings.component.NetworksAvailableForNotificationsComponent
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -23,4 +25,10 @@ internal interface WalletSettingsComponentModule {
|
|||
@Binds
|
||||
@Singleton
|
||||
fun bindRenameWalletComponentFactory(factory: DefaultRenameWalletComponent.Factory): RenameWalletComponent.Factory
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindNetworksComponentFactory(
|
||||
factory: DefaultNetworksAvailableForNotificationsComponent.Factory,
|
||||
): NetworksAvailableForNotificationsComponent.Factory
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.walletsettings.di
|
|||
|
||||
import com.tangem.core.decompose.di.ModelComponent
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.feature.walletsettings.component.impl.model.NetworksAvailableForNotificationsModel
|
||||
import com.tangem.feature.walletsettings.component.impl.model.RenameWalletModel
|
||||
import com.tangem.feature.walletsettings.model.WalletSettingsModel
|
||||
import dagger.Binds
|
||||
|
|
@ -23,4 +24,9 @@ internal interface WalletSettingsModelModule {
|
|||
@IntoMap
|
||||
@ClassKey(RenameWalletModel::class)
|
||||
fun bindRenameWalletModel(model: RenameWalletModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(NetworksAvailableForNotificationsModel::class)
|
||||
fun bindNetworksAvailableForNotificationsModel(model: NetworksAvailableForNotificationsModel): Model
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.tangem.feature.walletsettings.entity
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
internal object NetworksAvailableForNotificationBSConfig
|
||||
|
|
@ -13,9 +13,7 @@ import com.tangem.core.decompose.navigation.Router
|
|||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.navigation.settings.SettingsManager
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.DialogMessage
|
||||
import com.tangem.core.ui.message.EventMessageAction
|
||||
import com.tangem.core.ui.message.SnackbarMessage
|
||||
import com.tangem.core.ui.message.*
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
|
|
@ -31,6 +29,7 @@ import com.tangem.domain.wallets.usecase.*
|
|||
import com.tangem.feature.walletsettings.analytics.Settings
|
||||
import com.tangem.feature.walletsettings.component.WalletSettingsComponent
|
||||
import com.tangem.feature.walletsettings.entity.DialogConfig
|
||||
import com.tangem.feature.walletsettings.entity.NetworksAvailableForNotificationBSConfig
|
||||
import com.tangem.feature.walletsettings.entity.WalletSettingsItemUM
|
||||
import com.tangem.feature.walletsettings.entity.WalletSettingsUM
|
||||
import com.tangem.feature.walletsettings.impl.R
|
||||
|
|
@ -70,6 +69,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
|
||||
val params: WalletSettingsComponent.Params = paramsContainer.require()
|
||||
val dialogNavigation = SlotNavigation<DialogConfig>()
|
||||
val bottomSheetNavigation: SlotNavigation<NetworksAvailableForNotificationBSConfig> = SlotNavigation()
|
||||
|
||||
val state: MutableStateFlow<WalletSettingsUM> = MutableStateFlow(
|
||||
value = WalletSettingsUM(
|
||||
|
|
@ -215,7 +215,7 @@ internal class WalletSettingsModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun onNotificationsDescriptionClick() {
|
||||
// TODO [REDACTED_JIRA]
|
||||
bottomSheetNavigation.activate(NetworksAvailableForNotificationBSConfig)
|
||||
}
|
||||
|
||||
private fun openPushSystemSettings() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,171 @@
|
|||
package com.tangem.feature.walletsettings.ui
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.components.SpacerH24
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
|
||||
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter
|
||||
import com.tangem.core.ui.components.items.NetworkNameAndSymbolItem
|
||||
import com.tangem.core.ui.components.items.NetworkNameAndSymbolItemShimmer
|
||||
import com.tangem.core.ui.extensions.*
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.domain.notifications.models.NotificationsEligibleNetwork
|
||||
import com.tangem.feature.walletsettings.ui.state.NetworksAvailableForNotificationsUM
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
internal fun NetworksAvailableForNotificationsListBS(
|
||||
state: NetworksAvailableForNotificationsUM,
|
||||
onBack: () -> Unit,
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
|
||||
config = TangemBottomSheetConfig(
|
||||
isShown = true,
|
||||
onDismissRequest = onDismiss,
|
||||
content = TangemBottomSheetConfigContent.Empty,
|
||||
),
|
||||
containerColor = TangemTheme.colors.background.tertiary,
|
||||
onBack = onBack,
|
||||
title = {
|
||||
TangemModalBottomSheetTitle(
|
||||
endIconRes = R.drawable.ic_close_24,
|
||||
onEndClick = onDismiss,
|
||||
)
|
||||
},
|
||||
content = {
|
||||
NetworksAvailableForNotificationsListBottomSheetContent(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
state = state,
|
||||
)
|
||||
},
|
||||
footer = {
|
||||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
text = stringResourceSafe(R.string.balance_hidden_got_it_button),
|
||||
onClick = onDismiss,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NetworksAvailableForNotificationsListBottomSheetContent(
|
||||
state: NetworksAvailableForNotificationsUM,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier.background(TangemTheme.colors.background.primary),
|
||||
) {
|
||||
Header()
|
||||
SpacerH24()
|
||||
Networks(networks = state.networks, isLoading = state.isLoading)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.Header() {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_notification_48),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.size(TangemTheme.dimens.size56),
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.push_transactions_notifications_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing34,
|
||||
end = TangemTheme.dimens.spacing34,
|
||||
top = TangemTheme.dimens.spacing28,
|
||||
),
|
||||
)
|
||||
Text(
|
||||
text = stringResourceSafe(R.string.push_transactions_notifications_description),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing34,
|
||||
end = TangemTheme.dimens.spacing34,
|
||||
top = TangemTheme.dimens.spacing8,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Networks(
|
||||
networks: ImmutableList<NotificationsEligibleNetwork>,
|
||||
modifier: Modifier = Modifier,
|
||||
isLoading: Boolean = false,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
Text(
|
||||
modifier = Modifier.padding(top = 12.dp, bottom = 4.dp, start = 12.dp, end = 12.dp),
|
||||
text = stringResourceSafe(R.string.common_supported_networks),
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
if (isLoading) {
|
||||
repeat(SHIMMERS_COUNT) {
|
||||
NetworkNameAndSymbolItemShimmer()
|
||||
}
|
||||
} else {
|
||||
networks.fastForEach { network ->
|
||||
key(network.id) {
|
||||
NetworkNameAndSymbolItem(
|
||||
icon = network.icon,
|
||||
name = network.name,
|
||||
symbol = network.symbol,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val SHIMMERS_COUNT = 10
|
||||
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun Preview_CustomTokenNetworkSelectorContent() {
|
||||
TangemThemePreview {
|
||||
NetworksAvailableForNotificationsListBS(
|
||||
state = NetworksAvailableForNotificationsUM(
|
||||
networks = persistentListOf(),
|
||||
isLoading = true,
|
||||
),
|
||||
onDismiss = {},
|
||||
onBack = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.tangem.feature.walletsettings.ui.state
|
||||
|
||||
import com.tangem.domain.notifications.models.NotificationsEligibleNetwork
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class NetworksAvailableForNotificationsUM(
|
||||
val networks: ImmutableList<NotificationsEligibleNetwork>,
|
||||
val isLoading: Boolean,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue