feat(update): notify about app updates on launch (chat banner) (#891)
Fires one silent update check per installed version at app start (UpdateNoticeManager, release builds only) and shows a non-blocking banner on the chat screen when a newer release exists. The About tab adopts the launch result instead of re-pinging GitHub; dismissals return on the next launch via the persisted latest tag. Closes #890 Co-authored-by: M57 <hy4ri@users.noreply.github.com>
This commit is contained in:
1 parent
ff8370bb8d
commit
daf33dcb4c
14 files changed
+535
-31
No files matched your search
@@ -8,8 +8,11 @@ import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.m57.hermescontrol.BuildConfig
|
||||
import com.m57.hermescontrol.data.local.AuthManager
|
||||
import com.m57.hermescontrol.data.update.AppUpdateCache
|
||||
import com.m57.hermescontrol.data.update.AppUpdateChecker
|
||||
import com.m57.hermescontrol.data.update.AppUpdateState
|
||||
import com.m57.hermescontrol.data.update.isNewerVersion
|
||||
import com.m57.hermescontrol.data.update.releaseTag
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -19,36 +22,6 @@ import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
/** UI state of the About-tab in-app updater (issue #867). */
|
||||
sealed interface AppUpdateState {
|
||||
/** Nothing shown yet (no check run in this session). */
|
||||
data object Idle : AppUpdateState
|
||||
|
||||
/** A check is in flight. */
|
||||
data object Checking : AppUpdateState
|
||||
|
||||
/** Latest release equals the installed version. */
|
||||
data class UpToDate(val latestTag: String) : AppUpdateState
|
||||
|
||||
/** A newer release with an APK asset exists. */
|
||||
data class UpdateAvailable(
|
||||
val latestTag: String,
|
||||
val apkUrl: String,
|
||||
val sizeBytes: Long,
|
||||
) : AppUpdateState
|
||||
|
||||
/** APK download in progress; [progress] is 0..1. */
|
||||
data class Downloading(val progress: Float) : AppUpdateState
|
||||
|
||||
/** Download finished and the system package installer was launched. */
|
||||
data class Installing(val latestTag: String) : AppUpdateState
|
||||
|
||||
/** Install-from-unknown-sources not granted for this app yet. */
|
||||
data object NeedsUnknownSourcesPermission : AppUpdateState
|
||||
|
||||
data class Error(val message: String) : AppUpdateState
|
||||
}
|
||||
|
||||
/**
|
||||
* Drives the in-app self-update flow (issue #867): check the GitHub
|
||||
* releases API, download the release APK, and hand it to the system package
|
||||
@@ -76,6 +49,14 @@ class AppUpdateViewModel(
|
||||
// on every visit.
|
||||
if (AuthManager.getUpdateCheckDoneForVersion() != currentVersion) {
|
||||
checkForUpdate()
|
||||
} else {
|
||||
// Issue #890: the launch check (UpdateNoticeManager) already ran
|
||||
// for this version — adopt its result instead of pinging GitHub
|
||||
// again, so the About tab agrees with the chat banner.
|
||||
val cached = AppUpdateCache.state.value
|
||||
if (cached is AppUpdateState.UpdateAvailable || cached is AppUpdateState.UpToDate) {
|
||||
_state.value = cached
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +96,9 @@ class AppUpdateViewModel(
|
||||
} else {
|
||||
AppUpdateState.UpToDate(latestTag = info.tagName)
|
||||
}
|
||||
// Keep the launch notice (issue #890) in sync with manual checks.
|
||||
AppUpdateCache.update(_state.value)
|
||||
_state.value.releaseTag()?.let { AuthManager.setLastKnownLatestTag(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.m57.hermescontrol.BuildConfig
|
||||
import com.m57.hermescontrol.R
|
||||
import com.m57.hermescontrol.ui.settings.AppUpdateState
|
||||
import com.m57.hermescontrol.data.update.AppUpdateState
|
||||
import com.m57.hermescontrol.ui.settings.InfoRow
|
||||
import com.m57.hermescontrol.ui.settings.SectionCard
|
||||
|
||||
|
||||
Reference in new issue
Block a user