Created
December 8, 2023 00:26
-
-
Save victory316/0d349d278ca0c0bd9f39d42b31d03b90 to your computer and use it in GitHub Desktop.
Conditional event checker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private const val KEY_LAST_ACCESS = "KEY_LAST_ACCESS" | |
private const val KEY_SENT_EVENT = "KEY_SENT_EVENT" | |
private const val KEY_RETENTION_DAY_COUNT = "KEY_RETENTION_DAY_COUNT" | |
class SingularConditionEventChecker @Inject constructor( | |
private val logger: AnalyticsLogger, | |
private val preferenceRepository: PreferencesRepository, | |
@Dispatcher(IO) private val ioDispatcher: CoroutineDispatcher | |
) { | |
private var lastAccessDate: LocalDate? = null | |
private var retentionDayCount: Int? = null | |
private var sentEvents: Set<String> = setOf() | |
private var dataLoaded = false | |
private var actionQueued = false | |
private val targetEvents = listOf( | |
DayTwoRetentionEvent( | |
condition = { retentionDayCount == 2 }, | |
eventToSend = Event.DayTwoRetention | |
), | |
DayFiveRetentionEvent( | |
condition = { retentionDayCount == 5 }, | |
eventToSend = Event.DayFiveRetention | |
) | |
) | |
init { | |
CoroutineScope(ioDispatcher).launch { | |
combine( | |
preferenceRepository.getInteger(KEY_RETENTION_DAY_COUNT), | |
preferenceRepository.getLong(KEY_LAST_ACCESS), | |
preferenceRepository.getStringSet(KEY_SENT_EVENT) | |
) { dayCount, lastAccess, sentEvent -> | |
retentionDayCount = dayCount | |
lastAccessDate = lastAccess?.let { LocalDate.ofEpochDay(it) } | |
if (sentEvent != null) { | |
sentEvents = sentEvent | |
} | |
}.collect { | |
dataLoaded = true | |
if (actionQueued) { | |
updateConditionData() | |
checkEventsCondition() | |
actionQueued = false | |
} | |
} | |
} | |
} | |
fun doOnForeground() { | |
if (dataLoaded) { | |
updateConditionData() | |
checkEventsCondition() | |
} else { | |
actionQueued = true | |
} | |
} | |
private fun checkEventsCondition() { | |
targetEvents.forEach { event -> | |
if (event.isSatisfied() && !isEventLogged(event.getEventHash())) { | |
logger.logEvent(event.eventToSend) | |
saveSentEvent(event.getEventHash()) | |
} | |
} | |
} | |
private fun updateConditionData() { | |
CoroutineScope(ioDispatcher).launch { | |
try { | |
val betweenDaysInLastAccess = ChronoUnit.DAYS.between( | |
lastAccessDate, | |
LocalDate.now() | |
) | |
if (betweenDaysInLastAccess == 1L) { | |
updatePreferences((retentionDayCount ?: 0).plus(1)) | |
} else if (betweenDaysInLastAccess >= 2L) { | |
updatePreferences(0) | |
} | |
} catch (ignored: NullPointerException) { | |
updatePreferences(0) | |
} | |
} | |
} | |
private suspend fun updatePreferences(retentionDayCount: Int) { | |
preferenceRepository.saveLong( | |
key = KEY_LAST_ACCESS, | |
data = LocalDate.now().toEpochDay() | |
) | |
preferenceRepository.saveInteger( | |
key = KEY_RETENTION_DAY_COUNT, | |
data = retentionDayCount | |
) | |
} | |
private fun isEventLogged(eventHash: String) = sentEvents.contains(eventHash) | |
private fun saveSentEvent(eventHash: String) { | |
CoroutineScope(ioDispatcher).launch { | |
preferenceRepository.saveStringSet( | |
key = KEY_SENT_EVENT, | |
data = sentEvents.toMutableSet().apply { | |
add(eventHash) | |
}.toSet() | |
) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment