TP-66842 | Kamalesh | Db call migration (#10932)

Co-authored-by: kishan kumar <kishan.kumar@navi.com>
This commit is contained in:
Kamalesh Garnayak
2024-05-22 17:42:34 +05:30
committed by GitHub
parent ea9829eb6b
commit c0ca529230
18 changed files with 495 additions and 473 deletions

View File

@@ -1,12 +1,14 @@
/*
*
* * Copyright © 2023 by Navi Technologies Limited
* * Copyright © 2023-2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.base.cache.model
import com.navi.base.utils.EMPTY
data class NaviCacheAltSourceEntity(
val value: String? = null,
val version: Int? = null,
@@ -14,4 +16,14 @@ data class NaviCacheAltSourceEntity(
val ttl: Long = -1,
val clearOnLogout: Boolean = true,
val isSuccess: Boolean
)
) {
fun toNaviCacheEntity(key: String) =
NaviCacheEntity(
key = key,
value = value ?: EMPTY,
version = version ?: 1,
ttl = ttl,
clearOnLogout = clearOnLogout,
metaData = metaData
)
}

View File

@@ -17,33 +17,44 @@ import com.navi.common.network.models.RepoResult
import com.navi.common.network.retrofit.ResponseCallback
import com.navi.common.utils.Constants.GZIP
import com.navi.rr.network.retrofit.ResponseHandler
import com.navi.rr.utils.CacheHandlerProxy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
class CoinHistoryScreenRepo
@Inject
constructor(
private val retrofitService: RetrofitService,
private val responseHandler: ResponseHandler,
private val cacheHandlerProxy: CacheHandlerProxy
) : ResponseCallback() {
suspend fun fetchCoinHistoryScreenCoinBalanceUiTronConfigs(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchScreenUiTronConfigs(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = TRANSACTION_HISTORY_COINS_SCREEN_NAME
)
suspend fun fetchCoinHistoryScreenCoinBalanceUiTronConfigs():
Flow<RepoResult<ScreenDefinition>> =
cacheHandlerProxy.fetchData<ScreenDefinition>(
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchScreenUiTronConfigs(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = TRANSACTION_HISTORY_COINS_SCREEN_NAME
)
)
}
)
}
suspend fun fetchCoinHistoryScreenCashRewardsUiTronConfigs(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchScreenUiTronConfigs(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = TRANSACTION_HISTORY_CASH_SCREEN_NAME
)
suspend fun fetchCoinHistoryScreenCashRewardsUiTronConfigs():
Flow<RepoResult<ScreenDefinition>> =
cacheHandlerProxy.fetchData<ScreenDefinition>(
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchScreenUiTronConfigs(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = TRANSACTION_HISTORY_CASH_SCREEN_NAME
)
)
}
)
}
suspend fun fetchCoinsListData(
pageNo: Int,

View File

@@ -11,26 +11,38 @@ import com.navi.coin.models.model.RedemptionRequest
import com.navi.coin.network.RetrofitService
import com.navi.coin.utils.constant.Constants.SCREENS.COINS_LOADING_SCREEN_SCREEN_NAME
import com.navi.coin.utils.constant.Constants.SCREENS.COINS_SCREEN_SCREEN_NAME
import com.navi.common.constants.DBCacheConstants
import com.navi.common.forge.model.ScreenDefinition
import com.navi.common.model.ModuleName
import com.navi.common.model.ModuleNameV2
import com.navi.common.network.models.RepoResult
import com.navi.common.utils.Constants.GZIP
import com.navi.rr.network.retrofit.ResponseHandler
import com.navi.rr.utils.CacheHandlerProxy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
class CoinHomeScreenRepo
@Inject
constructor(
private val responseHandler: ResponseHandler,
private val retrofitService: RetrofitService,
private val cacheHandlerProxy: CacheHandlerProxy
) {
suspend fun fetchCoinHomeScreenUiTronConfigs() =
responseHandler.handleResponse(
retrofitService.fetchScreenUiTronConfigs(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = COINS_SCREEN_SCREEN_NAME
)
suspend fun fetchCoinHomeScreenUiTronConfigs(): Flow<RepoResult<ScreenDefinition>> {
return cacheHandlerProxy.fetchData<ScreenDefinition>(
key = DBCacheConstants.COIN_HOME_SCREEN_CACHE_KEY,
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchScreenUiTronConfigs(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = COINS_SCREEN_SCREEN_NAME
)
)
}
)
}
suspend fun validateUPIId(upiId: String) =
responseHandler.handleResponse(

View File

@@ -15,22 +15,28 @@ import com.navi.common.model.ModuleNameV2
import com.navi.common.network.models.RepoResult
import com.navi.common.utils.Constants.GZIP
import com.navi.rr.network.retrofit.ResponseHandler
import com.navi.rr.utils.CacheHandlerProxy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
class ScratchCardHistoryScreenRepo
@Inject
constructor(
private val retrofitService: RetrofitService,
private val responseHandler: ResponseHandler,
private val cacheHandlerProxy: CacheHandlerProxy
) {
suspend fun fetchScratchCardUiTronConfigs(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchScreenUiTronConfigs(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = REWARD_HISTORY_SCRATCH_CARD_SCREEN_NAME
)
suspend fun fetchScratchCardUiTronConfigs(): Flow<RepoResult<ScreenDefinition>> {
return cacheHandlerProxy.fetchData(
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchScreenUiTronConfigs(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = REWARD_HISTORY_SCRATCH_CARD_SCREEN_NAME
)
)
}
)
}

View File

@@ -11,8 +11,6 @@ import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import com.navi.base.cache.model.NaviCacheEntity
import com.navi.base.cache.repository.NaviCacheRepositoryImpl
import com.navi.coin.navigator.CoinNavigationActions
import com.navi.coin.repo.pagingsource.CashHistoryListSource
import com.navi.coin.repo.pagingsource.CoinHistoryListSource
@@ -20,14 +18,11 @@ import com.navi.coin.repo.repository.CoinHistoryScreenRepo
import com.navi.coin.repo.repository.CoinHomeScreenRepo
import com.navi.coin.utils.cacheCoinHomeImages
import com.navi.coin.utils.constant.Constants.CLOSE
import com.navi.common.CommonLibManager
import com.navi.common.constants.DBCacheConstants.COIN_HOME_SCREEN_CACHE_KEY
import com.navi.common.forge.model.ScreenDefinition
import com.navi.common.network.ApiConstants
import com.navi.common.uitron.model.action.CtaAction
import com.navi.common.utils.isValidResponse
import com.navi.rr.common.models.RRErrorData
import com.navi.rr.utils.getGsonBuilders
import com.navi.uitron.model.data.UiTronAction
import com.ramcosta.composedestinations.spec.Direction
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -36,6 +31,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
@HiltViewModel
class CoinHistoryScreenVM
@@ -44,7 +40,6 @@ constructor(
private val coinHistoryScreenRepo: CoinHistoryScreenRepo,
private val coinHistoryListSource: CoinHistoryListSource,
private val cashHistoryListSource: CashHistoryListSource,
private val naviCacheRepository: NaviCacheRepositoryImpl,
private val coinHomeScreenRepo: CoinHomeScreenRepo
) : CoinBaseVM() {
private val _coinHistoryScreenData =
@@ -119,36 +114,42 @@ constructor(
val cashRewardsResponse =
coinHistoryScreenRepo.fetchCoinHistoryScreenCashRewardsUiTronConfigs()
if (coinBalanceResponse.isValidResponse().not()) {
coinBalanceResponse.let { response ->
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
coinBalanceResponse
.combine(cashRewardsResponse) { coinBalanceResponse, cashRewardsResponse ->
coinBalanceResponse to cashRewardsResponse
}
return@launch
}
if (cashRewardsResponse.isValidResponse().not()) {
cashRewardsResponse.let { response ->
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
}
return@launch
}
.collect { (coinBalanceResponse, cashRewardsResponse) ->
if (coinBalanceResponse.isValidResponse().not()) {
coinBalanceResponse.let { response ->
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
}
return@collect
}
_coinHistoryScreenData.emit(
CoinHistoryScreenState.Success(
listOf(
coinBalanceResponse
.data!!, // Null check has been already applied above for both
cashRewardsResponse.data!!
if (cashRewardsResponse.isValidResponse().not()) {
cashRewardsResponse.let { response ->
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
}
return@collect
}
_coinHistoryScreenData.emit(
CoinHistoryScreenState.Success(
listOf(
coinBalanceResponse
.data!!, // Null check has been already applied above for both
cashRewardsResponse.data!!
)
)
)
)
)
}
}
}
@@ -174,16 +175,11 @@ constructor(
/** This should ideally be in AP as a Lambda Action */
fun fetchAndSaveCoinHomeScreen() {
launch {
val response = coinHomeScreenRepo.fetchCoinHomeScreenUiTronConfigs()
if (response.isValidResponse()) {
naviCacheRepository.save(
NaviCacheEntity(
key = COIN_HOME_SCREEN_CACHE_KEY,
value = getGsonBuilders().toJson(response.data).orEmpty(),
version = CommonLibManager.buildConfigDetails.appVersionCode.toInt()
)
)
cacheCoinHomeImages(response.data?.screenStructure)
coinHomeScreenRepo.fetchCoinHomeScreenUiTronConfigs().collect {
val response = it.data
if (it.isValidResponse()) {
cacheCoinHomeImages(response?.screenStructure)
}
}
}
}

View File

@@ -7,9 +7,6 @@
package com.navi.coin.vm
import com.navi.base.cache.model.NaviCacheAltSourceEntity
import com.navi.base.cache.model.NaviCacheEntity
import com.navi.base.cache.repository.NaviCacheRepositoryImpl
import com.navi.coin.models.model.RedemptionRequest
import com.navi.coin.models.model.RedemptionResponse
import com.navi.coin.models.model.RedemptionResponse.Companion.NAVI_CASH
@@ -29,8 +26,6 @@ import com.navi.coin.utils.analytics.NaviCoinsAnalytics.Companion.DEV_VALIDATE_U
import com.navi.coin.utils.analytics.NaviCoinsAnalytics.Companion.DEV_VALIDATE_UPI_ID_SUCCESS_EVENT
import com.navi.coin.utils.cacheCoinHomeImages
import com.navi.coin.utils.constant.Constants.CoinHomeScreen.BACK_FROM
import com.navi.common.CommonLibManager
import com.navi.common.constants.DBCacheConstants.COIN_HOME_SCREEN_CACHE_KEY
import com.navi.common.constants.FAILED
import com.navi.common.forge.model.ScreenDefinition
import com.navi.common.forge.model.ScreenStructure
@@ -74,7 +69,6 @@ class CoinHomeScreenVM
constructor(
private val coinHomeScreenRepo: CoinHomeScreenRepo,
private val coinHistoryScreenRepo: CoinHistoryScreenRepo,
private val naviCacheRepository: NaviCacheRepositoryImpl,
) : CoinBaseVM() {
private val eventPublisher: NaviCoinsAnalytics.BasicEvent =
NaviCoinsAnalytics.naviCoinsAnalytics.BasicEvent()
@@ -141,47 +135,23 @@ constructor(
fun fetchCoinHomeScreenUiTronConfigs() {
launch {
_coinHomeScreenData.update { CoinHomeScreenState.Loading }
naviCacheRepository
.getDataAndFetchFromAltSource(
key = COIN_HOME_SCREEN_CACHE_KEY,
version = CommonLibManager.buildConfigDetails.appVersionCode.toLongOrNull(),
getDataFromAltSource = { fetchDataFromApi() },
isCurrentAndAltDataSame = { currentData, altData ->
currentData?.version == altData.version &&
currentData?.value == altData.value
},
emitMultipleValues = true,
)
.collect { response ->
getGsonBuilders().fromJson(response.value, ScreenDefinition::class.java)?.let {
response ->
_coinHomeScreenData.update { CoinHomeScreenState.Success(response.copy()) }
initCoinHomeScreenImageCaching(response.screenStructure)
coinHomeScreenRepo.fetchCoinHomeScreenUiTronConfigs().collect { result ->
val response = result.data
when {
result.isValidResponse() -> {
if (result.isFromCache) {
setCachePresent()
}
_coinHomeScreenData.update {
CoinHomeScreenState.Success(response ?: ScreenDefinition())
}
initCoinHomeScreenImageCaching(response?.screenStructure)
}
setCachePresent()
}
}
}
}
private suspend fun fetchDataFromApi(): NaviCacheAltSourceEntity {
val response = coinHomeScreenRepo.fetchCoinHomeScreenUiTronConfigs()
if (!response.isValidResponse()) {
showError(
error =
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST,
)
)
return NaviCacheAltSourceEntity(isSuccess = false)
}
return NaviCacheAltSourceEntity(
value = getGsonBuilders().toJson(response.data),
version = CommonLibManager.buildConfigDetails.appVersionCode.toIntOrNull(),
isSuccess = true
)
}
private suspend fun navigateToScreen(url: String, action: UiTronAction?) {
when (url) {
CoinNavigationActions.BACK.name -> {
@@ -205,18 +175,18 @@ constructor(
fun fetchAndSaveCoinHistoryScreen() {
launch {
val coinResponse =
coinHistoryScreenRepo.fetchCoinHistoryScreenCoinBalanceUiTronConfigs()
val cashResponse =
coinHistoryScreenRepo.fetchCoinHistoryScreenCashRewardsUiTronConfigs()
coinResponse.isValidResponse().let {
if (it) {
cacheCoinHomeImages(coinResponse.data?.screenStructure)
coinHistoryScreenRepo.fetchCoinHistoryScreenCoinBalanceUiTronConfigs().collect {
response ->
if (response.isValidResponse()) {
cacheCoinHomeImages(response.data?.screenStructure)
}
}
cashResponse.isValidResponse().let {
if (it) {
cacheCoinHomeImages(cashResponse.data?.screenStructure)
}
launch {
coinHistoryScreenRepo.fetchCoinHistoryScreenCashRewardsUiTronConfigs().collect {
response ->
if (response.isValidResponse()) {
cacheCoinHomeImages(response.data?.screenStructure)
}
}
}
@@ -224,24 +194,15 @@ constructor(
fun fetchAndSaveCoinHomeScreen() {
launch {
val response = coinHomeScreenRepo.fetchCoinHomeScreenUiTronConfigs()
if (response.isValidResponse()) {
initCoinHomeScreenImageCaching(response.data?.screenStructure)
naviCacheRepository.save(
NaviCacheEntity(
key = COIN_HOME_SCREEN_CACHE_KEY,
value = getGsonBuilders().toJson(response.data).orEmpty(),
version =
CommonLibManager.buildConfigDetails.appVersionCode
.toIntOrNull()
.orVal(1)
)
)
coinHomeScreenRepo.fetchCoinHomeScreenUiTronConfigs().collect {
if (it.isValidResponse()) {
initCoinHomeScreenImageCaching(it?.data?.screenStructure)
}
}
}
}
private fun initCoinHomeScreenImageCaching(
fun initCoinHomeScreenImageCaching(
screenDefinitionStructure: ScreenStructure?,
) {
screenDefinitionStructure?.let { screenStructure ->

View File

@@ -109,18 +109,21 @@ constructor(
fun fetchScratchCardTopUiTronConfigs() {
launch {
_scratchCardHistoryScreenData.emit(ScratchCardHistoryScreenState.Loading)
val scratchCardResponse = scratchCardHistoryScreenRepo.fetchScratchCardUiTronConfigs()
if (!scratchCardResponse.isValidResponse()) {
showError(
RRErrorData(
statusCode = scratchCardResponse.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
} else {
scratchCardResponse.data?.let { scratchCardScreen ->
_scratchCardHistoryScreenData.emit(
ScratchCardHistoryScreenState.Success(scratchCardScreen.copy())
scratchCardHistoryScreenRepo.fetchScratchCardUiTronConfigs().collect {
scratchCardResponse ->
if (!scratchCardResponse.isValidResponse()) {
showError(
RRErrorData(
statusCode =
scratchCardResponse.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
} else {
scratchCardResponse.data?.let { scratchCardScreen ->
_scratchCardHistoryScreenData.emit(
ScratchCardHistoryScreenState.Success(scratchCardScreen.copy())
)
}
}
}
}
@@ -308,9 +311,10 @@ constructor(
fun prefetchImages() {
launch {
val response = scratchCardHistoryScreenRepo.fetchScratchCardUiTronConfigs()
if (response.isValidResponse()) {
cachingPngs(response.data)
scratchCardHistoryScreenRepo.fetchScratchCardUiTronConfigs().collect { response ->
if (response.isValidResponse()) {
cachingPngs(response.data)
}
}
}
}

View File

@@ -1,6 +1,6 @@
/*
*
* * Copyright © 2019-2023 by Navi Technologies Limited
* * Copyright © 2019-2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
@@ -12,7 +12,8 @@ data class RepoResult<T>(
var error: ErrorMessage? = null,
var errors: List<GenericErrorResponse>? = null,
var warning: GenericWarningResponse? = null,
var statusCode: Int? = null
var statusCode: Int? = null,
var isFromCache: Boolean = false
)
fun <T> RepoResult<T>.isSuccess() = this.error == null && this.errors.isNullOrEmpty()

View File

@@ -7,6 +7,7 @@
package com.navi.rr.leaderboard.repo
import com.navi.common.constants.DBCacheConstants
import com.navi.common.forge.model.ScreenDefinition
import com.navi.common.model.ModuleName
import com.navi.common.model.ModuleNameV2
@@ -17,31 +18,44 @@ import com.navi.rr.leaderboard.models.LeaderboardListResponse
import com.navi.rr.network.di.SuperAppRetrofitForRR
import com.navi.rr.network.retrofit.ResponseHandler
import com.navi.rr.network.retrofit.RetrofitService
import com.navi.rr.utils.CacheHandlerProxy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
class LeaderboardScreenRepo
@Inject
constructor(
private val responseHandler: ResponseHandler,
@SuperAppRetrofitForRR private val retrofitService: RetrofitService,
private val responseHandler: ResponseHandler,
private val cacheHandlerProxy: CacheHandlerProxy
) {
suspend fun fetchReferralForgeScreen(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = FORGE_LEADERBOARD_SCREEN
)
suspend fun fetchReferralForgeScreen(): Flow<RepoResult<ScreenDefinition>> =
cacheHandlerProxy.fetchData<ScreenDefinition>(
key = DBCacheConstants.LEADERBOARD_SCREEN_CACHE_KEY,
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = FORGE_LEADERBOARD_SCREEN
)
)
}
)
}
suspend fun fetchLeaderboardList(userEntered: Boolean): RepoResult<LeaderboardListResponse> {
return responseHandler.handleResponse(
retrofitService.fetchLeaderboardList(
target = ModuleName.REFERRAL.name,
userEntered = userEntered
)
suspend fun fetchLeaderboardList(
userEntered: Boolean
): Flow<RepoResult<LeaderboardListResponse>> =
cacheHandlerProxy.fetchData<LeaderboardListResponse>(
key = DBCacheConstants.LEADERBOARD_LIST_CACHE_KEY,
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchLeaderboardList(
target = ModuleName.REFERRAL.name,
userEntered = userEntered
)
)
}
)
}
}

View File

@@ -7,13 +7,6 @@
package com.navi.rr.leaderboard.vm
import com.navi.base.cache.model.NaviCacheAltSourceEntity
import com.navi.base.cache.model.NaviCacheEntity
import com.navi.base.cache.repository.NaviCacheRepositoryImpl
import com.navi.common.CommonLibManager
import com.navi.common.constants.DBCacheConstants
import com.navi.common.constants.DBCacheConstants.LEADERBOARD_LIST_CACHE_KEY
import com.navi.common.constants.DBCacheConstants.LEADERBOARD_SCREEN_CACHE_KEY
import com.navi.common.forge.model.ScreenStructure
import com.navi.common.network.ApiConstants
import com.navi.common.uitron.model.action.CtaAction
@@ -30,10 +23,7 @@ import com.navi.rr.referral.repo.ReferralHomeRepo
import com.navi.rr.utils.Constants.CLOSE_BOTTOM_SHEET
import com.navi.rr.utils.RRShareApp
import com.navi.rr.utils.cacheImages
import com.navi.rr.utils.deserializeWidgetResponseString
import com.navi.rr.utils.getGsonBuilders
import com.navi.uitron.model.data.UiTronAction
import com.navi.uitron.utils.orVal
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.delay
@@ -48,7 +38,6 @@ class LeaderboardScreenVM
@Inject
constructor(
private val leaderboardScreenRepo: LeaderboardScreenRepo,
private val naviCacheRepository: NaviCacheRepositoryImpl,
private val referralHomeRepo: ReferralHomeRepo,
val rrShareApp: RRShareApp
) : RRBaseVM() {
@@ -99,16 +88,10 @@ constructor(
private fun fetchAndSaveReferralHomeScreen() {
launch {
val response = referralHomeRepo.fetchReferralForgeScreen()
if (response.isValidResponse()) {
naviCacheRepository.save(
NaviCacheEntity(
key = DBCacheConstants.REFERRAL_HOME_SCREEN_CACHE_KEY,
value = getGsonBuilders().toJson(response.data).orEmpty(),
version = CommonLibManager.buildConfigDetails.appVersionCode.toInt()
)
)
cacheImages(response.data?.screenStructure)
referralHomeRepo.fetchReferralForgeScreen().collect { response ->
if (response.isValidResponse()) {
cacheImages(response.data?.screenStructure)
}
}
}
}
@@ -116,15 +99,14 @@ constructor(
private fun refreshLeaderboardUiTronConfigs() {
launch {
_leaderboardScreenUiTronData.emit(LeaderboardUiTronScreenState.Loading)
val leaderboardScreenUiTronResponse = leaderboardScreenRepo.fetchReferralForgeScreen()
if (leaderboardScreenUiTronResponse.isValidResponse()) {
leaderboardScreenUiTronResponse.data?.let {
saveToDB(LEADERBOARD_SCREEN_CACHE_KEY, it)
_leaderboardScreenUiTronData.emit(LeaderboardUiTronScreenState.Success(it))
}
} else {
leaderboardScreenUiTronResponse.let { response ->
leaderboardScreenRepo.fetchReferralForgeScreen().collect { response ->
if (response.isValidResponse()) {
response.data?.let { data ->
_leaderboardScreenUiTronData.emit(
LeaderboardUiTronScreenState.Success(data)
)
}
} else {
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
@@ -138,15 +120,39 @@ constructor(
private fun refreshLeaderboardList() {
launch {
_leaderboardScreenData.emit(LeaderboardScreenState.Loading)
val leaderboardListResponse = leaderboardScreenRepo.fetchLeaderboardList(true)
if (leaderboardListResponse.isValidResponse()) {
leaderboardListResponse.data?.let {
saveToDB(LEADERBOARD_LIST_CACHE_KEY, it)
_leaderboardScreenData.emit(LeaderboardScreenState.Success(it))
leaderboardScreenRepo.fetchLeaderboardList(userEntered = true).collect {
leaderboardListResponse ->
if (leaderboardListResponse.isValidResponse()) {
leaderboardListResponse.data?.let {
_leaderboardScreenData.emit(LeaderboardScreenState.Success(it))
}
} else {
leaderboardListResponse.let { response ->
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
}
}
} else {
leaderboardListResponse.let { response ->
}
}
}
private fun fetchLeaderboardUiTronConfigs() {
launch {
_leaderboardScreenUiTronData.emit(LeaderboardUiTronScreenState.Loading)
leaderboardScreenRepo.fetchReferralForgeScreen().collect { response ->
if (response.isValidResponse()) {
response.data?.let { data ->
_leaderboardScreenUiTronData.emit(
LeaderboardUiTronScreenState.Success(data.copy())
)
}
if (response.isFromCache) {
setCachePresent()
}
} else {
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
@@ -157,117 +163,48 @@ constructor(
}
}
private fun fetchLeaderboardUiTronConfigs() {
launch {
_leaderboardScreenUiTronData.emit(LeaderboardUiTronScreenState.Loading)
naviCacheRepository
.getDataAndFetchFromAltSource(
key = LEADERBOARD_SCREEN_CACHE_KEY,
version = CommonLibManager.buildConfigDetails.appVersionCode.toLongOrNull(),
getDataFromAltSource = { fetchLeaderboardUiTronConfigsFromApi() },
isCurrentAndAltDataSame = { currentData, altData ->
currentData?.version == altData.version &&
currentData?.value == altData.value
},
emitMultipleValues = true
)
.collect { response ->
deserializeWidgetResponseString(response)?.let {
initLeaderboardScreenImageCaching(it.screenStructure)
_leaderboardScreenUiTronData.emit(
LeaderboardUiTronScreenState.Success(it.copy())
)
}
setCachePresent()
}
}
}
private suspend fun fetchLeaderboardUiTronConfigsFromApi(): NaviCacheAltSourceEntity {
val response = leaderboardScreenRepo.fetchReferralForgeScreen()
if (!response.isValidResponse()) {
showError(RRErrorData(statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST))
return NaviCacheAltSourceEntity(isSuccess = false)
}
return NaviCacheAltSourceEntity(
value = getGsonBuilders().toJson(response.data),
version = CommonLibManager.buildConfigDetails.appVersionCode.toIntOrNull(),
isSuccess = true
)
}
private suspend fun fetchLeaderboardFromApi(): NaviCacheAltSourceEntity {
val response = leaderboardScreenRepo.fetchLeaderboardList(true)
if (!response.isValidResponse()) {
showError(RRErrorData(statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST))
return NaviCacheAltSourceEntity(isSuccess = false)
}
return NaviCacheAltSourceEntity(
value = getGsonBuilders().toJson(response.data),
version = CommonLibManager.buildConfigDetails.appVersionCode.toIntOrNull(),
isSuccess = true
)
}
private fun fetchLeaderboardList() {
launch {
_leaderboardScreenData.emit(LeaderboardScreenState.Loading)
naviCacheRepository
.getDataAndFetchFromAltSource(
key = LEADERBOARD_LIST_CACHE_KEY,
version = CommonLibManager.buildConfigDetails.appVersionCode.toLongOrNull(),
getDataFromAltSource = { fetchLeaderboardFromApi() },
isCurrentAndAltDataSame = { currentData, altData ->
currentData?.version == altData.version &&
currentData?.value == altData.value
},
emitMultipleValues = true
)
.collect { response ->
deserializeLeaderboardListResponseString(response)?.let {
initLeaderboardListImageCaching(it)
_leaderboardScreenData.emit(LeaderboardScreenState.Success(it.copy()))
leaderboardScreenRepo.fetchLeaderboardList(userEntered = true).collect { response ->
if (response.isValidResponse()) {
response.data?.let { data ->
_leaderboardScreenData.emit(LeaderboardScreenState.Success(data))
if (response.isFromCache) {
setCachePresent()
}
}
setCachePresent()
}
}
}
private fun fetchAndSaveLeaderboardUiTronConfigs() {
launch {
val leaderboardScreenUiTronResponse = leaderboardScreenRepo.fetchReferralForgeScreen()
if (leaderboardScreenUiTronResponse.isValidResponse()) {
initLeaderboardScreenImageCaching(
leaderboardScreenUiTronResponse.data?.screenStructure
)
leaderboardScreenUiTronResponse.data?.let {
saveToDB(LEADERBOARD_SCREEN_CACHE_KEY, it)
} else {
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
}
}
}
}
private suspend fun saveToDB(key: String, response: Any) {
private fun fetchAndSaveLeaderboardUiTronConfigs() {
launch {
naviCacheRepository.save(
NaviCacheEntity(
key = key,
value = getGsonBuilders().toJson(response).orEmpty(),
version =
CommonLibManager.buildConfigDetails.appVersionCode.toIntOrNull().orVal(1)
)
)
leaderboardScreenRepo.fetchReferralForgeScreen().collect {
leaderboardScreenUiTronResponse ->
if (leaderboardScreenUiTronResponse.isValidResponse()) {
initLeaderboardScreenImageCaching(
leaderboardScreenUiTronResponse.data?.screenStructure
)
}
}
}
}
private fun fetchAndSaveLeaderboardList() {
launch {
val leaderboardListResponse = leaderboardScreenRepo.fetchLeaderboardList(false)
if (leaderboardListResponse.isValidResponse()) {
initLeaderboardListImageCaching(leaderboardListResponse.data)
leaderboardListResponse.data?.let { saveToDB(LEADERBOARD_LIST_CACHE_KEY, it) }
leaderboardScreenRepo.fetchLeaderboardList(userEntered = false).collect {
leaderboardListResponse ->
if (leaderboardListResponse.isValidResponse()) {
initLeaderboardListImageCaching(leaderboardListResponse.data)
}
}
}
}
@@ -300,11 +237,6 @@ constructor(
}
}
private fun deserializeLeaderboardListResponseString(
response: NaviCacheEntity?
): LeaderboardListResponse? =
getGsonBuilders().fromJson(response?.value, LeaderboardListResponse::class.java)
fun refreshLeaderboardScreen() {
updateRefreshState(true)
refreshData()

View File

@@ -7,6 +7,7 @@
package com.navi.rr.referral.repo
import com.navi.common.constants.DBCacheConstants
import com.navi.common.forge.model.ScreenDefinition
import com.navi.common.model.ModuleName
import com.navi.common.model.ModuleNameV2
@@ -17,13 +18,16 @@ import com.navi.rr.common.constants.FORGE_REFEREE_TRACKER_SCREEN_V2
import com.navi.rr.network.di.SuperAppRetrofitForRR
import com.navi.rr.network.retrofit.ResponseHandler
import com.navi.rr.network.retrofit.RetrofitService
import com.navi.rr.utils.CacheHandlerProxy
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
class RefereeTrackerRepo
@Inject
constructor(
private val responseHandler: ResponseHandler,
@SuperAppRetrofitForRR private val retrofitService: RetrofitService,
private val responseHandler: ResponseHandler,
private val cacheHandlerProxy: CacheHandlerProxy,
) {
suspend fun postRefereeToReminder(refereeID: String) {
@@ -51,23 +55,31 @@ constructor(
)
)
suspend fun fetchRefereeTrackerForgeElement(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = FORGE_REFEREE_TRACKER_SCREEN
)
suspend fun fetchRefereeTrackerForgeElement(): Flow<RepoResult<ScreenDefinition>> =
cacheHandlerProxy.fetchData<ScreenDefinition>(
key = DBCacheConstants.REFEREE_TRACKER_SCREEN_CACHE_KEY,
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = FORGE_REFEREE_TRACKER_SCREEN
)
)
}
)
}
suspend fun fetchRefereeTrackerV2ForgeElement(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = FORGE_REFEREE_TRACKER_SCREEN_V2
)
suspend fun fetchRefereeTrackerV2ForgeElement(): Flow<RepoResult<ScreenDefinition>> =
cacheHandlerProxy.fetchData<ScreenDefinition>(
key = DBCacheConstants.REFEREE_TRACKER_SCREEN_V2_CACHE_KEY,
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = FORGE_REFEREE_TRACKER_SCREEN_V2
)
)
}
)
}
}

View File

@@ -16,46 +16,58 @@ import com.navi.rr.leaderboard.utils.Constants
import com.navi.rr.network.di.SuperAppRetrofitForRR
import com.navi.rr.network.retrofit.ResponseHandler
import com.navi.rr.network.retrofit.RetrofitService
import com.navi.rr.utils.CacheHandlerProxy
import com.navi.rr.utils.ReferralHomeConstants.REFERRAL_POPUP_SCREEN
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
class ReferralHomeRepo
@Inject
constructor(
private val responseHandler: ResponseHandler,
@SuperAppRetrofitForRR private val retrofitService: RetrofitService,
private val responseHandler: ResponseHandler,
private val cacheHandlerProxy: CacheHandlerProxy,
) {
suspend fun fetchReferralDetails() =
responseHandler.handleResponse(retrofitService.getReferralDetails())
suspend fun fetchReferralForgeScreen(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = FORGE_REFERRAL_HOME_SCREEN
)
suspend fun fetchReferralForgeScreen(): Flow<RepoResult<ScreenDefinition>> =
cacheHandlerProxy.fetchData<ScreenDefinition>(
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = FORGE_REFERRAL_HOME_SCREEN
)
)
}
)
}
suspend fun fetchReferralPopupScreen(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = REFERRAL_POPUP_SCREEN
)
suspend fun fetchReferralPopupScreen(): Flow<RepoResult<ScreenDefinition>> =
cacheHandlerProxy.fetchData<ScreenDefinition>(
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = REFERRAL_POPUP_SCREEN
)
)
}
)
}
suspend fun fetchLeaderboardPopUp(): RepoResult<ScreenDefinition> {
return responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = Constants.REFERRAL_LEADERBOARD_GRATIFICATION_SCREEN
)
suspend fun fetchLeaderboardPopUp(): Flow<RepoResult<ScreenDefinition>> =
cacheHandlerProxy.fetchData<ScreenDefinition>(
fetchFromAlternativeSource = {
responseHandler.handleResponse(
retrofitService.fetchForgeScreen(
acceptEncoding = GZIP,
target = ModuleNameV2.FORGE.name,
screenId = Constants.REFERRAL_LEADERBOARD_GRATIFICATION_SCREEN
)
)
}
)
}
}

View File

@@ -11,18 +11,11 @@ import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.cachedIn
import com.navi.alfred.utils.ApiConstants
import com.navi.alfred.utils.log
import com.navi.base.cache.model.NaviCacheAltSourceEntity
import com.navi.base.cache.model.NaviCacheEntity
import com.navi.base.cache.repository.NaviCacheRepositoryImpl
import com.navi.common.CommonLibManager
import com.navi.common.constants.DBCacheConstants
import com.navi.common.forge.model.ScreenDefinition
import com.navi.common.forge.model.ScreenStructure
import com.navi.common.uitron.model.action.CtaAction
import com.navi.common.utils.isValidResponse
import com.navi.rr.common.models.RRErrorData
import com.navi.rr.common.vm.RRBaseVM
import com.navi.rr.referral.repo.RefereeTrackerListSource
import com.navi.rr.referral.repo.RefereeTrackerListSourceV2
@@ -31,10 +24,7 @@ import com.navi.rr.referral.utils.ReferralNavigationActions
import com.navi.rr.referral.utils.getDirectionFromCtaUrl
import com.navi.rr.utils.RRShareApp
import com.navi.rr.utils.cacheImages
import com.navi.rr.utils.deserializeWidgetResponseString
import com.navi.rr.utils.getGsonBuilders
import com.navi.uitron.model.data.UiTronAction
import com.navi.uitron.utils.orVal
import com.ramcosta.composedestinations.spec.Direction
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
@@ -42,6 +32,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
@HiltViewModel
class RefereeTrackerVM
@@ -50,7 +41,6 @@ constructor(
private val refereeTrackerListSource: RefereeTrackerListSource,
private val refereeTrackerListSourceV2: RefereeTrackerListSourceV2,
private val refereeTrackerRepo: RefereeTrackerRepo,
private val naviCacheRepository: NaviCacheRepositoryImpl,
val rrShareApp: RRShareApp
) : RRBaseVM() {
@@ -115,48 +105,40 @@ constructor(
internal fun fetchRefereeTrackerForgeUI() {
launch {
_refereeTrackerData.emit(RefereeTrackerScreenState.Loading)
naviCacheRepository
.getDataAndFetchFromAltSource(
key = DBCacheConstants.REFEREE_TRACKER_SCREEN_CACHE_KEY,
version = CommonLibManager.buildConfigDetails.appVersionCode.toLongOrNull(),
getDataFromAltSource = { fetchScreenFromApi() },
isCurrentAndAltDataSame = { currentData, altData ->
currentData?.version == altData.version &&
currentData?.value == altData.value
},
emitMultipleValues = true,
)
.collect { response ->
deserializeWidgetResponseString(response)?.let {
initRefereeTrackerScreenImageCaching(it.screenStructure)
_refereeTrackerData.emit(RefereeTrackerScreenState.Success(it.copy()))
refereeTrackerRepo.fetchRefereeTrackerForgeElement().collect { result ->
val response = result.data
when {
result.isValidResponse() -> {
_refereeTrackerData.update {
RefereeTrackerScreenState.Success(response ?: ScreenDefinition())
}
initRefereeTrackerScreenImageCaching(response?.screenStructure)
if (result.isFromCache) {
setCachePresent()
}
}
setCachePresent()
}
}
}
}
internal fun fetchRefereeTrackerForgeUIV2() {
launch {
_refereeTrackerData.emit(RefereeTrackerScreenState.Loading)
naviCacheRepository
.getDataAndFetchFromAltSource(
key = DBCacheConstants.REFEREE_TRACKER_SCREEN_V2_CACHE_KEY,
version = CommonLibManager.buildConfigDetails.appVersionCode.toLongOrNull(),
getDataFromAltSource = { fetchScreenFromApiV2() },
isCurrentAndAltDataSame = { currentData, altData ->
currentData?.version == altData.version &&
currentData?.value == altData.value
},
emitMultipleValues = true,
)
.collect { response ->
deserializeWidgetResponseString(response)?.let {
initRefereeTrackerScreenImageCaching(it.screenStructure)
_refereeTrackerData.emit(RefereeTrackerScreenState.Success(it.copy()))
refereeTrackerRepo.fetchRefereeTrackerV2ForgeElement().collect { result ->
val response = result.data
when {
result.isValidResponse() -> {
_refereeTrackerData.update {
RefereeTrackerScreenState.Success(response ?: ScreenDefinition())
}
initRefereeTrackerScreenImageCaching(response?.screenStructure)
}
}
if (result.isFromCache) {
setCachePresent()
}
}
}
}
@@ -182,20 +164,13 @@ constructor(
fun fetchAndSaveRefereeTrackerScreenV2() {
launch {
val response = refereeTrackerRepo.fetchRefereeTrackerV2ForgeElement()
if (response.isValidResponse()) {
initRefereeTrackerScreenImageCaching(response.data?.screenStructure)
naviCacheRepository.save(
NaviCacheEntity(
key = DBCacheConstants.REFEREE_TRACKER_SCREEN_V2_CACHE_KEY,
value = getGsonBuilders().toJson(response.data).orEmpty(),
version =
CommonLibManager.buildConfigDetails.appVersionCode
.toIntOrNull()
.orVal(1)
)
)
refereeTrackerRepo.fetchRefereeTrackerV2ForgeElement().collect { response ->
if (response.isValidResponse()) {
initRefereeTrackerScreenImageCaching(response.data?.screenStructure)
if (response.isFromCache) {
setCachePresent()
}
}
}
}
}
@@ -213,36 +188,6 @@ constructor(
}
}
}
private suspend fun fetchScreenFromApi(): NaviCacheAltSourceEntity {
val response = refereeTrackerRepo.fetchRefereeTrackerForgeElement()
if (!response.isValidResponse()) {
showError(RRErrorData(statusCode = response.statusCode ?: ApiConstants.API_CODE_ERROR))
return NaviCacheAltSourceEntity(isSuccess = false)
}
return NaviCacheAltSourceEntity(
value = getGsonBuilders().toJson(response.data),
version = CommonLibManager.buildConfigDetails.appVersionCode.toIntOrNull(),
isSuccess = true
)
}
private suspend fun fetchScreenFromApiV2(): NaviCacheAltSourceEntity {
val response = refereeTrackerRepo.fetchRefereeTrackerV2ForgeElement()
if (!response.isValidResponse()) {
showError(RRErrorData(statusCode = response.statusCode ?: ApiConstants.API_CODE_ERROR))
return NaviCacheAltSourceEntity(isSuccess = false)
}
return NaviCacheAltSourceEntity(
value = getGsonBuilders().toJson(response.data),
version = CommonLibManager.buildConfigDetails.appVersionCode.toIntOrNull(),
isSuccess = true
)
}
}
sealed class RefereeTrackerScreenState {

View File

@@ -7,7 +7,6 @@
package com.navi.rr.referral.viewmodels
import com.navi.base.cache.repository.NaviCacheRepositoryImpl
import com.navi.base.utils.isNull
import com.navi.common.forge.model.ScreenDefinition
import com.navi.common.forge.model.ScreenStructure
@@ -39,8 +38,7 @@ class ReferralHomeVM
constructor(
private val referralHomeRepo: ReferralHomeRepo,
private val lottieRemoteHelper: LottieRemoteHelper,
val rrShareApp: RRShareApp,
private val naviCacheRepository: NaviCacheRepositoryImpl
val rrShareApp: RRShareApp
) : RRBaseVM() {
private val _referralHomeScreenData =
@@ -70,16 +68,19 @@ constructor(
fun fetchReferralForgeScreen() {
launch {
_referralHomeScreenData.emit(ReferralHomeScreenState.Loading)
val response = referralHomeRepo.fetchReferralForgeScreen()
if (response.isValidResponse()) {
response.data?.let { data ->
cacheImages(data.screenStructure)
_referralHomeScreenData.emit(ReferralHomeScreenState.Success(data))
referralHomeRepo.fetchReferralForgeScreen().collect { response ->
if (response.isValidResponse()) {
response.data?.let { data ->
cacheImages(data.screenStructure)
_referralHomeScreenData.emit(ReferralHomeScreenState.Success(data))
}
} else {
showError(
RRErrorData(
statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST
)
)
}
} else {
showError(
RRErrorData(statusCode = response.statusCode ?: ApiConstants.API_BAD_REQUEST)
)
}
}
}
@@ -87,11 +88,14 @@ constructor(
fun fetchReferralPopupScreen() {
launch {
_referralPopupScreenData.emit(ReferralGratificationScreenState.Loading)
val response = referralHomeRepo.fetchReferralPopupScreen()
if (response.isValidResponse()) {
response.data?.let { data ->
cacheImages(data.screenStructure)
_referralPopupScreenData.emit(ReferralGratificationScreenState.Success(data))
referralHomeRepo.fetchReferralPopupScreen().collect { response ->
if (response.isValidResponse()) {
response.data?.let { data ->
cacheImages(data.screenStructure)
_referralPopupScreenData.emit(
ReferralGratificationScreenState.Success(data)
)
}
}
}
}
@@ -120,13 +124,14 @@ constructor(
fun fetchLeaderboardPopUp() {
launch {
_referralLeaderboardPopupScreenData.emit(ReferralGratificationScreenState.Loading)
val response = referralHomeRepo.fetchLeaderboardPopUp()
if (response.error.isNull() && response.errors.isNullOrEmpty()) {
response.data?.let { data ->
cacheImages(data.screenStructure)
_referralLeaderboardPopupScreenData.emit(
ReferralGratificationScreenState.Success(data)
)
referralHomeRepo.fetchLeaderboardPopUp().collect { response ->
if (response.error.isNull() && response.errors.isNullOrEmpty()) {
response.data?.let { data ->
cacheImages(data.screenStructure)
_referralLeaderboardPopupScreenData.emit(
ReferralGratificationScreenState.Success(data)
)
}
}
}
}
@@ -134,9 +139,10 @@ constructor(
fun fetchAndSaveReferralHomeScreen() {
launch {
val response = referralHomeRepo.fetchReferralForgeScreen()
if (response.isValidResponse()) {
response.data?.let { initReferralHomeScreenImageCaching(it.screenStructure) }
referralHomeRepo.fetchReferralForgeScreen().collect { response ->
if (response.isValidResponse()) {
response.data?.let { initReferralHomeScreenImageCaching(it.screenStructure) }
}
}
}
}

View File

@@ -0,0 +1,29 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.rr.utils
import com.navi.common.network.models.RepoResult
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
class CacheHandlerProxy
@Inject
constructor(
val cacheManager: CacheManager,
) {
suspend inline fun <reified T> fetchData(
key: String? = null,
noinline fetchFromAlternativeSource: suspend () -> RepoResult<T>,
): Flow<RepoResult<T>> {
return if (key != null) {
cacheManager.fetchAndCacheData(key, fetchFromAlternativeSource)
} else {
cacheManager.fetchData(fetchFromAlternativeSource)
}
}
}

View File

@@ -0,0 +1,72 @@
/*
*
* * Copyright © 2024 by Navi Technologies Limited
* * All rights reserved. Strictly confidential
*
*/
package com.navi.rr.utils
import com.navi.base.cache.model.NaviCacheAltSourceEntity
import com.navi.base.cache.repository.NaviCacheRepositoryImpl
import com.navi.base.utils.orFalse
import com.navi.common.network.models.RepoResult
import com.navi.common.utils.isValidResponse
import com.navi.rr.common.ext.toType
import javax.inject.Inject
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
class CacheManager
@Inject
constructor(
val cacheRepository: NaviCacheRepositoryImpl,
) {
val cacheMutex by lazy { Mutex() }
suspend inline fun <reified T> fetchData(
noinline fetchFromAlternativeSource: suspend () -> RepoResult<T>,
) = flowOf(fetchFromAlternativeSource())
suspend inline fun <reified T> fetchAndCacheData(
key: String,
noinline fetchFromAlternativeSource: suspend () -> RepoResult<T>,
) = cacheRepository.getAndFetchDataFromAlternativeSource(key, fetchFromAlternativeSource)
suspend inline fun <reified T> NaviCacheRepositoryImpl.getAndFetchDataFromAlternativeSource(
key: String,
noinline fetchFromAlternativeSource: suspend () -> RepoResult<T>,
) = flow {
// Checking if the current value exists in the database
val cachedValue = get(key = key)
if (cachedValue != null) {
emit(RepoResult(data = cachedValue.value.toType<T>(), isFromCache = true))
}
// Fetching data from alternate source
val fetchResult = fetchFromAlternativeSource()
emit(fetchResult)
// Creating an entity to store data from the alternative source
val altSourceEntity =
NaviCacheAltSourceEntity(
value = fetchResult.data.toJson(),
isSuccess = fetchResult.isValidResponse()
)
// Checking if the retrieved data is valid
altSourceEntity
.takeIf { it.value != null && it.isSuccess.orFalse() }
?.let {
// Creating a cache entity to store the retrieved data
val cacheEntity = it.toNaviCacheEntity(key)
// Safely saving the cache entity using a mutex lock
cacheMutex.withLock { save(naviCacheEntity = cacheEntity) }
}
}
}

View File

@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout

View File

@@ -6,9 +6,7 @@
~ * All rights reserved. Strictly confidential
~
-->
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.compose.ui.platform.ComposeView
android:layout_width="match_parent"
android:id="@+id/compose_view"