mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-08-29 07:16:08 +00:00
fix: clear the downloading state when a download is cancelled
Addresses review on #812. Pressing the new stop button before a partial file exists -- while resolving the release, or waiting for Tor -- left the row disabled and spinning for the lifetime of the ViewModel. Two guards conspired: checkStatus() returns early while the state is Downloading, and the downloader observer deliberately ignores the Idle that WorkManager reports for a cancelled job. Both exist to stop a running job being second-guessed from cache contents, and neither anticipated a job that is no longer running. checkStatus() takes a force flag, used only by cancellation, and clears the stale progress along with the status. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b79ae8e7f1
commit
8e5bb2ea9a
@ -196,7 +196,12 @@ class ApkDownloadViewModel(application: Application) : AndroidViewModel(applicat
|
|||||||
|
|
||||||
private fun onCancelDownload() {
|
private fun onCancelDownload() {
|
||||||
downloader.cancelDownload()
|
downloader.cancelDownload()
|
||||||
checkStatus()
|
|
||||||
|
// Nothing else will move the UI off the spinner. checkStatus() refuses to
|
||||||
|
// overwrite a Downloading state, and the Idle that WorkManager reports for a
|
||||||
|
// cancelled job is ignored for the same reason -- both guards protect a job
|
||||||
|
// that is still running, which this one is not.
|
||||||
|
checkStatus(force = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startDownload() {
|
private fun startDownload() {
|
||||||
@ -210,21 +215,26 @@ class ApkDownloadViewModel(application: Application) : AndroidViewModel(applicat
|
|||||||
downloader.startDownload()
|
downloader.startDownload()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkStatus() {
|
/**
|
||||||
|
* @param force resolve even while the state says Downloading. Only cancellation
|
||||||
|
* should pass true: the guard below exists so a running job is never second-guessed
|
||||||
|
* from cache contents, but a cancelled one has no other route out of that state.
|
||||||
|
*/
|
||||||
|
private fun checkStatus(force: Boolean = false) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
// WorkManager is the source of truth for active work. A queued or
|
// WorkManager is the source of truth for active work. A queued or
|
||||||
// newly started job legitimately has no partial file yet, so never
|
// newly started job legitimately has no partial file yet, so never
|
||||||
// infer that it is orphaned from cache contents.
|
// infer that it is orphaned from cache contents.
|
||||||
if (_state.value.apkStatus is ApkPreparationStatus.Downloading) {
|
if (!force && _state.value.apkStatus is ApkPreparationStatus.Downloading) {
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
|
|
||||||
val resolvedStatus = resolveApkStatus()
|
val resolvedStatus = resolveApkStatus()
|
||||||
_state.update { current ->
|
_state.update { current ->
|
||||||
if (current.apkStatus is ApkPreparationStatus.Downloading) {
|
if (!force && current.apkStatus is ApkPreparationStatus.Downloading) {
|
||||||
current
|
current
|
||||||
} else {
|
} else {
|
||||||
current.copy(apkStatus = resolvedStatus)
|
current.copy(apkStatus = resolvedStatus, downloadProgress = 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user