Fix update version check
This commit is contained in:
@@ -4,7 +4,6 @@ import android.os.Build
|
|||||||
import io.nekohasekai.libbox.Libbox
|
import io.nekohasekai.libbox.Libbox
|
||||||
import io.nekohasekai.sfa.BuildConfig
|
import io.nekohasekai.sfa.BuildConfig
|
||||||
import io.nekohasekai.sfa.ktx.unwrap
|
import io.nekohasekai.sfa.ktx.unwrap
|
||||||
import io.nekohasekai.sfa.update.UpdateCheckException
|
|
||||||
import io.nekohasekai.sfa.update.UpdateInfo
|
import io.nekohasekai.sfa.update.UpdateInfo
|
||||||
import io.nekohasekai.sfa.update.UpdateTrack
|
import io.nekohasekai.sfa.update.UpdateTrack
|
||||||
import io.nekohasekai.sfa.utils.HTTPClient
|
import io.nekohasekai.sfa.utils.HTTPClient
|
||||||
@@ -27,18 +26,25 @@ class GitHubUpdateChecker : Closeable {
|
|||||||
private val json = Json { ignoreUnknownKeys = true }
|
private val json = Json { ignoreUnknownKeys = true }
|
||||||
|
|
||||||
fun checkUpdate(track: UpdateTrack): UpdateInfo? {
|
fun checkUpdate(track: UpdateTrack): UpdateInfo? {
|
||||||
val includePrerelease = track == UpdateTrack.BETA
|
val releases = getReleases()
|
||||||
val release = getLatestRelease(includePrerelease) ?: return null
|
var selected: ReleaseCandidate? = null
|
||||||
|
|
||||||
if (!release.assets.any { it.name == METADATA_FILENAME }) {
|
for (release in releases) {
|
||||||
throw UpdateCheckException.TrackNotSupported()
|
if (!isReleaseInTrack(release, track)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val metadata = runCatching { downloadMetadata(release) }.getOrNull() ?: continue
|
||||||
|
if (!isNewerThanCurrent(metadata.versionName)) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
val currentBest = selected
|
||||||
|
if (currentBest == null || isBetterVersion(metadata, currentBest.metadata)) {
|
||||||
|
selected = ReleaseCandidate(release, metadata)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val metadata = downloadMetadata(release)!!
|
val release = selected?.release ?: return null
|
||||||
|
val metadata = selected.metadata
|
||||||
if (metadata.versionCode <= BuildConfig.VERSION_CODE) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val isLegacy = Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
val isLegacy = Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||||
val apkAsset = release.assets.find { asset ->
|
val apkAsset = release.assets.find { asset ->
|
||||||
@@ -58,7 +64,7 @@ class GitHubUpdateChecker : Closeable {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLatestRelease(includePrerelease: Boolean): GitHubRelease? {
|
private fun getReleases(): List<GitHubRelease> {
|
||||||
val request = client.newRequest()
|
val request = client.newRequest()
|
||||||
request.setURL(RELEASES_URL)
|
request.setURL(RELEASES_URL)
|
||||||
request.setHeader("Accept", "application/vnd.github.v3+json")
|
request.setHeader("Accept", "application/vnd.github.v3+json")
|
||||||
@@ -67,13 +73,31 @@ class GitHubUpdateChecker : Closeable {
|
|||||||
val response = request.execute()
|
val response = request.execute()
|
||||||
val content = response.content.unwrap
|
val content = response.content.unwrap
|
||||||
|
|
||||||
val releases = json.decodeFromString<List<GitHubRelease>>(content)
|
return json.decodeFromString(content)
|
||||||
|
}
|
||||||
|
|
||||||
return if (includePrerelease) {
|
private fun isReleaseInTrack(release: GitHubRelease, track: UpdateTrack): Boolean {
|
||||||
releases.firstOrNull()
|
if (release.draft) {
|
||||||
} else {
|
return false
|
||||||
releases.firstOrNull { !it.prerelease && !it.draft }
|
|
||||||
}
|
}
|
||||||
|
return when (track) {
|
||||||
|
UpdateTrack.STABLE -> !release.prerelease
|
||||||
|
UpdateTrack.BETA -> true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isNewerThanCurrent(versionName: String): Boolean {
|
||||||
|
return Libbox.compareSemver(versionName, BuildConfig.VERSION_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isBetterVersion(version: VersionMetadata, other: VersionMetadata): Boolean {
|
||||||
|
if (Libbox.compareSemver(version.versionName, other.versionName)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (Libbox.compareSemver(other.versionName, version.versionName)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return version.versionCode > other.versionCode
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun downloadMetadata(release: GitHubRelease): VersionMetadata? {
|
private fun downloadMetadata(release: GitHubRelease): VersionMetadata? {
|
||||||
@@ -117,4 +141,9 @@ class GitHubUpdateChecker : Closeable {
|
|||||||
@SerialName("version_code") val versionCode: Int = 0,
|
@SerialName("version_code") val versionCode: Int = 0,
|
||||||
@SerialName("version_name") val versionName: String = "",
|
@SerialName("version_name") val versionName: String = "",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private data class ReleaseCandidate(
|
||||||
|
val release: GitHubRelease,
|
||||||
|
val metadata: VersionMetadata,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ class MainActivity :
|
|||||||
val updateInfo = Vendor.checkUpdateAsync()
|
val updateInfo = Vendor.checkUpdateAsync()
|
||||||
UpdateState.setUpdate(updateInfo)
|
UpdateState.setUpdate(updateInfo)
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
|
UpdateState.setUpdate(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -495,6 +496,7 @@ class MainActivity :
|
|||||||
val result = Vendor.checkUpdateAsync()
|
val result = Vendor.checkUpdateAsync()
|
||||||
UpdateState.setUpdate(result)
|
UpdateState.setUpdate(result)
|
||||||
} catch (_: Exception) {
|
} catch (_: Exception) {
|
||||||
|
UpdateState.setUpdate(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -188,6 +188,7 @@ fun AppSettingsScreen(navController: NavController) {
|
|||||||
currentTrack = currentTrack,
|
currentTrack = currentTrack,
|
||||||
onTrackSelected = { track ->
|
onTrackSelected = { track ->
|
||||||
currentTrack = track
|
currentTrack = track
|
||||||
|
UpdateState.clear()
|
||||||
scope.launch(Dispatchers.IO) {
|
scope.launch(Dispatchers.IO) {
|
||||||
Settings.updateTrack = track
|
Settings.updateTrack = track
|
||||||
}
|
}
|
||||||
@@ -932,25 +933,25 @@ fun AppSettingsScreen(navController: NavController) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.clickable(enabled = !isChecking) {
|
.clickable(enabled = !isChecking) {
|
||||||
if (hasUpdate && updateInfo != null) {
|
scope.launch {
|
||||||
showUpdateAvailableDialog = true
|
UpdateState.isChecking.value = true
|
||||||
} else {
|
withContext(Dispatchers.IO) {
|
||||||
scope.launch {
|
try {
|
||||||
UpdateState.isChecking.value = true
|
val result = Vendor.checkUpdateAsync()
|
||||||
withContext(Dispatchers.IO) {
|
UpdateState.setUpdate(result)
|
||||||
try {
|
if (result == null) {
|
||||||
val result = Vendor.checkUpdateAsync()
|
showErrorDialog = R.string.no_updates_available
|
||||||
UpdateState.setUpdate(result)
|
} else {
|
||||||
if (result == null) {
|
showUpdateAvailableDialog = true
|
||||||
showErrorDialog = R.string.no_updates_available
|
|
||||||
}
|
|
||||||
} catch (_: UpdateCheckException.TrackNotSupported) {
|
|
||||||
showErrorDialog = R.string.update_track_not_supported
|
|
||||||
} catch (_: Exception) {
|
|
||||||
}
|
}
|
||||||
|
} catch (_: UpdateCheckException.TrackNotSupported) {
|
||||||
|
UpdateState.setUpdate(null)
|
||||||
|
showErrorDialog = R.string.update_track_not_supported
|
||||||
|
} catch (_: Exception) {
|
||||||
|
UpdateState.setUpdate(null)
|
||||||
}
|
}
|
||||||
UpdateState.isChecking.value = false
|
|
||||||
}
|
}
|
||||||
|
UpdateState.isChecking.value = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
colors =
|
colors =
|
||||||
|
|||||||
Reference in New Issue
Block a user