Merge remote-tracking branch 'origin/master'

This commit is contained in:
kunfei
2023-10-20 07:25:23 +08:00
22 changed files with 72 additions and 28 deletions
@@ -163,7 +163,7 @@
"id": -21, "id": -21,
"enable": true, "enable": true,
"name": "书名 括号 序号", "name": "书名 括号 序号",
"rule": "^.{1,20}[((][\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}[)][  \t]{0,4}$", "rule": "^[一-龥]{1,20}[  \\t]{0,4}[((][\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}[))][  \\t]{0,4}$",
"example": "标题后面数字有括号(12)", "example": "标题后面数字有括号(12)",
"serialNumber": 20 "serialNumber": 20
}, },
@@ -171,7 +171,7 @@
"id": -22, "id": -22,
"enable": true, "enable": true,
"name": "书名 序号", "name": "书名 序号",
"rule": "^.{1,20}[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}[  \t]{0,4}$", "rule": "^[一-龥]{1,20}[  \\t]{0,4}[\\d〇零一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟]{1,8}[  \\t]{0,4}$",
"example": "标题后面数字没有括号124", "example": "标题后面数字没有括号124",
"serialNumber": 21 "serialNumber": 21
}, },
@@ -138,6 +138,7 @@ object PreferKey {
const val defaultHomePage = "defaultHomePage" const val defaultHomePage = "defaultHomePage"
const val showBookshelfFastScroller = "showBookshelfFastScroller" const val showBookshelfFastScroller = "showBookshelfFastScroller"
const val importKeepEnable = "importKeepEnable" const val importKeepEnable = "importKeepEnable"
const val previewImageByClick = "previewImageByClick"
const val cPrimary = "colorPrimary" const val cPrimary = "colorPrimary"
const val cAccent = "colorAccent" const val cAccent = "colorAccent"
@@ -26,7 +26,7 @@ object ReplaceAnalyzer {
return runCatching { return runCatching {
val replaceRule: ReplaceRule? = val replaceRule: ReplaceRule? =
GSON.fromJsonObject<ReplaceRule>(json.trim()).getOrNull() GSON.fromJsonObject<ReplaceRule>(json.trim()).getOrNull()
if (replaceRule == null || replaceRule.pattern.isBlank()) { if (replaceRule == null || replaceRule.pattern.isEmpty()) {
val jsonItem = jsonPath.parse(json.trim()) val jsonItem = jsonPath.parse(json.trim())
val rule = ReplaceRule() val rule = ReplaceRule()
rule.id = jsonItem.readLong("$.id") ?: System.currentTimeMillis() rule.id = jsonItem.readLong("$.id") ?: System.currentTimeMillis()
@@ -426,6 +426,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener {
appCtx.putPrefBoolean(PreferKey.importKeepEnable, value) appCtx.putPrefBoolean(PreferKey.importKeepEnable, value)
} }
var previewImageByClick: Boolean
get() = appCtx.getPrefBoolean(PreferKey.previewImageByClick, false)
set(value) {
appCtx.putPrefBoolean(PreferKey.previewImageByClick, value)
}
var preDownloadNum var preDownloadNum
get() = appCtx.getPrefInt(PreferKey.preDownloadNum, 10) get() = appCtx.getPrefInt(PreferKey.preDownloadNum, 10)
set(value) { set(value) {
@@ -28,7 +28,6 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
private var tasks = CompositeCoroutine() private var tasks = CompositeCoroutine()
private var bookSourceList = arrayListOf<BookSource>() private var bookSourceList = arrayListOf<BookSource>()
private var searchBooks = arrayListOf<SearchBook>() private var searchBooks = arrayListOf<SearchBook>()
private val emptyBookSource = BookSource()
@Volatile @Volatile
private var searchIndex = -1 private var searchIndex = -1
@@ -77,7 +76,6 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
return return
} }
searchIndex++ searchIndex++
val searchIndex = searchIndex
val source = bookSourceList[searchIndex] val source = bookSourceList[searchIndex]
val searchPool = searchPool ?: return val searchPool = searchPool ?: return
val task = WebBook.searchBook( val task = WebBook.searchBook(
@@ -93,7 +91,7 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
onSuccess(searchId, it) onSuccess(searchId, it)
} }
.onFinally { .onFinally {
onFinally(searchId, searchIndex) onFinally(searchId)
} }
tasks.add(task) tasks.add(task)
} }
@@ -109,15 +107,12 @@ class SearchModel(private val scope: CoroutineScope, private val callBack: CallB
} }
@Synchronized @Synchronized
private fun onFinally(searchId: Long, index: Int) { private fun onFinally(searchId: Long) {
if (searchIndex < bookSourceList.lastIndex) { if (searchIndex < bookSourceList.lastIndex) {
search(searchId) search(searchId)
} else { } else {
searchIndex++ searchIndex++
} }
if (index <= bookSourceList.lastIndex) {
bookSourceList[index] = emptyBookSource
}
if (searchIndex >= bookSourceList.lastIndex if (searchIndex >= bookSourceList.lastIndex
+ min(bookSourceList.size, threadCount) + min(bookSourceList.size, threadCount)
) { ) {
@@ -141,6 +141,8 @@ class ImportRssSourceDialog() : BaseDialogFragment(R.layout.dialog_recycler_view
AppConfig.importKeepName AppConfig.importKeepName
binding.toolBar.menu.findItem(R.id.menu_keep_group)?.isChecked = binding.toolBar.menu.findItem(R.id.menu_keep_group)?.isChecked =
AppConfig.importKeepGroup AppConfig.importKeepGroup
binding.toolBar.menu.findItem(R.id.menu_keep_enable)?.isChecked =
AppConfig.importKeepEnable
binding.toolBar.menu.findItem(R.id.menu_select_new_source)?.isVisible = false binding.toolBar.menu.findItem(R.id.menu_select_new_source)?.isVisible = false
binding.toolBar.menu.findItem(R.id.menu_select_update_source)?.isVisible = false binding.toolBar.menu.findItem(R.id.menu_select_update_source)?.isVisible = false
} }
@@ -158,6 +160,11 @@ class ImportRssSourceDialog() : BaseDialogFragment(R.layout.dialog_recycler_view
item.isChecked = !item.isChecked item.isChecked = !item.isChecked
putPrefBoolean(PreferKey.importKeepGroup, item.isChecked) putPrefBoolean(PreferKey.importKeepGroup, item.isChecked)
} }
R.id.menu_keep_enable -> {
item.isChecked = !item.isChecked
AppConfig.importKeepEnable = item.isChecked
}
} }
return false return false
} }
@@ -61,6 +61,7 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {
val group = groupName?.trim() val group = groupName?.trim()
val keepName = AppConfig.importKeepName val keepName = AppConfig.importKeepName
val keepGroup = AppConfig.importKeepGroup val keepGroup = AppConfig.importKeepGroup
val keepEnable = AppConfig.importKeepEnable
val selectSource = arrayListOf<RssSource>() val selectSource = arrayListOf<RssSource>()
selectStatus.forEachIndexed { index, b -> selectStatus.forEachIndexed { index, b ->
if (b) { if (b) {
@@ -72,6 +73,9 @@ class ImportRssSourceViewModel(app: Application) : BaseViewModel(app) {
if (keepGroup) { if (keepGroup) {
source.sourceGroup = it.sourceGroup source.sourceGroup = it.sourceGroup
} }
if (keepEnable) {
source.enabled = it.enabled
}
source.customOrder = it.customOrder source.customOrder = it.customOrder
} }
if (!group.isNullOrEmpty()) { if (!group.isNullOrEmpty()) {
@@ -1209,6 +1209,7 @@ class ReadBookActivity : BaseReadBookActivity(),
SelectItem(getString(R.string.show), "show"), SelectItem(getString(R.string.show), "show"),
SelectItem(getString(R.string.refresh), "refresh"), SelectItem(getString(R.string.refresh), "refresh"),
SelectItem(getString(R.string.action_save), "save"), SelectItem(getString(R.string.action_save), "save"),
SelectItem(getString(R.string.menu), "menu"),
SelectItem(getString(R.string.select_folder), "selectFolder") SelectItem(getString(R.string.select_folder), "selectFolder")
) )
) )
@@ -1227,6 +1228,7 @@ class ReadBookActivity : BaseReadBookActivity(),
} }
} }
"menu" -> showActionMenu()
"selectFolder" -> selectImageDir.launch() "selectFolder" -> selectImageDir.launch()
} }
popupAction.dismiss() popupAction.dismiss()
@@ -24,6 +24,7 @@ import io.legado.app.ui.book.read.page.entities.TextPos
import io.legado.app.ui.book.read.page.entities.column.* import io.legado.app.ui.book.read.page.entities.column.*
import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ChapterProvider
import io.legado.app.ui.book.read.page.provider.TextPageFactory import io.legado.app.ui.book.read.page.provider.TextPageFactory
import io.legado.app.ui.widget.dialog.PhotoDialog
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlin.math.min import kotlin.math.min
@@ -348,6 +349,11 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at
context.toastOnUi("Button Pressed!") context.toastOnUi("Button Pressed!")
handled = true handled = true
} }
is ImageColumn -> if (AppConfig.previewImageByClick) {
activity?.showDialogFragment(PhotoDialog(column.src))
handled = true
}
} }
} }
return handled return handled
@@ -558,7 +558,7 @@ object ChapterProvider {
} }
val residualWidth = visibleWidth - desiredWidth val residualWidth = visibleWidth - desiredWidth
val spaceSize = text.count { it == ' ' } val spaceSize = text.count { it == ' ' }
val (words, widths) = getStringArrayAndTextWidths(text, textWidths) val (words, widths) = getStringArrayAndTextWidths(text, textWidths, textPaint)
if (spaceSize > 1) { if (spaceSize > 1) {
val d = residualWidth / spaceSize val d = residualWidth / spaceSize
var x = startX var x = startX
@@ -589,7 +589,7 @@ object ChapterProvider {
x = x1 x = x1
} }
} }
exceed(absStartX, textLine) exceed(absStartX, textLine, words)
} }
/** /**
@@ -608,7 +608,7 @@ object ChapterProvider {
) { ) {
val indentLength = ReadBookConfig.paragraphIndent.length val indentLength = ReadBookConfig.paragraphIndent.length
var x = startX var x = startX
val (words, widths) = getStringArrayAndTextWidths(text, textWidths) val (words, widths) = getStringArrayAndTextWidths(text, textWidths, textPaint)
words.forEachIndexed { index, char -> words.forEachIndexed { index, char ->
val cw = widths[index] val cw = widths[index]
val x1 = x + cw val x1 = x + cw
@@ -618,12 +618,13 @@ object ChapterProvider {
textLine.indentWidth = x textLine.indentWidth = x
} }
} }
exceed(absStartX, textLine) exceed(absStartX, textLine, words)
} }
fun getStringArrayAndTextWidths( fun getStringArrayAndTextWidths(
text: String, text: String,
textWidths: List<Float> textWidths: List<Float>,
textPaint: TextPaint
): Pair<List<String>, List<Float>> { ): Pair<List<String>, List<Float>> {
val charArray = text.toCharArray() val charArray = text.toCharArray()
val strList = ArrayList<String>() val strList = ArrayList<String>()
@@ -639,7 +640,13 @@ object ChapterProvider {
charArray[i].toString() charArray[i].toString()
} }
strList.add(char) strList.add(char)
textWidthList.add(textWidths[i]) val w = textWidths[i]
if (w == 0f && i - 1 >= 0) {
textWidthList[i - 1] = textPaint.measureText(strList[i - 1])
textWidthList.add(textPaint.measureText(char))
} else {
textWidthList.add(w)
}
} }
return strList to textWidthList return strList to textWidthList
} }
@@ -690,15 +697,14 @@ object ChapterProvider {
/** /**
* 超出边界处理 * 超出边界处理
*/ */
private fun exceed(absStartX: Int, textLine: TextLine) { private fun exceed(absStartX: Int, textLine: TextLine, words: List<String>) {
val visibleEnd = absStartX + visibleWidth val visibleEnd = absStartX + visibleWidth
val columns = textLine.columns val endX = textLine.columns.lastOrNull()?.end ?: return
val endX = columns.lastOrNull()?.end ?: return
if (endX > visibleEnd) { if (endX > visibleEnd) {
val cc = (endX - visibleEnd) / columns.size val cc = (endX - visibleEnd) / words.size
for (i in 0..columns.lastIndex) { for (i in 0..words.lastIndex) {
textLine.getColumnReverseAt(i).let { textLine.getColumnReverseAt(i).let {
val py = cc * (columns.size - i) val py = cc * (words.size - i)
it.start = it.start - py it.start = it.start - py
it.end = it.end - py it.end = it.end - py
} }
@@ -53,7 +53,8 @@ class ZhLayout(
curPaint.getTextWidths(text as String, widthsArray) curPaint.getTextWidths(text as String, widthsArray)
val (words, widths) = ChapterProvider.getStringArrayAndTextWidths( val (words, widths) = ChapterProvider.getStringArrayAndTextWidths(
text, text,
widthsArray.asList() widthsArray.asList(),
curPaint
) )
var lineW = 0f var lineW = 0f
var cwPre = 0f var cwPre = 0f
@@ -143,9 +143,9 @@ data class SearchScope(private var scope: String) {
fun save() { fun save() {
AppConfig.searchScope = scope AppConfig.searchScope = scope
if (isAll()) { if (isAll() || isSource() || scope.contains(",")) {
AppConfig.searchGroup = "" AppConfig.searchGroup = ""
} else if (!isSource() && !scope.contains(",")) { } else {
AppConfig.searchGroup = scope AppConfig.searchGroup = scope
} }
} }
@@ -1132,4 +1132,5 @@
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string> <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string> <string name="export_all_use_book_source">导出所有书的书源</string>
<string name="keep_enable">保留启用状态</string> <string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
</resources> </resources>
@@ -1135,4 +1135,5 @@
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string> <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string> <string name="export_all_use_book_source">导出所有书的书源</string>
<string name="keep_enable">保留启用状态</string> <string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
</resources> </resources>
@@ -1135,4 +1135,5 @@
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string> <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string> <string name="export_all_use_book_source">导出所有书的书源</string>
<string name="keep_enable">保留启用状态</string> <string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
</resources> </resources>
+1
View File
@@ -1130,4 +1130,5 @@ Còn </string>
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string> <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string> <string name="export_all_use_book_source">导出所有书的书源</string>
<string name="keep_enable">保留启用状态</string> <string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
</resources> </resources>
@@ -1131,4 +1131,5 @@
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string> <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string> <string name="export_all_use_book_source">导出所有书的书源</string>
<string name="keep_enable">保留启用状态</string> <string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
</resources> </resources>
@@ -1133,4 +1133,5 @@
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string> <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string> <string name="export_all_use_book_source">导出所有书的书源</string>
<string name="keep_enable">保留启用状态</string> <string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
</resources> </resources>
+1
View File
@@ -1133,4 +1133,5 @@
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string> <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string> <string name="export_all_use_book_source">导出所有书的书源</string>
<string name="keep_enable">保留启用状态</string> <string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
</resources> </resources>
+1
View File
@@ -1135,4 +1135,5 @@
<string name="show_bookshelf_fast_scroller">显示快速滚动条</string> <string name="show_bookshelf_fast_scroller">显示快速滚动条</string>
<string name="export_all_use_book_source">导出所有书的书源</string> <string name="export_all_use_book_source">导出所有书的书源</string>
<string name="keep_enable">保留启用状态</string> <string name="keep_enable">保留启用状态</string>
<string name="preview_image_by_click">点击预览图片</string>
</resources> </resources>
@@ -143,6 +143,13 @@
app:iconSpaceReserved="false" app:iconSpaceReserved="false"
app:isBottomBackground="true" /> app:isBottomBackground="true" />
<io.legado.app.lib.prefs.SwitchPreference
android:defaultValue="false"
android:key="previewImageByClick"
android:title="@string/preview_image_by_click"
app:iconSpaceReserved="false"
app:isBottomBackground="true" />
<io.legado.app.lib.prefs.Preference <io.legado.app.lib.prefs.Preference
android:key="clickRegionalConfig" android:key="clickRegionalConfig"
android:title="@string/click_regional_config" android:title="@string/click_regional_config"
+4 -3
View File
@@ -5,10 +5,11 @@ pluginManagement {
google() google()
mavenCentral() mavenCentral()
//镜像仓库,无法连接源仓库自行启用镜像仓库,不要提交修改 //镜像仓库,无法连接源仓库自行启用镜像仓库,不要提交修改
//maven {url"https://maven-central-asia.storage-download.googleapis.com/maven2/"} //maven { url "https://maven-central-asia.storage-download.googleapis.com/maven2/" }
//maven { url 'https://maven.aliyun.com/repository/google' } //maven { url 'https://maven.aliyun.com/repository/google' }
//maven { url 'https://maven.aliyun.com/repository/public' } //maven { url 'https://maven.aliyun.com/repository/public' }
//maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } //maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
//maven { url 'https://repo.huaweicloud.com/repository/maven/' }
} }
} }
@@ -20,10 +21,10 @@ dependencyResolutionManagement {
mavenCentral() mavenCentral()
maven { url 'https://jitpack.io' } maven { url 'https://jitpack.io' }
//镜像仓库,无法连接源仓库自行启用镜像仓库,不要提交修改 //镜像仓库,无法连接源仓库自行启用镜像仓库,不要提交修改
//maven {url"https://maven-central-asia.storage-download.googleapis.com/maven2/"} //maven { url "https://maven-central-asia.storage-download.googleapis.com/maven2/" }
//maven { url 'https://maven.aliyun.com/repository/google' } //maven { url 'https://maven.aliyun.com/repository/google' }
//maven { url 'https://maven.aliyun.com/repository/public' } //maven { url 'https://maven.aliyun.com/repository/public' }
//maven { url 'https://repo.huaweicloud.com/repository/maven/' }
} }
} }
rootProject.name = 'legado' rootProject.name = 'legado'