From b6771a906d9af48f9d11d0c0515cdd0f07e8e1ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=89=E9=B2=AB=E9=9B=AA=E7=8B=90?= <139336664+ArcticFoxPro@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:39:00 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat(TIM):=20=E6=9B=B4=E6=96=B0=20TIM=20?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=95=B0=E6=8D=AE=E8=A7=A3=E6=9E=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 TIM 版本数据的获取方式,从旧的 URL 迁移到新的 URL - 更新 TIMVersionBean 中 fix 和 new 字段类型,从 String 改为 List - 优化 TIM 版本数据的解析逻辑,适应新的 JSON 结构 - 调整 TIMVersionAdapter 中版本信息的展示方式 - 更新 VersionUtil 中 resolveTIMRainbow 函数,以适应新的数据结构 --- app/build.gradle.kts | 2 +- .../qqversionlist/data/TIMVersionBean.kt | 6 +- .../xiaoniu/qqversionlist/ui/MainActivity.kt | 74 +++++++----- .../qqversionlist/ui/TIMVersionAdapter.kt | 13 ++- .../xiaoniu/qqversionlist/util/StringUtil.kt | 13 +++ .../xiaoniu/qqversionlist/util/VersionUtil.kt | 106 +++--------------- gradle/libs.versions.toml | 2 +- 7 files changed, 87 insertions(+), 129 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 75cecb0c..9b18b78c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -49,7 +49,7 @@ android { minSdk = 24 targetSdk = 35 versionCode = gitCommitCount - versionName = "1.4.5-$gitCommitHash" + versionName = "1.4.6-$gitCommitHash" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/data/TIMVersionBean.kt b/app/src/main/java/com/xiaoniu/qqversionlist/data/TIMVersionBean.kt index fc0b1be7..e66033e4 100644 --- a/app/src/main/java/com/xiaoniu/qqversionlist/data/TIMVersionBean.kt +++ b/app/src/main/java/com/xiaoniu/qqversionlist/data/TIMVersionBean.kt @@ -24,7 +24,7 @@ import kotlinx.serialization.Serializable * @param version TIM 版本号 * @param datetime TIM 版本发布日期 * @param fix TIM 版本优化描述 - * @param new TIM 版本新功能描述 + * @param feature TIM 版本新功能描述 * @param link TIM 最新官网正式版下载链接 * @param jsonString 该 TIM 版本 JSON 字符串详情 * @param displayType 卡片展示类型,0 为收起态,1 为展开态 @@ -36,8 +36,8 @@ import kotlinx.serialization.Serializable data class TIMVersionBean( val version: String, val datetime: String, - val fix: String, - val new: String, + val fix: List, + val feature: List, var link: String = "", var jsonString: String = "", diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/ui/MainActivity.kt b/app/src/main/java/com/xiaoniu/qqversionlist/ui/MainActivity.kt index 81b5f42a..6edbc1da 100644 --- a/app/src/main/java/com/xiaoniu/qqversionlist/ui/MainActivity.kt +++ b/app/src/main/java/com/xiaoniu/qqversionlist/ui/MainActivity.kt @@ -1580,42 +1580,58 @@ class MainActivity : AppCompatActivity() { withContext(Dispatchers.Main) { endProgress() } } try { + // https://im.qq.com/rainbow/TIMDownload/ 已弃用 val okHttpClient = OkHttpClient() - val request = - Request.Builder().url("https://im.qq.com/rainbow/TIMDownload/") + val preRequest = + Request.Builder().url("https://tim.qq.com/support.html").build() + val preResponse = okHttpClient.newCall(preRequest).execute() + val htmlData = preResponse.body?.string() + val regex = + """jQuery\.ajax\(\{\s*url:\s*'([^']+)'\s*\}\)\.done\(function \(versionData\)""".toRegex() + val matchResult = regex.find(htmlData!!) + val match = matchResult?.groupValues?.getOrNull(1) + if (match != null && (match.startsWith("https://") || match.startsWith("http://"))) { + val request = Request.Builder() + .url(match.replace("http://", "https://")) .build() - val response = okHttpClient.newCall(request).execute() - val responseData = response.body?.string() - if (responseData != null) { - VersionUtil.resolveTIMRainbow(this@MainActivity, responseData) - withContext(Dispatchers.Main) { - timVersionAdapter.submitList(timVersion) - if (!DataStoreUtil.getBooleanKV("closeSwipeLeftForTIM", false)) { - class TipTIMSnackbarActionListener : View.OnClickListener { - override fun onClick(v: View?) { - DataStoreUtil.putBooleanKV("closeSwipeLeftForTIM", true) + val response = okHttpClient.newCall(request).execute() + val responseData = response.body?.string() + if (responseData != null) { + VersionUtil.resolveTIMRainbow(this@MainActivity, responseData) + withContext(Dispatchers.Main) { + timVersionAdapter.submitList(timVersion) + if (!DataStoreUtil.getBooleanKV( + "closeSwipeLeftForTIM", false + ) + ) { + class TipTIMSnackbarActionListener : View.OnClickListener { + override fun onClick(v: View?) { + DataStoreUtil.putBooleanKV( + "closeSwipeLeftForTIM", true + ) + } } - } - val isDarkTheme: Boolean = - when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { - Configuration.UI_MODE_NIGHT_YES -> true - else -> false - } + val isDarkTheme: Boolean = + when (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { + Configuration.UI_MODE_NIGHT_YES -> true + else -> false + } - Snackbar.make( - binding.root, R.string.swipeLeftForTIMVersions, - Snackbar.LENGTH_INDEFINITE - ).setAction(R.string.ok, TipTIMSnackbarActionListener()) - .setAnchorView(binding.btnGuess) - .apply { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) if (isDarkTheme) setBackgroundTint( - getColor(com.google.android.material.R.color.m3_sys_color_dynamic_dark_secondary) - ) else setBackgroundTint(getColor(com.google.android.material.R.color.m3_sys_color_dynamic_light_secondary)) - }.show() + Snackbar.make( + binding.root, R.string.swipeLeftForTIMVersions, + Snackbar.LENGTH_INDEFINITE + ).setAction(R.string.ok, TipTIMSnackbarActionListener()) + .setAnchorView(binding.btnGuess) + .apply { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) if (isDarkTheme) setBackgroundTint( + getColor(com.google.android.material.R.color.m3_sys_color_dynamic_dark_secondary) + ) else setBackgroundTint(getColor(com.google.android.material.R.color.m3_sys_color_dynamic_light_secondary)) + }.show() + } } } - } + } else throw Exception("Can not get TIM version data.") } catch (e: Exception) { e.printStackTrace() dialogError(e) diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/ui/TIMVersionAdapter.kt b/app/src/main/java/com/xiaoniu/qqversionlist/ui/TIMVersionAdapter.kt index 4b7fec3c..32934878 100644 --- a/app/src/main/java/com/xiaoniu/qqversionlist/ui/TIMVersionAdapter.kt +++ b/app/src/main/java/com/xiaoniu/qqversionlist/ui/TIMVersionAdapter.kt @@ -127,17 +127,18 @@ class TIMVersionAdapter : is ViewHolderDetail -> { holder.binding.apply { val fix = bean.fix - val new = bean.new + val new = bean.feature tvTimOldVersion.text = bean.version tvTimDetailVersion.text = holder.itemView.context.getString(R.string.version) + bean.version tvTimDetailDate.text = holder.itemView.context.getString(R.string.releaseDateTIM) + bean.datetime - if (fix == "" && new == "") tvTimDesc.isVisible = false - else tvTimDesc.text = new.split("
") - .joinToString(separator = "\n") + (if (new != "") "\n" else "") + (if (fix != "") fix.split( - "
" - ).joinToString(separator = "\n") else "") + if (fix.isEmpty() && new.isEmpty()) tvTimDesc.isVisible = false + else tvTimDesc.text = (if (new.isEmpty()) "" else new.joinToString( + separator = "\n- ", prefix = "- " + )) + (if (new.isEmpty()) "" else "\n") + fix.joinToString( + separator = "\n- ", prefix = "- " + ) bindDisplayInstall(tvTimOldInstall, tvTimOldInstallCard, bean) bindVersionTCloud(tvTimOldVersion, holder.context) bindAccessibilityTag(accessibilityTimOldTag, holder.context, bean) diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/util/StringUtil.kt b/app/src/main/java/com/xiaoniu/qqversionlist/util/StringUtil.kt index 71179dc2..c4d5fe45 100644 --- a/app/src/main/java/com/xiaoniu/qqversionlist/util/StringUtil.kt +++ b/app/src/main/java/com/xiaoniu/qqversionlist/util/StringUtil.kt @@ -21,6 +21,7 @@ package com.xiaoniu.qqversionlist.util import android.content.Context import android.content.pm.PackageInfo import com.google.gson.Gson +import com.google.gson.reflect.TypeToken import com.xiaoniu.qqversionlist.util.FileUtil.ZipFileCompat import com.xiaoniu.qqversionlist.util.InfoUtil.dialogError import kotlinx.serialization.ExperimentalSerializationApi @@ -189,4 +190,16 @@ object StringUtil { "recentList" to recentList.map { it.asString } ) } + + /** + * 将 JsonArray 对象转换为 List 类型列表 + * + * @param jsonArray 一个包含字符串的 JsonArray 对象 + * @return 返回一个字符串列表,列表中的字符串是从 JsonArray 中解析出来的 + */ + fun jsonArrayToList(jsonArray: com.google.gson.JsonArray): List { + val gson = Gson() + val listType = object : TypeToken>() {}.type + return gson.fromJson(jsonArray.toString(), listType) + } } diff --git a/app/src/main/java/com/xiaoniu/qqversionlist/util/VersionUtil.kt b/app/src/main/java/com/xiaoniu/qqversionlist/util/VersionUtil.kt index a65c52e8..8ae153d3 100644 --- a/app/src/main/java/com/xiaoniu/qqversionlist/util/VersionUtil.kt +++ b/app/src/main/java/com/xiaoniu/qqversionlist/util/VersionUtil.kt @@ -32,6 +32,7 @@ import com.xiaoniu.qqversionlist.data.QQVersionBean import com.xiaoniu.qqversionlist.data.TIMVersionBean import com.xiaoniu.qqversionlist.ui.MainActivity import com.xiaoniu.qqversionlist.util.StringUtil.getQua +import com.xiaoniu.qqversionlist.util.StringUtil.jsonArrayToList import com.xiaoniu.qqversionlist.util.StringUtil.toPrettyFormat import kotlinx.serialization.json.Json import org.apache.maven.artifact.versioning.ComparableVersion @@ -81,102 +82,36 @@ object VersionUtil { } fun resolveTIMRainbow(thisActivity: MainActivity, responseData: String) { - val start = (responseData.indexOf("var params= ")) + 12 - val end = (responseData.indexOf(";\n" + " typeof")) - val jsonString = responseData.substring(start, end) val gson = Gson() - val jsonData = gson.fromJson(jsonString, JsonObject::class.java) + val jsonData = gson.fromJson(responseData, JsonObject::class.java) thisActivity.timVersion = mutableListOf() - val download = jsonData.getAsJsonObject("app").getAsJsonObject("download") - val androidVersion = download.get("androidVersion").asString - val androidDatetime = download.get("androidDatetime").asString - val androidLink = download.get("androidLink").asString - - (thisActivity.timVersion as MutableList).add( - TIMVersionBean( - version = androidVersion, - datetime = androidDatetime, - fix = "", - new = "", - jsonString = gson.toJson(JsonObject().apply { - addProperty("version", androidVersion) - addProperty("datetime", androidDatetime) - addProperty("fix", "") - addProperty("new", "") - }).toString(), - displayInstall = (DataStoreUtil.getStringKV( - "TIMVersionInstall", "" - ) == androidVersion), - isQQNTFramework = ComparableVersion(androidVersion) >= ComparableVersion( - EARLIEST_QQNT_FRAMEWORK_TIM_VERSION_STABLE - ), - isKuiklyInside = ComparableVersion(androidVersion) >= ComparableVersion( - EARLIEST_KUIKLY_FRAMEWORK_TIM_VERSION_STABLE - ) - ) - ) - - // 从 latest 项中获取 Android 版本 - val latest = jsonData.getAsJsonObject("app").getAsJsonArray("latest") - latest.forEach { item -> - val platform = item.asJsonObject.get("platform").asString - if (platform == "Android") { - val version = item.asJsonObject.get("version").asString - val datetime = item.asJsonObject.get("datetime").asString - val fix = item.asJsonObject.get("fix").asString - val newFeature = item.asJsonObject.get("new").asString - - (thisActivity.timVersion as MutableList).add( - TIMVersionBean( - version = version, - datetime = datetime, - fix = fix, - new = newFeature, - jsonString = gson.toJson(JsonObject().apply { - addProperty("version", version) - addProperty("datetime", datetime) - addProperty("fix", fix) - addProperty("new", newFeature) - }).toString(), - displayInstall = (DataStoreUtil.getStringKV( - "TIMVersionInstall", "" - ) == version), - isQQNTFramework = ComparableVersion(version) >= ComparableVersion( - EARLIEST_QQNT_FRAMEWORK_TIM_VERSION_STABLE - ), - isKuiklyInside = ComparableVersion(version) >= ComparableVersion( - EARLIEST_KUIKLY_FRAMEWORK_TIM_VERSION_STABLE - ) - ) - ) - } - } + val androidLink = jsonData.get("download_link").asJsonObject.get("android").asString - // 从 history 项中获取 Android 版本 - val history = jsonData.getAsJsonObject("app").getAsJsonArray("history") + // 从 `version_history` 项中获取 Android 版本 + val history = jsonData.getAsJsonArray("version_history") history.forEach { versionItem -> - val version = versionItem.asJsonObject.get("version").asString + val version = versionItem.asJsonObject.get("version_code").asString val logs = versionItem.asJsonObject.getAsJsonArray("logs") logs.forEach { logItem -> val platform = logItem.asJsonObject.get("platform").asString - if (platform == "Android") { + if (platform == "android") { val datetime = logItem.asJsonObject.get("datetime").asString - val fix = logItem.asJsonObject.get("fix").asString - val newFeature = logItem.asJsonObject.get("new").asString + val fix = logItem.asJsonObject.get("fix").asJsonArray + val feature = logItem.asJsonObject.get("feature").asJsonArray (thisActivity.timVersion as MutableList).add( TIMVersionBean( version = version, datetime = datetime, - fix = fix, - new = newFeature, + fix = jsonArrayToList(fix), + feature = jsonArrayToList(feature), jsonString = gson.toJson(JsonObject().apply { - addProperty("version", version) + addProperty("version_code", version) addProperty("datetime", datetime) - addProperty("fix", fix) - addProperty("new", newFeature) + addProperty("fix", fix.toString()) + addProperty("feature", feature.toString()) }).toString(), displayInstall = (DataStoreUtil.getStringKV( "TIMVersionInstall", "" @@ -193,19 +128,12 @@ object VersionUtil { } } - // 去除重复的版本号 - thisActivity.timVersion = - thisActivity.timVersion.distinctBy { it.jsonString.toPrettyFormat() } - if (thisActivity.timVersion[0].version == thisActivity.timVersion[1].version) (thisActivity.timVersion as MutableList).removeAt( - 0 - ) - thisActivity.timVersion[0].link = androidLink thisActivity.timVersion[0].jsonString = gson.toJson(JsonObject().apply { - addProperty("version", thisActivity.timVersion[0].version) + addProperty("version_code", thisActivity.timVersion[0].version) addProperty("datetime", thisActivity.timVersion[0].datetime) - addProperty("fix", thisActivity.timVersion[0].fix) - addProperty("new", thisActivity.timVersion[0].new) + addProperty("fix", thisActivity.timVersion[0].fix.toString()) + addProperty("feature", thisActivity.timVersion[0].feature.toString()) addProperty("link", androidLink) }).toString() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ff2de4fe..65aafb9c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,7 +10,7 @@ coreKtx = "1.15.0" coreSplashscreen = "1.1.0-rc01" datastorePreferences = "1.1.1" espressoCore = "3.6.1" -firebaseBom = "33.6.0" +firebaseBom = "33.7.0" fragmentKtx = "1.8.5" googleServices = "4.4.2" gson = "2.11.0" From 6e55a71a77885e9279b5a287b2e48b3520cbb792 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=89=E9=B2=AB=E9=9B=AA=E7=8B=90?= <139336664+ArcticFoxPro@users.noreply.github.com> Date: Sun, 22 Dec 2024 17:08:28 +0800 Subject: [PATCH 2/3] =?UTF-8?q?build(gradle):=20=E5=8D=87=E7=BA=A7=20Gradl?= =?UTF-8?q?e=20=E4=BB=8E=208.11.1=20=E5=88=B0=208.12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 更新 gradle-wrapper.properties 文件中的 distributionUrl - 从 https://services.gradle.org/distributions/gradle-8.11.1-bin.zip 更新为 https://services.gradle.org/distributions/gradle-8.12-bin.zip --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0cb7ce7d..1a22a070 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Tue Apr 09 19:38:08 CST 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From fd3ba08b781caedc87fd899301ed32d32db3e9a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=89=E9=B2=AB=E9=9B=AA=E7=8B=90?= <139336664+ArcticFoxPro@users.noreply.github.com> Date: Mon, 23 Dec 2024 08:34:41 +0800 Subject: [PATCH 3/3] =?UTF-8?q?build(deps):=20=E6=9B=B4=E6=96=B0=20materia?= =?UTF-8?q?l=20=E8=AE=BE=E8=AE=A1=E5=BA=93=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 material 设计库版本从 1.13.0-alpha08 升级到 1.13.0-alpha09 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 65aafb9c..f1bccad9 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,7 +22,7 @@ kotlinxCoroutinesAndroid = "1.9.0" kotlinxSerializationJson = "1.7.3" library = "1.3.0" lifecycleRuntimeKtx = "2.8.7" -material = "1.13.0-alpha08" +material = "1.13.0-alpha09" mavenArtifact = "3.9.9" okhttp = "4.12.0" ossLicensesPluginVersion = "0.10.6"