diff --git a/app/schemas/io.legado.app.data.AppDatabase/50.json b/app/schemas/io.legado.app.data.AppDatabase/50.json
new file mode 100644
index 000000000..05ebf3e6f
--- /dev/null
+++ b/app/schemas/io.legado.app.data.AppDatabase/50.json
@@ -0,0 +1,1666 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 50,
+ "identityHash": "524cf3564400bd897a49355afd984ac1",
+ "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, `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",
+ "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": "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
+ }
+ ],
+ "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, `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": "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, 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
+ }
+ ],
+ "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, '524cf3564400bd897a49355afd984ac1')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/assets/help/appHelp.md b/app/src/main/assets/help/appHelp.md
index 63c170809..193dbd591 100644
--- a/app/src/main/assets/help/appHelp.md
+++ b/app/src/main/assets/help/appHelp.md
@@ -1,190 +1,215 @@
# 帮助文档
-## **新人必读**
+【温馨提醒】 *本帮助可以在“**我的**”——右上角帮助按钮再次打开,更新前一定要做好备份,以免数据丢失!*
-【温馨提醒】 *本帮助可以在我的-右上角帮助按钮再次打开,更新前一定要做好备份,以免数据丢失!*
+## 新人必读
-1. 为什么第一次安装好之后什么东西都没有?
-* 阅读只是一个转码工具,不提供内容,第一次安装app,需要自己手动导入书源,可以从公众号 **[开源阅读]**、QQ群、酷安评论里获取由书友制作分享的书源。
+### 1. 为什么第一次安装好之后什么东西都没有?
+阅读只是一个转码工具,不提供内容,第一次安装 APP,需要自己手动导入书源,可以从公众号 **【开源阅读】**、QQ 群或酷安评论里获取由书友制作分享的书源。
-2. 正文出现缺字漏字、内容缺失、排版错乱等情况,如何处理?
-* 有可能是净化规则出现问题,先关闭替换净化并刷新,再观察是否正常。如果正常说明净化规则存在误杀,如果关闭后仍然出现相关问题,请点击源链接查看原文与正文是否相同,如果不同,再进行反馈。
+### 2. 正文出现缺字漏字、内容缺失或排版错乱等情况,如何处理?
+有可能是净化规则出现问题,先关闭替换净化并刷新,再观察是否正常。如果正常说明净化规则存在误杀,如果关闭后仍然出现相关问题,请点击源链接查看原文与正文是否相同,如果不同,再进行反馈。
-3. 漫画源看书显示乱码,如何解决?
-* 异次元和阅读是两个不同的软件,**两个软件的源并不通用**,请导入阅读的支持的漫画源!
+### 3. 漫画源看书显示乱码,如何解决?
+【异次元】和【阅读】是两个不同的软件,**两个软件的源并不通用**,请导入【阅读】的支持的漫画源!
## 书源相关
-1. 如何导入本地书源文件?
-* 下载群文件里的书源文件(书源格式后缀有txt、json,其中json文件某些情况下无法导入,需要修改后缀为txt格式才可导入);
-* 打开阅读软件;
-* 我的 - 点击“书源管理”;
-* 点击右上角选择“本地导入”;
+### 1. 如何导入本地书源文件?
+以导入 QQ 接收到的书源文件为例:
+* 下载群文件里的书源文件;
+* 打开【阅读】软件;
+* 点击“**我的**”——“**书源管理**”;
+* 点击右上角选择“**本地导入**”;
* 左下角选择书源文件所在的路径;
* 点击书源文件导入;
* 导入后返回书源管理界面;
-* 新版qq下载路径:Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/
-![QQ导入书源](https://cdn.jsdelivr.net/gh/gedoor/gedoor.github.io@master/images/importSource.jpg)
+**【注】**
+1. *新版 QQ 文件下载路径:`Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/`。*
+2. *书源格式后缀有 .txt 和 .json,其中 .json 文件在某些情况下可能无法导入,需要修改后缀为 .txt 才可导入。*
+
+![QQ 导入书源](https://cdn.jsdelivr.net/gh/gedoor/gedoor.github.io@master/images/importSource.jpg)
-2. 如何新建大佬发的单独书源?
+### 2. 如何新建大佬发的单独书源?
* 复制书源代码;
* 打开阅读软件;
-* 我的 - 点击“书源管理”;
-* 右上角选择“新建书源”;
-* 进入新建书源后点击右上角“粘贴源”;
-* 粘贴书源完成后点击上方保存;
+* 点击“**我的**”——“**书源管理**”;
+* 右上角“**⁝**”——“**+ 新建书源**”;
+* 进入后点击右上角“**⁝**”——“**粘贴源**”;
+* 粘贴完成后点击上方保存“**🖫**”按钮;
* 本次新建单独书源操作完成。
-* 注:如果书源有错误或者复制不全会显示格式错误,请重新复制。
-3. 为什么导入2.0书源后无法阅读?
-* 部分2.0书源并不适用于3.0版本的阅读,建议导入后进行筛选。
+**【注】** *如果书源有错误或者复制不全会显示格式错误,请重新复制。*
-4. 阅读2.0数据如何导入阅读3.0?
-* 先对阅读2.0的数据进行备份,然后进入阅读3.0,点击“我的”,选择“备份与恢复”,再点击“导入旧版本数据”。
+### 3. 为什么导入 2.0 书源后无法阅读?
+部分 2.0 书源并不适用于 3.0 版本的阅读,建议导入后进行筛选。
-5. 如何给朋友分享我的书源?
-* 打开阅读软件;
+### 4. 【阅读】2.0 数据如何导入【阅读】3.0?
+先对【阅读】2.0 的数据进行备份,然后进入【阅读】3.0,点击“**我的**”,选择“**备份与恢复**”,再点击“**导入旧版本数据**”。
+
+### 5. 如何给朋友分享我的书源?
+* 打开【阅读】软件;
* 点击备份;
-* 打开手机自带的文件管理;
-* 手机自带内存根目录找到YueDu3.0文件夹;
-* 找到myBookSource.json长按选择分享;
-* 选择微信分享或者QQ分享;
+* 打开手机系统自带的文件管理;
+* 在手机内置存储根目录找到 `YueDu3.0` 文件夹;
+* 找到 `myBookSource.json`,长按选择分享;
+* 选择微信分享或者 QQ 分享;
* 选择你要分享的好友点击发送;
-* 好友接收后在手机自带内存根目录找到myBookSource.json文件(最新版QQ 安卓10及以下版本在Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/,安卓11版本用户由于系统限制无法访问data目录,微信在Tencent/MicroMsg/Download);
-* 复制该文件到手机自带内存根目录找到YueDu3.0文件夹(如已有该文件请先删除该文件或者备份到其他地方再复制到文件夹);
-* 打开阅读软件点击恢复。
-* 注:备份路径如已修改过请在修改后的路径下查找书源文件。
+* 好友接收后在手机内置存储根目录找到 `myBookSource.json` 文件;
+* 复制该文件到手机内置存储根目录找到 `YueDu3.0` 文件夹(如已有该文件请先删除该文件或者备份到其他地方再复制到文件夹);
+* 打开【阅读】软件点击恢复。
-6. 效验书源显示失效就说明书源不能用了吗?
-* 效验书源只是测试书源,可以做个参考,失效了不代表书源不能用了。
+**【注】**
+1. *备份路径如已修改过请在修改后的路径下查找书源文件。*
+2. *Android 10 及以下版本系统,新版 QQ 文件接收路径在 `Android/data/com.tencent.mobileqq/Tencent/QQfile_recv/`,旧版 QQ 文件接收路径则在 `Tencent/QQfile_recv/`;新版微信文件接收路径在 `Android/data/com.tencent.mobileqq/Tencent/MicroMsg/Download`,旧版微信文件接收路径则在 `Tencent/MicroMsg/Download`。*
+3. *Android 11 及以上系统版本用户,由于系统限制,无法访问 `Android/data` 目录。*
-7. 发现和正版书源能不能使用?
-* 发现和正版书源只能用来找书,看排行榜,不能用来看书,如需看书请切换书源。
+### 6. 效验书源显示失效就说明书源不能用了吗?
+效验书源只是测试书源,可以做为参考,但失效了不代表书源不能用了。
-8. 为什么书源这么多,发现里却只有一点点?
-* 书源想要在发现界面里显示需要在书源里添加发现规则,并不是所有书源都有发现规则。
+### 7. “发现”和正版书源能不能使用?
+发现和正版书源只能用来找书或看排行榜,不能用来看书,如需看书请切换书源。
+
+### 8. 为什么书源这么多,“发现”里却只有一点点?
+书源想要在发现界面里显示需要在书源里添加发现规则,并不是所有书源都有发现规则。
## 本地书籍相关
-1. 目前阅读支持哪些格式的本地书籍?
-* 目前支持TXT、EPUB格式
-2. 如何导入本地书籍?
-* 在书架页面点击右上角,选择“添加本地”,授予相关权限后即可导入本地书籍。也可在文件管理器中使用 **阅读** 打开相关书籍。
+### 1. 目前阅读支持哪些格式的本地书籍?
+目前支持 TXT 和 EPUB 格式。
+
+### 2. 如何导入本地书籍?
+在书架页面点击右上角“**⁝**”,选择“**添加本地**”,授予相关权限后即可导入本地书籍。也可在文件管理器中使用【阅读】打开相关书籍。
-3. 导入TXT文件提示“LoadTocError”或“List is empty”是怎么回事?
-* 请先去应用详情中确认是否授予了阅读“读写手机存储”的权限。
+### 3. 导入 TXT 文件提示“LoadTocError”或“List is empty”是怎么回事?
+* 请先去应用详情中确认是否授予了【阅读】“读写手机存储”的权限。
* 自动识别目录失败,可能是相关目录规则未开启,请点击右上角的换源按钮手动更换目录规则。
-* 如果尝试所有规则均无法识别,请在github上提交issue并附件相关txt文件,也可以发送邮件至i@qnmlgb.trade(标题:legado本地文件章节无法识别,内容对其具体情况进行简要说明,附件上传相关txt文件)。
-4. 如何下载书籍到本地?
-* 把在线书籍加入到书架后,在书架页面点击右上角,选择“离线缓存”即可。
+如果尝试所有规则均无法识别,请在 GitHub 上提交 Issue 并附上相关 TXT 文件,也可以发送邮件至 i@qnmlgb.trade(标题:legado 本地文件章节无法识别;内容对其具体情况进行简要说明,附件上传相关 TXT 文件)。
+
+### 4. 如何下载书籍到本地?
+把在线书籍加入到书架后,在书架页面点击右上角,选择“**离线缓存**”即可。
-5. 如何自定义导出的txt/epub文件名称?
-* 点击 **离线缓存** - **导出文件名**.
+### 5. 如何自定义导出的 TXT 或 EPUB 文件名称?
+* 点击“**离线缓存**“——”**导出文件名**“
* 使用方法:
- - 导出文件名支持js语法
- - 可用变量: name - 书名 author-作者
- - 示例:
- > {name+"作者:"+author}
+ - 导出文件名支持 js 语法
+ - 可用变量: name(书名)和 author(作者)
+ - 示例:
+ > name + "作者:" + author
- 导出文件名:
- > Legado是最好的在线阅读软件 作者: kunfei.
+ > Legado 是最好的在线阅读软件 作者: kunfei
-**注意:** name、author等变量与字符串的拼接都需要在js环境中进行,即必须使用{ } 将变量与字符串包裹起来.
+**【注】** *name、author 等变量与字符串的拼接都需要在 JSON 上下文环境中进行,即必须使用 `{}` 将变量与字符串包裹起来。*
-6. 为什么我打开本地的TXT文件,显示内容却是乱码?
-* 部分编码在阅读上会识别错误,建议先用文本编辑器转换为常用的UTF-8格式。
+### 6. 为什么我打开本地的 TXT 文件,显示内容却是乱码?
+部分编码在阅读上会识别错误,建议先用文本编辑器转换为常用的 UTF-8 格式。
-7. 阅读对部分把正文(如所有含引号的句子)识别成标题,如何解决?
-* 点击右上角更换目录规则即可。
+### 7. 阅读对部分把正文(如所有含引号的句子)识别成标题,如何解决?
+点击右上角更换目录规则即可。
## 书籍界面相关
-1. 如何刷新书架?
-* 在书架界面下拉即可刷新。
+### 1. 如何刷新书架?
+在书架界面下拉即可刷新。
-2. 书架界面书籍右上角的红色或者灰色背景小数字代表什么?
-* 红色代表书籍有更新,灰色代表无更新,数字代表未读章节。
+### 2. 书架界面书籍右上角的红色或者灰色背景小数字代表什么?
+红色代表书籍有更新,灰色代表无更新,数字代表未读章节。
-3. 如何查看书籍详情?
-* 长按书籍。
+### 3. 如何查看书籍详情?
+长按书籍即可查看。
-4. 如何对书架上的书进行删除、切换书架的操作?
-* 书籍详情页操作即可。
+### 4. 如何对书架上的书进行删除、切换书架的操作?
+书籍详情页操作即可。
-5. 如何禁止或允许某本书更新?
-* 书籍详情页,点击右上角 - “允许更新”。
+### 5. 如何禁止或允许某本书更新?
+书籍详情页,点击右上角——“**允许更新**”。
-6. 如何更换小说封面、名字、作者或简介?
-* 书籍详情页,点击右上角修改按钮。
+### 6. 如何更换小说封面、名字、作者或简介?
+书籍详情页,点击右上角修改按钮。
-7. 怎么使用自定义字体?
-* 阅读界面 - 字体-点击右上角选择字体文件路径。
+### 7. 怎么使用自定义字体?
+阅读界面——“**字体**”——点击右上角选择字体文件路径。
-8. 目前支持哪些格式的字体文件?
-* 目前支持ttf、otf格式。
+### 8. 目前支持哪些格式的字体文件?
+目前支持 TTF 和 OTF 格式。
-9. 书籍经常“正在加载中”怎么办?
-* 在线书籍出现这个问题通常是由于源质量不好或不兼容引起的,可以换其它源多试试;本地书籍出现这个问题大概率是目录规则问题,手动切换规则可以解决。
+### 9. 书籍经常“正在加载中”怎么办?
+在线书籍出现这个问题通常是由于源质量不好或不兼容引起的,可以换其它源多试试;本地书籍出现这个问题大概率是目录规则问题,手动切换规则可以解决。
-10. 书籍内容只有标题,正文内容是路径怎么办?
-* 通常是缓存路径引起的,更换缓存路径即可。
+### 10. 书籍内容只有标题,正文内容是路径怎么办?
+通常是缓存路径引起的,更换缓存路径即可。
-11. 看书时如遇到“目录为空”、“加载失败”和长串英文等情况怎么办?
-* 在线书籍一般是书源问题,切换或更新书源即可。本地书籍请尝试手动更换目录规则。
+### 11. 看书时如遇到“目录为空”、“加载失败”或长串英文等情况怎么办?
+在线书籍一般是书源问题,切换或更新书源即可。本地书籍请尝试手动更换目录规则。
-12. 为什么每一章的最后一页,阅读的文字和横线背景总是对不齐?
-* 请在 设置-文字底部对齐 选项中关闭底部对齐,再调整排版。
+### 12. 为什么每一章的最后一页,阅读的文字和横线背景总是对不齐?
+请在“**设置**”——“**文字底部对齐**”选项中关闭底部对齐,再调整排版。
-13. 漫画源或图片章节只能看到第一页,如何解决?
-* 请先查看原网页是否正常,若正常,请在书籍阅读界面点击右上角的 **⁝** 按钮,在弹出的菜单中,选择 **翻页动画(本书)**,将翻页动画更改为 **滚动**。
+### 13. 漫画源或图片章节只能看到第一页,如何解决?
+请先查看原网页是否正常,若正常,请在书籍阅读界面点击右上角的“**⁝**”按钮,在弹出的菜单中,选择“**翻页动画(本书)**”,将翻页动画更改为“**滚动**”。
-14. 阅读图片章节、漫画或epub插图时,图片被缩放到一页中,以至无法看清,如何处理?
-* 临时处理方案:长按图片可以进行双指缩放。图片章节请先参考Q13中的方案将翻页动画更改为**滚动**
-* 3.0旧版可以点击书籍界面的章节标题进入 **编辑书源** 界面,在 正文-图片样式 中填入 *full*,保存更改,刷新当前章节即可。
-* 3.0新版可以直接在书籍阅读界面点击右上角的 **⁝** 按钮,选择 图片样式- *full*.
+### 14. 阅读图片章节、漫画或 EPUB 插图时,图片被缩放到一页中,以至无法看清,如何处理?
+* 临时处理方案:长按图片可以进行双指缩放。图片章节请先参考 Q13 中的方案将翻页动画更改为“**滚动**”。
+* 3.0 旧版可以点击书籍界面的章节标题进入“**编辑书源**”界面,在“**正文**”——“**图片样式**”中填入 *`full`*,保存更改,刷新当前章节即可。
+* 3.0 新版可以直接在书籍阅读界面点击右上角的“**⁝**”按钮,选择“**图片样式**”——***`full`***。
## 替换净化相关
-1. 替换净化是什么?
-* 替换净化可以去除书籍内容里的广告、错别字、屏蔽词等。
-2. 如何自己填写净化替换规则?
-* 第一行:替换规则名称 - 根据自己需求对替换净化规则进行命名;
-* 第二行:分组 - 净化规则的分组组别;
-* 第三行:替换规则 - 填写需要被替换的内容;
-* 第四行:替换为 - 填写想替换成的内容(如不填则默认表示删除第三行里填写的内容);
-* 第五行:替换范围,选填书名或者源名 - 填写此替换净化规则需要对哪本书籍或者哪个书源生效(如不填则对所有书籍和书源生效)。
-* 注:如常规去除方法去除不掉,则需要勾选“使用正则表达式”,同时第三行里的替换规则也需要按照正则表达式来填写(正则表达式填写方法可自行百度学习)。
+### 1. 替换净化是什么?
+替换净化可以去除书籍内容里的广告、错别字、屏蔽词等。
+
+### 2. 如何自己填写净化替换规则?
+* 第一行:替换规则名称。请根据自己需求对替换净化规则进行命名;
+* 第二行:分组。净化规则的分组组别;
+* 第三行:替换规则。填写需要被替换的内容;
+* 第四行:替换为。填写想替换成的内容(如不填则默认表示删除第三行里填写的内容);
+* 第五行:替换范围,选填书名或者源名。填写此替换净化规则需要对哪本书籍或者哪个书源生效(如不填则对所有书籍和书源生效)。
+
+**【注】** *如常规去除方法去除不掉,则需要勾选“使用正则表达式”,同时第三行里的替换规则也需要按照正则表达式来填写(正则表达式填写方法可自行网上搜索学习)。*
## 备份相关
-1. 云备份在哪?
-* 我的 - 备份与恢复 - WebDav设置。
+### 1. 云备份在哪?
+“**我的**”——“**备份与恢复**”——“**WebDav 设置**”。
+
+### 2. 如何操作进行云备份?
+* 侧栏设置,WebDav 设置;
+* 正确填写 WebDAV 服务器地址、账号和密码;
+* 无需操作,APP 默认每天自动云备份一次。
+
+作者在此诚挚推荐使用【坚果云】进行 WebDav 备份。
-2. 如何操作进行云备份?
-* 侧栏设置,WebDav设置;
-* 正确填写WebDAV 服务器地址、WebDAV 账号、WebDAV 密码;(要获得这三项的信息,需要注册一个坚果云账号,如果直接在手机上注册,坚果云会让你下载app,过程比较麻烦,为了一步到位,最好是在电脑上打开这个注册链接:https://www.jianguoyun.com/d/signup ;注册后,进入坚果云;点击右上角账户名处选择 “账户信息”,然后选择“安全选项”;在“安全选项” 中找到“第三方应用管理”,并选择“添加应用”,输入名称如“阅读”后,会生成密码,选择完成;其中 https://dav.jianguoyun.com/dav/ 就是填入“WebDAV 服务器地址”的内容,“使用情况”后面的邮箱地址就是你的“WebDAV 账号”,点击显示密码后得到的密码就是你的“WebDAV 密码”。)
-* 无需操作,APP默认每天自动云备份一次。
+如果直接在手机上注册,须下载【坚果云】APP,步骤较为繁琐。推荐在电脑上进行操作:
+1. 打开注册链接:https://www.jianguoyun.com/d/signup ;
+2. 注册后,进入坚果云;
+3. 点击右上角账户名处选择“**账户信息**”,然后选择“**安全选项**”;
+4. 在“**安全选项**”中找到“**第三方应用管理**”,并选择“**添加应用**”,输入名称(如“阅读”)后,会生成密码,选择完成;
+5. 其中 `https://dav.jianguoyun.com/dav/` 就是填入“**WebDAV 服务器地址**”的内容,“**使用情况**”后面的邮箱地址就是你的“**WebDAV 账号**”,点击“**显示密码**“后得到的密码就是你的“**WebDAV 密码**”。
-3. 关于云备份的相关说明
-* 在正确设置好云备份的情况下,APP默认每天自动云备份一次,当日多次手动云备份会对当日的旧云备份文件进行覆盖,并不会覆盖之前及之后不同日期的备份文件,每天所自动云备份的文件会按照日期进行命名。
+### 3. 关于云备份的相关说明
-4. 本地备份和云备份都能备份哪些东西?
-* 书架、看书进度、搜索记录、书源、替换、APP设置等都会备份,基本涵盖所有内容。
+在正确设置好云备份的情况下,APP 默认每天自动云备份一次,当日多次手动云备份会对当日的旧云备份文件进行覆盖,并不会覆盖之前及之后不同日期的备份文件,每天所自动云备份的文件会按照日期进行命名。
-5. 出现某些未知bug怎么办?
-* 清除软件数据试试看,不行再进行反馈。
+### 4. 本地备份和云备份都能备份哪些东西?
+书架、看书进度、搜索记录、书源、替换和 APP 设置等都会备份,基本涵盖所有内容。
+
+### 5. 出现某些未知 Bug 怎么办?
+清除软件数据试试看,不行再进行反馈。
## 其他
-1. 如何听书?
-* 可以使用手机自带的朗读引擎,也可使用第三方如谷歌、小米等朗读引擎。
-* 【具体操作:安装-系统设置-其他高级设置-辅助功能-TTS输出-选择安装的朗读引擎(不同品牌手机的操作方法及步骤也不同,视情况而定)。】
-2. 如何设置屏幕方向、屏幕显示时长、显示/隐藏状态栏、显示/隐藏导航栏、音量键翻页、长按选择文本、点击总是翻下一页、自定义翻页案件?
-* 阅读界面,设置(可上划,下面还有其他设置)。
+### 1. 如何听书?
+可以使用手机自带的朗读引擎,也可使用第三方如 Google(谷歌)或小米等朗读引擎。
+
+【具体操作】*安装——系统设置——其他高级设置——辅助功能——TTS 输出——选择安装的朗读引擎(不同品牌手机的操作方法及步骤也不同,视情况而定)。*
+
+### 2. 如何设置屏幕方向、屏幕显示时长、显示/隐藏状态栏、显示/隐藏导航栏、音量键翻页、长按选择文本、点击总是翻下一页或自定义翻页按键?
+阅读界面——“**设置**”(可上划,下面还有其他设置)。
-3. 搜索的时候感觉手机卡顿,如何解决?
-* 我的 - 其他设置 - “更新和搜索线程数”调低。
+### 3. 搜索的时候感觉手机卡顿,如何解决?
+“**我的**”——“**其他设置**”——调低“**更新和搜索线程数**”。
diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md
index c113b2031..c9d308efb 100644
--- a/app/src/main/assets/updateLog.md
+++ b/app/src/main/assets/updateLog.md
@@ -11,6 +11,10 @@
* 正文出现缺字漏字、内容缺失、排版错乱等情况,有可能是净化规则或简繁转换出现问题。
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
+**2022/06/05**
+
+* 添加源变量说明,输入源变量界面显示说明
+
**2022/06/01**
* 更新cronet: 102.0.5005.78
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 1cb68c80d..c03e049e9 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 = 49,
+ version = 50,
exportSchema = true,
entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class,
ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class,
@@ -33,7 +33,8 @@ val appDb by lazy {
AutoMigration(from = 45, to = 46),
AutoMigration(from = 46, to = 47),
AutoMigration(from = 47, to = 48),
- AutoMigration(from = 48, to = 49)
+ AutoMigration(from = 48, to = 49),
+ AutoMigration(from = 49, to = 50)
]
)
abstract class AppDatabase : RoomDatabase() {
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 4d76d1713..72d2b7589 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
@@ -54,6 +54,8 @@ data class BookSource(
var loginCheckJs: String? = null,
// 注释
var bookSourceComment: String? = null,
+ // 自定义变量说明
+ var variableComment: String? = null,
// 最后更新时间,用于排序
var lastUpdateTime: Long = 0,
// 响应时间,用于排序
@@ -211,6 +213,14 @@ data class BookSource(
}?.joinToString() ?: ""
}
+ fun getDisplayVariableComment(otherComment: String): String {
+ return if (variableComment.isNullOrBlank()) {
+ otherComment
+ } else {
+ "${variableComment}\n$otherComment"
+ }
+ }
+
fun equal(source: BookSource) =
equal(bookSourceName, source.bookSourceName)
&& equal(bookSourceUrl, source.bookSourceUrl)
diff --git a/app/src/main/java/io/legado/app/data/entities/RssSource.kt b/app/src/main/java/io/legado/app/data/entities/RssSource.kt
index 90a17273a..dd4eaa9b5 100644
--- a/app/src/main/java/io/legado/app/data/entities/RssSource.kt
+++ b/app/src/main/java/io/legado/app/data/entities/RssSource.kt
@@ -15,22 +15,35 @@ import splitties.init.appCtx
data class RssSource(
@PrimaryKey
var sourceUrl: String = "",
+ // 名称
var sourceName: String = "",
+ // 图标
var sourceIcon: String = "",
+ // 分组
var sourceGroup: String? = null,
+ // 注释
var sourceComment: String? = null,
+ // 是否启用
var enabled: Boolean = true,
+ // 自定义变量说明
+ var variableComment: String? = null,
@ColumnInfo(defaultValue = "0")
override var enabledCookieJar: Boolean? = false,
- override var concurrentRate: String? = null, //并发率
- override var header: String? = null, // 请求头
- override var loginUrl: String? = null, // 登录地址
- override var loginUi: String? = null, //登录UI
- var loginCheckJs: String? = null, //登录检测js
+ //并发率
+ override var concurrentRate: String? = null,
+ // 请求头
+ override var header: String? = null,
+ // 登录地址
+ override var loginUrl: String? = null,
+ //登录UI
+ override var loginUi: String? = null,
+ //登录检测js
+ var loginCheckJs: String? = null,
var sortUrl: String? = null,
var singleUrl: Boolean = false,
/*列表规则*/
- var articleStyle: Int = 0, //列表样式,0,1,2
+ //列表样式,0,1,2
+ var articleStyle: Int = 0,
var ruleArticles: String? = null,
var ruleNextPage: String? = null,
var ruleTitle: String? = null,
@@ -131,6 +144,14 @@ data class RssSource(
}
}
+ fun getDisplayVariableComment(otherComment: String): String {
+ return if (variableComment.isNullOrBlank()) {
+ otherComment
+ } else {
+ "${variableComment}\n$otherComment"
+ }
+ }
+
@Suppress("MemberVisibilityCanBePrivate")
companion object {
diff --git a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt
index b12e0726e..428cccb82 100644
--- a/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt
+++ b/app/src/main/java/io/legado/app/model/localBook/EpubFile.kt
@@ -122,11 +122,10 @@ class EpubFile(var book: Book) {
private fun getContent(chapter: BookChapter): String? {
/**
- *
- *
- * titlepage.xhtml
+ *
+ * ...titlepage.xhtml
*/
- if (chapter.url == "titlepage.xhtml") {
+ if (chapter.url.contains("titlepage.xhtml")) {
return ""
}
/*获取当前章节文本*/
diff --git a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
index 4819cf85c..b53d1cb32 100644
--- a/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
+++ b/app/src/main/java/io/legado/app/model/localBook/LocalBook.kt
@@ -76,7 +76,8 @@ object LocalBook {
if (chapters.isEmpty()) {
throw TocEmptyException(appCtx.getString(R.string.chapter_list_empty))
}
- return chapters
+ val lh = LinkedHashSet(chapters)
+ return ArrayList(lh)
}
fun getContent(book: Book, chapter: BookChapter): String? {
diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
index 4655c07c1..d08e0c956 100644
--- a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
+++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
@@ -49,7 +49,11 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
val bindings = SimpleBindings()
bindings["name"] = book.name
bindings["author"] = book.getRealAuthor()
- return AppConst.SCRIPT_ENGINE.eval(jsStr, bindings).toString()
+ return kotlin.runCatching {
+ AppConst.SCRIPT_ENGINE.eval(jsStr, bindings).toString()
+ }.onFailure {
+ context.toastOnUi("书名规则错误\n${it.localizedMessage}")
+ }.getOrDefault("${book.name} 作者:${book.getRealAuthor()}")
}
fun export(path: String, book: Book) {
diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
index 176c08f76..0f93ba53b 100644
--- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoActivity.kt
@@ -247,7 +247,11 @@ class BookInfoActivity :
binding.tvToc.text = getString(R.string.toc_s, getString(R.string.loading))
}
chapterList.isNullOrEmpty() -> {
- binding.tvToc.text = if (viewModel.isImportBookOnLine) getString(R.string.click_read_button_load) else getString(R.string.toc_s, getString(R.string.error_load_toc))
+ binding.tvToc.text =
+ if (viewModel.isImportBookOnLine) getString(R.string.click_read_button_load) else getString(
+ R.string.toc_s,
+ getString(R.string.error_load_toc)
+ )
}
else -> {
viewModel.bookData.value?.let {
@@ -358,9 +362,14 @@ class BookInfoActivity :
private fun setSourceVariable() {
launch {
- val variable = withContext(IO) { viewModel.bookSource?.getVariable() }
+ val source = viewModel.bookSource
+ if (source == null) {
+ toastOnUi("书源不存在")
+ return@launch
+ }
+ val variable = withContext(IO) { source.getVariable() }
alert(R.string.set_source_variable) {
- setMessage("源变量可在js中通过source.getVariable()获取")
+ setMessage(source.getDisplayVariableComment("源变量可在js中通过source.getVariable()获取"))
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "source variable"
editView.setText(variable)
@@ -379,9 +388,14 @@ class BookInfoActivity :
private fun setBookVariable() {
launch {
+ val source = viewModel.bookSource
+ if (source == null) {
+ toastOnUi("书源不存在")
+ return@launch
+ }
val variable = withContext(IO) { viewModel.bookData.value?.getVariable("custom") }
alert(R.string.set_source_variable) {
- setMessage("""书籍变量可在js中通过book.getVariable("custom")获取""")
+ setMessage(source.getDisplayVariableComment("""书籍变量可在js中通过book.getVariable("custom")获取"""))
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
editView.hint = "book variable"
editView.setText(variable)
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 fdf694bb3..acc770fff 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
@@ -215,13 +215,8 @@ class BookSourceEditActivity :
add(EditEntity("loginCheckJs", source?.loginCheckJs, R.string.login_check_js))
add(EditEntity("bookUrlPattern", source?.bookUrlPattern, R.string.book_url_pattern))
add(EditEntity("header", source?.header, R.string.source_http_header))
- add(
- EditEntity(
- "concurrentRate",
- source?.concurrentRate,
- R.string.source_concurrent_rate
- )
- )
+ add(EditEntity("variableComment", source?.variableComment, R.string.variable_comment))
+ add(EditEntity("concurrentRate", source?.concurrentRate, R.string.concurrent_rate))
}
//搜索
val sr = source?.getSearchRule()
@@ -328,6 +323,7 @@ class BookSourceEditActivity :
"header" -> source.header = it.value
"bookSourceComment" -> source.bookSourceComment = it.value ?: ""
"concurrentRate" -> source.concurrentRate = it.value
+ "variableComment" -> source.variableComment = it.value
}
}
searchEntities.forEach {
diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt
index cf769b459..a2d8cc935 100644
--- a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt
@@ -17,11 +17,8 @@ import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.login.SourceLoginActivity
import io.legado.app.ui.rss.source.edit.RssSourceEditActivity
-import io.legado.app.utils.StartActivityContract
-import io.legado.app.utils.gone
-import io.legado.app.utils.startActivity
+import io.legado.app.utils.*
import io.legado.app.utils.viewbindingdelegate.viewBinding
-import io.legado.app.utils.visible
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
@@ -106,9 +103,14 @@ class RssSortActivity : VMBaseActivity
return true
}
- @Suppress("DEPRECATION")
+ @Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
url?.let {
return shouldOverrideUrlLoading(Uri.parse(it))
diff --git a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt
index 01bd4bbe6..45cea1484 100644
--- a/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/rss/source/edit/RssSourceEditActivity.kt
@@ -170,11 +170,8 @@ class RssSourceEditActivity :
add(EditEntity("loginUi", source?.loginUi, R.string.login_ui))
add(EditEntity("loginCheckJs", source?.loginCheckJs, R.string.login_check_js))
add(EditEntity("header", source?.header, R.string.source_http_header))
- add(
- EditEntity(
- "concurrentRate", source?.concurrentRate, R.string.source_concurrent_rate
- )
- )
+ add(EditEntity("variableComment", source?.variableComment, R.string.variable_comment))
+ add(EditEntity("concurrentRate", source?.concurrentRate, R.string.concurrent_rate))
add(EditEntity("sortUrl", source?.sortUrl, R.string.sort_url))
add(EditEntity("ruleArticles", source?.ruleArticles, R.string.r_articles))
add(EditEntity("ruleNextPage", source?.ruleNextPage, R.string.r_next))
@@ -207,6 +204,7 @@ class RssSourceEditActivity :
"loginUi" -> source.loginUi = it.value
"loginCheckJs" -> source.loginCheckJs = it.value
"header" -> source.header = it.value
+ "variableComment" -> source.variableComment = it.value
"concurrentRate" -> source.concurrentRate = it.value
"sortUrl" -> source.sortUrl = it.value
"ruleArticles" -> source.ruleArticles = it.value
diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml
index 5827eba82..49bd444fd 100644
--- a/app/src/main/res/values-es-rES/strings.xml
+++ b/app/src/main/res/values-es-rES/strings.xml
@@ -388,7 +388,7 @@
源分组(sourceGroup)
自定义源分组
输入自定义源分组名称
- 并发率(concurrentRate)
+ 并发率(concurrentRate)
分类Url(sortUrl)
登录URL(loginUrl)
登录UI(loginUi)
@@ -995,4 +995,5 @@
Fail to decode bitmap
Image url is empty, check replacement rules
+ 变量说明(variableComment)
diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml
index 88570cfdc..324995eb8 100644
--- a/app/src/main/res/values-ja-rJP/strings.xml
+++ b/app/src/main/res/values-ja-rJP/strings.xml
@@ -392,7 +392,7 @@
源分组(sourceGroup)
自定义源分组
输入自定义源分组名称
- 并发率(concurrentRate)
+ 并发率(concurrentRate)
分类Url(sortUrl)
登录URL(loginUrl)
登录UI(loginUi)
@@ -998,4 +998,5 @@
Fail to decode bitmap
Image url is empty, check replacement rules
+ 变量说明(variableComment)
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index ee55c893a..6fae8a053 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -390,7 +390,7 @@
源分组(fonteGrupo)
自定义源分组
输入自定义源分组名称
- 并发率(taxaSimultânea)
+ 并发率(taxaSimultânea)
分类Url(ordenarUrl)
登录URL(loginUrl)
登UI(loginIU)
@@ -998,4 +998,5 @@
Fail to decode bitmap
Image url is empty, check replacement rules
+ 变量说明(variableComment)
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 22c20f729..8afa0fb70 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -388,7 +388,7 @@
源URL (sourceUrl)
源分組 (sourceGroup)
分類 Url(sortUrl)
- 並發率(concurrentRate)
+ 並發率(concurrentRate)
登錄 URL(loginUrl)
登錄UI(loginUi)
登錄檢查JS(loginCheckJs)
@@ -995,4 +995,5 @@
图片解码失败
图片链接为空,检查替换净化规则
+ 变量说明(variableComment)
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 963cff29e..2958a2c5a 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -391,7 +391,7 @@
源分組(sourceGroup)
自訂源分組
輸入自訂源分組名稱
- 並發率(concurrentRate)
+ 並發率(concurrentRate)
分類Url(sortUrl)
登入URL(loginUrl)
登入UI(loginUi)
@@ -997,4 +997,5 @@
图片解码失败
图片链接为空,检查替换净化规则
+ 变量说明(variableComment)
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
index a4727df79..c9bb20512 100644
--- a/app/src/main/res/values-zh/strings.xml
+++ b/app/src/main/res/values-zh/strings.xml
@@ -2,20 +2,20 @@
阅读
阅读·搜索
- 阅读需要访问存储卡权限,请前往“设置”—“应用权限”—打开所需权限
+ 阅读需要访问存储卡权限,请前往“设置”—“应用权限”,打开所需权限
Home
恢复
导入阅读数据
离线缓存书籍备份
- 导出本地同时备份到legado文件夹下exports目录
+ 导出本地同时备份到 legado 文件夹下的 exports 目录
备份路径
请选择备份路径
导入旧版数据
- 导入Github数据
+ 导入 Github 数据
净化替换
- Send
+ 发送
提示
取消
@@ -59,7 +59,7 @@
添加本地
书源
书源管理
- 新建/导入/编辑/管理书源
+ 新建、导入、编辑或管理书源
设置
主题设置
与界面/颜色相关的一些设置
@@ -68,33 +68,33 @@
关于
捐赠
退出
- 尚未保存,是否继续编辑
+ 尚未保存,是否继续编辑
阅读样式设置
版本
本地
搜索
- 来源: %s
- 最近: %s
+ 来源:%s
+ 最近:%s
书名
- 最新: %s
+ 最新:%s
是否将《%s》放入书架?
- 共%s个Text文件
+ 共 %s 个文本文件
加载中…
重试
Web 服务
- 浏览器写源,看书
- web编辑书源
+ 用浏览器写源或看书
+ Web 编辑书源
离线缓存
离线缓存
缓存选择的章节到本地
换源
- \u3000\u3000这是一款使用Kotlin全新开发的开源的阅读软件,欢迎您的加入。关注公众号[开源阅读]!
+ \u3000\u3000这是一款使用 Kotlin 全新开发的开源的阅读软件,欢迎您的加入。关注公众号【开源阅读】!
- 阅读3.0下载地址:\nhttps://www.coolapk.com/apk/256030
+ 阅读 3.0 下载地址:\nhttps://www.coolapk.com/apk/256030
- Version %s
+ 版本 %s
后台校验书源
打开后可以在校验书源时自由操作
自动刷新
@@ -102,16 +102,16 @@
自动下载最新章节
更新书籍时自动下载最新章节
备份与恢复
- WebDav设置
- WebDav设置/导入旧版本数据
+ WebDav 设置
+ WebDav 设置/导入旧版本数据
备份
恢复
- 备份请给与存储权限
- 恢复请给与存储权限
+ 备份请给予存储权限
+ 恢复请给予存储权限
确认
取消
确认备份吗?
- 新备份会替换原有备份。\n备份文件夹YueDu
+ 新备份会替换原有备份。\n备份文件夹 YueDu
确认恢复吗?
恢复书架会覆盖现有书架。
备份成功
@@ -125,7 +125,7 @@
竖向
跟随系统
免责声明
- 共%d章
+ 共 %d 章
界面
亮度
目录
@@ -148,8 +148,8 @@
继续
定时
朗读暂停
- 正在朗读(还剩%d分钟)
- 正在播放(还剩%d分钟)
+ 正在朗读(还剩 %d 分钟)
+ 正在播放(还剩 %d 分钟)
阅读界面隐藏虚拟按键
隐藏导航栏
导航栏颜色
@@ -162,7 +162,7 @@
添加书籍网址
背景
作者
- 作者: %s
+ 作者:%s
朗读停止
清理缓存
成功清理缓存
@@ -197,20 +197,20 @@
音量键翻页
点击翻页
翻页动画
- 翻页动画(本书)
+ 翻页动画(本书)
屏幕超时
返回
菜单
调节
滚动条
- 清除缓存会删除所有已保存章节,是否确认删除?
+ 清除缓存会删除所有已保存章节,是否确认删除?
书源共享
替换规则名称
替换规则为空或者不满足正则表达式要求
选择操作
全选
- 全选(%1$d/%2$d)
- 取消全选(%1$d/%2$d)
+ 全选(%1$d/%2$d)
+ 取消全选(%1$d/%2$d)
深色模式
启动页
开始下载
@@ -218,17 +218,17 @@
暂无任务
已下载 %1$d/%2$d
导入选择书籍
- 更新和搜索线程数,太多会卡顿
+ 更新和搜索线程数(太多会卡顿)
切换图标
删除书籍
开始阅读
加载数据中…
- 加载失败,点击重试
+ 加载失败,点击重试
内容简介
- 简介:%s
- 简介: 暂无简介
+ 简介:%s
+ 简介:暂无简介
打开外部书籍
- 来源: %s
+ 来源:%s
导入替换规则
导入在线规则
检查更新间隔
@@ -239,11 +239,11 @@
阅读方式
排版
删除所选
- 是否确认删除?
+ 是否确认删除?
默认字体
发现
发现管理
- 没有内容,去书源里自定义吧!
+ 还没有内容,去书源里自定义吧!
删除所有
搜索历史
清除
@@ -257,9 +257,9 @@
拷贝内容
一键缓存
这是一段测试文字\n\u3000\u3000只是让你看看效果的
- 文字颜色和背景(长按自定义)
+ 文字颜色和背景(长按自定义)
沉浸式状态栏
- 还剩%d章未下载
+ 还剩 %d 章未下载
长按输入颜色值
加载中…
追更区
@@ -268,14 +268,14 @@
添加书签
删除
加载超时
- 关注:%s
+ 关注:%s
已拷贝
书架管理
这将会删除所有书籍,请谨慎操作。
搜索书源
搜索订阅源
- 搜索(共%d个书源)
- 目录(%d)
+ 搜索(共 %d 个书源)
+ 目录(%d)
加粗
字体
文字
@@ -292,19 +292,19 @@
校验书源
校验所选
%1$s 进度 %2$d/%3$d
- 请安装并选择中文TTS!
- TTS初始化失败!
+ 请安装并选择中文 TTS!
+ TTS 初始化失败!
简繁转换
关闭
简转繁
繁转简
翻页模式
%1$d 项
- 存储卡:
+ 存储卡:
加入书架
- 加入书架(%1$d)
- 成功添加%1$d本书
- 请将字体文件放到SD根目录Fonts文件夹下重新选择
+ 加入书架(%1$d)
+ 成功添加 %1$d 本书
+ 请将字体文件放到存储根目录 Fonts 文件夹下后重新选择
默认字体
选择字体
字号
@@ -325,14 +325,14 @@
书籍信息编辑
默认打开书架
自动跳转最近阅读
- 替换范围,选填书名或者书源url
+ 替换范围,选填书名或者书源 URL
分组
内容缓存路径
系统文件选择器
新版本
下载更新
朗读时音量键翻页
- Tip边距跟随边距调整
+ 提示边距跟随页边距调整
允许更新
禁止更新
拆分超长章节
@@ -344,7 +344,7 @@
显示所有发现
关闭则只显示勾选源的发现
更新目录
- Txt目录正则
+ TXT 目录正则
设置编码
倒序-顺序
排序
@@ -375,74 +375,74 @@
无动画
此书源使用了高级功能,请到捐赠里点击支付宝红包搜索码领取红包开启。
后台更新换源最新章节
- 开启则会在软件打开1分钟后开始更新
- 书架ToolBar自动隐藏
- 滚动书架时ToolBar自动隐藏与显示
+ 开启则会在软件打开 1 分钟后开始更新
+ 书架工具栏自动隐藏
+ 滚动书架时工具栏自动隐藏与显示
登录
- 登录%s
+ 登录 %s
成功
当前源没有配置登陆地址
没有上一页
没有下一页
- 源名称(sourceName)
- 源URL(sourceUrl)
- 源分组(sourceGroup)
+ 源名称(sourceName)
+ 源 URL(sourceUrl)
+ 源分组(sourceGroup)
自定义源分组
输入自定义源分组名称
- 并发率(concurrentRate)
- 分类Url(sortUrl)
- 登录URL(loginUrl)
- 登录UI(loginUi)
- 登录检查JS(loginCheckJs)
- 源注释(sourceComment)
- 搜索地址(url)
- 发现地址规则(url)
- 书籍列表规则(bookList)
- 书名规则(name)
- 详情页url规则(bookUrl)
- 作者规则(author)
- 分类规则(kind)
- 简介规则(intro)
- 封面规则(coverUrl)
- 最新章节规则(lastChapter)
- 字数规则(wordCount)
- 书籍URL正则(bookUrlPattern)
- 预处理规则(bookInfoInit)
- 目录URL规则(tocUrl)
- 允许修改书名作者(canReName)
- 目录下一页规则(nextTocUrl)
- 目录列表规则(chapterList)
- 章节名称规则(ChapterName)
- 章节URL规则(chapterUrl)
- Volume标识(isVolume)
- VIP标识(isVip)
- 更新时间(ChapterInfo)
- 更新之前Js(preUpdateJs)
- 正文规则(content)
- 正文下一页URL规则(nextContentUrl)
- WebViewJs(webJs)
- 图片样式(imageStyle)
- 替换规则(replaceRegex)
- 资源正则(sourceRegex)
- 购买操作(payAction)
+ 并发率(concurrentRate)
+ 分类 URL(sortUrl)
+ 登录 URL(loginUrl)
+ 登录 UI(loginUi)
+ 登录检查 JS(loginCheckJs)
+ 源注释(sourceComment)
+ 搜索地址(url)
+ 发现地址规则(url)
+ 书籍列表规则(bookList)
+ 书名规则(name)
+ 详情页 URL 规则(bookUrl)
+ 作者规则(author)
+ 分类规则(kind)
+ 简介规则(intro)
+ 封面规则(coverUrl)
+ 最新章节规则(lastChapter)
+ 字数规则(wordCount)
+ 书籍 URL 正则(bookUrlPattern)
+ 预处理规则(bookInfoInit)
+ 目录 URL 规则(tocUrl)
+ 允许修改书名作者(canReName)
+ 目录下一页规则(nextTocUrl)
+ 目录列表规则(chapterList)
+ 章节名称规则(ChapterName)
+ 章节 URL 规则(chapterUrl)
+ Volume 标识(isVolume)
+ VIP 标识(isVip)
+ 更新时间(ChapterInfo)
+ 更新之前 JS(preUpdateJs)
+ 正文规则(content)
+ 正文下一页 URL 规则(nextContentUrl)
+ WebView JS(webJs)
+ 图片样式(imageStyle)
+ 替换规则(replaceRegex)
+ 资源正则(sourceRegex)
+ 购买操作(payAction)
- 图标(sourceIcon)
- 列表规则(ruleArticles)
- 列表下一页规则(ruleArticles)
- 标题规则(ruleTitle)
- guid规则(ruleGuid)
- 时间规则(rulePubDate)
- 类别规则(ruleCategories)
- 描述规则(ruleDescription)
- 图片url规则(ruleImage)
- 内容规则(ruleContent)
- 样式(style)
- 链接规则(ruleLink)
- 校验关键字(checkKeyWord)
- 操作(actions)
- 购买标识(isPay)
+ 图标(sourceIcon)
+ 列表规则(ruleArticles)
+ 列表下一页规则(ruleArticles)
+ 标题规则(ruleTitle)
+ GUID 规则(ruleGuid)
+ 时间规则(rulePubDate)
+ 类别规则(ruleCategories)
+ 描述规则(ruleDescription)
+ 图片 URL 规则(ruleImage)
+ 内容规则(ruleContent)
+ 样式(style)
+ 链接规则(ruleLink)
+ 校验关键字(checkKeyWord)
+ 操作(actions)
+ 购买标识(isPay)
@@ -450,7 +450,7 @@
书籍信息获取失败
内容获取失败
目录获取失败
- 访问网站失败:%s
+ 访问网站失败:%s
文件读取失败
加载目录失败
获取数据失败!
@@ -460,7 +460,7 @@
数据解析失败
- 请求头(header)
+ 请求头(header)
调试源
二维码导入
分享选中源
@@ -469,23 +469,23 @@
主题
主题模式
选择主题模式
- 加入QQ群
+ 加入 QQ 群
获取背景图片需存储权限
输入书源网址
删除文件
删除文件成功
- 确定删除文件吗?
+ 确定删除文件吗?
手机目录
智能导入
发现
切换显示样式
- 导入本地书籍需存储权限
+ 导入本地书籍需要存储权限
夜间模式
E-Ink 模式
电子墨水屏模式
需要存储权限
再按一次退出程序
- 导入本地书籍需存储权限
+ 导入本地书籍需要存储权限
网络连接不可用
是
否
@@ -495,14 +495,14 @@
是否删除全部书籍?
是否同时删除已下载的书籍目录?
扫描二维码需相机权限
- 朗读正在运行,不能自动翻页
+ 朗读正在运行,不能自动翻页
输入编码
- TXT目录规则
- 打开外部书籍需获取存储权限
+ TXT 目录规则
+ 打开外部书籍需要存储权限
未获取到书名
输入替换规则网址
- 搜索列表获取成功%d
- 名称和URL不能为空
+ 搜索列表获取成功 %d
+ 名称和 URL 不能为空
图库
领支付宝红包
没有获取到更新地址
@@ -536,14 +536,14 @@
正文
E-Ink 模式
- 去除动画,优化电纸书使用体验
- Web服务
- web端口
+ 去除动画,优化电纸书使用体验
+ Web 服务
+ Web 端口
当前端口 %s
二维码分享
字符串分享
- wifi分享
- 请给于存储权限
+ WiFi 分享
+ 请给予存储权限
减速
加速
上一个
@@ -551,8 +551,8 @@
音乐
音频
启用
- 启用JS
- 加载BaseUrl
+ 启用 JavaScript
+ 加载 BaseUrl
全部书源
输入不能为空
清空发现缓存
@@ -562,8 +562,8 @@
我的
阅读
%d%%
- %d分钟
- 自动亮度%s
+ %d 分钟
+ 自动亮度 %s
按页朗读
朗读引擎
背景图片
@@ -578,8 +578,8 @@
移除分组
新建替换
分组
- 分组: %s
- 目录: %s
+ 分组:%s
+ 目录:%s
启用发现
禁用发现
启用所选
@@ -590,11 +590,11 @@
加载详情页
TTS
WebDav 密码
- 输入你的WebDav授权密码
+ 输入你的 WebDav 授权密码
输入你的服务器地址
WebDav 服务器地址
WebDav 账号
- 输入你的WebDav账号
+ 输入你的 WebDav 账号
订阅源
编辑订阅源
筛选
@@ -606,11 +606,11 @@
文件选择
文件夹选择
我是有底线的
- Uri转Path失败
+ URI 转 Path 失败
刷新封面
封面换源
选择本地图片
- 类型:
+ 类型:
后台
正在导入
正在导出
@@ -622,28 +622,28 @@
上一句
下一句
其它目录
- 文字太多,生成二维码失败
- 分享RSS源
+ 文字太多,生成二维码失败
+ 分享 RSS 源
分享书源
自动切换夜间模式
夜间模式跟随系统
上级
在线朗读音色
- (%1$d/%2$d)
+ (%1$d/%2$d)
显示订阅
服务已停止
- 正在启动服务\n具体信息查看通知栏
+ 正在启动服务\n具体信息请查看通知栏
默认路径
系统文件夹选择器
自带文件夹选择器
自带文件选择器
- Android10以上因权限限制可能无法读写文件
+ Android 10 以上因系统权限限制可能无法读写文件
长按文字在操作菜单中显示阅读·搜索
文字操作显示搜索
记录日志
日志
中文简繁体转换
- 图标为矢量图标,Android8.0以前不支持
+ 图标为矢量图标,Android 8.0 以前不支持
朗读设置
主界面
长按选择文本
@@ -675,11 +675,11 @@
设置分组
查看目录
导航栏阴影
- 当前阴影大小(elevation): %s
+ 当前阴影大小(elevation):%s
默认
主菜单
点击授予权限
- 阅读需要访问存储卡权限,请点击下方的"授予权限"按钮,或前往“设置”—“应用权限”—打开所需权限。如果授予权限后仍然不正常,请点击右上角的“选择文件夹”,使用系统文件夹选择器。
+ 阅读需要访问存储卡权限,请点击下方的“授予权限”按钮,或前往“设置”—“应用权限”,打开所需权限。如果授予权限后仍然不正常,请点击右上角的“选择文件夹”,使用系统文件夹选择器。
全文朗读中不能朗读选中文字
扩展到刘海
更新目录中
@@ -693,7 +693,7 @@
关注公众号
微信
您的支持是我更新的动力
- 公众号[开源阅读]
+ 公众号【开源阅读】
正在自动换源
点击加入
中
@@ -723,27 +723,27 @@
文字底部对齐
自动翻页速度
地址排序
- 本地和WebDav一起备份
- 优先从WebDav恢复,长按从本地恢复
+ 本地和 WebDav 一起备份
+ 优先从 WebDav 恢复,长按从本地恢复
选择旧版备份文件夹
已启用
已禁用
正在启动下载
该书已在下载列表
点击打开
- 关注[开源阅读]点击广告支持我
+ 关注【开源阅读】点击广告支持我
微信赞赏码
支付宝
支付宝红包搜索码
537954522 点击复制
支付宝红包二维码
支付宝收款二维码
- QQ收款二维码
- gedoor,Invinciblelee,Xwite等,详情请在github中查看
+ QQ 收款二维码
+ gedoor、Invinciblelee 和 Xwite 等,详情请在 GitHub 中查看
清除已下载书籍和字体缓存
默认封面
恢复忽略列表
- 恢复时忽略一些内容不恢复,方便不同手机配置不同
+ 恢复时忽略一些内容不恢复,方便不同手机配置不同
阅读界面设置
分组名称
备注内容
@@ -762,10 +762,10 @@
语言
导入订阅源
您的支持是我更新的动力
- 公众号[开源阅读软件]
+ 公众号【开源阅读软件】
阅读记录
阅读时间记录
- 本地TTS
+ 本地 TTS
线程数
总阅读时间
全不选
@@ -775,25 +775,25 @@
保存白天主题配置以供调用和分享
保存夜间主题配置以供调用和分享
主题列表
- 使用保存主题,导入,分享主题
+ 使用、保存、导入或分享主题
切换默认主题
更新时间排序
全文搜索
搜索结果
- 搜索内容为空,检查净化/简繁设置
- Empty now!
- 当前没有发现源!
- 将焦点放到输入框按下物理按键会自动录入键值,多个按键会自动用英文逗号隔开.
+ 搜索内容为空,请检查净化或简繁设置
+ RSS 源目前为空!
+ 当前没有发现源!
+ 将焦点放到输入框按下物理按键会自动录入键值,多个按键会自动用英文逗号隔开。
主题名称
自动清除过期搜索数据
超过一天的搜索数据
重新分段
- 样式名称:
- 点击右上角文件夹图标,选择文件夹
+ 样式名称:
+ 点击右上角文件夹图标,选择文件夹
智能扫描
导入文件名
- 拷贝书籍URL
- 拷贝目录URL
+ 拷贝书籍 URL
+ 拷贝目录 URL
没有书籍
保留原名
点击区域设置
@@ -807,30 +807,30 @@
规则订阅
添加大佬们提供的规则导入地址\n添加后点击可导入规则
拉取云端进度
- 当前进度超过云端进度,是否同步?
+ 当前进度超过云端进度,是否同步?
同步阅读进度
进入退出阅读界面时同步阅读进度
创建书签失败
- 单URL
+ 单 URL
导出书单
导入书单
预下载
- 预先下载%s章正文
+ 预先下载 %s 章正文
是否启用
背景图片
背景图片虚化
虚化半径
- 0为停用,启用范围1~25\n半径数值越大,虚化效果越高
+ 0 为停用,启用范围 1~25\n半径数值越大,虚化效果越高
导出文件夹
导出编码
- TXT不导出章节名
- 导出到WebDav
+ TXT 不导出章节名
+ 导出到 WebDav
反转内容
调试
崩溃日志
使用自定义中文分行
图片样式
- 系统TTS
+ 系统 TTS
导出格式
校验作者
搜索源码
@@ -838,14 +838,14 @@
目录源码
正文源码
列表源码
- 此url已订阅
- 高刷
+ 此 URL 已订阅
+ 高刷新率
使用屏幕最高刷新率
导出所有
完成
显示未读标志
总是使用默认封面
- 总是显示默认封面,不显示网络封面
+ 总是显示默认封面(不显示网络封面)
字号
上边距
下边距
@@ -858,7 +858,7 @@
分组样式
导出文件名
重置
- url为空
+ URL 为空
字典
未知错误
自动备份失败\n%s
@@ -866,22 +866,22 @@
关闭替换分组/开启添加分组
媒体按钮•上一首|下一首
上一段|下一段/上一章|下一章
- 及时翻页,翻页时会停顿一下
+ 及时翻页,翻页时会停顿一下
校验显示详细信息
书源校验时显示网络请求步骤和时间
- 需登录
- 使用Cronet网络组件
+ 需要登录
+ 使用 Cronet 网络组件
抗锯齿
绘制图片时抗锯齿
- 上传URL
- 下载URL规则
+ 上传 URL
+ 下载 URL 规则
响应时间排序
导出成功
路径
直链上传规则
- 用于导出书源书单时生成直链url
+ 用于导出书源书单时生成直链 URL
直链上传配置
- 拷贝播放Url
+ 拷贝播放 URL
设置源变量
设置书籍变量
注释
@@ -903,20 +903,20 @@
购买
平板/横屏双页
浏览器打开
- 拷贝url
+ 拷贝 URL
打开方式
- 是否使用外部浏览器打开?
+ 是否使用外部浏览器打开?
查看
打开
删除登录头
查看登录头
登录头
字体大小
- 当前字体大小:%.1f
+ 当前字体大小:%.1f
语速减
语速加
- 打开系统文件夹选择器出错,自动打开应用文件夹选择器
- 打开系统文件选择器出错,自动打开应用文件选择器
+ 打开系统文件夹选择器出错,将自动打开应用文件夹选择器
+ 打开系统文件选择器出错,将自动打开应用文件选择器
展开文本选择菜单
书籍保存位置
从其它应用打开的书籍保存位置
@@ -927,19 +927,19 @@
校验设置
校验项目
- 单个书源校验超时(秒)
+ 单个书源校验超时(秒)
超时
秒
小于
- 校验超时: %1$s秒\n校验项目:%2$s
+ 校验超时:%1$s秒\n校验项目:%2$s
记录调试日志
子文件夹
全局
使用替换
作用于标题
作用于正文
- 加入QQ频道
- 点击加入阅读QQ频道
+ 加入 QQ 频道
+ 点击加入阅读 QQ 频道
刷新当前章节
刷新之后章节
刷新全部章节
@@ -961,14 +961,14 @@
显示默认书籍图标
缓存/导出
辅助按键配置
- Url参数
- 仅WIFI
- 仅在wifi下加载网络封面
+ URL 参数
+ 仅 WiFi
+ 仅在 WiFi 下加载网络封面
封面规则
进入详情页时使用封面规则重新获取封面
定位到当前书源
- 系统tts设置
- 打开系统tts设置界面
+ 系统 TTS 设置
+ 打开系统 TTS 设置界面
非播放状态无法定时
所有书签
批量换源
@@ -977,24 +977,25 @@
输入验证码
验证码
超时毫秒数
- 文件%1$s 不受支持,是否继续打开?
- 导入TTS
+ 文件 %1$s 不受支持,是否继续打开?
+ 导入 TTS
导入主题
- 导入txt目录规则
+ 导入 TXT 目录规则
CookieJar
点击阅读加载目录
- 清除cookie
+ 清除 Cookie
导入在线书籍文件
- Upload Success
- Upload Fail
- Download Success
- Download Fail
- 上传WebDav
- WebDav书籍
+ 上传成功
+ 上传失败
+ 下载成功
+ 下载失败
+ 上传 WebDav
+ WebDav 书籍
当前最大缓存 %1$s MB
图片绘制缓存
- TXT导出图片
+ TXT 导出图片
图片解码失败
图片链接为空,检查替换净化规则
+ 变量说明(variableComment)
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d6905d954..c81e399db 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -392,7 +392,7 @@
源分组(sourceGroup)
自定义源分组
输入自定义源分组名称
- 并发率(concurrentRate)
+ 并发率(concurrentRate)
分类Url(sortUrl)
登录URL(loginUrl)
Login UI(loginUi)
@@ -998,4 +998,5 @@
Fail to decode bitmap
Image url is empty, check replacement rules
+ 变量说明(variableComment)