Updated on 2026-08-14

This commit is contained in:
Tangem 2024-05-07 20:27:28 +02:00
parent 326352be30
commit 75e2b0b554
27 changed files with 194 additions and 2 deletions

View file

@ -0,0 +1,31 @@
package com.tangem.tap.common.haptic
import android.os.Build
import android.os.VibrationEffect
import android.os.Vibrator
import com.tangem.core.ui.haptic.HapticManager
class DefaultHapticManager(private val vibrator: Vibrator) : HapticManager {
override fun vibrateShort() {
vibrate(VIBRATION_SHORT_DURATION)
}
override fun vibrateLong() {
vibrate(VIBRATION_MEDIUM_DURATION)
}
private fun vibrate(durationMs: Long) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(durationMs, VibrationEffect.DEFAULT_AMPLITUDE))
} else {
vibrator.vibrate(durationMs)
}
}
companion object {
const val VIBRATION_SHORT_DURATION = 50L
const val VIBRATION_MEDIUM_DURATION = 100L
const val VIBRATION_LONG_DURATION = 200L
}
}

View file

@ -0,0 +1,37 @@
package com.tangem.tap.di
import android.content.Context
import android.os.Build
import android.os.Vibrator
import android.os.VibratorManager
import com.tangem.tap.common.haptic.DefaultHapticManager
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.haptic.MockHapticManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
class HapticModule {
@Provides
@Singleton
fun provideHapticManager(@ApplicationContext context: Context): HapticManager {
val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val vibratorManager = context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager
vibratorManager.defaultVibrator
} else {
context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
}
return if (vibrator.hasVibrator()) {
DefaultHapticManager(vibrator = vibrator)
} else {
MockHapticManager
}
}
}

View file

@ -6,6 +6,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.hilt.navigation.compose.hiltViewModel
import com.tangem.core.ui.components.SystemBarsEffect
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
@ -25,6 +26,9 @@ internal class AddCustomTokenFragment : ComposeFragment() {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
@Composable
override fun ScreenContent(modifier: Modifier) {
val viewModel = hiltViewModel<AddCustomTokenViewModel>().apply {

View file

@ -6,6 +6,7 @@ import androidx.compose.ui.Modifier
import androidx.fragment.app.viewModels
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.components.SystemBarsEffect
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
@ -18,6 +19,9 @@ internal class AppCurrencySelectorFragment : ComposeFragment() {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
private val viewModel: AppCurrencySelectorViewModel by viewModels()
@Composable

View file

@ -7,6 +7,7 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.domain.appcurrency.repository.AppCurrencyRepository
@ -21,6 +22,9 @@ internal class AppSettingsFragment : ComposeFragment() {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
@Inject
lateinit var appCurrencyRepository: AppCurrencyRepository

View file

@ -5,6 +5,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.fragment.app.viewModels
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.features.details.redux.DetailsAction
@ -18,6 +19,9 @@ internal class CardSettingsFragment : ComposeFragment() {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
private val viewModel: CardSettingsViewModel by viewModels()
@Composable

View file

@ -5,6 +5,7 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.features.details.redux.DetailsState
@ -24,6 +25,9 @@ class AccessCodeRecoveryFragment : ComposeFragment(), StoreSubscriber<DetailsSta
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
@Composable
override fun ScreenContent(modifier: Modifier) {
AccessCodeRecoveryScreen(

View file

@ -6,6 +6,7 @@ import androidx.compose.ui.Modifier
import com.tangem.core.analytics.Analytics
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.navigation.email.EmailSender
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.domain.feedback.FeedbackManagerFeatureToggles
@ -25,6 +26,9 @@ internal class DetailsFragment : ComposeFragment(), StoreSubscriber<DetailsState
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
@Inject
lateinit var walletsRepository: WalletsRepository

View file

@ -5,6 +5,7 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.features.details.redux.DetailsState
@ -19,6 +20,9 @@ internal class ResetCardFragment : ComposeFragment(), StoreSubscriber<DetailsSta
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
private val viewModel = ResetCardViewModel(store)
private var screenState: MutableState<ResetCardScreenState> =

View file

@ -5,6 +5,7 @@ import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.features.details.redux.DetailsState
@ -19,6 +20,9 @@ internal class SecurityModeFragment : ComposeFragment(), StoreSubscriber<Details
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
private val viewModel = SecurityModeViewModel(store)
private var screenState: MutableState<SecurityModeScreenState> =

View file

@ -8,6 +8,7 @@ import androidx.compose.ui.Modifier
import androidx.fragment.app.viewModels
import com.tangem.core.analytics.Analytics
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.tap.common.analytics.events.WalletConnect
@ -23,6 +24,9 @@ internal class WalletConnectFragment : ComposeFragment(), StoreSubscriber<Wallet
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
private val viewModel: WalletConnectViewModel by viewModels()
private var screenState: MutableState<WalletConnectScreenState>? = null

View file

@ -13,6 +13,7 @@ import com.tangem.core.analytics.Analytics
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.ui.components.SystemBarsEffect
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
import com.tangem.domain.tokens.TokensAction
@ -32,6 +33,9 @@ class HomeFragment : ComposeFragment(), StoreSubscriber<HomeState> {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
private var homeState: MutableState<HomeState> = mutableStateOf(store.state.homeState)
override fun onCreate(savedInstanceState: Bundle?) {

View file

@ -9,6 +9,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeBottomSheetFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
@ -24,6 +25,9 @@ internal class ModalNotificationBottomSheetFragment : ComposeBottomSheetFragment
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
private val viewModel: MainViewModel by activityViewModels()
@Composable

View file

@ -11,6 +11,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.fragment.app.viewModels
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeBottomSheetFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
@ -27,6 +28,9 @@ internal class SaveWalletBottomSheetFragment : ComposeBottomSheetFragment() {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
override val expandedHeightFraction: Float = .98f
private val viewModel by viewModels<SaveWalletViewModel>()

View file

@ -6,6 +6,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.hilt.navigation.compose.hiltViewModel
import com.tangem.core.ui.components.SystemBarsEffect
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
@ -25,6 +26,9 @@ internal class TokensListFragment : ComposeFragment() {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
@Composable
override fun ScreenContent(modifier: Modifier) {
val viewModel = hiltViewModel<TokensListViewModel>().apply {

View file

@ -16,6 +16,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.analytics.Analytics
import com.tangem.core.ui.components.SystemBarsEffect
import com.tangem.core.ui.haptic.HapticManager
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.screen.ComposeFragment
import com.tangem.core.ui.theme.AppThemeModeHolder
@ -33,6 +34,9 @@ internal class WelcomeFragment : ComposeFragment() {
@Inject
override lateinit var appThemeModeHolder: AppThemeModeHolder
@Inject
override lateinit var hapticManager: HapticManager
override fun onStart() {
super.onStart()
Analytics.eraseContext()