Updated on 2026-08-14

This commit is contained in:
Tangem 2025-03-11 18:55:37 +03:00
parent 330ae73357
commit e7efe7b76a
4636 changed files with 234864 additions and 63507 deletions

View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,47 @@
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.pushnotifications.impl"
}
dependencies {
/** AndroidX */
implementation(deps.androidx.fragment.ktx)
implementation(deps.androidx.activity.compose)
/** Compose */
implementation(deps.compose.foundation)
implementation(deps.compose.accompanist.systemUiController)
implementation(deps.compose.accompanist.permission)
/** Other dependencies */
implementation(deps.timber)
implementation(deps.arrow.core)
implementation(deps.kotlin.immutable.collections)
/** Core modules */
implementation(projects.core.ui)
implementation(projects.core.configToggles)
implementation(projects.core.navigation)
implementation(projects.core.analytics)
implementation(projects.core.analytics.models)
/** Common modules */
implementation(projects.common.routing)
/** Domain module */
implementation(projects.domain.settings)
/** Feature modules */
implementation(projects.features.pushNotifications.api)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
}

View file

@ -0,0 +1,39 @@
package com.tangem.features.pushnotifications.impl
import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.fragment.app.viewModels
import com.tangem.core.ui.UiDependencies
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.features.pushnotifications.impl.presentation.ui.PushNotificationsScreen
import com.tangem.features.pushnotifications.impl.presentation.viewmodel.PushNotificationViewModel
import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
internal class PushNotificationsFragment : ComposeFragment() {
@Inject
override lateinit var uiDependencies: UiDependencies
private val viewModel by viewModels<PushNotificationViewModel>()
@Composable
override fun ScreenContent(modifier: Modifier) {
BackHandler(onBack = requireActivity()::finish)
NavigationBar3ButtonsScrim()
PushNotificationsScreen(
onRequest = viewModel::onRequest,
onNeverRequest = viewModel::onNeverRequest,
onAllowPermission = viewModel::onAllowPermission,
onDenyPermission = viewModel::onDenyPermission,
)
}
companion object {
/** Create push notifications fragment instance */
fun create(): PushNotificationsFragment = PushNotificationsFragment()
}
}

View file

@ -0,0 +1,24 @@
package com.tangem.features.pushnotifications.impl.di
import com.tangem.common.routing.AppRouter
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
import com.tangem.features.pushnotifications.impl.navigation.DefaultPushNotificationsRouter
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.scopes.ActivityScoped
/**
* DI module provides implementation of [PushNotificationsRouter]
*/
@Module
@InstallIn(ActivityComponent::class)
object PushNotificationsModule {
@Provides
@ActivityScoped
fun provideDisclaimerRouter(appRouter: AppRouter): PushNotificationsRouter {
return DefaultPushNotificationsRouter(appRouter)
}
}

View file

@ -0,0 +1,18 @@
package com.tangem.features.pushnotifications.impl.navigation
import androidx.fragment.app.Fragment
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.AppRouter
import com.tangem.features.pushnotifications.impl.PushNotificationsFragment
import javax.inject.Inject
internal class DefaultPushNotificationsRouter @Inject constructor(
private val appRouter: AppRouter,
) : InnerPushNotificationsRouter {
override fun entryFragment(): Fragment = PushNotificationsFragment.create()
override fun openHome() {
appRouter.push(AppRoute.Home)
}
}

View file

@ -0,0 +1,8 @@
package com.tangem.features.pushnotifications.impl.navigation
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
interface InnerPushNotificationsRouter : PushNotificationsRouter {
fun openHome()
}

View file

