Updated on 2026-08-14
This commit is contained in:
commit
f229c7bc70
8 changed files with 30 additions and 54 deletions
|
|
@ -29,6 +29,7 @@ import com.tangem.domain.settings.IncrementAppLaunchCounterUseCase
|
|||
import com.tangem.domain.settings.usercountry.FetchUserCountryUseCase
|
||||
import com.tangem.domain.staking.FetchStakingTokensUseCase
|
||||
import com.tangem.domain.wallets.legacy.UserWalletsListManager
|
||||
import com.tangem.feature.swap.analytics.StoriesEvents
|
||||
import com.tangem.features.onramp.OnrampFeatureToggles
|
||||
import com.tangem.features.swap.SwapFeatureToggles
|
||||
import com.tangem.tap.common.extensions.setContext
|
||||
|
|
@ -300,19 +301,32 @@ internal class MainViewModel @Inject constructor(
|
|||
private fun preloadImages() {
|
||||
try {
|
||||
viewModelScope.launch {
|
||||
val swapStories = if (swapFeatureToggles.isPromoStoriesEnabled) {
|
||||
getStoryContentUseCase.invokeSync(StoryContentIds.STORY_FIRST_TIME_SWAP.id)
|
||||
.getOrNull()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
if (swapFeatureToggles.isPromoStoriesEnabled) {
|
||||
val swapStories = getStoryContentUseCase.invokeSync(
|
||||
id = StoryContentIds.STORY_FIRST_TIME_SWAP.id,
|
||||
refresh = true,
|
||||
).getOrNull()
|
||||
|
||||
val storiesImages = swapStories?.getImageUrls()
|
||||
// try to preload images for stories
|
||||
storiesImages?.forEach(imagePreloader::preload)
|
||||
if (swapStories == null) {
|
||||
analyticsEventHandler.send(
|
||||
StoriesEvents.Error(
|
||||
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
|
||||
),
|
||||
)
|
||||
} else {
|
||||
val storiesImages = swapStories.getImageUrls()
|
||||
// try to preload images for stories
|
||||
storiesImages.forEach(imagePreloader::preload)
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Timber.e(ex.message)
|
||||
analyticsEventHandler.send(
|
||||
StoriesEvents.Error(
|
||||
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -44,15 +44,15 @@ internal class DefaultPromoRepository(
|
|||
}
|
||||
|
||||
override fun getStoryById(id: String): Flow<StoryContent?> = isReadyToShowStories(id).mapLatest {
|
||||
getStoryByIdSync(id)
|
||||
getStoryByIdSync(id = id, refresh = false)
|
||||
}
|
||||
|
||||
override suspend fun getStoryByIdSync(id: String): StoryContent? = withContext(dispatchers.io) {
|
||||
override suspend fun getStoryByIdSync(id: String, refresh: Boolean): StoryContent? = withContext(dispatchers.io) {
|
||||
if (!isReadyToShowStoriesSync(id)) return@withContext null
|
||||
|
||||
val storedPromo = promoStoriesStore.getSyncOrNull(storyId = id)
|
||||
// Get last stored promo by id if possible or get from network
|
||||
val story = if (storedPromo == null) {
|
||||
val story = if (storedPromo == null && refresh) {
|
||||
val storyContent = runCatching {
|
||||
// Important to return
|
||||
withTimeoutOrNull(STORIES_LOAD_DELAY) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class GetStoryContentUseCase(
|
|||
.catch { emit(it.left()) }
|
||||
.onEmpty { emit(null.right()) }
|
||||
|
||||
suspend fun invokeSync(id: String): Either<Throwable, StoryContent?> = Either.catch {
|
||||
promoRepository.getStoryByIdSync(id)
|
||||
suspend fun invokeSync(id: String, refresh: Boolean = false): Either<Throwable, StoryContent?> = Either.catch {
|
||||
promoRepository.getStoryByIdSync(id, refresh)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ interface PromoRepository {
|
|||
// region Stories
|
||||
fun getStoryById(id: String): Flow<StoryContent?>
|
||||
|
||||
suspend fun getStoryByIdSync(id: String): StoryContent?
|
||||
suspend fun getStoryByIdSync(id: String, refresh: Boolean): StoryContent?
|
||||
|
||||
fun isReadyToShowStories(storyId: String): Flow<Boolean>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,15 +19,4 @@ sealed class StoriesEvents(
|
|||
WATCHED to watchCount,
|
||||
),
|
||||
)
|
||||
|
||||
data class Error(
|
||||
val source: String,
|
||||
val type: String,
|
||||
) : StoriesEvents(
|
||||
event = "Error",
|
||||
params = mapOf(
|
||||
AnalyticsParam.SOURCE to source,
|
||||
AnalyticsParam.TYPE to type,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -53,22 +53,10 @@ internal class StoriesModel @Inject constructor(
|
|||
getStoryContentUseCase.invokeSync(params.storyId).fold(
|
||||
ifLeft = {
|
||||
Timber.e("Unable to load stories for ${StoryContentIds.STORY_FIRST_TIME_SWAP.id}")
|
||||
analyticsEventHandler.send(
|
||||
StoriesEvents.Error(
|
||||
source = params.screenSource,
|
||||
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
|
||||
),
|
||||
)
|
||||
openScreen(hideStories = false) // Fallback to target screen
|
||||
},
|
||||
ifRight = { swapStory ->
|
||||
if (swapStory == null) {
|
||||
analyticsEventHandler.send(
|
||||
StoriesEvents.Error(
|
||||
source = params.screenSource,
|
||||
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
|
||||
),
|
||||
)
|
||||
openScreen(hideStories = false) // Fallback to target screen
|
||||
} else {
|
||||
_state.update {
|
||||
|
|
|
|||
|
|
@ -21,12 +21,10 @@ sealed class StoriesEvents(
|
|||
)
|
||||
|
||||
data class Error(
|
||||
val source: String,
|
||||
val type: String,
|
||||
) : StoriesEvents(
|
||||
event = "Error",
|
||||
params = mapOf(
|
||||
AnalyticsParam.SOURCE to source,
|
||||
AnalyticsParam.TYPE to type,
|
||||
),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ internal class SwapModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val blockchainInteractor: BlockchainInteractor,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getCryptoCurrencyStatusUseCase: GetCryptoCurrencyStatusSyncUseCase,
|
||||
private val updateDelayedCurrencyStatusUseCase: UpdateDelayedNetworkStatusUseCase,
|
||||
|
|
@ -96,6 +95,7 @@ internal class SwapModel @Inject constructor(
|
|||
private val shouldShowStoriesUseCase: ShouldShowStoriesUseCase,
|
||||
private val getStoryContentUseCase: GetStoryContentUseCase,
|
||||
private val featureToggles: SwapFeatureToggles,
|
||||
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
swapInteractorFactory: SwapInteractor.Factory,
|
||||
private val urlOpener: UrlOpener,
|
||||
router: AppRouter,
|
||||
|
|
@ -278,23 +278,10 @@ internal class SwapModel @Inject constructor(
|
|||
getStoryContentUseCase.invokeSync(StoryContentIds.STORY_FIRST_TIME_SWAP.id).fold(
|
||||
ifLeft = {
|
||||
Timber.e("Unable to load stories for ${StoryContentIds.STORY_FIRST_TIME_SWAP.id}")
|
||||
analyticsEventHandler.send(
|
||||
StoriesEvents.Error(
|
||||
source = params.screenSource,
|
||||
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
|
||||
),
|
||||
)
|
||||
},
|
||||
ifRight = { story ->
|
||||
if (story != null) {
|
||||
uiState = stateBuilder.createStoriesState(uiState, story)
|
||||
} else {
|
||||
analyticsEventHandler.send(
|
||||
StoriesEvents.Error(
|
||||
source = params.screenSource,
|
||||
type = StoryContentIds.STORY_FIRST_TIME_SWAP.analyticType,
|
||||
),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue