From 6b22ab046eecf1abf6b952ac806cdfebb7687051 Mon Sep 17 00:00:00 2001 From: Seidko Date: Sun, 21 Aug 2022 23:09:26 +0800 Subject: [PATCH 01/19] Add: Add ReviewRule and related codes --- .../io.legado.app.data.AppDatabase/52.json | 94 +++++++++++-------- .../io/legado/app/data/dao/BookSourceDao.kt | 3 + .../io/legado/app/data/entities/BookSource.kt | 21 ++++- .../app/data/entities/rule/ReviewRule.kt | 18 ++++ .../res/layout/activity_book_source_edit.xml | 21 ++++- app/src/main/res/values-es-rES/strings.xml | 1 + app/src/main/res/values-ja-rJP/strings.xml | 1 + app/src/main/res/values-pt-rBR/strings.xml | 1 + app/src/main/res/values-zh-rHK/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 12 files changed, 119 insertions(+), 45 deletions(-) create mode 100644 app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt diff --git a/app/schemas/io.legado.app.data.AppDatabase/52.json b/app/schemas/io.legado.app.data.AppDatabase/52.json index 4f3ee4e9a..e9a5947e9 100644 --- a/app/schemas/io.legado.app.data.AppDatabase/52.json +++ b/app/schemas/io.legado.app.data.AppDatabase/52.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 52, - "identityHash": "0221c385ed7393f47afe9579d3106541", + "identityHash": "c55dac79aa9cc3dcdb72e91da4282005", "entities": [ { "tableName": "books", @@ -208,10 +208,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "bookUrl" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -263,17 +263,17 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "groupId" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] }, { "tableName": "book_sources", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceUrl` TEXT NOT NULL, `bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `enabledCookieJar` INTEGER DEFAULT 0, `concurrentRate` TEXT, `header` TEXT, `loginUrl` TEXT, `loginUi` TEXT, `loginCheckJs` TEXT, `bookSourceComment` TEXT, `variableComment` TEXT, `lastUpdateTime` INTEGER NOT NULL, `respondTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, PRIMARY KEY(`bookSourceUrl`))", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceUrl` TEXT NOT NULL, `bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `enabledCookieJar` INTEGER DEFAULT 0, `concurrentRate` TEXT, `header` TEXT, `loginUrl` TEXT, `loginUi` TEXT, `enabledReview` INTEGER, `loginCheckJs` TEXT, `bookSourceComment` TEXT, `variableComment` TEXT, `lastUpdateTime` INTEGER NOT NULL, `respondTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, `ruleReview` TEXT, PRIMARY KEY(`bookSourceUrl`))", "fields": [ { "fieldPath": "bookSourceUrl", @@ -354,6 +354,12 @@ "affinity": "TEXT", "notNull": false }, + { + "fieldPath": "enabledReview", + "columnName": "enabledReview", + "affinity": "INTEGER", + "notNull": false + }, { "fieldPath": "loginCheckJs", "columnName": "loginCheckJs", @@ -431,13 +437,19 @@ "columnName": "ruleContent", "affinity": "TEXT", "notNull": false + }, + { + "fieldPath": "ruleReview", + "columnName": "ruleReview", + "affinity": "TEXT", + "notNull": false } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "bookSourceUrl" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -548,11 +560,11 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "url", "bookUrl" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -676,10 +688,10 @@ } ], "primaryKey": { - "autoGenerate": true, "columnNames": [ "id" - ] + ], + "autoGenerate": true }, "indices": [ { @@ -790,10 +802,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "bookUrl" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -853,10 +865,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "word" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -889,10 +901,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "url" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -1082,10 +1094,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "sourceUrl" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -1154,10 +1166,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "time" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -1245,11 +1257,11 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "origin", "link" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -1272,10 +1284,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "record" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -1346,11 +1358,11 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "origin", "link" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -1397,10 +1409,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "id" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -1437,11 +1449,11 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "deviceId", "bookName" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -1521,10 +1533,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "id" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -1553,10 +1565,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "key" - ] + ], + "autoGenerate": false }, "indices": [ { @@ -1619,10 +1631,10 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "id" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -1661,11 +1673,11 @@ } ], "primaryKey": { - "autoGenerate": false, "columnNames": [ "type", "key" - ] + ], + "autoGenerate": false }, "indices": [], "foreignKeys": [] @@ -1674,7 +1686,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0221c385ed7393f47afe9579d3106541')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c55dac79aa9cc3dcdb72e91da4282005')" ] } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt index f98063115..c9aff1b65 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookSourceDao.kt @@ -50,6 +50,9 @@ interface BookSourceDao { @Query("select * from book_sources where enabledExplore = 1 and trim(exploreUrl) <> '' order by customOrder asc") fun flowExplore(): Flow> +// @Query("select * from book_sources where enabledReview = 1 order by customOrder asc") +// fun flowReview(): Flow> + @Query("select * from book_sources where loginUrl is not null and loginUrl != ''") fun flowLogin(): Flow> diff --git a/app/src/main/java/io/legado/app/data/entities/BookSource.kt b/app/src/main/java/io/legado/app/data/entities/BookSource.kt index 9f27a31a7..f1302d091 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookSource.kt @@ -49,6 +49,8 @@ data class BookSource( override var loginUrl: String? = null, // 登录UI override var loginUi: String? = null, + // 启用段评 + var enabledReview: Boolean? = false, // 登录检测js var loginCheckJs: String? = null, // 注释 @@ -74,7 +76,9 @@ data class BookSource( // 目录页规则 var ruleToc: TocRule? = null, // 正文页规则 - var ruleContent: ContentRule? = null + var ruleContent: ContentRule? = null, + // 段评规则 + var ruleReview: ReviewRule? = null ) : Parcelable, BaseSource { override fun getTag(): String { @@ -170,6 +174,13 @@ data class BookSource( return rule } + fun getReviewRule(): ReviewRule { + ruleReview?.let { return it } + val rule = ReviewRule() + ruleReview = rule + return rule + } + fun getDisPlayNameGroup(): String { return if (bookSourceGroup.isNullOrBlank()) { bookSourceName @@ -303,5 +314,13 @@ data class BookSource( fun stringToContentRule(json: String?) = GSON.fromJsonObject(json).getOrNull() + @TypeConverter + fun stringToReviewRule(json: String?) = + GSON.fromJsonObject(json).getOrNull() + + @TypeConverter + fun reviewRuleToString(reviewRule: ReviewRule?): String = + GSON.toJson(reviewRule) + } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt new file mode 100644 index 000000000..80bed45eb --- /dev/null +++ b/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt @@ -0,0 +1,18 @@ +package io.legado.app.data.entities.rule + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@Parcelize +data class ReviewRule( + var reviewUrl: String? = null, // 段评URL + var avatarRule: String? = null, // 段评发布者头像 + var contentRule: String? = null, // 段评内容 + var postTimeRule: String? = null, // 段评发布时间 + var reviewReplyUrl: String? = null, // 获取段评回复URL + + // 这些功能将在以上功能完成以后实现 + var voteUpUrl: String? = null, // 点赞URL + var voteDownUrl: String? = null, // 点踩URL + var replyUrl: String? = null // 回复URL +): Parcelable \ No newline at end of file diff --git a/app/src/main/res/layout/activity_book_source_edit.xml b/app/src/main/res/layout/activity_book_source_edit.xml index ceae414f2..4b6366974 100644 --- a/app/src/main/res/layout/activity_book_source_edit.xml +++ b/app/src/main/res/layout/activity_book_source_edit.xml @@ -40,18 +40,33 @@ android:checked="true" android:text="@string/auto_save_cookie" /> - + + + + + diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml index c94c43ea5..48bf4a0b8 100644 --- a/app/src/main/res/values-es-rES/strings.xml +++ b/app/src/main/res/values-es-rES/strings.xml @@ -1010,4 +1010,5 @@ 选中所选区间 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 + Review diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 0fa495693..fad7b4f6d 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -1013,4 +1013,5 @@ 选中所选区间 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 + Review diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 3ad76156f..2f95b824a 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1013,4 +1013,5 @@ 选中所选区间 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 + Review diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 9948080db..e44b8780d 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -1010,4 +1010,5 @@ 选中所选区间 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 + 段评 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 5210c961a..811ef3d55 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1012,4 +1012,5 @@ 选中所选区间 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 + 段评 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index cc6801538..8fddc6150 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1012,4 +1012,5 @@ 选中所选区间 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 + 段评 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d64ef8432..a5e5b0889 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1013,4 +1013,5 @@ 选中所选区间 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 + Review From 15bae4b00acf682e7d2a396fb4c423b9a51eb342 Mon Sep 17 00:00:00 2001 From: Seidko Date: Sun, 28 Aug 2022 11:11:18 +0800 Subject: [PATCH 02/19] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=AE=B5=E8=AF=84?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E9=A1=B5=E9=9D=A2=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=86=E4=B8=80=E4=BA=9B=E4=B8=8D=E7=BB=9F=E4=B8=80=E7=9A=84?= =?UTF-8?q?=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/data/entities/BookSource.kt | 6 +- .../app/data/entities/rule/ReviewRule.kt | 8 ++- .../java/io/legado/app/help/SourceAnalyzer.kt | 18 +++-- .../source/edit/BookSourceEditActivity.kt | 65 +++++++++++++++---- .../res/layout/activity_book_source_edit.xml | 7 +- app/src/main/res/values-es-rES/strings.xml | 10 +++ app/src/main/res/values-ja-rJP/strings.xml | 10 +++ app/src/main/res/values-pt-rBR/strings.xml | 10 +++ app/src/main/res/values-zh-rHK/strings.xml | 10 +++ app/src/main/res/values-zh-rTW/strings.xml | 10 +++ app/src/main/res/values-zh/strings.xml | 10 +++ app/src/main/res/values/non_translat.xml | 36 +++++----- app/src/main/res/values/strings.xml | 10 +++ 13 files changed, 168 insertions(+), 42 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/entities/BookSource.kt b/app/src/main/java/io/legado/app/data/entities/BookSource.kt index f1302d091..0184b8688 100644 --- a/app/src/main/java/io/legado/app/data/entities/BookSource.kt +++ b/app/src/main/java/io/legado/app/data/entities/BookSource.kt @@ -37,7 +37,9 @@ data class BookSource( // 是否启用 var enabled: Boolean = true, // 启用发现 - var enabledExplore: Boolean = true, + var enabledExplore: Boolean = false, + // 启用段评 + var enabledReview: Boolean? = false, // 启用okhttp CookieJAr 自动保存每次请求的cookie @ColumnInfo(defaultValue = "0") override var enabledCookieJar: Boolean? = false, @@ -49,8 +51,6 @@ data class BookSource( override var loginUrl: String? = null, // 登录UI override var loginUi: String? = null, - // 启用段评 - var enabledReview: Boolean? = false, // 登录检测js var loginCheckJs: String? = null, // 注释 diff --git a/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt index 80bed45eb..2d2dc249c 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt @@ -9,10 +9,12 @@ data class ReviewRule( var avatarRule: String? = null, // 段评发布者头像 var contentRule: String? = null, // 段评内容 var postTimeRule: String? = null, // 段评发布时间 - var reviewReplyUrl: String? = null, // 获取段评回复URL + var reviewQuoteUrl: String? = null, // 获取段评回复URL // 这些功能将在以上功能完成以后实现 var voteUpUrl: String? = null, // 点赞URL var voteDownUrl: String? = null, // 点踩URL - var replyUrl: String? = null // 回复URL -): Parcelable \ No newline at end of file + var postReviewUrl: String? = null, // 发送回复URL + var postQuoteUrl: String? = null, // 发送回复段评URL + var deleteUrl: String? = null, // 删除段评URL +): Parcelable diff --git a/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt b/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt index 5fb5e8437..1efc4e86e 100644 --- a/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt +++ b/app/src/main/java/io/legado/app/help/SourceAnalyzer.kt @@ -151,6 +151,7 @@ object SourceAnalyzer { source.enabled = sourceAny.enabled source.enabledExplore = sourceAny.enabledExplore source.enabledCookieJar = sourceAny.enabledCookieJar + source.enabledReview = sourceAny.enabledReview source.concurrentRate = sourceAny.concurrentRate source.header = sourceAny.header source.loginUrl = when (sourceAny.loginUrl) { @@ -205,6 +206,13 @@ object SourceAnalyzer { GSON.fromJsonObject(GSON.toJson(sourceAny.ruleContent)) .getOrNull() } + source.ruleReview = if (sourceAny.ruleReview is String) { + GSON.fromJsonObject(sourceAny.ruleReview.toString()) + .getOrNull() + } else { + GSON.fromJsonObject(GSON.toJson(sourceAny.ruleReview)) + .getOrNull() + } } source } @@ -220,13 +228,14 @@ object SourceAnalyzer { var customOrder: Int = 0, // 手动排序编号 var enabled: Boolean = true, // 是否启用 var enabledExplore: Boolean = true, // 启用发现 - var enabledCookieJar: Boolean = false, // 启用CookieJar + var enabledReview: Boolean = false, // 启用段评 + var enabledCookieJar: Boolean = false, // 启用CookieJar var concurrentRate: String? = null, // 并发率 var header: String? = null, // 请求头 var loginUrl: Any? = null, // 登录规则 var loginUi: Any? = null, // 登录UI - var loginCheckJs: String? = null, //登录检测js - var bookSourceComment: String? = "", //书源注释 + var loginCheckJs: String? = null, // 登录检测js + var bookSourceComment: String? = "", // 书源注释 var lastUpdateTime: Long = 0, // 最后更新时间,用于排序 var respondTime: Long = 180000L, // 响应时间,用于排序 var weight: Int = 0, // 智能排序的权重 @@ -236,7 +245,8 @@ object SourceAnalyzer { var ruleSearch: Any? = null, // 搜索规则 var ruleBookInfo: Any? = null, // 书籍信息页规则 var ruleToc: Any? = null, // 目录页规则 - var ruleContent: Any? = null // 正文页规则 + var ruleContent: Any? = null, // 正文页规则 + var ruleReview: Any? = null // 段评规则 ) // default规则适配 diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt index da0d39aac..d733ca71e 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt @@ -41,10 +41,11 @@ class BookSourceEditActivity : private val adapter by lazy { BookSourceEditAdapter() } private val sourceEntities: ArrayList = ArrayList() private val searchEntities: ArrayList = ArrayList() - private val findEntities: ArrayList = ArrayList() + private val exploreEntities: ArrayList = ArrayList() private val infoEntities: ArrayList = ArrayList() private val tocEntities: ArrayList = ArrayList() private val contentEntities: ArrayList = ArrayList() + private val reviewEntities: ArrayList = ArrayList() private val qrCodeResult = registerForActivityResult(QrCodeResult()) { it ?: return@registerForActivityResult viewModel.importSource(it) { source -> @@ -180,10 +181,11 @@ class BookSourceEditActivity : private fun setEditEntities(tabPosition: Int?) { when (tabPosition) { 1 -> adapter.editEntities = searchEntities - 2 -> adapter.editEntities = findEntities + 2 -> adapter.editEntities = exploreEntities 3 -> adapter.editEntities = infoEntities 4 -> adapter.editEntities = tocEntities 5 -> adapter.editEntities = contentEntities + 6 -> adapter.editEntities = reviewEntities else -> adapter.editEntities = sourceEntities } binding.recyclerView.scrollToPosition(0) @@ -192,8 +194,9 @@ class BookSourceEditActivity : private fun upSourceView(source: BookSource? = viewModel.bookSource) { source?.let { binding.cbIsEnable.isChecked = it.enabled - binding.cbIsEnableFind.isChecked = it.enabledExplore + binding.cbIsEnableExplore.isChecked = it.enabledExplore binding.cbIsEnableCookie.isChecked = it.enabledCookieJar ?: false + binding.cbIsEnableReview.isChecked = it.enabledReview ?: false binding.spType.setSelection( when (it.bookSourceType) { BookType.file -> 3 @@ -203,7 +206,7 @@ class BookSourceEditActivity : } ) } - //基本信息 + // 基本信息 sourceEntities.clear() sourceEntities.apply { add(EditEntity("bookSourceUrl", source?.bookSourceUrl, R.string.source_url)) @@ -218,7 +221,7 @@ class BookSourceEditActivity : add(EditEntity("variableComment", source?.variableComment, R.string.variable_comment)) add(EditEntity("concurrentRate", source?.concurrentRate, R.string.concurrent_rate)) } - //搜索 + // 搜索 val sr = source?.getSearchRule() searchEntities.clear() searchEntities.apply { @@ -234,10 +237,10 @@ class BookSourceEditActivity : add(EditEntity("coverUrl", sr?.coverUrl, R.string.rule_cover_url)) add(EditEntity("bookUrl", sr?.bookUrl, R.string.r_book_url)) } - //发现 + // 发现 val er = source?.getExploreRule() - findEntities.clear() - findEntities.apply { + exploreEntities.clear() + exploreEntities.apply { add(EditEntity("exploreUrl", source?.exploreUrl, R.string.r_find_url)) add(EditEntity("bookList", er?.bookList, R.string.r_book_list)) add(EditEntity("name", er?.name, R.string.r_book_name)) @@ -249,7 +252,7 @@ class BookSourceEditActivity : add(EditEntity("coverUrl", er?.coverUrl, R.string.rule_cover_url)) add(EditEntity("bookUrl", er?.bookUrl, R.string.r_book_url)) } - //详情页 + // 详情页 val ir = source?.getBookInfoRule() infoEntities.clear() infoEntities.apply { @@ -265,7 +268,7 @@ class BookSourceEditActivity : add(EditEntity("canReName", ir?.canReName, R.string.rule_can_re_name)) add(EditEntity("downloadUrls", ir?.downloadUrls, R.string.download_url_rule)) } - //目录页 + // 目录页 val tr = source?.getTocRule() tocEntities.clear() tocEntities.apply { @@ -279,7 +282,7 @@ class BookSourceEditActivity : add(EditEntity("isPay", tr?.isPay, R.string.rule_is_pay)) add(EditEntity("nextTocUrl", tr?.nextTocUrl, R.string.rule_next_toc_url)) } - //正文页 + // 正文页 val cr = source?.getContentRule() contentEntities.clear() contentEntities.apply { @@ -291,6 +294,21 @@ class BookSourceEditActivity : add(EditEntity("imageStyle", cr?.imageStyle, R.string.rule_image_style)) add(EditEntity("payAction", cr?.payAction, R.string.rule_pay_action)) } + // 段评 + val rr = source?.getReviewRule() + reviewEntities.clear() + reviewEntities.apply { + add(EditEntity("reviewUrl", rr?.reviewUrl, R.string.rule_review_url)) + add(EditEntity("avatarRule", rr?.reviewUrl, R.string.rule_avatar)) + add(EditEntity("contentRule", rr?.contentRule, R.string.rule_review_content)) + add(EditEntity("postTimeRule", rr?.postTimeRule, R.string.rule_post_time)) + add(EditEntity("reviewQuoteUrl", rr?.reviewQuoteUrl, R.string.rule_review_quote)) + add(EditEntity("voteUpUrl", rr?.voteUpUrl, R.string.review_vote_up)) + add(EditEntity("voteDownUrl", rr?.voteDownUrl, R.string.review_vote_down)) + add(EditEntity("postReviewUrl", rr?.postReviewUrl, R.string.post_review_url)) + add(EditEntity("postQuoteUrl", rr?.postQuoteUrl, R.string.post_quote_url)) + add(EditEntity("deleteUrl", rr?.deleteUrl, R.string.delete_review_url)) + } binding.tabLayout.selectTab(binding.tabLayout.getTabAt(0)) setEditEntities(0) } @@ -298,8 +316,9 @@ class BookSourceEditActivity : private fun getSource(): BookSource { val source = viewModel.bookSource?.copy() ?: BookSource() source.enabled = binding.cbIsEnable.isChecked - source.enabledExplore = binding.cbIsEnableFind.isChecked + source.enabledExplore = binding.cbIsEnableExplore.isChecked source.enabledCookieJar = binding.cbIsEnableCookie.isChecked + source.enabledReview = binding.cbIsEnableReview.isChecked source.bookSourceType = when (binding.spType.selectedItemPosition) { 3 -> BookType.file 2 -> BookType.image @@ -311,6 +330,7 @@ class BookSourceEditActivity : val bookInfoRule = BookInfoRule() val tocRule = TocRule() val contentRule = ContentRule() + val reviewRule = ReviewRule() sourceEntities.forEach { when (it.key) { "bookSourceUrl" -> source.bookSourceUrl = it.value ?: "" @@ -351,7 +371,7 @@ class BookSourceEditActivity : viewModel.ruleComplete(it.value, searchRule.bookList, 2) } } - findEntities.forEach { + exploreEntities.forEach { when (it.key) { "exploreUrl" -> source.exploreUrl = it.value "bookList" -> exploreRule.bookList = it.value @@ -429,11 +449,30 @@ class BookSourceEditActivity : "payAction" -> contentRule.payAction = it.value } } + reviewEntities.forEach { + when (it.key) { + "reviewUrl" -> reviewRule.reviewUrl = it.value + "avatarRule" -> reviewRule.avatarRule = + viewModel.ruleComplete(it.value, reviewRule.reviewUrl, 3) + "contentRule" -> reviewRule.contentRule = + viewModel.ruleComplete(it.value, reviewRule.reviewUrl) + "postTimeRule" -> reviewRule.postTimeRule = + viewModel.ruleComplete(it.value, reviewRule.reviewUrl) + "reviewQuoteUrl" -> reviewRule.reviewQuoteUrl = + viewModel.ruleComplete(it.value, reviewRule.reviewUrl, 2) + "voteUpUrl" -> reviewRule.voteUpUrl = it.value + "voteDownUrl" -> reviewRule.voteDownUrl = it.value + "postReviewUrl" -> reviewRule.postReviewUrl = it.value + "postQuoteUrl" -> reviewRule.postQuoteUrl = it.value + "deleteUrl" -> reviewRule.deleteUrl =it.value + } + } source.ruleSearch = searchRule source.ruleExplore = exploreRule source.ruleBookInfo = bookInfoRule source.ruleToc = tocRule source.ruleContent = contentRule + source.ruleReview = reviewRule return source } diff --git a/app/src/main/res/layout/activity_book_source_edit.xml b/app/src/main/res/layout/activity_book_source_edit.xml index 4b6366974..bed6d5a36 100644 --- a/app/src/main/res/layout/activity_book_source_edit.xml +++ b/app/src/main/res/layout/activity_book_source_edit.xml @@ -27,7 +27,7 @@ android:text="@string/is_enable" /> + + 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 Review + 段评URL(reviewUrl) + 段评发布者头像(avatarRule) + 段评内容(contentRule) + 段评回复URL(reviewQuoteUrl) + 段评发布时间(postTimeRule) + 点踩URL(voteUpUrl) + 点赞URL(voteDownUrl) + 发送回复URL(postReviewUrl) + 发送回复段评URL(postQuoteUrl) + 删除段评URL(deleteUrl) diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index fad7b4f6d..dac88a90e 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -1014,4 +1014,14 @@ 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 Review + 段评URL(reviewUrl) + 段评发布者头像(avatarRule) + 段评内容(contentRule) + 段评发布时间(postTimeRule) + 段评回复URL(reviewQuoteUrl) + 点踩URL(voteUpUrl) + 点赞URL(voteDownUrl) + 发送回复URL(postReviewUrl) + 发送回复段评URL(postQuoteUrl) + 删除段评URL(deleteUrl) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 2f95b824a..dadd131f9 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -1014,4 +1014,14 @@ 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 Review + 段评URL(reviewUrl) + 段评发布者头像(avatarRule) + 段评内容(contentRule) + 段评发布时间(postTimeRule) + 段评回复URL(reviewQuoteUrl) + 点踩URL(voteUpUrl) + 点赞URL(voteDownUrl) + 发送回复URL(postReviewUrl) + 发送回复段评URL(postQuoteUrl) + 删除段评URL(deleteUrl) diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index e44b8780d..21ab5348f 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -1011,4 +1011,14 @@ 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 段评 + 段评URL(reviewUrl) + 段评发布者头像(avatarRule) + 段评内容(contentRule) + 段评发布时间(postTimeRule) + 段评回复URL(reviewQuoteUrl) + 点踩URL(voteUpUrl) + 点赞URL(voteDownUrl) + 发送回复URL(postReviewUrl) + 发送回复段评URL(postQuoteUrl) + 删除段评URL(deleteUrl) diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 811ef3d55..8d77a5605 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -1013,4 +1013,14 @@ 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 段评 + 段评URL(reviewUrl) + 段评发布者头像(avatarRule) + 段评内容(contentRule) + 段评发布时间(postTimeRule) + 段评回复URL(reviewQuoteUrl) + 点踩URL(voteUpUrl) + 点赞URL(voteDownUrl) + 发送回复URL(postReviewUrl) + 发送回复段评URL(postQuoteUrl) + 删除段评URL(deleteUrl) diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 8fddc6150..02a44245a 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -1013,4 +1013,14 @@ 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 段评 + 段评URL(reviewUrl) + 段评发布者头像(avatarRule) + 段评内容(contentRule) + 段评发布时间(postTimeRule) + 段评回复URL(reviewQuoteUrl) + 点踩URL(voteUpUrl) + 点赞URL(voteDownUrl) + 发送回复URL(postReviewUrl) + 发送回复段评URL(postQuoteUrl) + 删除段评URL(deleteUrl) diff --git a/app/src/main/res/values/non_translat.xml b/app/src/main/res/values/non_translat.xml index 14d5c13bd..2b6917391 100644 --- a/app/src/main/res/values/non_translat.xml +++ b/app/src/main/res/values/non_translat.xml @@ -1,25 +1,25 @@ - bookshelf_px - 开源阅读 - kunfei.ge@gmail.com + bookshelf_px + 开源阅读 + kunfei.ge@gmail.com - https://alanskycn.gitee.io/teachme/ - https://github.com/gedoor/legado - https://github.com/gedoor/legado/graphs/contributors - https://gedoor.github.io - https://github.com/gedoor/legado/blob/master/LICENSE - https://github.com/gedoor/legado/releases/latest - https://api.github.com/repos/gedoor/legado/releases/latest - https://t.me/legado_channels - https://discord.gg/qDE52P5xGW + https://alanskycn.gitee.io/teachme/ + https://github.com/gedoor/legado + https://github.com/gedoor/legado/graphs/contributors + https://gedoor.github.io + https://github.com/gedoor/legado/blob/master/LICENSE + https://github.com/gedoor/legado/releases/latest + https://api.github.com/repos/gedoor/legado/releases/latest + https://t.me/legado_channels + https://discord.gg/qDE52P5xGW - http://%1$s:%2$d - GitHub - 【%s】 - 🔒%s - 🔓%s + http://%1$s:%2$d + GitHub + 【%s】 + 🔒%s + 🔓%s - + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a5e5b0889..60b8bb72c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1014,4 +1014,14 @@ 返回时提示放入书架 阅读未放入书架的书籍在返回时提示放入书架 Review + 段评发布者头像(avatarRule) + 段评URL(reviewUrl) + 段评内容(contentRule) + 段评发布时间(postTimeRule) + 段评回复URL(reviewQuoteUrl) + 点踩URL(voteUpUrl) + 点赞URL(voteDownUrl) + 发送回复URL(postReviewUrl) + 发送回复段评URL(postQuoteUrl) + 删除段评URL(deleteUrl) From b21659c23a3c1fb496a1a6027cb9ae0ba21cd0b0 Mon Sep 17 00:00:00 2001 From: Seidko Date: Mon, 5 Sep 2022 22:19:34 +0800 Subject: [PATCH 03/19] =?UTF-8?q?=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E4=BA=86=E6=8C=89=E9=92=AE=E7=9A=84UI=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=EF=BC=8C=E6=9A=82=E6=9C=AA=E5=AE=9E=E8=A3=85=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E8=A7=A6=E6=91=B8=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/help/config/ReadBookConfig.kt | 2 +- .../app/ui/book/read/ReadBookActivity.kt | 3 + .../app/ui/book/read/page/ContentTextView.kt | 80 ++++++++++++++++++- .../ui/book/read/page/entities/TextChar.kt | 3 +- .../ui/book/read/page/entities/TextLine.kt | 1 + .../ui/book/read/page/entities/TextPage.kt | 7 +- .../read/page/provider/ChapterProvider.kt | 37 ++++++--- .../source/edit/BookSourceEditActivity.kt | 2 +- app/src/main/res/menu/book_read.xml | 7 ++ 9 files changed, 127 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/config/ReadBookConfig.kt b/app/src/main/java/io/legado/app/help/config/ReadBookConfig.kt index 605070c0e..4b500e078 100644 --- a/app/src/main/java/io/legado/app/help/config/ReadBookConfig.kt +++ b/app/src/main/java/io/legado/app/help/config/ReadBookConfig.kt @@ -449,7 +449,7 @@ object ReadBookConfig { var letterSpacing: Float = 0.1f,//字间距 var lineSpacingExtra: Int = 12,//行间距 var paragraphSpacing: Int = 2,//段距 - var titleMode: Int = 0,//标题居中 + var titleMode: Int = 0,//标题位置 0:居左 1:居中 2:隐藏 var titleSize: Int = 0, var titleTopSpacing: Int = 0, var titleBottomSpacing: Int = 0, diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index c4a97a1ce..930ccf0c2 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -355,6 +355,9 @@ class ReadBookActivity : BaseReadBookActivity(), menu?.findItem(R.id.menu_re_segment)?.isChecked = it.getReSegment() ReadBook.loadContent(false) } + R.id.menu_enable_review -> ReadBook.book?.let { + // TODO + } R.id.menu_page_anim -> showPageAnimConfig { binding.readView.upPageAnim() ReadBook.loadContent(false) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 232e90959..71712c180 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -4,6 +4,8 @@ import android.content.Context import android.graphics.Canvas import android.graphics.Paint import android.graphics.RectF +import android.text.StaticLayout +import android.text.TextPaint import android.util.AttributeSet import android.view.View import io.legado.app.R @@ -150,6 +152,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at ChapterProvider.contentPaint } val textColor = if (textLine.isReadAloud) context.accentColor else ReadBookConfig.textColor + val linePaint = Paint() + linePaint.strokeWidth = textPaint.textSize / 21 + linePaint.color = textColor + val reviewCountPaint = TextPaint() + reviewCountPaint.textSize = textPaint.textSize * 0.6F + reviewCountPaint.color = textColor textLine.textChars.forEach { if (it.isImage) { drawImage(canvas, textPage, textLine, it, lineTop, lineBottom) @@ -158,7 +166,74 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at if (it.isSearchResult) { textPaint.color = context.accentColor } - canvas.drawText(it.charData, it.start, lineBase, textPaint) + if (it.charData == "\uD83D\uDCAC" && it.isLineEnd) { + if (textLine.reviewCount <= 0) return@forEach + canvas.drawLine( + it.start, + lineBase - textPaint.textSize * 2 / 5, + it.start + textPaint.textSize / 6, + lineBase - textPaint.textSize / 4, + linePaint + ) + canvas.drawLine( + it.start, + lineBase - textPaint.textSize * 0.38F, + it.start + textPaint.textSize / 6, + lineBase - textPaint.textSize * 0.55F, + linePaint + ) + canvas.drawLine( + it.start + textPaint.textSize / 6, + lineBase - textPaint.textSize / 4, + it.start + textPaint.textSize / 6, + lineBase, + linePaint + ) + canvas.drawLine( + it.start + textPaint.textSize / 6, + lineBase - textPaint.textSize * 0.55F, + it.start + textPaint.textSize / 6, + lineBase - textPaint.textSize * 0.8F, + linePaint + ) + canvas.drawLine( + it.start + textPaint.textSize / 6, + lineBase, + it.start + textPaint.textSize * 1.6F, + lineBase, + linePaint + ) + canvas.drawLine( + it.start + textPaint.textSize / 6, + lineBase - textPaint.textSize * 0.8F, + it.start + textPaint.textSize * 1.6F, + lineBase - textPaint.textSize * 0.8F, + linePaint + ) + canvas.drawLine( + it.start + textPaint.textSize * 1.6F, + lineBase - textPaint.textSize * 0.8F, + it.start + textPaint.textSize * 1.6F, + lineBase, + linePaint + ) + if (textLine.reviewCount < 100) canvas.drawText( + textLine.reviewCount.toString(), + it.start + textPaint.textSize * 0.87F - + StaticLayout.getDesiredWidth( + textLine.reviewCount.toString(), + reviewCountPaint + ) / 2, + lineBase - textPaint.textSize / 6, + reviewCountPaint + ) + else canvas.drawText( + "99+", + it.start + textPaint.textSize * 0.35F, + lineBase - textPaint.textSize / 6, + reviewCountPaint + ) + } else canvas.drawText(it.charData, it.start, lineBase, textPaint) } if (it.selected) { canvas.drawRect(it.start, lineTop, it.end, lineBottom, selectedPaint) @@ -276,6 +351,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at callBack.onImageLongPress(x, y, textChar.charData) } else { if (!selectAble) return@touch + if (textChar.charData == "\uD83D\uDCAC" && textChar.isLineEnd) return@touch textChar.selected = true invalidate() select(relativePos, lineIndex, charIndex) @@ -292,6 +368,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit, ) { touch(x, y) { _, relativePos, _, lineIndex, _, charIndex, textChar -> + if (textChar.charData == "\uD83D\uDCAC" && textChar.isLineEnd) return@touch textChar.selected = true invalidate() select(relativePos, lineIndex, charIndex) @@ -415,6 +492,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at textPos.lineIndex = lineIndex for ((charIndex, textChar) in textLine.textChars.withIndex()) { textPos.charIndex = charIndex + if (textChar.charData == "\uD83D\uDCAC" && textChar.isLineEnd) continue textChar.selected = textPos.compare(selectStart) >= 0 && textPos.compare(selectEnd) <= 0 textChar.isSearchResult = textChar.selected && callBack.isSelectingSearchResult diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt index 518067182..77442194f 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt @@ -6,7 +6,8 @@ data class TextChar( var end: Float, var selected: Boolean = false, var isImage: Boolean = false, - var isSearchResult: Boolean = false + var isSearchResult: Boolean = false, + var isLineEnd: Boolean = false ) { fun isTouch(x: Float): Boolean { diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt index 3ec66b3ca..56225b2ee 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt @@ -8,6 +8,7 @@ import io.legado.app.utils.textHeight data class TextLine( var text: String = "", val textChars: ArrayList = arrayListOf(), + val reviewCount: Int = 0, var lineTop: Float = 0f, var lineBase: Float = 0f, var lineBottom: Float = 0f, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt index 3997b1ead..94cf56748 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt @@ -111,7 +111,12 @@ data class TextPage( val cw = StaticLayout.getDesiredWidth(char, ChapterProvider.contentPaint) val x1 = x + cw textLine.textChars.add( - TextChar(char, start = x, end = x1) + TextChar( + char, + start = x, + end = x1, + isLineEnd = textLine.text.length - 1 == i + ) ) x = x1 } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index 5ae48f727..f86ee6e66 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -116,7 +116,13 @@ object ChapterProvider { if (ReadBookConfig.titleMode != 2) { displayTitle.splitNotBlank("\n").forEach { text -> setTypeText( - book, absStartX, durY, text, textPages, stringBuilder, titlePaint, + book, + absStartX, + durY, + text + "\ud83d\udcac", + textPages, + stringBuilder, + titlePaint, isTitle = true, isTitleWithNoContent = contents.isEmpty(), isVolumeTitle = bookChapter.isVolume @@ -171,7 +177,13 @@ object ChapterProvider { val text = content.substring(start, content.length) if (text.isNotBlank()) { setTypeText( - book, absStartX, durY, text, textPages, stringBuilder, contentPaint + book, + absStartX, + durY, + text + "\ud83d\udcac", + textPages, + stringBuilder, + contentPaint ).let { absStartX = it.first durY = it.second @@ -276,9 +288,8 @@ object ChapterProvider { srcList: LinkedList? = null ): Pair { var absStartX = x - val layout = if (ReadBookConfig.useZhLayout) { - ZhLayout(text, textPaint, visibleWidth) - } else StaticLayout( + val layout = if (ReadBookConfig.useZhLayout) ZhLayout(text, textPaint, visibleWidth) + else StaticLayout( text, textPaint, visibleWidth, Layout.Alignment.ALIGN_NORMAL, 0f, 0f, true ) var durY = when { @@ -398,10 +409,15 @@ object ChapterProvider { } val bodyIndent = ReadBookConfig.paragraphIndent val icw = StaticLayout.getDesiredWidth(bodyIndent, textPaint) / bodyIndent.length - bodyIndent.toStringArray().forEach { char -> + for ((index, char) in bodyIndent.toStringArray().withIndex()) { val x1 = x + icw textLine.textChars.add( - TextChar(charData = char, start = absStartX + x, end = absStartX + x1) + TextChar( + charData = char, + start = absStartX + x, + end = absStartX + x1, + isLineEnd = bodyIndent.length - 1 == index + ) ) x = x1 } @@ -492,7 +508,8 @@ object ChapterProvider { TextChar( charData = char, start = absStartX + xStart, - end = absStartX + xEnd + end = absStartX + xEnd, + isLineEnd = true ) ) } @@ -612,12 +629,12 @@ object ChapterProvider { * 更新绘制尺寸 */ fun upLayout() { - when(AppConfig.doublePageHorizontal){ + when (AppConfig.doublePageHorizontal) { "0" -> doublePage = false "1" -> doublePage = true "2" -> { doublePage = (viewWidth > viewHeight) - && ReadBook.pageAnim() != 3 + && ReadBook.pageAnim() != 3 } } diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt index d733ca71e..b1e799e51 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditActivity.kt @@ -299,7 +299,7 @@ class BookSourceEditActivity : reviewEntities.clear() reviewEntities.apply { add(EditEntity("reviewUrl", rr?.reviewUrl, R.string.rule_review_url)) - add(EditEntity("avatarRule", rr?.reviewUrl, R.string.rule_avatar)) + add(EditEntity("avatarRule", rr?.avatarRule, R.string.rule_avatar)) add(EditEntity("contentRule", rr?.contentRule, R.string.rule_review_content)) add(EditEntity("postTimeRule", rr?.postTimeRule, R.string.rule_post_time)) add(EditEntity("reviewQuoteUrl", rr?.reviewQuoteUrl, R.string.rule_review_quote)) diff --git a/app/src/main/res/menu/book_read.xml b/app/src/main/res/menu/book_read.xml index 3f2b0b563..32915270e 100644 --- a/app/src/main/res/menu/book_read.xml +++ b/app/src/main/res/menu/book_read.xml @@ -84,6 +84,13 @@ android:checked="false" app:showAsAction="never" /> + + Date: Tue, 6 Sep 2022 11:17:43 +0800 Subject: [PATCH 04/19] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/help/JsExtensions.kt | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 8280c8e6b..3e4ba7689 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -433,13 +433,15 @@ interface JsExtensions { } /** - * js实现文件夹内所有文件读取 + * js实现文件夹内所有文本文件读取 + * @param path 文件夹相对路径 + * @return 所有文件字符串换行连接 */ - fun getTxtInFolder(unzipPath: String): String { - if (unzipPath.isEmpty()) return "" - val unzipFolder = getFile(unzipPath) + fun getTxtInFolder(path: String): String { + if (path.isEmpty()) return "" + val folder = getFile(path) val contents = StringBuilder() - unzipFolder.listFiles().let { + folder.listFiles().let { if (it != null) { for (f in it) { val charsetName = EncodingDetect.getEncode(f) @@ -449,7 +451,7 @@ interface JsExtensions { contents.deleteCharAt(contents.length - 1) } } - FileUtils.delete(unzipFolder.absolutePath) + FileUtils.delete(folder.absolutePath) return contents.toString() } From 4255749968f5439d95bcc5c9cb1cd72655742b50 Mon Sep 17 00:00:00 2001 From: Seidko Date: Tue, 6 Sep 2022 12:31:20 +0800 Subject: [PATCH 05/19] =?UTF-8?q?=E6=9C=AA=E5=AE=8C=E6=88=90=E7=9A=84?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E7=82=B9=E5=87=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/data/entities/rule/ReviewRule.kt | 2 +- .../app/ui/book/read/page/ContentTextView.kt | 18 ++++++++++++++++++ .../legado/app/ui/book/read/page/PageView.kt | 4 ++++ .../legado/app/ui/book/read/page/ReadView.kt | 5 +++++ .../app/ui/book/read/page/entities/TextLine.kt | 2 +- 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt b/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt index 2d2dc249c..07ff9fb32 100644 --- a/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt +++ b/app/src/main/java/io/legado/app/data/entities/rule/ReviewRule.kt @@ -14,7 +14,7 @@ data class ReviewRule( // 这些功能将在以上功能完成以后实现 var voteUpUrl: String? = null, // 点赞URL var voteDownUrl: String? = null, // 点踩URL - var postReviewUrl: String? = null, // 发送回复URL + var postReviewUrl: String? = null, // 发送回复URL var postQuoteUrl: String? = null, // 发送回复段评URL var deleteUrl: String? = null, // 删除段评URL ): Parcelable diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 71712c180..a0164302d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -51,6 +51,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at private var cacheIncreased = false private val increaseSize = 8 * 1024 * 1024 private val maxCacheSize = 256 * 1024 * 1024 + private val reviewButtonArea: ArrayList = arrayListOf() //滚动参数 private val pageFactory: TextPageFactory get() = callBack.pageFactory @@ -110,6 +111,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at if (!pageFactory.hasNext()) return val textPage1 = relativePage(1) relativeOffset = relativeOffset(1) + reviewButtonArea.clear() textPage1.textLines.forEach { textLine -> draw(canvas, textPage1, textLine, relativeOffset) } @@ -168,6 +170,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } if (it.charData == "\uD83D\uDCAC" && it.isLineEnd) { if (textLine.reviewCount <= 0) return@forEach + reviewButtonArea.add( + floatArrayOf( + it.start, lineBase, it.start + textPaint.textSize * 1.6F, + lineBase - textPaint.textSize * 0.8F, + ) + ) canvas.drawLine( it.start, lineBase - textPaint.textSize * 2 / 5, @@ -338,6 +346,16 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at pageOffset = 0 } + /** + * 点击评论按钮 + */ + fun pressReviewButton(x: Float, y: Float): Boolean { + reviewButtonArea.forEach { + if (x in it[0]..it[2] && y + textPage.height in it[3]..it[1]) return true + } + return false + } + /** * 长按 */ diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index f8d86fa9e..32584b3f1 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -268,6 +268,10 @@ class PageView(context: Context) : FrameLayout(context) { binding.contentTextView.selectAble = selectAble } + fun pressReviewButton(x: Float, y: Float): Boolean { + return binding.contentTextView.pressReviewButton(x, y) + } + fun longPress( x: Float, y: Float, select: (relativePagePos: Int, lineIndex: Int, charIndex: Int) -> Unit, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index 6a8abc9bf..7583c318c 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -28,6 +28,7 @@ import io.legado.app.ui.book.read.page.provider.TextPageFactory import io.legado.app.utils.activity import io.legado.app.utils.invisible import io.legado.app.utils.screenshot +import io.legado.app.utils.toastOnUi import java.text.BreakIterator import java.util.* import kotlin.math.abs @@ -369,6 +370,10 @@ class ReadView(context: Context, attrs: AttributeSet) : */ private fun onSingleTapUp() { when { + curPage.pressReviewButton(startX, startY) -> { + context.toastOnUi("Button Pressed!") + ReadBook.upMsg(null) + } isTextSelected -> Unit mcRect.contains(startX, startY) -> if (!isAbortAnim) { click(AppConfig.clickActionMC) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt index 56225b2ee..faa53a124 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt @@ -8,7 +8,7 @@ import io.legado.app.utils.textHeight data class TextLine( var text: String = "", val textChars: ArrayList = arrayListOf(), - val reviewCount: Int = 0, + val reviewCount: Int = 1, var lineTop: Float = 0f, var lineBase: Float = 0f, var lineBottom: Float = 0f, From 5d2c43da527353f037641278493a43ba0484397e Mon Sep 17 00:00:00 2001 From: Horis <821938089@qq.com> Date: Tue, 6 Sep 2022 14:04:43 +0800 Subject: [PATCH 06/19] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/book/read/page/delegate/HorizontalPageDelegate.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt index 9201880ea..ee703faf9 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/delegate/HorizontalPageDelegate.kt @@ -119,7 +119,11 @@ abstract class HorizontalPageDelegate(readView: ReadView) : PageDelegate(readVie abortAnim() if (!hasNext()) return setDirection(PageDirection.NEXT) - readView.setStartPoint(viewWidth.toFloat(), 1f, false) + val y = when { + viewHeight / 2 < startY -> viewHeight.toFloat() * 0.9f + else -> 1f + } + readView.setStartPoint(viewWidth.toFloat() * 0.9f, y, false) onAnimStart(animationSpeed) } From 1e9cecef8135e1222430cc8c4f97f553b8cdd48d Mon Sep 17 00:00:00 2001 From: Seidko Date: Tue, 6 Sep 2022 14:09:47 +0800 Subject: [PATCH 07/19] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/ui/book/read/page/ContentTextView.kt | 12 ++++++++---- .../java/io/legado/app/ui/book/read/page/PageView.kt | 2 +- .../java/io/legado/app/ui/book/read/page/ReadView.kt | 1 - 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index a0164302d..f95f4f196 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -102,6 +102,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at * 绘制页面 */ private fun drawPage(canvas: Canvas) { + reviewButtonArea.clear() var relativeOffset = relativeOffset(0) textPage.textLines.forEach { textLine -> draw(canvas, textPage, textLine, relativeOffset) @@ -111,7 +112,6 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at if (!pageFactory.hasNext()) return val textPage1 = relativePage(1) relativeOffset = relativeOffset(1) - reviewButtonArea.clear() textPage1.textLines.forEach { textLine -> draw(canvas, textPage1, textLine, relativeOffset) } @@ -172,8 +172,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at if (textLine.reviewCount <= 0) return@forEach reviewButtonArea.add( floatArrayOf( - it.start, lineBase, it.start + textPaint.textSize * 1.6F, - lineBase - textPaint.textSize * 0.8F, + it.start - textPaint.textSize * 0.4F, + lineBase + textPaint.textSize * 0.2F, + it.start + textPaint.textSize * 2F, + lineBase - textPaint.textSize * 1F, ) ) canvas.drawLine( @@ -351,7 +353,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at */ fun pressReviewButton(x: Float, y: Float): Boolean { reviewButtonArea.forEach { - if (x in it[0]..it[2] && y + textPage.height in it[3]..it[1]) return true + if (x in it[0]..it[2] && y in it[3]..it[1]) { + return true + } } return false } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index 32584b3f1..9103231ce 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -269,7 +269,7 @@ class PageView(context: Context) : FrameLayout(context) { } fun pressReviewButton(x: Float, y: Float): Boolean { - return binding.contentTextView.pressReviewButton(x, y) + return binding.contentTextView.pressReviewButton(x, y - headerHeight) } fun longPress( diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index 7583c318c..fa4e4d8e0 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -372,7 +372,6 @@ class ReadView(context: Context, attrs: AttributeSet) : when { curPage.pressReviewButton(startX, startY) -> { context.toastOnUi("Button Pressed!") - ReadBook.upMsg(null) } isTextSelected -> Unit mcRect.contains(startX, startY) -> if (!isAbortAnim) { From d8f6575416263628aff84c59f05ebedffd0080bc Mon Sep 17 00:00:00 2001 From: kunfei Date: Tue, 6 Sep 2022 14:44:51 +0800 Subject: [PATCH 08/19] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/help/JsExtensions.kt | 54 ++++++++++++++----- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index 3e4ba7689..16c9dc14e 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -27,6 +27,7 @@ import splitties.init.appCtx import java.io.ByteArrayInputStream import java.io.ByteArrayOutputStream import java.io.File +import java.io.FileOutputStream import java.net.URLEncoder import java.nio.charset.Charset import java.text.SimpleDateFormat @@ -125,7 +126,7 @@ interface JsExtensions { html = html, javaScript = js, headerMap = getSource()?.getHeaderMap(true), - tag = getSource()?.getKey() + tag = getSource()?.getKey() ).getStrResponse().body } } @@ -143,15 +144,18 @@ interface JsExtensions { * 使用内置浏览器打开链接,并等待网页结果 */ fun startBrowserAwait(url: String, title: String): StrResponse { - return StrResponse(url, SourceVerificationHelp.getVerificationResult(getSource(), url, title, true)) + return StrResponse( + url, + SourceVerificationHelp.getVerificationResult(getSource(), url, title, true) + ) } /** * 打开图片验证码对话框,等待返回验证结果 */ - fun getVerificationCode(imageUrl: String): String { - return SourceVerificationHelp.getVerificationResult(getSource(), imageUrl, "", false) - } + fun getVerificationCode(imageUrl: String): String { + return SourceVerificationHelp.getVerificationResult(getSource(), imageUrl, "", false) + } /** * 可从网络,本地文件(阅读私有缓存目录和书籍保存位置支持相对路径)导入JavaScript脚本 @@ -203,6 +207,29 @@ interface JsExtensions { } } + /** + * 下载文件 + * @param url 下载地址:可带参数type,文件后缀,不带默认zip + * @return 下载的文件相对路径 + */ + fun downloadFile(url: String): String { + val analyzeUrl = AnalyzeUrl(url, source = getSource()) + val type = analyzeUrl.type ?: "zip" + val path = FileUtils.getPath( + FileUtils.createFolderIfNotExist(FileUtils.getCachePath()), + "${MD5Utils.md5Encode16(url)}.${type}" + ) + FileUtils.delete(path) + analyzeUrl.getInputStream().use { iStream -> + val file = FileUtils.createFileIfNotExist(path) + FileOutputStream(file).use { oStream -> + iStream.copyTo(oStream) + } + } + return path.substring(FileUtils.getCachePath().length) + } + + /** * 实现16进制字符串转文件 * @param content 需要转成文件的16进制字符串 @@ -211,18 +238,18 @@ interface JsExtensions { */ fun downloadFile(content: String, url: String): String { val type = AnalyzeUrl(url, source = getSource()).type ?: return "" - val zipPath = FileUtils.getPath( + val path = FileUtils.getPath( FileUtils.createFolderIfNotExist(FileUtils.getCachePath()), "${MD5Utils.md5Encode16(url)}.${type}" ) - FileUtils.delete(zipPath) - val zipFile = FileUtils.createFileIfNotExist(zipPath) + FileUtils.delete(path) + val file = FileUtils.createFileIfNotExist(path) StringUtils.hexStringToByte(content).let { if (it.isNotEmpty()) { - zipFile.writeBytes(it) + file.writeBytes(it) } } - return zipPath.substring(FileUtils.getCachePath().length) + return path.substring(FileUtils.getCachePath().length) } /** @@ -835,7 +862,7 @@ interface JsExtensions { } fun desBase64DecodeToString( - data: String, key: String, transformation: String, iv: String + data: String, key: String, transformation: String, iv: String ): String? { return EncoderUtils.decryptBase64DES( data.encodeToByteArray(), @@ -1030,7 +1057,10 @@ interface JsExtensions { algorithm: String, key: String ): String { - return Base64.encodeToString(HMac(algorithm, key.toByteArray()).digest(data), Base64.NO_WRAP) + return Base64.encodeToString( + HMac(algorithm, key.toByteArray()).digest(data), + Base64.NO_WRAP + ) } fun md5Encode(str: String): String { From 6f7581a254401eb53936121472b4a02ab3815875 Mon Sep 17 00:00:00 2001 From: kunfei Date: Tue, 6 Sep 2022 20:39:58 +0800 Subject: [PATCH 09/19] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/ui/book/read/page/PageView.kt | 54 +++++++++++++++++++ .../legado/app/ui/book/read/page/ReadView.kt | 4 +- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index f8d86fa9e..0b15507c7 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -104,6 +104,9 @@ class PageView(context: Context) : FrameLayout(context) { isGone = ReadBookConfig.hideStatusBar || readBookActivity?.isInMultiWindow == true } + /** + * 更新阅读信息 + */ private fun upTipStyle() = binding.run { tvHeaderLeft.tag = null tvHeaderMiddle.tag = null @@ -189,6 +192,10 @@ class PageView(context: Context) : FrameLayout(context) { } } + /** + * 获取信息视图 + * @param tip 信息类型 + */ private fun getTipView(tip: Int): BatteryView? = binding.run { return when (tip) { ReadTipConfig.tipHeaderLeft -> tvHeaderLeft @@ -201,6 +208,9 @@ class PageView(context: Context) : FrameLayout(context) { } } + /** + * 更新背景 + */ fun upBg() { if (ReadBookConfig.bgAlpha < 100) { binding.vwRoot.backgroundColor = ReadBookConfig.bgMeanColor @@ -211,15 +221,24 @@ class PageView(context: Context) : FrameLayout(context) { upBgAlpha() } + /** + * 更新背景透明度 + */ fun upBgAlpha() { binding.vwBg.alpha = ReadBookConfig.bgAlpha / 100f } + /** + * 更新时间信息 + */ fun upTime() { tvTime?.text = timeFormat.format(Date(System.currentTimeMillis())) upTimeBattery() } + /** + * 更新电池信息 + */ @SuppressLint("SetTextI18n") fun upBattery(battery: Int) { this.battery = battery @@ -228,6 +247,9 @@ class PageView(context: Context) : FrameLayout(context) { upTimeBattery() } + /** + * 更新电池信息 + */ @SuppressLint("SetTextI18n") private fun upTimeBattery() { val time = timeFormat.format(Date(System.currentTimeMillis())) @@ -235,6 +257,9 @@ class PageView(context: Context) : FrameLayout(context) { tvTimeBatteryP?.text = "$time $battery%" } + /** + * 设置内容 + */ fun setContent(textPage: TextPage, resetPageOffset: Boolean = true) { setProgress(textPage) if (resetPageOffset) { @@ -243,14 +268,23 @@ class PageView(context: Context) : FrameLayout(context) { binding.contentTextView.setContent(textPage) } + /** + * 设置无障碍文本 + */ fun setContentDescription(content: String) { binding.contentTextView.contentDescription = content } + /** + * 重置滚动位置 + */ fun resetPageOffset() { binding.contentTextView.resetPageOffset() } + /** + * 设置进度 + */ @SuppressLint("SetTextI18n") fun setProgress(textPage: TextPage) = textPage.apply { tvBookName?.text = ReadBook.book?.name @@ -260,14 +294,31 @@ class PageView(context: Context) : FrameLayout(context) { tvPageAndTotal?.text = "${index.plus(1)}/$pageSize $readProgress" } + /** + * 滚动事件 + */ fun scroll(offset: Int) { binding.contentTextView.scroll(offset) } + /** + * 更新是否开启选择功能 + */ fun upSelectAble(selectAble: Boolean) { binding.contentTextView.selectAble = selectAble } + /** + * 优先处理页面内单击 + * @return true:已处理, false:未处理 + */ + fun onClick(x: Float, y: Float): Boolean { + return false + } + + /** + * 长按事件 + */ fun longPress( x: Float, y: Float, select: (relativePagePos: Int, lineIndex: Int, charIndex: Int) -> Unit, @@ -275,6 +326,9 @@ class PageView(context: Context) : FrameLayout(context) { return binding.contentTextView.longPress(x, y - headerHeight, select) } + /** + * 选择文本 + */ fun selectText( x: Float, y: Float, select: (relativePagePos: Int, lineIndex: Int, charIndex: Int) -> Unit, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index 6a8abc9bf..b4fef733a 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -222,7 +222,9 @@ class ReadView(context: Context, attrs: AttributeSet) : pressDown = false if (!isPageMove) { if (!longPressed && !pressOnTextSelected) { - onSingleTapUp() + if (!curPage.onClick(startX, startY)) { + onSingleTapUp() + } return true } } From 93e0cb7eeab75345b0cd02901f8367fb1f02eb1e Mon Sep 17 00:00:00 2001 From: kunfei Date: Tue, 6 Sep 2022 20:47:24 +0800 Subject: [PATCH 10/19] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/book/read/page/ContentTextView.kt | 8 ++++++++ .../main/java/io/legado/app/ui/book/read/page/PageView.kt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 232e90959..b4f9dc173 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -283,6 +283,14 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } } + /** + * 单击 + * @return true:已处理, false:未处理 + */ + fun click(x: Float, y: Float): Boolean { + return false + } + /** * 选择文字 */ diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index 0b15507c7..286dc8aa0 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -313,7 +313,7 @@ class PageView(context: Context) : FrameLayout(context) { * @return true:已处理, false:未处理 */ fun onClick(x: Float, y: Float): Boolean { - return false + return binding.contentTextView.click(x, y - headerHeight) } /** From 9d5f197997fb88baaf47426b809741d846214d31 Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 7 Sep 2022 10:04:55 +0800 Subject: [PATCH 11/19] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/page/ContentTextView.kt | 21 ++++++++++++++++++- .../legado/app/ui/book/read/page/PageView.kt | 2 +- .../legado/app/ui/book/read/page/ReadView.kt | 4 +++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index b4f9dc173..e11d5c335 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -28,7 +28,7 @@ import io.legado.app.utils.toastOnUi import kotlin.math.min /** - * 阅读内容界面 + * 阅读内容视图 */ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, attrs) { var selectAble = context.getPrefBoolean(PreferKey.textSelectAble, true) @@ -65,12 +65,18 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at callBack = activity as CallBack } + /** + * 设置内容 + */ fun setContent(textPage: TextPage) { this.textPage = textPage imagePaint.isAntiAlias = AppConfig.useAntiAlias invalidate() } + /** + * 更新绘制区域 + */ fun upVisibleRect() { visibleRect.set( ChapterProvider.paddingLeft.toFloat(), @@ -121,6 +127,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } } + /** + * 绘制页面 + */ private fun draw( canvas: Canvas, textPage: TextPage, @@ -259,6 +268,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at invalidate() } + /** + * 重置滚动位置 + */ fun resetPageOffset() { pageOffset = 0 } @@ -288,6 +300,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at * @return true:已处理, false:未处理 */ fun click(x: Float, y: Float): Boolean { + touch(x, y) { _, relativePos, textPage, lineIndex, textLine, charIndex, textChar -> + + } return false } @@ -342,6 +357,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } } + /** + * 触碰位置信息 + * @param touched 回调 + */ private fun touch( x: Float, y: Float, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index 286dc8aa0..3637438f1 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -24,7 +24,7 @@ import splitties.views.backgroundColor import java.util.* /** - * 阅读界面 + * 页面视图 */ class PageView(context: Context) : FrameLayout(context) { diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index b4fef733a..eafd9a7bb 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -32,7 +32,9 @@ import java.text.BreakIterator import java.util.* import kotlin.math.abs - +/** + * 阅读视图 + */ class ReadView(context: Context, attrs: AttributeSet) : FrameLayout(context, attrs), DataSource { From 949cdb3a904eeba3678158dee67391c62b2e568e Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 7 Sep 2022 12:24:32 +0800 Subject: [PATCH 12/19] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/book/read/page/ContentTextView.kt | 41 ++++++++----------- .../legado/app/ui/book/read/page/PageView.kt | 5 ++- .../legado/app/ui/book/read/page/ReadView.kt | 36 +++++++++------- .../ui/book/read/page/entities/TextChapter.kt | 3 ++ .../ui/book/read/page/entities/TextChar.kt | 3 ++ .../ui/book/read/page/entities/TextLine.kt | 3 ++ .../ui/book/read/page/entities/TextPage.kt | 3 ++ .../app/ui/book/read/page/entities/TextPos.kt | 3 ++ 8 files changed, 58 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index e11d5c335..fe1e9e09d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -281,16 +281,16 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at fun longPress( x: Float, y: Float, - select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit, + select: (textPos: TextPos) -> Unit, ) { - touch(x, y) { _, relativePos, _, lineIndex, _, charIndex, textChar -> + touch(x, y) { _, textPos, _, _, textChar -> if (textChar.isImage) { callBack.onImageLongPress(x, y, textChar.charData) } else { if (!selectAble) return@touch textChar.selected = true invalidate() - select(relativePos, lineIndex, charIndex) + select(textPos) } } } @@ -300,7 +300,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at * @return true:已处理, false:未处理 */ fun click(x: Float, y: Float): Boolean { - touch(x, y) { _, relativePos, textPage, lineIndex, textLine, charIndex, textChar -> + touch(x, y) { _, textPos, textPage, textLine, textChar -> } return false @@ -312,12 +312,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at fun selectText( x: Float, y: Float, - select: (relativePage: Int, lineIndex: Int, charIndex: Int) -> Unit, + select: (textPos: TextPos) -> Unit, ) { - touch(x, y) { _, relativePos, _, lineIndex, _, charIndex, textChar -> + touch(x, y) { _, textPos, _, _, textChar -> textChar.selected = true invalidate() - select(relativePos, lineIndex, charIndex) + select(textPos) } } @@ -325,11 +325,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at * 开始选择符移动 */ fun selectStartMove(x: Float, y: Float) { - touch(x, y) { relativeOffset, relativePos, _, lineIndex, textLine, charIndex, textChar -> - val pos = TextPos(relativePos, lineIndex, charIndex) - if (selectStart.compare(pos) != 0) { - if (pos.compare(selectEnd) <= 0) { - selectStart.upData(pos = pos) + touch(x, y) { relativeOffset, textPos, _, textLine, textChar -> + if (selectStart.compare(textPos) != 0) { + if (textPos.compare(selectEnd) <= 0) { + selectStart.upData(pos = textPos) upSelectedStart( textChar.start, textLine.lineBottom + relativeOffset, @@ -345,11 +344,10 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at * 结束选择符移动 */ fun selectEndMove(x: Float, y: Float) { - touch(x, y) { relativeOffset, relativePos, _, lineIndex, textLine, charIndex, textChar -> - val pos = TextPos(relativePos, lineIndex, charIndex) - if (pos.compare(selectEnd) != 0) { - if (pos.compare(selectStart) >= 0) { - selectEnd.upData(pos) + touch(x, y) { relativeOffset, textPos, _, textLine, textChar -> + if (textPos.compare(selectEnd) != 0) { + if (textPos.compare(selectStart) >= 0) { + selectEnd.upData(textPos) upSelectedEnd(textChar.end, textLine.lineBottom + relativeOffset) upSelectChars() } @@ -366,11 +364,9 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at y: Float, touched: ( relativeOffset: Float, - relativePos: Int, + textPos: TextPos, textPage: TextPage, - lineIndex: Int, textLine: TextLine, - charIndex: Int, textChar: TextChar ) -> Unit ) { @@ -390,9 +386,8 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at if (textChar.isTouch(x)) { touched.invoke( relativeOffset, - relativePos, textPage, - lineIndex, textLine, - charIndex, textChar + TextPos(relativePos, lineIndex, charIndex), + textPage, textLine, textChar ) return } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt index 3637438f1..048f9725b 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/PageView.kt @@ -14,6 +14,7 @@ import io.legado.app.help.config.ReadTipConfig import io.legado.app.model.ReadBook import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.page.entities.TextPage +import io.legado.app.ui.book.read.page.entities.TextPos import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.widget.BatteryView import io.legado.app.utils.activity @@ -321,7 +322,7 @@ class PageView(context: Context) : FrameLayout(context) { */ fun longPress( x: Float, y: Float, - select: (relativePagePos: Int, lineIndex: Int, charIndex: Int) -> Unit, + select: (textPos: TextPos) -> Unit, ) { return binding.contentTextView.longPress(x, y - headerHeight, select) } @@ -331,7 +332,7 @@ class PageView(context: Context) : FrameLayout(context) { */ fun selectText( x: Float, y: Float, - select: (relativePagePos: Int, lineIndex: Int, charIndex: Int) -> Unit, + select: (textPos: TextPos) -> Unit, ) { return binding.contentTextView.selectText(x, y - headerHeight, select) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index eafd9a7bb..3ac543f11 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -296,18 +296,18 @@ class ReadView(context: Context, attrs: AttributeSet) : */ private fun onLongPress() { kotlin.runCatching { - curPage.longPress(startX, startY) { relativePos, lineIndex, charIndex -> + curPage.longPress(startX, startY) { textPos: TextPos -> isTextSelected = true pressOnTextSelected = true - initialTextPos.upData(relativePos, lineIndex, charIndex) - val startPos = TextPos(relativePos, lineIndex, charIndex) - val endPos = TextPos(relativePos, lineIndex, charIndex) - val page = curPage.relativePage(relativePos) + initialTextPos.upData(textPos) + val startPos = textPos.copy() + val endPos = textPos.copy() + val page = curPage.relativePage(textPos.relativePagePos) val stringBuilder = StringBuilder() - var cIndex = charIndex - var lineStart = lineIndex - var lineEnd = lineIndex - for (index in lineIndex - 1 downTo 0) { + var cIndex = textPos.charIndex + var lineStart = textPos.lineIndex + var lineEnd = textPos.lineIndex + for (index in textPos.lineIndex - 1 downTo 0) { val textLine = page.getLine(index) if (textLine.isParagraphEnd) { break @@ -317,7 +317,7 @@ class ReadView(context: Context, attrs: AttributeSet) : cIndex += textLine.charSize } } - for (index in lineIndex until page.lineSize) { + for (index in textPos.lineIndex until page.lineSize) { val textLine = page.getLine(index) stringBuilder.append(textLine.text) lineEnd += 1 @@ -423,11 +423,15 @@ class ReadView(context: Context, attrs: AttributeSet) : * 选择文本 */ private fun selectText(x: Float, y: Float) { - curPage.selectText(x, y) { relativePagePos, lineIndex, charIndex -> - val compare = initialTextPos.compare(relativePagePos, lineIndex, charIndex) + curPage.selectText(x, y) { textPos -> + val compare = initialTextPos.compare(textPos) when { compare >= 0 -> { - curPage.selectStartMoveIndex(relativePagePos, lineIndex, charIndex) + curPage.selectStartMoveIndex( + textPos.relativePagePos, + textPos.lineIndex, + textPos.charIndex + ) curPage.selectEndMoveIndex( initialTextPos.relativePagePos, initialTextPos.lineIndex, @@ -440,7 +444,11 @@ class ReadView(context: Context, attrs: AttributeSet) : initialTextPos.lineIndex, initialTextPos.charIndex ) - curPage.selectEndMoveIndex(relativePagePos, lineIndex, charIndex) + curPage.selectEndMoveIndex( + textPos.relativePagePos, + textPos.lineIndex, + textPos.charIndex + ) } } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChapter.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChapter.kt index dfbf4a9cf..50d254e58 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChapter.kt @@ -2,6 +2,9 @@ package io.legado.app.ui.book.read.page.entities import kotlin.math.min +/** + * 章节信息 + */ @Suppress("unused") data class TextChapter( val position: Int, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt index 518067182..f52525597 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt @@ -1,5 +1,8 @@ package io.legado.app.ui.book.read.page.entities +/** + * 字符信息 + */ data class TextChar( val charData: String, var start: Float, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt index 3ec66b3ca..176c4fea4 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt @@ -4,6 +4,9 @@ import android.text.TextPaint import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.utils.textHeight +/** + * 行信息 + */ @Suppress("unused", "MemberVisibilityCanBePrivate") data class TextLine( var text: String = "", diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt index 3997b1ead..82966b138 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt @@ -11,6 +11,9 @@ import splitties.init.appCtx import java.text.DecimalFormat import kotlin.math.min +/** + * 页面信息 + */ @Suppress("unused", "MemberVisibilityCanBePrivate") data class TextPage( var index: Int = 0, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPos.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPos.kt index cc650c622..35dbfa589 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPos.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPos.kt @@ -1,5 +1,8 @@ package io.legado.app.ui.book.read.page.entities +/** + * 位置信息 + */ data class TextPos( var relativePagePos: Int, var lineIndex: Int, From 1523f1ca959885af8f5a7470c8cfbef470194238 Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 7 Sep 2022 20:49:10 +0800 Subject: [PATCH 13/19] =?UTF-8?q?=E5=87=86=E5=A4=87=E5=9C=A8=E6=AD=A3?= =?UTF-8?q?=E6=96=87=E6=B7=BB=E5=8A=A0=E6=8C=89=E9=92=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../legado/app/ui/book/read/page/ContentTextView.kt | 10 +++++----- .../page/entities/{TextChar.kt => TextColumn.kt} | 4 ++-- .../app/ui/book/read/page/entities/TextLine.kt | 6 +++--- .../app/ui/book/read/page/entities/TextPage.kt | 2 +- .../ui/book/read/page/provider/ChapterProvider.kt | 12 ++++++------ 5 files changed, 17 insertions(+), 17 deletions(-) rename app/src/main/java/io/legado/app/ui/book/read/page/entities/{TextChar.kt => TextColumn.kt} (79%) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index fe1e9e09d..7408efd7d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -14,7 +14,7 @@ import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.lib.theme.accentColor import io.legado.app.model.ReadBook -import io.legado.app.ui.book.read.page.entities.TextChar +import io.legado.app.ui.book.read.page.entities.TextColumn import io.legado.app.ui.book.read.page.entities.TextLine import io.legado.app.ui.book.read.page.entities.TextPage import io.legado.app.ui.book.read.page.entities.TextPos @@ -160,7 +160,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at } val textColor = if (textLine.isReadAloud) context.accentColor else ReadBookConfig.textColor textLine.textChars.forEach { - if (it.isImage) { + if (it.style == 1) { drawImage(canvas, textPage, textLine, it, lineTop, lineBottom) } else { textPaint.color = textColor @@ -183,7 +183,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at canvas: Canvas, textPage: TextPage, textLine: TextLine, - textChar: TextChar, + textChar: TextColumn, lineTop: Float, lineBottom: Float ) { @@ -284,7 +284,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at select: (textPos: TextPos) -> Unit, ) { touch(x, y) { _, textPos, _, _, textChar -> - if (textChar.isImage) { + if (textChar.style == 1) { callBack.onImageLongPress(x, y, textChar.charData) } else { if (!selectAble) return@touch @@ -367,7 +367,7 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at textPos: TextPos, textPage: TextPage, textLine: TextLine, - textChar: TextChar + textColumn: TextColumn ) -> Unit ) { if (!visibleRect.contains(x, y)) return diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextColumn.kt similarity index 79% rename from app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt rename to app/src/main/java/io/legado/app/ui/book/read/page/entities/TextColumn.kt index f52525597..82badb33f 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextChar.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextColumn.kt @@ -3,12 +3,12 @@ package io.legado.app.ui.book.read.page.entities /** * 字符信息 */ -data class TextChar( +data class TextColumn( val charData: String, var start: Float, var end: Float, + val style: Int = 0, //0:文字,1:图片,2:按钮 var selected: Boolean = false, - var isImage: Boolean = false, var isSearchResult: Boolean = false ) { diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt index 176c4fea4..28ac5b24f 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt @@ -10,7 +10,7 @@ import io.legado.app.utils.textHeight @Suppress("unused", "MemberVisibilityCanBePrivate") data class TextLine( var text: String = "", - val textChars: ArrayList = arrayListOf(), + val textChars: ArrayList = arrayListOf(), var lineTop: Float = 0f, var lineBase: Float = 0f, var lineBottom: Float = 0f, @@ -30,13 +30,13 @@ data class TextLine( lineBase = lineBottom - textPaint.fontMetrics.descent } - fun getTextChar(index: Int): TextChar { + fun getTextChar(index: Int): TextColumn { return textChars.getOrElse(index) { textChars.last() } } - fun getTextCharReverseAt(index: Int): TextChar { + fun getTextCharReverseAt(index: Int): TextColumn { return textChars[textChars.lastIndex - index] } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt index 82966b138..a69483ab2 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextPage.kt @@ -114,7 +114,7 @@ data class TextPage( val cw = StaticLayout.getDesiredWidth(char, ChapterProvider.contentPaint) val x1 = x + cw textLine.textChars.add( - TextChar(char, start = x, end = x1) + TextColumn(char, start = x, end = x1) ) x = x1 } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index 5ae48f727..185d251e6 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -14,7 +14,7 @@ import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.model.ReadBook import io.legado.app.ui.book.read.page.entities.TextChapter -import io.legado.app.ui.book.read.page.entities.TextChar +import io.legado.app.ui.book.read.page.entities.TextColumn import io.legado.app.ui.book.read.page.entities.TextLine import io.legado.app.ui.book.read.page.entities.TextPage import io.legado.app.utils.* @@ -252,7 +252,7 @@ object ChapterProvider { Pair(0f, width.toFloat()) } textLine.textChars.add( - TextChar(charData = src, start = x + start, end = x + end, isImage = true) + TextColumn(charData = src, start = x + start, end = x + end, style = 1) ) textPages.last().textLines.add(textLine) } @@ -401,7 +401,7 @@ object ChapterProvider { bodyIndent.toStringArray().forEach { char -> val x1 = x + icw textLine.textChars.add( - TextChar(charData = char, start = absStartX + x, end = absStartX + x1) + TextColumn(charData = char, start = absStartX + x, end = absStartX + x1) ) x = x1 } @@ -480,16 +480,16 @@ object ChapterProvider { val src = srcList.removeFirst() ImageProvider.cacheImage(book, src, ReadBook.bookSource) textLine.textChars.add( - TextChar( + TextColumn( charData = src, start = absStartX + xStart, end = absStartX + xEnd, - isImage = true + style = 1 ) ) } else { textLine.textChars.add( - TextChar( + TextColumn( charData = char, start = absStartX + xStart, end = absStartX + xEnd From 64e34fb614e027ee2d9a3b52e670bdef1f0f9ef8 Mon Sep 17 00:00:00 2001 From: kunfei Date: Wed, 7 Sep 2022 20:56:47 +0800 Subject: [PATCH 14/19] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 634f47a01..bf011d6b2 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -11,11 +11,11 @@ * 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。 * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源! -**2022/09/03** +**2022/09/07** * 更新cronet: 105.0.5195.79 -* 更新cronet: 105.0.5195.77 * 更新web端书源编辑 by jgckM +* 修复仿真翻页点击时翻页动画异常,化仿真翻页点击翻页效果 by 821938089 **2022/08/31** From f0ead5b4882cb17f5a478f03ac8c2ce580b8f5b4 Mon Sep 17 00:00:00 2001 From: Seidko Date: Wed, 7 Sep 2022 22:42:09 +0800 Subject: [PATCH 15/19] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=AE=B5=E8=AF=84?= =?UTF-8?q?=E5=BC=80=E5=90=AF=E5=85=B3=E9=97=AD=E5=8A=9F=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E5=87=86=E5=A4=87=E5=AE=9E=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/constant/PreferKey.kt | 1 + .../legado/app/data/entities/BookChapterReview.kt | 15 +++++++++++++++ .../java/io/legado/app/help/config/AppConfig.kt | 6 ++++++ .../java/io/legado/app/model/webBook/WebBook.kt | 7 +++++++ .../legado/app/ui/book/read/ReadBookActivity.kt | 7 +++++-- .../app/ui/book/read/page/ContentTextView.kt | 13 ++----------- .../app/ui/book/read/page/entities/TextLine.kt | 2 +- .../ui/book/read/page/provider/ChapterProvider.kt | 4 ++-- 8 files changed, 39 insertions(+), 16 deletions(-) create mode 100644 app/src/main/java/io/legado/app/data/entities/BookChapterReview.kt diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index b1bbf3663..761250413 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -32,6 +32,7 @@ object PreferKey { const val prevKeys = "prevKeyCodes" const val nextKeys = "nextKeyCodes" const val showDiscovery = "showDiscovery" + const val enableReview = "enableReview" const val showRss = "showRss" const val bookshelfLayout = "bookshelfLayout" const val bookshelfSort = "bookshelfSort" diff --git a/app/src/main/java/io/legado/app/data/entities/BookChapterReview.kt b/app/src/main/java/io/legado/app/data/entities/BookChapterReview.kt new file mode 100644 index 000000000..64a838f42 --- /dev/null +++ b/app/src/main/java/io/legado/app/data/entities/BookChapterReview.kt @@ -0,0 +1,15 @@ +package io.legado.app.data.entities + +import android.os.Parcelable +import androidx.room.ColumnInfo +import kotlinx.parcelize.Parcelize + +@Parcelize +class BookChapterReview( + @ColumnInfo(defaultValue = "0") + var bookId: Long = 0, + var chapterId: Long = 0, + var summaryUrl: String = "", +): Parcelable { + +} diff --git a/app/src/main/java/io/legado/app/help/config/AppConfig.kt b/app/src/main/java/io/legado/app/help/config/AppConfig.kt index 60ea20f46..dcc797eec 100644 --- a/app/src/main/java/io/legado/app/help/config/AppConfig.kt +++ b/app/src/main/java/io/legado/app/help/config/AppConfig.kt @@ -154,6 +154,12 @@ object AppConfig : SharedPreferences.OnSharedPreferenceChangeListener { val autoRefreshBook: Boolean get() = appCtx.getPrefBoolean(PreferKey.autoRefresh) + var enableReview: Boolean + get() = appCtx.getPrefBoolean(PreferKey.enableReview, false) + set(value) { + appCtx.putPrefBoolean(PreferKey.enableReview, value) + } + var threadCount: Int get() = appCtx.getPrefInt(PreferKey.threadCount, 16) set(value) { diff --git a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt index 7d37300a1..f80a4e0a7 100644 --- a/app/src/main/java/io/legado/app/model/webBook/WebBook.kt +++ b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt @@ -300,6 +300,13 @@ object WebBook { } } + /** + * 获取段评 + */ + fun getReview() { + // TODO + } + /** * 精准搜索 */ diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt index 930ccf0c2..3aba40f8b 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt @@ -255,6 +255,7 @@ class ReadBookActivity : BaseReadBookActivity(), else -> when (item.itemId) { R.id.menu_enable_replace -> item.isChecked = book.getUseReplaceRule() R.id.menu_re_segment -> item.isChecked = book.getReSegment() + R.id.menu_enable_review -> item.isChecked = AppConfig.enableReview R.id.menu_reverse_content -> item.isVisible = onLine } } @@ -355,8 +356,10 @@ class ReadBookActivity : BaseReadBookActivity(), menu?.findItem(R.id.menu_re_segment)?.isChecked = it.getReSegment() ReadBook.loadContent(false) } - R.id.menu_enable_review -> ReadBook.book?.let { - // TODO + R.id.menu_enable_review -> { + AppConfig.enableReview = !AppConfig.enableReview + menu?.findItem(R.id.menu_enable_review)?.isChecked = AppConfig.enableReview + ReadBook.loadContent(false) } R.id.menu_page_anim -> showPageAnimConfig { binding.readView.upPageAnim() diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 661873485..a9e72ed91 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -16,10 +16,7 @@ import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.lib.theme.accentColor import io.legado.app.model.ReadBook -import io.legado.app.ui.book.read.page.entities.TextColumn -import io.legado.app.ui.book.read.page.entities.TextLine -import io.legado.app.ui.book.read.page.entities.TextPage -import io.legado.app.ui.book.read.page.entities.TextPos +import io.legado.app.ui.book.read.page.entities.* import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ImageProvider import io.legado.app.ui.book.read.page.provider.TextPageFactory @@ -30,7 +27,7 @@ import io.legado.app.utils.toastOnUi import kotlin.math.min /** - * 阅读内容视图 + * 阅读内容界面 */ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, attrs) { var selectAble = context.getPrefBoolean(PreferKey.textSelectAble, true) @@ -67,18 +64,12 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at callBack = activity as CallBack } - /** - * 设置内容 - */ fun setContent(textPage: TextPage) { this.textPage = textPage imagePaint.isAntiAlias = AppConfig.useAntiAlias invalidate() } - /** - * 更新绘制区域 - */ fun upVisibleRect() { visibleRect.set( ChapterProvider.paddingLeft.toFloat(), diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt index c1a5b4597..076c1bc2f 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt @@ -11,7 +11,7 @@ import io.legado.app.utils.textHeight data class TextLine( var text: String = "", val textChars: ArrayList = arrayListOf(), - val reviewCount: Int = 1, + val reviewCount: Int = 0, var lineTop: Float = 0f, var lineBase: Float = 0f, var lineBottom: Float = 0f, diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index e16513b8b..8dd49e208 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -119,7 +119,7 @@ object ChapterProvider { book, absStartX, durY, - text + "\ud83d\udcac", + if (AppConfig.enableReview) text + "\ud83d\udcac" else text, textPages, stringBuilder, titlePaint, @@ -180,7 +180,7 @@ object ChapterProvider { book, absStartX, durY, - text + "\ud83d\udcac", + if (AppConfig.enableReview) text + "\ud83d\udcac" else text, textPages, stringBuilder, contentPaint From a4fd455a045e6cb9905f7786ad91f8ce37956858 Mon Sep 17 00:00:00 2001 From: Seidko Date: Wed, 7 Sep 2022 22:58:00 +0800 Subject: [PATCH 16/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/data/AppDatabase.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/AppDatabase.kt b/app/src/main/java/io/legado/app/data/AppDatabase.kt index 64624717a..270614a1e 100644 --- a/app/src/main/java/io/legado/app/data/AppDatabase.kt +++ b/app/src/main/java/io/legado/app/data/AppDatabase.kt @@ -20,7 +20,7 @@ val appDb by lazy { } @Database( - version = 52, + version = 53, exportSchema = true, entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class, @@ -36,7 +36,8 @@ val appDb by lazy { AutoMigration(from = 48, to = 49), AutoMigration(from = 49, to = 50), AutoMigration(from = 50, to = 51), - AutoMigration(from = 51, to = 52) + AutoMigration(from = 51, to = 52), + AutoMigration(from = 52, to = 53) ] ) abstract class AppDatabase : RoomDatabase() { From 13d48f5dbdb6d84b7dddcef684df9cf55beeb3d4 Mon Sep 17 00:00:00 2001 From: Seidko Date: Wed, 7 Sep 2022 22:58:00 +0800 Subject: [PATCH 17/19] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io.legado.app.data.AppDatabase/52.json | 94 +- .../io.legado.app.data.AppDatabase/53.json | 1692 +++++++++++++++++ 2 files changed, 1733 insertions(+), 53 deletions(-) create mode 100644 app/schemas/io.legado.app.data.AppDatabase/53.json diff --git a/app/schemas/io.legado.app.data.AppDatabase/52.json b/app/schemas/io.legado.app.data.AppDatabase/52.json index e9a5947e9..4f3ee4e9a 100644 --- a/app/schemas/io.legado.app.data.AppDatabase/52.json +++ b/app/schemas/io.legado.app.data.AppDatabase/52.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 52, - "identityHash": "c55dac79aa9cc3dcdb72e91da4282005", + "identityHash": "0221c385ed7393f47afe9579d3106541", "entities": [ { "tableName": "books", @@ -208,10 +208,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "bookUrl" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -263,17 +263,17 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "groupId" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] }, { "tableName": "book_sources", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceUrl` TEXT NOT NULL, `bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `enabledCookieJar` INTEGER DEFAULT 0, `concurrentRate` TEXT, `header` TEXT, `loginUrl` TEXT, `loginUi` TEXT, `enabledReview` INTEGER, `loginCheckJs` TEXT, `bookSourceComment` TEXT, `variableComment` TEXT, `lastUpdateTime` INTEGER NOT NULL, `respondTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, `ruleReview` TEXT, PRIMARY KEY(`bookSourceUrl`))", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceUrl` TEXT NOT NULL, `bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `enabledCookieJar` INTEGER DEFAULT 0, `concurrentRate` TEXT, `header` TEXT, `loginUrl` TEXT, `loginUi` TEXT, `loginCheckJs` TEXT, `bookSourceComment` TEXT, `variableComment` TEXT, `lastUpdateTime` INTEGER NOT NULL, `respondTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, PRIMARY KEY(`bookSourceUrl`))", "fields": [ { "fieldPath": "bookSourceUrl", @@ -354,12 +354,6 @@ "affinity": "TEXT", "notNull": false }, - { - "fieldPath": "enabledReview", - "columnName": "enabledReview", - "affinity": "INTEGER", - "notNull": false - }, { "fieldPath": "loginCheckJs", "columnName": "loginCheckJs", @@ -437,19 +431,13 @@ "columnName": "ruleContent", "affinity": "TEXT", "notNull": false - }, - { - "fieldPath": "ruleReview", - "columnName": "ruleReview", - "affinity": "TEXT", - "notNull": false } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "bookSourceUrl" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -560,11 +548,11 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "url", "bookUrl" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -688,10 +676,10 @@ } ], "primaryKey": { + "autoGenerate": true, "columnNames": [ "id" - ], - "autoGenerate": true + ] }, "indices": [ { @@ -802,10 +790,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "bookUrl" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -865,10 +853,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "word" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -901,10 +889,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "url" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -1094,10 +1082,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "sourceUrl" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -1166,10 +1154,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "time" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -1257,11 +1245,11 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "origin", "link" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -1284,10 +1272,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "record" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -1358,11 +1346,11 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "origin", "link" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -1409,10 +1397,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "id" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -1449,11 +1437,11 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "deviceId", "bookName" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -1533,10 +1521,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "id" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -1565,10 +1553,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "key" - ], - "autoGenerate": false + ] }, "indices": [ { @@ -1631,10 +1619,10 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "id" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -1673,11 +1661,11 @@ } ], "primaryKey": { + "autoGenerate": false, "columnNames": [ "type", "key" - ], - "autoGenerate": false + ] }, "indices": [], "foreignKeys": [] @@ -1686,7 +1674,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c55dac79aa9cc3dcdb72e91da4282005')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0221c385ed7393f47afe9579d3106541')" ] } } \ No newline at end of file diff --git a/app/schemas/io.legado.app.data.AppDatabase/53.json b/app/schemas/io.legado.app.data.AppDatabase/53.json new file mode 100644 index 000000000..518a1bfb7 --- /dev/null +++ b/app/schemas/io.legado.app.data.AppDatabase/53.json @@ -0,0 +1,1692 @@ +{ + "formatVersion": 1, + "database": { + "version": 53, + "identityHash": "c55dac79aa9cc3dcdb72e91da4282005", + "entities": [ + { + "tableName": "books", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL DEFAULT '', `tocUrl` TEXT NOT NULL DEFAULT '', `origin` TEXT NOT NULL DEFAULT '', `originName` TEXT NOT NULL DEFAULT '', `name` TEXT NOT NULL DEFAULT '', `author` TEXT NOT NULL DEFAULT '', `kind` TEXT, `customTag` TEXT, `coverUrl` TEXT, `customCoverUrl` TEXT, `intro` TEXT, `customIntro` TEXT, `charset` TEXT, `type` INTEGER NOT NULL DEFAULT 0, `group` INTEGER NOT NULL DEFAULT 0, `latestChapterTitle` TEXT, `latestChapterTime` INTEGER NOT NULL DEFAULT 0, `lastCheckTime` INTEGER NOT NULL DEFAULT 0, `lastCheckCount` INTEGER NOT NULL DEFAULT 0, `totalChapterNum` INTEGER NOT NULL DEFAULT 0, `durChapterTitle` TEXT, `durChapterIndex` INTEGER NOT NULL DEFAULT 0, `durChapterPos` INTEGER NOT NULL DEFAULT 0, `durChapterTime` INTEGER NOT NULL DEFAULT 0, `wordCount` TEXT, `canUpdate` INTEGER NOT NULL DEFAULT 1, `order` INTEGER NOT NULL DEFAULT 0, `originOrder` INTEGER NOT NULL DEFAULT 0, `variable` TEXT, `readConfig` TEXT, PRIMARY KEY(`bookUrl`))", + "fields": [ + { + "fieldPath": "bookUrl", + "columnName": "bookUrl", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "tocUrl", + "columnName": "tocUrl", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "origin", + "columnName": "origin", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "originName", + "columnName": "originName", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "kind", + "columnName": "kind", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "customTag", + "columnName": "customTag", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "coverUrl", + "columnName": "coverUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "customCoverUrl", + "columnName": "customCoverUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "intro", + "columnName": "intro", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "customIntro", + "columnName": "customIntro", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "charset", + "columnName": "charset", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "latestChapterTitle", + "columnName": "latestChapterTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "latestChapterTime", + "columnName": "latestChapterTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "lastCheckTime", + "columnName": "lastCheckTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "lastCheckCount", + "columnName": "lastCheckCount", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "totalChapterNum", + "columnName": "totalChapterNum", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "durChapterTitle", + "columnName": "durChapterTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "durChapterIndex", + "columnName": "durChapterIndex", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "durChapterPos", + "columnName": "durChapterPos", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "durChapterTime", + "columnName": "durChapterTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "wordCount", + "columnName": "wordCount", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "canUpdate", + "columnName": "canUpdate", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "originOrder", + "columnName": "originOrder", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "readConfig", + "columnName": "readConfig", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "bookUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_books_name_author", + "unique": true, + "columnNames": [ + "name", + "author" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_books_name_author` ON `${TABLE_NAME}` (`name`, `author`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "book_groups", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`groupId` INTEGER NOT NULL, `groupName` TEXT NOT NULL, `cover` TEXT, `order` INTEGER NOT NULL, `show` INTEGER NOT NULL, PRIMARY KEY(`groupId`))", + "fields": [ + { + "fieldPath": "groupId", + "columnName": "groupId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "groupName", + "columnName": "groupName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "cover", + "columnName": "cover", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "show", + "columnName": "show", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "groupId" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "book_sources", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookSourceUrl` TEXT NOT NULL, `bookSourceName` TEXT NOT NULL, `bookSourceGroup` TEXT, `bookSourceType` INTEGER NOT NULL, `bookUrlPattern` TEXT, `customOrder` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `enabledExplore` INTEGER NOT NULL, `enabledReview` INTEGER, `enabledCookieJar` INTEGER DEFAULT 0, `concurrentRate` TEXT, `header` TEXT, `loginUrl` TEXT, `loginUi` TEXT, `loginCheckJs` TEXT, `bookSourceComment` TEXT, `variableComment` TEXT, `lastUpdateTime` INTEGER NOT NULL, `respondTime` INTEGER NOT NULL, `weight` INTEGER NOT NULL, `exploreUrl` TEXT, `ruleExplore` TEXT, `searchUrl` TEXT, `ruleSearch` TEXT, `ruleBookInfo` TEXT, `ruleToc` TEXT, `ruleContent` TEXT, `ruleReview` TEXT, PRIMARY KEY(`bookSourceUrl`))", + "fields": [ + { + "fieldPath": "bookSourceUrl", + "columnName": "bookSourceUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookSourceName", + "columnName": "bookSourceName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookSourceGroup", + "columnName": "bookSourceGroup", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "bookSourceType", + "columnName": "bookSourceType", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "bookUrlPattern", + "columnName": "bookUrlPattern", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "customOrder", + "columnName": "customOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabledExplore", + "columnName": "enabledExplore", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enabledReview", + "columnName": "enabledReview", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "enabledCookieJar", + "columnName": "enabledCookieJar", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "concurrentRate", + "columnName": "concurrentRate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "header", + "columnName": "header", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUrl", + "columnName": "loginUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUi", + "columnName": "loginUi", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginCheckJs", + "columnName": "loginCheckJs", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "bookSourceComment", + "columnName": "bookSourceComment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "variableComment", + "columnName": "variableComment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastUpdateTime", + "columnName": "lastUpdateTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "respondTime", + "columnName": "respondTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "weight", + "columnName": "weight", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "exploreUrl", + "columnName": "exploreUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleExplore", + "columnName": "ruleExplore", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "searchUrl", + "columnName": "searchUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleSearch", + "columnName": "ruleSearch", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleBookInfo", + "columnName": "ruleBookInfo", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleToc", + "columnName": "ruleToc", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleContent", + "columnName": "ruleContent", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleReview", + "columnName": "ruleReview", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "bookSourceUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_book_sources_bookSourceUrl", + "unique": false, + "columnNames": [ + "bookSourceUrl" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_book_sources_bookSourceUrl` ON `${TABLE_NAME}` (`bookSourceUrl`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "chapters", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `title` TEXT NOT NULL, `isVolume` INTEGER NOT NULL, `baseUrl` TEXT NOT NULL, `bookUrl` TEXT NOT NULL, `index` INTEGER NOT NULL, `isVip` INTEGER NOT NULL, `isPay` INTEGER NOT NULL, `resourceUrl` TEXT, `tag` TEXT, `start` INTEGER, `end` INTEGER, `startFragmentId` TEXT, `endFragmentId` TEXT, `variable` TEXT, PRIMARY KEY(`url`, `bookUrl`), FOREIGN KEY(`bookUrl`) REFERENCES `books`(`bookUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "isVolume", + "columnName": "isVolume", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "baseUrl", + "columnName": "baseUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookUrl", + "columnName": "bookUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "index", + "columnName": "index", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isVip", + "columnName": "isVip", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isPay", + "columnName": "isPay", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "resourceUrl", + "columnName": "resourceUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tag", + "columnName": "tag", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "start", + "columnName": "start", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "end", + "columnName": "end", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "startFragmentId", + "columnName": "startFragmentId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "endFragmentId", + "columnName": "endFragmentId", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "url", + "bookUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_chapters_bookUrl", + "unique": false, + "columnNames": [ + "bookUrl" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_chapters_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)" + }, + { + "name": "index_chapters_bookUrl_index", + "unique": true, + "columnNames": [ + "bookUrl", + "index" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_chapters_bookUrl_index` ON `${TABLE_NAME}` (`bookUrl`, `index`)" + } + ], + "foreignKeys": [ + { + "table": "books", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "bookUrl" + ], + "referencedColumns": [ + "bookUrl" + ] + } + ] + }, + { + "tableName": "replace_rules", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL DEFAULT '', `group` TEXT, `pattern` TEXT NOT NULL DEFAULT '', `replacement` TEXT NOT NULL DEFAULT '', `scope` TEXT, `scopeTitle` INTEGER NOT NULL DEFAULT 0, `scopeContent` INTEGER NOT NULL DEFAULT 1, `isEnabled` INTEGER NOT NULL DEFAULT 1, `isRegex` INTEGER NOT NULL DEFAULT 1, `timeoutMillisecond` INTEGER NOT NULL DEFAULT 3000, `sortOrder` INTEGER NOT NULL DEFAULT 0)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "group", + "columnName": "group", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "pattern", + "columnName": "pattern", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "replacement", + "columnName": "replacement", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "scope", + "columnName": "scope", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "scopeTitle", + "columnName": "scopeTitle", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "scopeContent", + "columnName": "scopeContent", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "isEnabled", + "columnName": "isEnabled", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "isRegex", + "columnName": "isRegex", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "1" + }, + { + "fieldPath": "timeoutMillisecond", + "columnName": "timeoutMillisecond", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "3000" + }, + { + "fieldPath": "order", + "columnName": "sortOrder", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "index_replace_rules_id", + "unique": false, + "columnNames": [ + "id" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_replace_rules_id` ON `${TABLE_NAME}` (`id`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "searchBooks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookUrl` TEXT NOT NULL, `origin` TEXT NOT NULL, `originName` TEXT NOT NULL, `type` INTEGER NOT NULL, `name` TEXT NOT NULL, `author` TEXT NOT NULL, `kind` TEXT, `coverUrl` TEXT, `intro` TEXT, `wordCount` TEXT, `latestChapterTitle` TEXT, `tocUrl` TEXT NOT NULL, `time` INTEGER NOT NULL, `variable` TEXT, `originOrder` INTEGER NOT NULL, PRIMARY KEY(`bookUrl`), FOREIGN KEY(`origin`) REFERENCES `book_sources`(`bookSourceUrl`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "bookUrl", + "columnName": "bookUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "origin", + "columnName": "origin", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "originName", + "columnName": "originName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "author", + "columnName": "author", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "kind", + "columnName": "kind", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "coverUrl", + "columnName": "coverUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "intro", + "columnName": "intro", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "wordCount", + "columnName": "wordCount", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "latestChapterTitle", + "columnName": "latestChapterTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "tocUrl", + "columnName": "tocUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "originOrder", + "columnName": "originOrder", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "bookUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_searchBooks_bookUrl", + "unique": true, + "columnNames": [ + "bookUrl" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_searchBooks_bookUrl` ON `${TABLE_NAME}` (`bookUrl`)" + }, + { + "name": "index_searchBooks_origin", + "unique": false, + "columnNames": [ + "origin" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_searchBooks_origin` ON `${TABLE_NAME}` (`origin`)" + } + ], + "foreignKeys": [ + { + "table": "book_sources", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "origin" + ], + "referencedColumns": [ + "bookSourceUrl" + ] + } + ] + }, + { + "tableName": "search_keywords", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`word` TEXT NOT NULL, `usage` INTEGER NOT NULL, `lastUseTime` INTEGER NOT NULL, PRIMARY KEY(`word`))", + "fields": [ + { + "fieldPath": "word", + "columnName": "word", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "usage", + "columnName": "usage", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastUseTime", + "columnName": "lastUseTime", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "word" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_search_keywords_word", + "unique": true, + "columnNames": [ + "word" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_search_keywords_word` ON `${TABLE_NAME}` (`word`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "cookies", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `cookie` TEXT NOT NULL, PRIMARY KEY(`url`))", + "fields": [ + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "cookie", + "columnName": "cookie", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "url" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_cookies_url", + "unique": true, + "columnNames": [ + "url" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_cookies_url` ON `${TABLE_NAME}` (`url`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "rssSources", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`sourceUrl` TEXT NOT NULL, `sourceName` TEXT NOT NULL, `sourceIcon` TEXT NOT NULL, `sourceGroup` TEXT, `sourceComment` TEXT, `enabled` INTEGER NOT NULL, `variableComment` TEXT, `enabledCookieJar` INTEGER DEFAULT 0, `concurrentRate` TEXT, `header` TEXT, `loginUrl` TEXT, `loginUi` TEXT, `loginCheckJs` TEXT, `sortUrl` TEXT, `singleUrl` INTEGER NOT NULL, `articleStyle` INTEGER NOT NULL, `ruleArticles` TEXT, `ruleNextPage` TEXT, `ruleTitle` TEXT, `rulePubDate` TEXT, `ruleDescription` TEXT, `ruleImage` TEXT, `ruleLink` TEXT, `ruleContent` TEXT, `style` TEXT, `enableJs` INTEGER NOT NULL, `loadWithBaseUrl` INTEGER NOT NULL, `customOrder` INTEGER NOT NULL, PRIMARY KEY(`sourceUrl`))", + "fields": [ + { + "fieldPath": "sourceUrl", + "columnName": "sourceUrl", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourceName", + "columnName": "sourceName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourceIcon", + "columnName": "sourceIcon", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sourceGroup", + "columnName": "sourceGroup", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sourceComment", + "columnName": "sourceComment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enabled", + "columnName": "enabled", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "variableComment", + "columnName": "variableComment", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enabledCookieJar", + "columnName": "enabledCookieJar", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "concurrentRate", + "columnName": "concurrentRate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "header", + "columnName": "header", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUrl", + "columnName": "loginUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUi", + "columnName": "loginUi", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginCheckJs", + "columnName": "loginCheckJs", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "sortUrl", + "columnName": "sortUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "singleUrl", + "columnName": "singleUrl", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "articleStyle", + "columnName": "articleStyle", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "ruleArticles", + "columnName": "ruleArticles", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleNextPage", + "columnName": "ruleNextPage", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleTitle", + "columnName": "ruleTitle", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "rulePubDate", + "columnName": "rulePubDate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleDescription", + "columnName": "ruleDescription", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleImage", + "columnName": "ruleImage", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleLink", + "columnName": "ruleLink", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "ruleContent", + "columnName": "ruleContent", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "style", + "columnName": "style", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enableJs", + "columnName": "enableJs", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "loadWithBaseUrl", + "columnName": "loadWithBaseUrl", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "customOrder", + "columnName": "customOrder", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "sourceUrl" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_rssSources_sourceUrl", + "unique": false, + "columnNames": [ + "sourceUrl" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_rssSources_sourceUrl` ON `${TABLE_NAME}` (`sourceUrl`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "bookmarks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`time` INTEGER NOT NULL, `bookName` TEXT NOT NULL, `bookAuthor` TEXT NOT NULL, `chapterIndex` INTEGER NOT NULL, `chapterPos` INTEGER NOT NULL, `chapterName` TEXT NOT NULL, `bookText` TEXT NOT NULL, `content` TEXT NOT NULL, PRIMARY KEY(`time`))", + "fields": [ + { + "fieldPath": "time", + "columnName": "time", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "bookName", + "columnName": "bookName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookAuthor", + "columnName": "bookAuthor", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "chapterIndex", + "columnName": "chapterIndex", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chapterPos", + "columnName": "chapterPos", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "chapterName", + "columnName": "chapterName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookText", + "columnName": "bookText", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "time" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_bookmarks_bookName_bookAuthor", + "unique": false, + "columnNames": [ + "bookName", + "bookAuthor" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_bookmarks_bookName_bookAuthor` ON `${TABLE_NAME}` (`bookName`, `bookAuthor`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "rssArticles", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`origin` TEXT NOT NULL, `sort` TEXT NOT NULL, `title` TEXT NOT NULL, `order` INTEGER NOT NULL, `link` TEXT NOT NULL, `pubDate` TEXT, `description` TEXT, `content` TEXT, `image` TEXT, `read` INTEGER NOT NULL, `variable` TEXT, PRIMARY KEY(`origin`, `link`))", + "fields": [ + { + "fieldPath": "origin", + "columnName": "origin", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sort", + "columnName": "sort", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "order", + "columnName": "order", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "link", + "columnName": "link", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pubDate", + "columnName": "pubDate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "image", + "columnName": "image", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "read", + "columnName": "read", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "origin", + "link" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "rssReadRecords", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`record` TEXT NOT NULL, `read` INTEGER NOT NULL, PRIMARY KEY(`record`))", + "fields": [ + { + "fieldPath": "record", + "columnName": "record", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "read", + "columnName": "read", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "record" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "rssStars", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`origin` TEXT NOT NULL, `sort` TEXT NOT NULL, `title` TEXT NOT NULL, `starTime` INTEGER NOT NULL, `link` TEXT NOT NULL, `pubDate` TEXT, `description` TEXT, `content` TEXT, `image` TEXT, `variable` TEXT, PRIMARY KEY(`origin`, `link`))", + "fields": [ + { + "fieldPath": "origin", + "columnName": "origin", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sort", + "columnName": "sort", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "title", + "columnName": "title", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "starTime", + "columnName": "starTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "link", + "columnName": "link", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "pubDate", + "columnName": "pubDate", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "content", + "columnName": "content", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "image", + "columnName": "image", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "variable", + "columnName": "variable", + "affinity": "TEXT", + "notNull": false + } + ], + "primaryKey": { + "columnNames": [ + "origin", + "link" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "txtTocRules", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `rule` TEXT NOT NULL, `example` TEXT, `serialNumber` INTEGER NOT NULL, `enable` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "rule", + "columnName": "rule", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "example", + "columnName": "example", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "serialNumber", + "columnName": "serialNumber", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "enable", + "columnName": "enable", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "readRecord", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`deviceId` TEXT NOT NULL, `bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL DEFAULT 0, `lastRead` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`deviceId`, `bookName`))", + "fields": [ + { + "fieldPath": "deviceId", + "columnName": "deviceId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "bookName", + "columnName": "bookName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "readTime", + "columnName": "readTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "lastRead", + "columnName": "lastRead", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "deviceId", + "bookName" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "httpTTS", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `contentType` TEXT, `concurrentRate` TEXT DEFAULT '0', `loginUrl` TEXT, `loginUi` TEXT, `header` TEXT, `enabledCookieJar` INTEGER DEFAULT 0, `loginCheckJs` TEXT, `lastUpdateTime` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "contentType", + "columnName": "contentType", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "concurrentRate", + "columnName": "concurrentRate", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "'0'" + }, + { + "fieldPath": "loginUrl", + "columnName": "loginUrl", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "loginUi", + "columnName": "loginUi", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "header", + "columnName": "header", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "enabledCookieJar", + "columnName": "enabledCookieJar", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "loginCheckJs", + "columnName": "loginCheckJs", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "lastUpdateTime", + "columnName": "lastUpdateTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "caches", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`key` TEXT NOT NULL, `value` TEXT, `deadline` INTEGER NOT NULL, PRIMARY KEY(`key`))", + "fields": [ + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "deadline", + "columnName": "deadline", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "key" + ], + "autoGenerate": false + }, + "indices": [ + { + "name": "index_caches_key", + "unique": true, + "columnNames": [ + "key" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_caches_key` ON `${TABLE_NAME}` (`key`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "ruleSubs", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, `type` INTEGER NOT NULL, `customOrder` INTEGER NOT NULL, `autoUpdate` INTEGER NOT NULL, `update` INTEGER NOT NULL, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "url", + "columnName": "url", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "customOrder", + "columnName": "customOrder", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "autoUpdate", + "columnName": "autoUpdate", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "update", + "columnName": "update", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "id" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "keyboardAssists", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`type` INTEGER NOT NULL DEFAULT 0, `key` TEXT NOT NULL DEFAULT '', `value` TEXT NOT NULL DEFAULT '', `serialNo` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`type`, `key`))", + "fields": [ + { + "fieldPath": "type", + "columnName": "type", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT", + "notNull": true, + "defaultValue": "''" + }, + { + "fieldPath": "serialNo", + "columnName": "serialNo", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "type", + "key" + ], + "autoGenerate": false + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'c55dac79aa9cc3dcdb72e91da4282005')" + ] + } +} \ No newline at end of file From dc2422bbf30b9ea3e3001e5f9d53fb1e1f98b9a9 Mon Sep 17 00:00:00 2001 From: Seidko Date: Wed, 7 Sep 2022 23:22:44 +0800 Subject: [PATCH 18/19] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E8=A2=AB=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/ui/book/read/page/ContentTextView.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index a9e72ed91..25c0286fd 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -64,12 +64,18 @@ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, at callBack = activity as CallBack } + /** + * 设置内容 + */ fun setContent(textPage: TextPage) { this.textPage = textPage imagePaint.isAntiAlias = AppConfig.useAntiAlias invalidate() } + /** + * 更新绘制区域 + */ fun upVisibleRect() { visibleRect.set( ChapterProvider.paddingLeft.toFloat(), From aaa591ae73f6858325c35e11726317a5b23988cc Mon Sep 17 00:00:00 2001 From: Seidko Date: Wed, 7 Sep 2022 23:26:40 +0800 Subject: [PATCH 19/19] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E8=A2=AB=E8=BF=98?= =?UTF-8?q?=E5=8E=9F=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/ui/book/read/page/ContentTextView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt index 25c0286fd..27642ab6a 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ContentTextView.kt @@ -27,7 +27,7 @@ import io.legado.app.utils.toastOnUi import kotlin.math.min /** - * 阅读内容界面 + * 阅读内容视图 */ class ContentTextView(context: Context, attrs: AttributeSet?) : View(context, attrs) { var selectAble = context.getPrefBoolean(PreferKey.textSelectAble, true)