1
0
mirror of https://github.com/fumiama/copymanga.git synced 2026-06-28 14:50:29 +08:00
新增
1. 搜索可以加载更多
修复
1. 服务器错误数据导致的闪退(#34)
2. 保存封面超时导致的闪退(870551a6)
优化
1. 更新 targetSdkVersion 到 34(870551a6)
2. 搜索支持嵌套滚动
3. 底部按导航栏高度垫高
4. 升级 Gson 库
This commit is contained in:
源文雨
2023-10-31 00:03:10 +09:00
parent 870551a67c
commit 9972530851
20 changed files with 153 additions and 40 deletions

View File

@@ -8,8 +8,8 @@ android {
applicationId 'top.fumiama.copymanga' applicationId 'top.fumiama.copymanga'
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 34 targetSdkVersion 34
versionCode 37 versionCode 38
versionName '2.0.1' versionName '2.0.2'
resConfigs 'zh', 'zh-rCN' resConfigs 'zh', 'zh-rCN'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -69,7 +69,7 @@ dependencies {
implementation 'com.to.aboomy:pager2banner:1.0.1' implementation 'com.to.aboomy:pager2banner:1.0.1'
implementation 'com.github.bumptech.glide:glide:4.14.2' implementation 'com.github.bumptech.glide:glide:4.14.2'
annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2' annotationProcessor 'com.github.bumptech.glide:compiler:4.14.2'
implementation 'com.google.code.gson:gson:2.9.1' implementation 'com.google.code.gson:gson:2.10.1'
implementation 'com.github.vovaksenov99:OverscrollableScrollView:1.0' implementation 'com.github.vovaksenov99:OverscrollableScrollView:1.0'
implementation 'com.liaoinstan.springview:library:1.7.0' implementation 'com.liaoinstan.springview:library:1.7.0'
implementation 'com.github.zawadz88.materialpopupmenu:material-popup-menu:4.0.1' implementation 'com.github.zawadz88.materialpopupmenu:material-popup-menu:4.0.1'

View File

@@ -91,6 +91,8 @@ open class MangaPagesFragmentTemplate(inflateRes:Int, val isLazy: Boolean = true
Log.d("MyMPAT", "Card per row: $cardPerRow") Log.d("MyMPAT", "Card per row: $cardPerRow")
Log.d("MyMPAT", "Card width: $cardWidth") Log.d("MyMPAT", "Card width: $cardWidth")
mydll?.setPadding(0, 0, 0, navBarHeight)
initCardList(WeakReference(this)) initCardList(WeakReference(this))
managePage() managePage()
setListeners() setListeners()

View File

@@ -6,11 +6,13 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import top.fumiama.copymanga.tools.ui.UITools
open class NoBackRefreshFragment(private val layoutToLoad: Int): Fragment() { open class NoBackRefreshFragment(private val layoutToLoad: Int): Fragment() {
private var _rootView: View? = null private var _rootView: View? = null
val rootView: View get() = _rootView!! val rootView: View get() = _rootView!!
var isFirstInflate = true var isFirstInflate = true
var navBarHeight = 0
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@@ -24,6 +26,7 @@ open class NoBackRefreshFragment(private val layoutToLoad: Int): Fragment() {
isFirstInflate = false isFirstInflate = false
Log.d("MyNBRF", "not first inflate") Log.d("MyNBRF", "not first inflate")
} }
navBarHeight = context?.let { UITools.getNavigationBarHeight(it) } ?: 0
return rootView return rootView
} }
override fun onDestroy() { override fun onDestroy() {

View File

@@ -113,14 +113,25 @@ class UITools(that: Context?, w: WeakReference<Activity>? = null) {
val totalWidth = ((zis?.resources?.displayMetrics?.widthPixels?:1080)-marginPx)/numPerRow val totalWidth = ((zis?.resources?.displayMetrics?.widthPixels?:1080)-marginPx)/numPerRow
return listOf(numPerRow, w, totalWidth) return listOf(numPerRow, w, totalWidth)
} }
fun toHexStr(byteArray: ByteArray) = companion object {
with(StringBuilder()) { fun toHexStr(byteArray: ByteArray) =
byteArray.forEach { with(StringBuilder()) {
val hex = it.toInt() and (0xFF) byteArray.forEach {
val hexStr = Integer.toHexString(hex) val hex = it.toInt() and (0xFF)
if (hexStr.length == 1) append("0").append(hexStr) val hexStr = Integer.toHexString(hex)
else append(hexStr) if (hexStr.length == 1) append("0").append(hexStr)
else append(hexStr)
}
toString()
}
fun getNavigationBarHeight(context: Context): Int {
val resources = context.resources
val resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android")
return if (resourceId > 0) {
resources.getDimensionPixelSize(resourceId)
} else {
0
} }
toString()
} }
}
} }

View File

@@ -8,6 +8,7 @@ import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.android.synthetic.main.fragment_book.*
import kotlinx.android.synthetic.main.line_bookinfo_text.* import kotlinx.android.synthetic.main.line_bookinfo_text.*
import kotlinx.android.synthetic.main.line_booktandb.* import kotlinx.android.synthetic.main.line_booktandb.*
import top.fumiama.copymanga.MainActivity import top.fumiama.copymanga.MainActivity
@@ -30,6 +31,7 @@ class BookFragment: NoBackRefreshFragment(R.layout.fragment_book) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
ComicDlFragment.exit = false ComicDlFragment.exit = false
fbl?.setPadding(0, 0, 0, navBarHeight)
if(isFirstInflate) { if(isFirstInflate) {
var path = "" var path = ""

View File

@@ -385,19 +385,24 @@ class BookHandler(private val th: WeakReference<BookFragment>, val path: String)
File(mangaFolder, "grps.json").writeText(Gson().toJson(keys)) File(mangaFolder, "grps.json").writeText(Gson().toJson(keys))
that?.apply { that?.apply {
Thread { Thread {
sleep(1000) var cnt = 0
if (exit) return@Thread var success = false
File(mangaFolder, "head.jpg").let { head -> while (cnt++ < 10 && !success) {
val fo = head.outputStream() sleep(1000)
try { if (exit) return@Thread
imic.drawable.toBitmap().compress(Bitmap.CompressFormat.JPEG, 90, fo) File(mangaFolder, "head.jpg").let { head ->
} catch (e: Exception) { val fo = head.outputStream()
e.printStackTrace() try {
that?.activity?.runOnUiThread { imic.drawable.toBitmap().compress(Bitmap.CompressFormat.JPEG, 90, fo)
Toast.makeText(that?.context, R.string.download_cover_timeout, Toast.LENGTH_SHORT).show() success = true
} catch (e: Exception) {
e.printStackTrace()
} }
fo.close()
} }
fo.close() }
if (!success) that?.activity?.runOnUiThread {
Toast.makeText(that?.context, R.string.download_cover_timeout, Toast.LENGTH_SHORT).show()
} }
}.start() }.start()
} }

View File

@@ -0,0 +1,24 @@
package top.fumiama.copymanga.ui.cardflow.search
import android.os.Bundle
import android.util.Log
import top.fumiama.copymanga.template.ui.InfoCardLoader
import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.dmzj.copymanga.R
@ExperimentalStdlibApi
class SearchFragment : InfoCardLoader(R.layout.fragment_search, R.id.action_nav_search_to_nav_book) {
private var query: String? = null
private var type: String? = null
override fun getApiUrl() =
getString(R.string.searchApiUrl).format(CMApi.myHostApiUrl, page * 21, query, type)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (isFirstInflate) {
query = arguments?.getCharSequence("query")?.toString()
type = arguments?.getString("type")
Log.d("MySF", "get query=$query, type=$type")
}
}
}

View File

@@ -5,6 +5,7 @@ import android.os.Looper
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import com.google.gson.Gson import com.google.gson.Gson
import kotlinx.android.synthetic.main.fragment_dlcomic.*
import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference import top.fumiama.copymanga.MainActivity.Companion.mainWeakReference
import top.fumiama.copymanga.json.ChapterStructure import top.fumiama.copymanga.json.ChapterStructure
import top.fumiama.copymanga.json.VolumeStructure import top.fumiama.copymanga.json.VolumeStructure
@@ -22,6 +23,7 @@ class ComicDlFragment: NoBackRefreshFragment(R.layout.fragment_dlcomic) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
exit = false exit = false
ldwn?.setPadding(0, 0, 0, navBarHeight)
if(isFirstInflate){ if(isFirstInflate){
when { when {
arguments?.getBoolean("callFromOldDL", false) == true -> initOldComicData() arguments?.getBoolean("callFromOldDL", false) == true -> initOldComicData()

View File

@@ -38,7 +38,8 @@ class DownloadFragment: NoBackRefreshFragment(R.layout.fragment_download) {
if(o1.endsWith(".zip") && o2.endsWith(".zip")) (10000*getFloat(o1) - 10000*getFloat(o2) + 0.5).toInt() if(o1.endsWith(".zip") && o2.endsWith(".zip")) (10000*getFloat(o1) - 10000*getFloat(o2) + 0.5).toInt()
else o1[0] - o2[0] else o1[0] - o2[0]
}?.let { }?.let {
mylv.apply { mylv?.apply {
setPadding(0, 0, 0, navBarHeight)
context.let { c -> context.let { c ->
adapter = ArrayAdapter(c, android.R.layout.simple_list_item_1, it) adapter = ArrayAdapter(c, android.R.layout.simple_list_item_1, it)
setOnItemClickListener { _, _, position, _ -> setOnItemClickListener { _, _, position, _ ->

View File

@@ -30,6 +30,7 @@ import top.fumiama.copymanga.template.general.NoBackRefreshFragment
import top.fumiama.copymanga.template.http.AutoDownloadThread import top.fumiama.copymanga.template.http.AutoDownloadThread
import top.fumiama.copymanga.tools.api.CMApi import top.fumiama.copymanga.tools.api.CMApi
import top.fumiama.copymanga.tools.ui.Navigate import top.fumiama.copymanga.tools.ui.Navigate
import top.fumiama.copymanga.tools.ui.UITools
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import java.lang.Thread.sleep import java.lang.Thread.sleep
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@@ -37,6 +38,7 @@ import java.lang.ref.WeakReference
class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) { class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
lateinit var homeHandler: HomeHandler lateinit var homeHandler: HomeHandler
@SuppressLint("ClickableViewAccessibility")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
if(isFirstInflate) { if(isFirstInflate) {
@@ -47,8 +49,13 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
resources.getColor(R.color.colorGreen, theme)) resources.getColor(R.color.colorGreen, theme))
swiperefresh?.isEnabled = true swiperefresh?.isEnabled = true
fhs.apply { fhl?.setPadding(0, 0, 0, navBarHeight)
fhs?.apply {
isNestedScrollingEnabled = true
val recyclerView = findViewById<RecyclerView>(R.id.search_recycler_view) val recyclerView = findViewById<RecyclerView>(R.id.search_recycler_view)
recyclerView.isNestedScrollingEnabled = true
recyclerView.setPadding(0, 0, 0, navBarHeight)
setAdapterLayoutManager(LinearLayoutManager(context)) setAdapterLayoutManager(LinearLayoutManager(context))
val adapter = ListViewHolder(recyclerView).RecyclerViewAdapter() val adapter = ListViewHolder(recyclerView).RecyclerViewAdapter()
setAdapter(adapter) setAdapter(adapter)
@@ -182,7 +189,9 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
inner class RecyclerViewAdapter : inner class RecyclerViewAdapter :
RecyclerView.Adapter<ListViewHolder>() { RecyclerView.Adapter<ListViewHolder>() {
private var results: BookListStructure? = null private var results: BookListStructure? = null
var type = "" var type = ""
private var query: CharSequence? = null
private var count = 0
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
return ListViewHolder( return ListViewHolder(
LayoutInflater.from(parent.context) LayoutInflater.from(parent.context)
@@ -193,7 +202,21 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
@SuppressLint("ClickableViewAccessibility", "SetTextI18n") @SuppressLint("ClickableViewAccessibility", "SetTextI18n")
override fun onBindViewHolder(holder: ListViewHolder, position: Int) { override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
Log.d("MyMain", "Bind open at $position") Log.d("MyMain", "Bind open at $position")
if (position == itemCount-1) {
holder.itemView.tn.setText(R.string.button_more)
holder.itemView.ta.text = "搜索 \"$query\""
holder.itemView.tb.text = "$count 条结果"
holder.itemView.lwi.visibility = View.INVISIBLE
if (query?.isNotEmpty() == true) holder.itemView.lwc.setOnClickListener {
val bundle = Bundle()
bundle.putCharSequence("query", query)
bundle.putString("type", type)
Navigate.safeNavigateTo(findNavController(), R.id.action_nav_home_to_nav_search, bundle)
}
return
}
results?.results?.list?.get(position)?.apply { results?.results?.list?.get(position)?.apply {
holder.itemView.lwi.visibility = View.VISIBLE
holder.itemView.tn.text = name holder.itemView.tn.text = name
holder.itemView.ta.text = author.let { holder.itemView.ta.text = author.let {
var t = "" var t = ""
@@ -215,12 +238,14 @@ class HomeFragment : NoBackRefreshFragment(R.layout.fragment_home) {
} }
} }
override fun getItemCount() = results?.results?.list?.size?:0 override fun getItemCount() = (results?.results?.list?.size?:0)+1
fun refresh(query: CharSequence) { fun refresh(q: CharSequence) {
query = q
mainWeakReference?.get()?.apply { mainWeakReference?.get()?.apply {
AutoDownloadThread(getString(R.string.searchApiUrl).format(CMApi.myHostApiUrl, 0, query, type)) { AutoDownloadThread(getString(R.string.searchApiUrl).format(CMApi.myHostApiUrl, 0, query, type)) {
results = Gson().fromJson(it?.decodeToString(), BookListStructure::class.java) results = Gson().fromJson(it?.decodeToString(), BookListStructure::class.java)
count = results?.results?.total?:0
runOnUiThread { notifyDataSetChanged() } runOnUiThread { notifyDataSetChanged() }
}.start() }.start()
} }

View File

@@ -4,12 +4,14 @@ import android.animation.ObjectAnimator
import android.graphics.Rect import android.graphics.Rect
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.View
import android.view.Window import android.view.Window
import androidx.annotation.Keep import androidx.annotation.Keep
import androidx.preference.EditTextPreference import androidx.preference.EditTextPreference
import androidx.preference.EditTextPreferenceDialogFragmentCompat import androidx.preference.EditTextPreferenceDialogFragmentCompat
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import top.fumiama.copymanga.tools.ui.UITools
import top.fumiama.dmzj.copymanga.R import top.fumiama.dmzj.copymanga.R
import java.lang.Thread.sleep import java.lang.Thread.sleep
@@ -18,6 +20,13 @@ class SettingsFragment: PreferenceFragmentCompat() {
setPreferencesFromResource(R.xml.pref_setting, rootKey) setPreferencesFromResource(R.xml.pref_setting, rootKey)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
context?.let { c ->
view.setPadding(0, 0, 0, UITools.getNavigationBarHeight(c))
}
}
override fun onDisplayPreferenceDialog(preference: Preference) { override fun onDisplayPreferenceDialog(preference: Preference) {
if (preference is EditTextPreference) { if (preference is EditTextPreference) {
Log.d("MySF", "preference is EditTextPreference") Log.d("MySF", "preference is EditTextPreference")
@@ -41,7 +50,7 @@ class SettingsFragment: PreferenceFragmentCompat() {
Log.d("MySF", "diff: $diff") Log.d("MySF", "diff: $diff")
} }
Log.d("MySF", "diff out while: $diff") Log.d("MySF", "diff out while: $diff")
if (diff == 0) return@Thread if (diff <= 0) return@Thread
Log.d("MySF", "f.dialog is ${f.dialog}") Log.d("MySF", "f.dialog is ${f.dialog}")
f.activity?.runOnUiThread { f.activity?.runOnUiThread {
f.dialog?.window?.apply { f.dialog?.window?.apply {

View File

@@ -47,7 +47,7 @@ object Update {
} }
}) { }) {
val md5 = msg.substringAfterLast("md5:") val md5 = msg.substringAfterLast("md5:")
if (md5 == toolsBox.toHexStr( if (md5 == UITools.toHexStr(
MessageDigest.getInstance("MD5").digest(it) MessageDigest.getInstance("MD5").digest(it)
) )
) { ) {

View File

@@ -13,8 +13,7 @@
android:id="@+id/fbl" android:id="@+id/fbl"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"/>
android:paddingBottom="@dimen/global_content_padding_bottom"/>
</top.fumiama.copymanga.views.OverScrollView> </top.fumiama.copymanga.views.OverScrollView>
<ProgressBar <ProgressBar

View File

@@ -14,8 +14,7 @@
android:id="@+id/ldwn" android:id="@+id/ldwn"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"/>
android:paddingBottom="@dimen/global_content_padding_bottom"/>
</top.fumiama.copymanga.views.LazyScrollView> </top.fumiama.copymanga.views.LazyScrollView>
<include <include

View File

@@ -3,5 +3,4 @@
android:id="@+id/mylv" android:id="@+id/mylv"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:nestedScrollingEnabled="true" android:nestedScrollingEnabled="true"/>
android:paddingBottom="@dimen/global_content_padding_bottom"/>

View File

@@ -28,8 +28,7 @@
android:id="@+id/fhl" android:id="@+id/fhl"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical">
android:paddingBottom="@dimen/global_content_padding_bottom">
</LinearLayout> </LinearLayout>
</top.fumiama.copymanga.views.ScrollRefreshView> </top.fumiama.copymanga.views.ScrollRefreshView>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
layout="@layout/line_lazybooklines"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -25,8 +25,7 @@
android:id="@+id/mydll" android:id="@+id/mydll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="vertical"/>
android:paddingBottom="@dimen/global_content_padding_bottom"/>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
</com.liaoinstan.springview.widget.SpringView> </com.liaoinstan.springview.widget.SpringView>

View File

@@ -45,6 +45,13 @@
app:exitAnim="@anim/slide_out_left" app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_out_left_exit" app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/> app:popExitAnim="@anim/slide_in_right_exit"/>
<action
android:id="@+id/action_nav_home_to_nav_search"
app:destination="@id/nav_search"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/>
</fragment> </fragment>
<fragment <fragment
@@ -217,7 +224,7 @@
<fragment <fragment
android:id="@+id/nav_newest" android:id="@+id/nav_newest"
android:name="top.fumiama.copymanga.ui.cardflow.newest.NewestFragment" android:name="top.fumiama.copymanga.ui.cardflow.search.SearchFragment"
android:label="@string/new_list" android:label="@string/new_list"
tools:layout="@layout/fragment_newest" > tools:layout="@layout/fragment_newest" >
<action <action
@@ -284,4 +291,18 @@
app:popEnterAnim="@anim/slide_out_left_exit" app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/> app:popExitAnim="@anim/slide_in_right_exit"/>
</fragment> </fragment>
<fragment
android:id="@+id/nav_search"
android:name="top.fumiama.copymanga.ui.cardflow.search.SearchFragment"
android:label="@string/page_search"
tools:layout="@layout/fragment_search" >
<action
android:id="@+id/action_nav_search_to_nav_book"
app:destination="@id/nav_book"
app:enterAnim="@anim/slide_in_right"
app:exitAnim="@anim/slide_out_left"
app:popEnterAnim="@anim/slide_out_left_exit"
app:popExitAnim="@anim/slide_in_right_exit"/>
</fragment>
</navigation> </navigation>

View File

@@ -21,6 +21,7 @@
<string name="page_chapter">章节内容</string> <string name="page_chapter">章节内容</string>
<string name="page_group">漫画下载</string> <string name="page_group">漫画下载</string>
<string name="page_topic">专题系列</string> <string name="page_topic">专题系列</string>
<string name="page_search">漫画搜索</string>
<string name="check_update">检查更新</string> <string name="check_update">检查更新</string>
<string name="set_search_types">设置搜索类别</string> <string name="set_search_types">设置搜索类别</string>
@@ -37,6 +38,7 @@
<string name="text_null">N/A</string> <string name="text_null">N/A</string>
<string name="null_book">获取图书信息失败</string> <string name="null_book">获取图书信息失败</string>
<string name="web_error">网络错误</string> <string name="web_error">网络错误</string>
<string name="download_cover_failed">保存封面失败</string>
<string name="download_cover_timeout">保存封面超时</string> <string name="download_cover_timeout">保存封面超时</string>
<string name="mainPageApiUrl">https://%1$s/api/v3/h5/homeIndex?platform=3</string> <string name="mainPageApiUrl">https://%1$s/api/v3/h5/homeIndex?platform=3</string>
@@ -93,6 +95,7 @@
<string name="button_sub">加入书架</string> <string name="button_sub">加入书架</string>
<string name="button_sub_subscribed">已加书架</string> <string name="button_sub_subscribed">已加书架</string>
<string name="button_start">开始阅读</string> <string name="button_start">开始阅读</string>
<string name="button_more">更多</string>
<string name="text_format_hit">热度 %1$d</string> <string name="text_format_hit">热度 %1$d</string>
<string name="text_format_stat">状态 %1$s</string> <string name="text_format_stat">状态 %1$s</string>