So here is an android/kotlin question we discussed...
# android
c
So here is an android/kotlin question we discussed in our mob yesterday. We have a chat channel and we show a since label (how long since the message was sent). Of course this should update right? 5 minutes from now it should say ‘5 minutes ago,’ 10 minutes ago 10. Right? So the question is this: the whole idea in LiveData to trigger observers on sets called on the Viewmodel property. Thing is of course, this is a computed field. I did not find anything about this, which surprised me. What would be the best approach (it’s computed of course as a time interval from posted to now).
e
schedule an update when the value should change? the code below is totally untested (because it would be a pain to) but something along these lines…
Copy code
fun relativeDateTimeLiveData(context: Context, millis: Long): Flow<CharSequence> = flow {
    while (true) {
        val elapsed = System.currentTimeMillis() - millis
        emit(DateUtils.getRelativeDateTimeString(context, millis, DateUtils.SECOND_IN_MILLIS, DateUtils.WEEK_IN_MILLIS, 0))
        val interval = when (elapsed) {
            in (1 - DateUtils.MINUTE_IN_MILLIS) until DateUtils.MINUTE_IN_MILLIS -> DateUtils.SECOND_IN_MILLIS
            in (1 - DateUtils.HOUR_IN_MILLIS) until DateUtils.HOUR_IN_MILLIS -> DateUtils.MINUTE_IN_MILLIS
            in (1 - DateUtils.DAY_IN_MILLIS) until DateUtils.DAY_IN_MILLIS -> DateUtils.HOUR_IN_MILLIS
            in (1 - DateUtils.WEEK_IN_MILLIS) until DateUtils.WEEK_IN_MILLIS -> DateUtils.DAY_IN_MILLIS
            else -> break
        }
        delay(interval - elapsed.mod(interval))
    }
}
👍🏻 1
j
We do something similar, we collectLatest on the flow that contains an object with the date, then in the while loop do this updating. I think a flatMapLatest would work as well. Nice part is that if the date changes, the block is cancelled and therefore the while loop breaks and it starts again with the new date. Then when the (viewModel/lifecycle)Scope gets closed everything gets cleaned up nicely.