@ -0,0 +1,59 @@
package com.tangem.features.pushnotifications.impl.presentation.ui
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.showcase.Showcase
import com.tangem.core.ui.components.showcase.model.ShowcaseButtonModel
import com.tangem.core.ui.components.showcase.model.ShowcaseItemModel
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.utils.requestPushPermission
import com.tangem.feature.pushnotifications.impl.R
import com.tangem.features.pushnotifications.api.utils.getPushPermissionOrNull
import kotlinx.collections.immutable.persistentListOf
@Composable
internal fun PushNotificationsScreen(
onRequest: () -> Unit,
onNeverRequest: () -> Unit,
onAllowPermission: () -> Unit,
onDenyPermission: () -> Unit,
) {
val isClicked = remember { mutableStateOf(false) }
val requestPushPermission = requestPushPermission(
isClicked = isClicked,
onAllow = onAllowPermission,
onDeny = onDenyPermission,
pushPermission = getPushPermissionOrNull(),
)
Showcase(
headerIconRes = R.drawable.ic_notifications_unread_24,
headerText = resourceReference(R.string.user_push_notification_agreement_header),
showcaseItems = persistentListOf(
ShowcaseItemModel(
R.drawable.ic_rocket_launch_24,
resourceReference(R.string.user_push_notification_agreement_argument_one),
),
ShowcaseItemModel(
R.drawable.ic_storefront_24,
resourceReference(R.string.user_push_notification_agreement_argument_two),
),
),
primaryButton = ShowcaseButtonModel(
buttonText = resourceReference(R.string.common_allow),
onClick = {
isClicked.value = true
onRequest()
requestPushPermission()
},
),
secondaryButton = ShowcaseButtonModel(
buttonText = resourceReference(R.string.common_later),
onClick = onNeverRequest,
),
modifier = Modifier.systemBarsPadding(),
)
}

View file

@ -0,0 +1,63 @@
package com.tangem.features.pushnotifications.impl.presentation.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.domain.settings.NeverRequestPermissionUseCase
import com.tangem.domain.settings.NeverToInitiallyAskPermissionUseCase
import com.tangem.features.pushnotifications.api.analytics.PushNotificationAnalyticEvents
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
import com.tangem.features.pushnotifications.impl.navigation.DefaultPushNotificationsRouter
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@Suppress("LongParameterList")
@HiltViewModel
internal class PushNotificationViewModel @Inject constructor(
private val neverRequestPermissionUseCase: NeverRequestPermissionUseCase,
private val neverToInitiallyAskPermissionUseCase: NeverToInitiallyAskPermissionUseCase,
private val router: DefaultPushNotificationsRouter,
private val analyticHandler: AnalyticsEventHandler,
) : ViewModel(), PushNotificationsClickIntents {
override fun onRequest() {
analyticHandler.send(
PushNotificationAnalyticEvents.ButtonAllow(AnalyticsParam.ScreensSources.Stories),
)
}
override fun onNeverRequest() {
analyticHandler.send(
PushNotificationAnalyticEvents.ButtonLater(AnalyticsParam.ScreensSources.Stories),
)
viewModelScope.launch {
neverRequestPermissionUseCase(PUSH_PERMISSION)
neverToInitiallyAskPermissionUseCase(PUSH_PERMISSION)
router.openHome()
}
}
override fun onAllowPermission() {
analyticHandler.send(
PushNotificationAnalyticEvents.PermissionStatus(isAllowed = true),
)
viewModelScope.launch {
neverRequestPermissionUseCase(PUSH_PERMISSION)
neverToInitiallyAskPermissionUseCase(PUSH_PERMISSION)
router.openHome()
}
}
override fun onDenyPermission() {
analyticHandler.send(
PushNotificationAnalyticEvents.PermissionStatus(isAllowed = false),
)
viewModelScope.launch {
neverRequestPermissionUseCase(PUSH_PERMISSION)
neverToInitiallyAskPermissionUseCase(PUSH_PERMISSION)
router.openHome()
}
}
}

View file

@ -0,0 +1,11 @@
package com.tangem.features.pushnotifications.impl.presentation.viewmodel
internal interface PushNotificationsClickIntents {
fun onRequest()
fun onNeverRequest()
fun onAllowPermission()
fun onDenyPermission()
}