@@ -2,40 +2,112 @@ package eu.kanade.tachiyomi.data.updater
22
33import dev.zacsweers.metro.Inject
44import eu.kanade.tachiyomi.BuildConfig
5+ import eu.kanade.tachiyomi.network.GET
6+ import eu.kanade.tachiyomi.network.NetworkHelper
7+ import eu.kanade.tachiyomi.network.awaitSuccess
58import eu.kanade.tachiyomi.util.system.isFossBuildType
69import kotlinx.coroutines.Dispatchers
710import kotlinx.coroutines.withContext
11+ import kotlinx.serialization.json.Json
12+ import kotlinx.serialization.Serializable
13+ import logcat.LogPriority
14+ import logcat.logcat
815import tachiyomi.domain.release.interactor.GetApplicationRelease
16+ import tachiyomi.domain.release.model.Release
17+
18+ val GITHUB_REPO : String = " ydqsgl/ydmihon"
919
1020@Inject
1121class AppUpdateChecker (
1222 private val getApplicationRelease : GetApplicationRelease ,
23+ private val networkHelper : NetworkHelper ,
1324) {
1425
1526 suspend fun checkForUpdate (forceCheck : Boolean = false): GetApplicationRelease .Result {
16- // Disable app update checks for older Android versions that we're going to drop support for
17- // if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
18- // return GetApplicationRelease.Result.OsTooOld
19- // }
27+ // First try the standard flow (uses GitHub API)
28+ val standardResult = withContext(Dispatchers .IO ) {
29+ try {
30+ getApplicationRelease.await(
31+ GetApplicationRelease .Arguments (
32+ isFossBuildType,
33+ false ,
34+ BuildConfig .COMMIT_COUNT .toInt(),
35+ BuildConfig .VERSION_NAME ,
36+ GITHUB_REPO ,
37+ forceCheck,
38+ ),
39+ )
40+ } catch (e: Exception ) {
41+ logcat(LogPriority .WARN , e) { " Standard update check failed, trying fallback" }
42+ null
43+ }
44+ }
45+
46+ // If standard flow returned a new update, use it
47+ if (standardResult is GetApplicationRelease .Result .NewUpdate ) {
48+ return standardResult
49+ }
2050
51+ // Fallback: directly query the latest release page HTML to detect version
2152 return withContext(Dispatchers .IO ) {
22- val result = getApplicationRelease.await(
23- GetApplicationRelease .Arguments (
24- isFossBuildType,
25- false ,
26- BuildConfig .COMMIT_COUNT .toInt(),
27- BuildConfig .VERSION_NAME ,
28- GITHUB_REPO ,
29- forceCheck,
53+ try {
54+ checkForUpdateFallback()
55+ } catch (e: Exception ) {
56+ logcat(LogPriority .ERROR , e) { " Fallback update check also failed" }
57+ GetApplicationRelease .Result .NoNewUpdate
58+ }
59+ }
60+ }
61+
62+ private suspend fun checkForUpdateFallback (): GetApplicationRelease .Result {
63+ // Use the GitHub API with a shorter timeout to avoid long waits
64+ val json = Json { ignoreUnknownKeys = true }
65+ val response = networkHelper.client.newCall(
66+ GET (" https://api.github.com/repos/$GITHUB_REPO /releases/latest" ),
67+ ).awaitSuccess()
68+
69+ val releaseInfo = json.decodeFromString<GithubLatestRelease >(
70+ response.body?.string() ? : return GetApplicationRelease .Result .NoNewUpdate ,
71+ )
72+
73+ val latestVersion = releaseInfo.tag_name.removePrefix(" v" ).removePrefix(" r" )
74+ val currentVersion = BuildConfig .VERSION_NAME
75+
76+ // Simple version comparison
77+ if (isVersionNewer(latestVersion, currentVersion)) {
78+ val downloadUrl = " https://github.com/$GITHUB_REPO /releases/download/${releaseInfo.tag_name} /app-universal-debug.apk"
79+ return GetApplicationRelease .Result .NewUpdate (
80+ Release (
81+ version = latestVersion,
82+ info = releaseInfo.body ? : " 新版本可用" ,
83+ releaseLink = " https://github.com/$GITHUB_REPO /releases/tag/${releaseInfo.tag_name} " ,
84+ downloadLink = downloadUrl,
3085 ),
3186 )
87+ }
3288
33- result
89+ return GetApplicationRelease .Result .NoNewUpdate
90+ }
91+
92+ private fun isVersionNewer (new : String , old : String ): Boolean {
93+ val newParts = new.split(" ." ).mapNotNull { it.toIntOrNull() }
94+ val oldParts = old.split(" ." ).mapNotNull { it.toIntOrNull() }
95+ val maxLen = maxOf(newParts.size, oldParts.size)
96+ for (i in 0 until maxLen) {
97+ val newPart = newParts.getOrElse(i) { 0 }
98+ val oldPart = oldParts.getOrElse(i) { 0 }
99+ if (newPart > oldPart) return true
100+ if (newPart < oldPart) return false
34101 }
102+ return false
35103 }
36104}
37105
38- val GITHUB_REPO : String = " ydqsgl/ydmihon"
106+ @Serializable
107+ private data class GithubLatestRelease (
108+ val tag_name : String ,
109+ val body : String? = null ,
110+ )
39111
40112val RELEASE_TAG : String by lazy {
41113 " v${BuildConfig .VERSION_NAME } "
0 commit comments