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:
parent
5424dfb385
commit
ecbe98f9e4
3 changed files with 68 additions and 63 deletions
|
@ -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
|
||||
|
|
|
@ -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>> {
|
||||
|
|
13
app/src/main/java/be/digitalia/fosdem/model/LoadingState.kt
Normal file
13
app/src/main/java/be/digitalia/fosdem/model/LoadingState.kt
Normal 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>()
|
||||
}
|
Loading…
Reference in a new issue