Bladeren bron

实时更新日志

HapeLee 1 jaar geleden
bovenliggende
commit
5d6665b009

+ 17 - 0
app/src/main/java/io/legado/app/help/update/AppUpdateGitHub.kt

@@ -64,6 +64,23 @@ object AppUpdateGitHub : AppUpdate.AppUpdateInterface {
         }
     }
 
+    suspend fun getReleaseByTag(tag: String): AppUpdate.UpdateInfo? {
+        val url = "https://api.github.com/repos/HapeLee/legado-with-MD3/releases/tags/$tag"
+        val res = okHttpClient.newCallResponse { url(url) }
+        if (!res.isSuccessful) return null
+
+        val body = res.body.text()
+        val release = GSON.fromJsonObject<GithubRelease>(body).getOrElse { return null }
+        val info = release.gitReleaseToAppReleaseInfo().firstOrNull() ?: return null
+
+        return AppUpdate.UpdateInfo(
+            tagName = info.versionName,
+            updateLog = info.note,
+            downloadUrl = info.downloadUrl,
+            fileName = info.name
+        )
+    }
+
     override fun check(scope: CoroutineScope): Coroutine<AppUpdate.UpdateInfo> {
         return Coroutine.async(scope) {
             val currentVersion = AppConst.appInfo.versionName

+ 1 - 1
app/src/main/java/io/legado/app/ui/about/AboutActivity.kt

@@ -123,7 +123,7 @@ class AboutActivity : BaseActivity<ActivityAboutBinding>() {
         AppUpdate.gitHubUpdate?.run {
             check(lifecycleScope)
                 .onSuccess {
-                    showDialogFragment(UpdateDialog(it))
+                    showDialogFragment(UpdateDialog(it, UpdateDialog.Mode.UPDATE))
                 }.onError {
                     appCtx.toastOnUi("${getString(R.string.check_update)}\n${it.localizedMessage}")
                 }.onFinally {

+ 31 - 21
app/src/main/java/io/legado/app/ui/about/UpdateDialog.kt

@@ -12,6 +12,7 @@ import io.legado.app.help.config.AppConfig
 import io.legado.app.help.update.AppUpdate
 import io.legado.app.help.update.AppVariant
 import io.legado.app.model.Download
+import io.legado.app.utils.gone
 import io.legado.app.utils.toastOnUi
 import io.legado.app.utils.viewbindingdelegate.viewBinding
 import io.noties.markwon.Markwon
@@ -21,12 +22,15 @@ import io.noties.markwon.image.glide.GlideImagesPlugin
 
 class UpdateDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_update) {
 
-    constructor(updateInfo: AppUpdate.UpdateInfo) : this() {
+    enum class Mode { UPDATE, VIEW_LOG }
+
+    constructor(updateInfo: AppUpdate.UpdateInfo, mode: Mode = Mode.UPDATE) : this() {
         arguments = Bundle().apply {
             putString("newVersion", updateInfo.tagName)
             putString("updateBody", updateInfo.updateLog)
             putString("url", updateInfo.downloadUrl)
             putString("name", updateInfo.fileName)
+            putString("mode", mode.name)
         }
     }
 
@@ -38,28 +42,24 @@ class UpdateDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_update) {
             else -> AppConst.appInfo.appVariant
         }
 
-    val binding by viewBinding(DialogUpdateBinding::bind)
+    private val binding by viewBinding(DialogUpdateBinding::bind)
 
-    override fun onStart() {
-        super.onStart()
-    }
+    private val mode: Mode
+        get() = Mode.valueOf(arguments?.getString("mode") ?: Mode.UPDATE.name)
 
     override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
-        //binding.toolBar.setBackgroundColor(primaryColor)
-
         binding.tvCurrentVersion.text = BuildConfig.VERSION_NAME
         binding.tvVersion.text = arguments?.getString("newVersion")
-
         binding.tvAbi.text = Build.SUPPORTED_ABIS.firstOrNull() ?: "unknown"
-        binding.tvUrl.text = arguments?.getString("url")
         binding.tvVariable.text = checkVariant.toString()
 
         val updateBody = arguments?.getString("updateBody")
-        if (updateBody == null) {
+        if (updateBody.isNullOrBlank()) {
             toastOnUi("没有数据")
             dismiss()
             return
         }
+
         binding.textView.post {
             Markwon.builder(requireContext())
                 .usePlugin(GlideImagesPlugin.create(requireContext()))
@@ -69,19 +69,29 @@ class UpdateDialog() : BaseBottomSheetDialogFragment(R.layout.dialog_update) {
                 .setMarkdown(binding.textView, updateBody)
         }
 
-        binding.btnUpdate.setOnClickListener {
-            val url = arguments?.getString("url")
-            val fileName = arguments?.getString("name")
-
-            if (url.isNullOrBlank() || fileName.isNullOrBlank()) {
-                toastOnUi("下载信息不完整")
-                return@setOnClickListener
+        when (mode) {
+            Mode.UPDATE -> {
+                val url = arguments?.getString("url")
+                val fileName = arguments?.getString("name")
+                binding.ivAward.gone()
+                binding.btnUpdate.setOnClickListener {
+                    if (url.isNullOrBlank() || fileName.isNullOrBlank()) {
+                        toastOnUi("下载信息不完整")
+                        return@setOnClickListener
+                    }
+                    Download.start(requireContext(), url, fileName)
+                    toastOnUi("开始下载: $fileName")
+                }
             }
 
-            Download.start(requireContext(), url, fileName)
-            toastOnUi("开始下载: $fileName")
+            Mode.VIEW_LOG -> {
+                binding.bottomSheetTitle.text = "已经更新至"
+                binding.tvVersion.text = BuildConfig.VERSION_NAME
+                binding.btnUpdate.gone()
+                binding.llCurrent.gone()
+                binding.tvCurrentVersion.gone()
+                binding.tvUrl.gone()
+            }
         }
-
     }
-
 }

+ 27 - 10
app/src/main/java/io/legado/app/ui/main/MainActivity.kt

@@ -39,8 +39,10 @@ import io.legado.app.help.config.AppConfig
 import io.legado.app.help.config.LocalConfig
 import io.legado.app.help.coroutine.Coroutine
 import io.legado.app.help.storage.Backup
+import io.legado.app.help.update.AppUpdateGitHub
 import io.legado.app.lib.dialogs.alert
 import io.legado.app.ui.about.CrashLogsDialog
+import io.legado.app.ui.about.UpdateDialog
 import io.legado.app.ui.book.read.ReadBookActivity
 import io.legado.app.ui.book.search.SearchActivity
 import io.legado.app.ui.main.bookshelf.BaseBookshelfFragment
@@ -235,7 +237,7 @@ open class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
     /**
      * 版本更新日志
      */
-    private suspend fun upVersion() = suspendCoroutine { block ->
+    private suspend fun upVersion() = suspendCoroutine<Unit?> { block ->
         if (LocalConfig.versionCode == appInfo.versionCode) {
             block.resume(null)
             return@suspendCoroutine
@@ -244,17 +246,32 @@ open class MainActivity : VMBaseActivity<ActivityMainBinding, MainViewModel>(),
         if (LocalConfig.isFirstOpenApp) {
             val help = String(assets.open("web/help/md/appHelp.md").readBytes())
             val dialog = TextDialog(getString(R.string.help), help, TextDialog.Mode.MD)
-            dialog.setOnDismissListener {
-                block.resume(null)
-            }
+            dialog.setOnDismissListener { block.resume(null) }
             showDialogFragment(dialog)
-        } else if (!BuildConfig.DEBUG) {
-            val log = String(assets.open("updateLog.md").readBytes())
-            val dialog = TextDialog(getString(R.string.update_log), log, TextDialog.Mode.MD)
-            dialog.setOnDismissListener {
-                block.resume(null)
+            return@suspendCoroutine
+        }
+        if (!BuildConfig.DEBUG) {
+            lifecycleScope.launch {
+                try {
+                    val info = AppUpdateGitHub.getReleaseByTag(BuildConfig.VERSION_NAME)
+                    if (info != null) {
+                        val dialog = UpdateDialog(info, UpdateDialog.Mode.VIEW_LOG)
+                        dialog.setOnDismissListener { block.resume(null) }
+                        showDialogFragment(dialog)
+                    } else {
+                        val fallback = String(assets.open("updateLog.md").readBytes())
+                        val dialog = TextDialog(getString(R.string.update_log), fallback, TextDialog.Mode.MD)
+                        dialog.setOnDismissListener { block.resume(null) }
+                        showDialogFragment(dialog)
+                    }
+                } catch (e: Exception) {
+                    e.printStackTrace()
+                    val fallback = String(assets.open("updateLog.md").readBytes())
+                    val dialog = TextDialog(getString(R.string.update_log), fallback, TextDialog.Mode.MD)
+                    dialog.setOnDismissListener { block.resume(null) }
+                    showDialogFragment(dialog)
+                }
             }
-            showDialogFragment(dialog)
         } else {
             block.resume(null)
         }

+ 11 - 0
app/src/main/res/drawable/ic_award.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M363,650L480,579L597,650L566,517L670,427L533,416L480,290L427,416L290,427L394,517L363,650ZM480,932L346,800L160,800L160,614L28,480L160,346L160,160L346,160L480,28L614,160L800,160L800,346L932,480L800,614L800,800L614,800L480,932ZM480,820L580,720L720,720L720,580L820,480L720,380L720,240L580,240L480,140L380,240L240,240L240,380L140,480L240,580L240,720L380,720L480,820ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
+</vector>

+ 31 - 15
app/src/main/res/layout/dialog_update.xml

@@ -11,7 +11,7 @@
         android:layout_height="wrap_content"
         android:orientation="vertical"
         android:gravity="center"
-        android:paddingBottom="16dp">
+        android:paddingBottom="4dp">
 
         <com.google.android.material.bottomsheet.BottomSheetDragHandleView
             android:layout_width="wrap_content"
@@ -20,41 +20,57 @@
             android:minHeight="0dp"
             android:layout_gravity="center_horizontal" />
 
-        <LinearLayout
+        <androidx.constraintlayout.widget.ConstraintLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:gravity="center"
             android:orientation="horizontal">
 
+            <com.google.android.material.button.MaterialButton
+                android:id="@+id/iv_award"
+                android:layout_width="48dp"
+                android:layout_height="56dp"
+                android:clickable="false"
+                app:iconSize="32dp"
+                app:iconGravity="textStart"
+                app:iconPadding="0dp"
+                style="@style/Widget.Material3Expressive.Button.TonalButton"
+                app:icon="@drawable/ic_award"
+                app:layout_constraintTop_toTopOf="parent"
+                app:layout_constraintStart_toStartOf="parent" />
+
             <TextView
                 android:id="@+id/bottom_sheet_title"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:includeFontPadding="false"
+                android:layout_gravity="bottom"
                 android:text="@string/update_available"
                 android:textSize="20sp"
-                android:textStyle="bold" />
-
-            <View
-                android:layout_width="0dp"
-                android:layout_height="match_parent"
-                android:layout_weight="1"/>
+                android:textStyle="bold"
+                app:layout_constraintStart_toStartOf="parent"
+                app:layout_constraintTop_toBottomOf="@id/iv_award"
+                app:layout_constraintBottom_toBottomOf="parent"/>
 
             <com.google.android.material.button.MaterialButton
                 android:id="@+id/btn_update"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 app:icon="@drawable/ic_download"
-                style="@style/Widget.Material3Expressive.Button.IconButton.Tonal" />
-        </LinearLayout>
+                style="@style/Widget.Material3Expressive.Button.IconButton.Tonal"
+                app:layout_constraintEnd_toEndOf="parent"
+                app:layout_constraintBottom_toBottomOf="parent"/>
+        </androidx.constraintlayout.widget.ConstraintLayout>
 
     </LinearLayout>
 
     <LinearLayout
+        android:id="@+id/ll_current"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:gravity="bottom"
-        android:paddingBottom="4dp">
+        android:paddingVertical="4dp">
 
         <TextView
             android:id="@+id/tv_current_version"
@@ -90,7 +106,7 @@
     <View
         android:layout_width="match_parent"
         android:layout_height="2dp"
-        android:layout_marginVertical="2dp"
+        android:layout_marginVertical="4dp"
         android:background="?attr/colorPrimaryContainer" />
 
     <LinearLayout
@@ -104,6 +120,7 @@
             android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_weight="1"
+            android:maxLines="1"
             android:text="@string/text"
             android:textColor="?attr/colorPrimary"
             android:textSize="24sp"
@@ -113,7 +130,6 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             app:cardBackgroundColor="?attr/colorTertiaryContainer"
-
             app:cardCornerRadius="8dp"
             app:strokeWidth="0dp">
 
@@ -147,6 +163,7 @@
         android:layout_height="wrap_content"
         android:textStyle="bold"
         android:textSize="14sp"
+        android:paddingTop="8dp"
         android:text="@string/update_log"/>
 
     <androidx.core.widget.NestedScrollView
@@ -165,5 +182,4 @@
         </LinearLayout>
     </androidx.core.widget.NestedScrollView>
 
-
 </LinearLayout>