add launcher update check

This commit is contained in:
qimiko committed 2024-01-23 03:15:39 -07:00
1 parent 199b6f142b
commit 7f64236e89
8 files changed
+139 -11

No files matched your search

@@ -23,7 +23,8 @@ class Release(
val tagName: String,
val createdAt: Instant,
val publishedAt: Instant,
val assets: List<Asset>
val assets: List<Asset>,
val htmlUrl: String
) {
fun getDescription(): String {
if (tagName == "nightly") {
@@ -42,7 +43,7 @@ class Release(
return createdAt.epochSeconds
}
fun getAndroidDownload(): Asset? {
fun getGeodeDownload(): Asset? {
// try to find an asset that matches the architecture first
val platform = LaunchUtils.platformName
@@ -51,4 +52,22 @@ class Release(
it.name.endsWith(releaseSuffix)
}
}
fun getLauncherDownload(): Asset? {
val platform = LaunchUtils.platformName
val use32BitPlatform = platform == "android32"
return assets.find { asset ->
/* you know it's good when you pull out the truth table
* u32bp | contains | found
* 1 | 1 | 1
* 0 | 1 | 0
* 1 | 0 | 0
* 0 | 0 | 1
* surprise! it's an xnor
*/
(asset.name.contains("android32")) == use32BitPlatform
}
}
}
@@ -2,6 +2,8 @@ package com.geode.launcher.updater
import android.content.Context
import android.util.Log
import androidx.compose.runtime.mutableStateOf
import com.geode.launcher.BuildConfig
import com.geode.launcher.utils.DownloadUtils
import com.geode.launcher.utils.LaunchUtils
import com.geode.launcher.utils.PreferenceUtils
@@ -77,6 +79,9 @@ class ReleaseManager private constructor(
val isInUpdate: Boolean
get() = _uiState.value !is ReleaseManagerState.Failure && _uiState.value !is ReleaseManagerState.Finished
private val _availableLauncherUpdate = MutableStateFlow<Release?>(null)
val availableLauncherUpdate = _availableLauncherUpdate.asStateFlow()
private fun sendError(e: Exception) {
_uiState.value = ReleaseManagerState.Failure(e)
@@ -87,6 +92,15 @@ class ReleaseManager private constructor(
}
}
fun dismissLauncherUpdate() {
val update = availableLauncherUpdate.value ?: return
val sharedPreferences = PreferenceUtils.get(applicationContext)
sharedPreferences.setString(PreferenceUtils.Key.LAST_DISMISSED_UPDATE, update.tagName)
_availableLauncherUpdate.value = null
}
private suspend fun getLatestRelease(): Release? {
val sharedPreferences = PreferenceUtils.get(applicationContext)
val useNightly = sharedPreferences.getBoolean(PreferenceUtils.Key.RELEASE_CHANNEL)
@@ -95,7 +109,7 @@ class ReleaseManager private constructor(
}
private suspend fun performUpdate(release: Release) {
val releaseAsset = release.getAndroidDownload()
val releaseAsset = release.getGeodeDownload()
if (releaseAsset == null) {
val noAssetException = Exception("missing Android download")
_uiState.value = ReleaseManagerState.Failure(noAssetException)
@@ -153,6 +167,24 @@ class ReleaseManager private constructor(
return originalFileHash != currentFileHash
}
private fun checkLauncherUpdate(launcherUpdate: Release) {
if (BuildConfig.DEBUG) {
println("ignoring launcher update check - in debug mode!")
return
}
val sharedPreferences = PreferenceUtils.get(applicationContext)
val lastDismissedVersion = sharedPreferences.getString(PreferenceUtils.Key.LAST_DISMISSED_UPDATE)
if (!lastDismissedVersion.isNullOrEmpty() && launcherUpdate.tagName == lastDismissedVersion) {
return
}
if (launcherUpdate.tagName != BuildConfig.VERSION_NAME) {
_availableLauncherUpdate.value = launcherUpdate
}
}
private suspend fun checkForNewRelease(allowOverwriting: Boolean = false) {
val release = try {
getLatestRelease()
@@ -161,6 +193,17 @@ class ReleaseManager private constructor(
return
}
val launcherRelease = try {
releaseRepository.getLatestLauncherRelease()
} catch (e: Exception) {
sendError(e)
return
}
if (launcherRelease != null) {
checkLauncherUpdate(launcherRelease)
}
if (release == null) {
_uiState.value = ReleaseManagerState.Finished()
return
@@ -43,8 +43,6 @@ class ReleaseRepository(private val httpClient: OkHttpClient) {
.addHeader(GITHUB_API_HEADER, GITHUB_API_VERSION)
.build()
println("fetching url $url")
val call = httpClient.newCall(request)
val response = call.executeCoroutine()
@@ -7,6 +7,7 @@ import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.AP
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
@@ -52,6 +53,8 @@ class ReleaseViewModel(private val application: Application): ViewModel() {
val isInUpdate
get() = ReleaseManager.get(application).isInUpdate
val nextLauncherUpdate = ReleaseManager.get(application).availableLauncherUpdate
var hasPerformedCheck = false
private set
@@ -77,7 +80,7 @@ class ReleaseViewModel(private val application: Application): ViewModel() {
fun useGlobalCheckState() {
hasPerformedCheck = true
viewModelScope.launch {
viewModelScope.launch(Dispatchers.IO) {
val releaseFlow = ReleaseManager.get(application)
.uiState
@@ -88,11 +91,17 @@ class ReleaseViewModel(private val application: Application): ViewModel() {
fun runReleaseCheck(isManual: Boolean = false) {
hasPerformedCheck = true
viewModelScope.launch {
viewModelScope.launch(Dispatchers.IO) {
val releaseFlow = ReleaseManager.get(application)
.checkForUpdates(isManual)
syncUiState(releaseFlow)
}
}
fun dismissLauncherUpdate() {
viewModelScope.launch(Dispatchers.IO) {
ReleaseManager.get(application).dismissLauncherUpdate()
}
}
}