1
0
Fork 0
mirror of https://github.com/MatomoCamp/matomocamp-companion-android.git synced 2024-09-19 16:13:46 +02:00

combine download schedule progress and result into LoadingState

This commit is contained in:
Christophe Beyls 2020-05-02 00:46:14 +02:00
parent 5424dfb385
commit ecbe98f9e4
3 changed files with 68 additions and 63 deletions

View file

@ -37,6 +37,7 @@ import be.digitalia.fosdem.api.FosdemUrls
import be.digitalia.fosdem.db.AppDatabase
import be.digitalia.fosdem.fragments.*
import be.digitalia.fosdem.model.DownloadScheduleResult
import be.digitalia.fosdem.model.LoadingState
import be.digitalia.fosdem.utils.*
import be.digitalia.fosdem.widgets.FadeOutViewMediator
import com.google.android.material.navigation.NavigationView
@ -95,50 +96,52 @@ class MainActivity : AppCompatActivity(R.layout.main), CreateNfcAppDataCallback
// Progress bar setup
val progressBar: ProgressBar = findViewById(R.id.progress)
val progressBarMediator = FadeOutViewMediator(progressBar)
FosdemApi.downloadScheduleProgress.observe(this) { progressValue ->
if (progressValue != 100) {
// Visible
progressBarMediator.isVisible = true
with(progressBar) {
if (progressValue == -1) {
isIndeterminate = true
} else {
isIndeterminate = false
progress = progressValue
}
}
} else {
// Invisible
progressBarMediator.isVisible = false
with(progressBar) {
isIndeterminate = false
progress = 100
}
}
}
// Monitor the schedule download result
FosdemApi.downloadScheduleResult.observe(this) { singleEvent ->
val result = singleEvent.consume() ?: return@observe
val snackbar = when (result) {
is DownloadScheduleResult.Error -> {
Snackbar.make(contentView, R.string.schedule_loading_error, ERROR_MESSAGE_DISPLAY_DURATION)
.setAction(R.string.schedule_loading_retry_action) { FosdemApi.downloadSchedule(this) }
}
is DownloadScheduleResult.UpToDate -> {
Snackbar.make(contentView, R.string.events_download_up_to_date, Snackbar.LENGTH_LONG)
}
is DownloadScheduleResult.Success -> {
val eventsCount = result.eventsCount
val message = if (eventsCount == 0) {
getString(R.string.events_download_empty)
} else {
resources.getQuantityString(R.plurals.events_download_completed, eventsCount, eventsCount)
// Monitor the schedule download
FosdemApi.downloadScheduleState.observe(this) { state ->
when (state) {
is LoadingState.Loading -> {
progressBarMediator.isVisible = true
with(progressBar) {
val progressValue = state.progress
if (progressValue == -1) {
isIndeterminate = true
} else {
isIndeterminate = false
progress = progressValue
}
}
}
is LoadingState.Idle -> {
progressBarMediator.isVisible = false
with(progressBar) {
isIndeterminate = false
progress = 100
}
state.result.consume()?.let { result ->
val snackbar = when (result) {
is DownloadScheduleResult.Error -> {
Snackbar.make(contentView, R.string.schedule_loading_error, ERROR_MESSAGE_DISPLAY_DURATION)
.setAction(R.string.schedule_loading_retry_action) { FosdemApi.downloadSchedule(this) }
}
is DownloadScheduleResult.UpToDate -> {
Snackbar.make(contentView, R.string.events_download_up_to_date, Snackbar.LENGTH_LONG)
}
is DownloadScheduleResult.Success -> {
val eventsCount = result.eventsCount
val message = if (eventsCount == 0) {
getString(R.string.events_download_empty)
} else {
resources.getQuantityString(R.plurals.events_download_completed, eventsCount, eventsCount)
}
Snackbar.make(contentView, message, Snackbar.LENGTH_LONG)
}
}
snackbar.show()
}
Snackbar.make(contentView, message, Snackbar.LENGTH_LONG)
}
}
snackbar.show()
}
// Setup drawer layout

View file

@ -13,6 +13,7 @@ import be.digitalia.fosdem.db.AppDatabase
import be.digitalia.fosdem.livedata.LiveDataFactory.scheduler
import be.digitalia.fosdem.livedata.SingleEvent
import be.digitalia.fosdem.model.DownloadScheduleResult
import be.digitalia.fosdem.model.LoadingState
import be.digitalia.fosdem.model.RoomStatus
import be.digitalia.fosdem.parsers.EventsParser
import be.digitalia.fosdem.parsers.RoomStatusesParser
@ -42,8 +43,7 @@ object FosdemApi {
private const val ROOM_STATUS_EXPIRATION_DELAY = 6L * DateUtils.MINUTE_IN_MILLIS
private var downloadJob: Job? = null
private val _downloadScheduleProgress = MutableLiveData<Int>()
private val _downloadScheduleResult = MutableLiveData<SingleEvent<DownloadScheduleResult>>()
private val _downloadScheduleState = MutableLiveData<LoadingState<DownloadScheduleResult>>()
private var roomStatuses: LiveData<Map<String, RoomStatus>>? = null
/**
@ -67,7 +67,7 @@ object FosdemApi {
@MainThread
private suspend fun downloadScheduleInternal(context: Context) {
_downloadScheduleProgress.value = -1
_downloadScheduleState.value = LoadingState.Loading()
val res = try {
val scheduleDao = AppDatabase.getInstance(context).scheduleDao
val response = HttpUtils.get(FosdemUrls.schedule, scheduleDao.lastModifiedTag) { body, rawResponse ->
@ -77,7 +77,7 @@ object FosdemApi {
ByteCountSource(body.source(), length / 10L) { byteCount ->
// Cap percent to 100
val percent = (byteCount * 100L / length).toInt().coerceAtMost(100)
_downloadScheduleProgress.postValue(percent)
_downloadScheduleState.postValue(LoadingState.Loading(percent))
}.buffer()
} else {
body.source()
@ -87,31 +87,20 @@ object FosdemApi {
scheduleDao.storeSchedule(events, rawResponse.lastModified)
}
when (response) {
is HttpUtils.Response.NotModified -> DownloadScheduleResult.UpToDate // Nothing to parse, the result is up-to-date
is HttpUtils.Response.Success -> DownloadScheduleResult.Success(response.body)
is HttpUtils.Response.NotModified -> DownloadScheduleResult.UpToDate // Nothing parsed, the result is up-to-date
is HttpUtils.Response.Success -> {
FosdemAlarmManager.onScheduleRefreshed()
DownloadScheduleResult.Success(response.body)
}
}
} catch (e: Exception) {
DownloadScheduleResult.Error
}
_downloadScheduleProgress.value = 100
if (res is DownloadScheduleResult.Success) {
FosdemAlarmManager.onScheduleRefreshed()
}
_downloadScheduleResult.value = SingleEvent(res)
_downloadScheduleState.value = LoadingState.Idle(SingleEvent(res))
}
/**
* @return The current schedule download progress:
* -1 : in progress, indeterminate
* 0..99: progress value
* 100 : download complete or inactive
*/
val downloadScheduleProgress: LiveData<Int>
get() = _downloadScheduleProgress
val downloadScheduleResult: LiveData<SingleEvent<DownloadScheduleResult>>
get() = _downloadScheduleResult
val downloadScheduleState: LiveData<LoadingState<DownloadScheduleResult>>
get() = _downloadScheduleState
@MainThread
fun getRoomStatuses(context: Context): LiveData<Map<String, RoomStatus>> {

View file

@ -0,0 +1,13 @@
package be.digitalia.fosdem.model
import be.digitalia.fosdem.livedata.SingleEvent
sealed class LoadingState<out T : Any> {
/**
* The current download progress:
* -1 : in progress, indeterminate
* 0..99: progress value in percents
*/
class Loading(val progress: Int = -1) : LoadingState<Nothing>()
class Idle<T : Any>(val result: SingleEvent<T>) : LoadingState<T>()
}