HapeLee 1 год назад
Родитель
Сommit
f3918f4a69

+ 1 - 1
app/build.gradle

@@ -120,7 +120,7 @@ android {
             manifestPlaceholders.put("app_name", "@string/app_name")
 
             //applicationIdSuffix '.debug'
-            versionNameSuffix "_debug-${getGitCommitHash()}"
+            versionNameSuffix "_debug+${getGitCommitHash()}"
             minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro', 'cronet-proguard-rules.pro'
         }

+ 18 - 15
app/src/main/java/io/legato/kazusa/help/update/AppReleaseInfo.kt

@@ -11,13 +11,9 @@ data class AppReleaseInfo(
     val note: String,
     val name: String,
     val downloadUrl: String,
-    val assetUrl: String
-) {
-    val versionName: String = Regex("""legado_app_([\d.]+)\.apk""")
-        .find(name)
-        ?.groupValues?.get(1)
-        ?: ""
-}
+    val assetUrl: String,
+    val versionName: String
+)
 
 enum class AppVariant {
     OFFICIAL,
@@ -43,11 +39,14 @@ data class GithubRelease(
     val createdAt: String?
 ) {
     fun gitReleaseToAppReleaseInfo(): List<AppReleaseInfo> {
+        val version = tagName // 直接用 release 的 tag_name 作为版本号
         assets ?: throw NoStackTraceException("获取新版本出错")
+
         return assets
             .filter { it.isValid }
-            .map { it.assetToAppReleaseInfo(isPreRelease, body) }
+            .map { it.assetToAppReleaseInfo(isPreRelease, body, version) }
     }
+
 }
 
 
@@ -69,17 +68,21 @@ data class Asset(
     val isValid: Boolean
         get() = (contentType == "application/vnd.android.package-archive") && (state == "uploaded")
 
-    fun assetToAppReleaseInfo(preRelease: Boolean, note: String): AppReleaseInfo {
+    fun assetToAppReleaseInfo(preRelease: Boolean, note: String, version: String): AppReleaseInfo {
         val instant = Instant.parse(createdAt)
         val timestamp: Long = instant.toEpochMilli()
 
-        val appVariant = if (preRelease) {
-            AppVariant.BETA_RELEASE
-        } else {
-            AppVariant.OFFICIAL
-        }
+        val appVariant = if (preRelease) AppVariant.BETA_RELEASE else AppVariant.OFFICIAL
 
-        return AppReleaseInfo(appVariant, timestamp, note, name, apkUrl, url)
+        return AppReleaseInfo(
+            appVariant = appVariant,
+            createdAt = timestamp,
+            note = note,
+            name = name,
+            downloadUrl = apkUrl,
+            assetUrl = url,
+            versionName = version // 直接传入 tagName
+        )
     }
 
 }

+ 58 - 37
app/src/main/java/io/legato/kazusa/help/update/AppUpdateGitHub.kt

@@ -29,16 +29,10 @@ object AppUpdateGitHub : AppUpdate.AppUpdateInterface {
             "https://api.github.com/repos/HapeLee/legado-with-MD3/releases/latest"
         }
 
-        val res = okHttpClient.newCallResponse {
-            url(lastReleaseUrl)
-        }
-        if (!res.isSuccessful) {
-            throw NoStackTraceException("获取新版本出错(${res.code})")
-        }
+        val res = okHttpClient.newCallResponse { url(lastReleaseUrl) }
+        if (!res.isSuccessful) throw NoStackTraceException("获取新版本出错(${res.code})")
         val body = res.body.text()
-        if (body.isBlank()) {
-            throw NoStackTraceException("获取新版本出错")
-        }
+        if (body.isBlank()) throw NoStackTraceException("获取新版本出错")
 
         return if (checkVariant.isBeta()) {
             val releases = GSON.fromJsonArray<GithubRelease>(body)
@@ -60,11 +54,16 @@ object AppUpdateGitHub : AppUpdate.AppUpdateInterface {
     override fun check(scope: CoroutineScope): Coroutine<AppUpdate.UpdateInfo> {
         return Coroutine.async(scope) {
             val currentVersion = AppConst.appInfo.versionName
-
             val releases = getLatestRelease()
                 .filter { it.appVariant == checkVariant }
 
-            val latest = releases.firstOrNull { it.versionName.versionCompare(currentVersion) > 0 }
+            val latest = releases.firstOrNull { r ->
+                try {
+                    r.versionName.versionCompare(currentVersion) > 0
+                } catch (e: Exception) {
+                    false
+                }
+            }
 
             if (latest != null) {
                 return@async AppUpdate.UpdateInfo(
@@ -79,35 +78,57 @@ object AppUpdateGitHub : AppUpdate.AppUpdateInterface {
         }.timeout(10000)
     }
 
-    fun String.versionCompare(other: String): Int {
-        val regex = Regex("""(\d+)|(\D+)""")
-        val thisParts = regex.findAll(this).map { it.value }.toList()
-        val otherParts = regex.findAll(other).map { it.value }.toList()
-        val maxLength = maxOf(thisParts.size, otherParts.size)
-
-        for (i in 0 until maxLength) {
-            val a = thisParts.getOrNull(i)
-            val b = otherParts.getOrNull(i)
-
-            if (a == null) return -1
-            if (b == null) return 1
-
-            val isANum = a.all { it.isDigit() }
-            val isBNum = b.all { it.isDigit() }
-
-            if (isANum && a.length > 1 && a.startsWith("0")) return -1
-            if (isBNum && b.length > 1 && b.startsWith("0")) return 1
-
-            val cmp = if (isANum && isBNum) {
-                a.toInt() - b.toInt()
-            } else {
-                a.compareTo(b)
+    private data class SemVer(
+        val major: Int,
+        val minor: Int,
+        val patch: Int,
+        val preRelease: String? = null
+    ) : Comparable<SemVer> {
+        override fun compareTo(other: SemVer): Int {
+            if (major != other.major) return major - other.major
+            if (minor != other.minor) return minor - other.minor
+            if (patch != other.patch) return patch - other.patch
+
+            if (preRelease == null && other.preRelease != null) return 1
+            if (preRelease != null && other.preRelease == null) return -1
+            if (preRelease == null && other.preRelease == null) return 0
+
+            val aParts = preRelease!!.split(".")
+            val bParts = other.preRelease!!.split(".")
+            val maxLen = maxOf(aParts.size, bParts.size)
+
+            for (i in 0 until maxLen) {
+                val a = aParts.getOrNull(i)
+                val b = bParts.getOrNull(i)
+                if (a == null) return -1
+                if (b == null) return 1
+
+                val isANum = a.all { it.isDigit() }
+                val isBNum = b.all { it.isDigit() }
+                if (isANum && isBNum) {
+                    val cmp = a.toInt().compareTo(b.toInt())
+                    if (cmp != 0) return cmp
+                } else {
+                    val cmp = a.compareTo(b)
+                    if (cmp != 0) return cmp
+                }
             }
-
-            if (cmp != 0) return cmp
+            return 0
         }
 
-        return 0
+        companion object {
+            fun parse(version: String): SemVer {
+                val regex = Regex("""(\d+)\.(\d+)\.(\d+)(?:-([\w.]+))?""")
+                val match = regex.matchEntire(version)
+                    ?: throw IllegalArgumentException("Invalid version: $version")
+                val (maj, min, pat, pre) = match.destructured
+                return SemVer(maj.toInt(), min.toInt(), pat.toInt(), pre.ifBlank { null })
+            }
+        }
     }
 
+    fun String.versionCompare(other: String): Int {
+        return SemVer.parse(this).compareTo(SemVer.parse(other))
+    }
 }
+

+ 10 - 10
app/src/main/res/xml/pref_config_other.xml

@@ -9,6 +9,16 @@
         app:entries="@array/language"
         app:entryValues="@array/language_value" />
 
+    <io.legato.kazusa.lib.prefs.NameListPreference
+        android:defaultValue="official_version"
+        android:key="updateToVariant"
+        android:summary="@string/update_to_variant_summary"
+        android:title="@string/update_to_variant_title"
+        app:allowDividerAbove="false"
+        app:allowDividerBelow="false"
+        app:entries="@array/default_app_variant"
+        app:entryValues="@array/default_app_variant_value" />
+
     <io.legato.kazusa.lib.prefs.PreferenceCategory
         android:title="@string/main_activity"
         app:allowDividerAbove="false"
@@ -151,16 +161,6 @@
         app:iconSpaceReserved="false"
         app:layout="@layout/view_preference_category">
 
-        <io.legato.kazusa.lib.prefs.NameListPreference
-            android:defaultValue="official_version"
-            android:key="updateToVariant"
-            android:summary="@string/update_to_variant_summary"
-            android:title="@string/update_to_variant_title"
-            app:allowDividerAbove="false"
-            app:allowDividerBelow="false"
-            app:entries="@array/default_app_variant"
-            app:entryValues="@array/default_app_variant_value" />
-
         <io.legato.kazusa.lib.prefs.SwitchPreference
             android:defaultValue="true"
             android:key="sharedElementEnterTransitionEnable"