From 21729149cc48bbe6f6f8f79d06b55e2d1b50a41f Mon Sep 17 00:00:00 2001 From: kunfei Date: Sun, 2 Oct 2022 22:57:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B9=A6=E7=B1=8D=E7=B1=BB=E5=9E=8B=E9=87=87?= =?UTF-8?q?=E7=94=A8=E4=BD=8D=E8=BF=90=E7=AE=97,=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=9B=B4=E9=AB=98=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io.legado.app.data.AppDatabase/54.json | 8 +- .../io.legado.app.data.AppDatabase/55.json | 1711 +++++++++++++++++ .../app/api/controller/BookController.kt | 7 +- .../io/legado/app/constant/BookSourceType.kt | 26 + .../java/io/legado/app/constant/BookType.kt | 43 +- .../java/io/legado/app/data/AppDatabase.kt | 3 +- .../io/legado/app/data/DatabaseMigrations.kt | 83 +- .../java/io/legado/app/data/dao/BookDao.kt | 20 +- .../io/legado/app/data/dao/BookGroupDao.kt | 12 +- .../java/io/legado/app/data/entities/Book.kt | 42 +- .../io/legado/app/data/entities/BookSource.kt | 4 +- .../io/legado/app/data/entities/SearchBook.kt | 3 +- .../java/io/legado/app/help/BookExtensions.kt | 65 + .../main/java/io/legado/app/help/BookHelp.kt | 10 +- .../legado/app/help/source/SourceAnalyzer.kt | 7 +- .../legado/app/help/storage/ImportOldData.kt | 6 +- .../io/legado/app/help/storage/Restore.kt | 4 + .../java/io/legado/app/model/BookCover.kt | 12 +- .../java/io/legado/app/model/CacheBook.kt | 3 +- .../main/java/io/legado/app/model/Debug.kt | 2 +- .../main/java/io/legado/app/model/ReadBook.kt | 10 +- .../legado/app/model/localBook/LocalBook.kt | 31 +- .../io/legado/app/model/webBook/BookInfo.kt | 2 +- .../io/legado/app/model/webBook/BookList.kt | 5 +- .../io/legado/app/model/webBook/WebBook.kt | 5 +- .../legado/app/service/CheckSourceService.kt | 4 +- .../app/ui/book/audio/AudioPlayActivity.kt | 4 +- .../legado/app/ui/book/cache/CacheActivity.kt | 4 +- .../legado/app/ui/book/cache/CacheAdapter.kt | 7 +- .../app/ui/book/info/BookInfoActivity.kt | 17 +- .../app/ui/book/info/BookInfoViewModel.kt | 11 +- .../ui/book/info/edit/BookInfoEditActivity.kt | 16 +- .../legado/app/ui/book/manage/BookAdapter.kt | 3 +- .../book/manage/BookshelfManageViewModel.kt | 3 +- .../app/ui/book/read/ContentEditDialog.kt | 3 +- .../app/ui/book/read/ReadBookActivity.kt | 15 +- .../app/ui/book/read/ReadBookViewModel.kt | 9 +- .../book/read/page/provider/ImageProvider.kt | 3 +- .../app/ui/book/remote/RemoteBookViewModel.kt | 2 +- .../book/remote/manager/RemoteBookWebDav.kt | 2 +- .../searchContent/SearchContentActivity.kt | 3 +- .../source/edit/BookSourceEditActivity.kt | 16 +- .../app/ui/book/toc/ChapterListFragment.kt | 3 +- .../io/legado/app/ui/main/MainViewModel.kt | 5 +- .../style1/books/BooksAdapterGrid.kt | 4 +- .../style1/books/BooksAdapterList.kt | 4 +- .../bookshelf/style1/books/BooksFragment.kt | 10 +- .../main/bookshelf/style2/BooksAdapterGrid.kt | 4 +- .../main/bookshelf/style2/BooksAdapterList.kt | 4 +- .../bookshelf/style2/BookshelfFragment2.kt | 10 +- 50 files changed, 2074 insertions(+), 216 deletions(-) create mode 100644 app/schemas/io.legado.app.data.AppDatabase/55.json create mode 100644 app/src/main/java/io/legado/app/constant/BookSourceType.kt create mode 100644 app/src/main/java/io/legado/app/help/BookExtensions.kt diff --git a/app/schemas/io.legado.app.data.AppDatabase/54.json b/app/schemas/io.legado.app.data.AppDatabase/54.json index 03bb967a4..897fb0f7e 100644 --- a/app/schemas/io.legado.app.data.AppDatabase/54.json +++ b/app/schemas/io.legado.app.data.AppDatabase/54.json @@ -2,11 +2,11 @@ "formatVersion": 1, "database": { "version": 54, - "identityHash": "9045ef48ed80bddcaa0c7b4b05d15f24", + "identityHash": "2b32177325d903e84445cc80ad7cbce8", "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`))", + "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 1, `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", @@ -97,7 +97,7 @@ "columnName": "type", "affinity": "INTEGER", "notNull": true, - "defaultValue": "0" + "defaultValue": "1" }, { "fieldPath": "group", @@ -1705,7 +1705,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, '9045ef48ed80bddcaa0c7b4b05d15f24')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2b32177325d903e84445cc80ad7cbce8')" ] } } \ No newline at end of file diff --git a/app/schemas/io.legado.app.data.AppDatabase/55.json b/app/schemas/io.legado.app.data.AppDatabase/55.json new file mode 100644 index 000000000..865f5e394 --- /dev/null +++ b/app/schemas/io.legado.app.data.AppDatabase/55.json @@ -0,0 +1,1711 @@ +{ + "formatVersion": 1, + "database": { + "version": 55, + "identityHash": "09020e77cffa237f9a98c62eed0a01f2", + "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 'loc_book', `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 1, `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": "'loc_book'" + }, + { + "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": "1" + }, + { + "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, `coverDecodeJs` 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": "coverDecodeJs", + "columnName": "coverDecodeJs", + "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, `coverDecodeJs` 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, `lastUpdateTime` INTEGER NOT NULL DEFAULT 0, `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": "coverDecodeJs", + "columnName": "coverDecodeJs", + "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": "lastUpdateTime", + "columnName": "lastUpdateTime", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "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, '09020e77cffa237f9a98c62eed0a01f2')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/api/controller/BookController.kt b/app/src/main/java/io/legado/app/api/controller/BookController.kt index 21493181f..2209153c8 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookController.kt @@ -7,10 +7,7 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookProgress import io.legado.app.data.entities.BookSource -import io.legado.app.help.AppWebDav -import io.legado.app.help.BookHelp -import io.legado.app.help.CacheManager -import io.legado.app.help.ContentProcessor +import io.legado.app.help.* import io.legado.app.help.glide.ImageLoader import io.legado.app.model.BookCover import io.legado.app.model.localBook.LocalBook @@ -98,7 +95,7 @@ object BookController { } val book = appDb.bookDao.getBook(bookUrl) ?: return returnData.setErrorMsg("bookUrl不对") - if (book.isLocalBook()) { + if (book.isLocal) { val toc = LocalBook.getChapterList(book) appDb.bookChapterDao.delByBook(book.bookUrl) appDb.bookChapterDao.insert(*toc.toTypedArray()) diff --git a/app/src/main/java/io/legado/app/constant/BookSourceType.kt b/app/src/main/java/io/legado/app/constant/BookSourceType.kt new file mode 100644 index 000000000..e64f95731 --- /dev/null +++ b/app/src/main/java/io/legado/app/constant/BookSourceType.kt @@ -0,0 +1,26 @@ +package io.legado.app.constant + +import androidx.annotation.IntDef + +object BookSourceType { + + const val default = 0 // 0 文本 + const val audio = 1 // 1 音频 + const val image = 2 // 2 图片 + const val file = 3 // 3 只提供下载服务的网站 + + @Target(AnnotationTarget.VALUE_PARAMETER) + @Retention(AnnotationRetention.SOURCE) + @IntDef(default, audio, image, file) + annotation class Type + + fun toBookType(sourceType: Int) { + when (sourceType) { + file -> BookType.text or BookType.webFile + image -> BookType.image + audio -> BookType.audio + else -> BookType.text + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/constant/BookType.kt b/app/src/main/java/io/legado/app/constant/BookType.kt index 4e66053b1..24a079b5a 100644 --- a/app/src/main/java/io/legado/app/constant/BookType.kt +++ b/app/src/main/java/io/legado/app/constant/BookType.kt @@ -2,20 +2,49 @@ package io.legado.app.constant import androidx.annotation.IntDef +/** + * 以二进制位来区分,可能一本书籍包含多个类型,每一位代表一个类型,数值为2的n次方 + * 以二进制位来区分,数据库查询更高效 + */ object BookType { - const val default = 0 // 0 文本 - const val audio = 1 // 1 音频 - const val image = 2 // 2 图片 - const val file = 3 // 3 只提供下载服务的网站 - const val local = "loc_book" + /** + * 8 文本 + */ + const val text = 0b1000 + + /** + * 16 音频 + */ + const val audio = 0b100000 + + /** + * 32 图片 + */ + const val image = 0b1000000 + + /** + * 64 只提供下载服务的网站 + */ + const val webFile = 0b10000000 + + /** + * 128 本地 + */ + const val local = 0b100000000 + + + /** + * 本地书籍书源标志 + */ + const val localTag = "loc_book" /** * 书源已webDav::开头的书籍,可以从webDav更新或重新下载 */ - const val webDav = "webDav::" + const val webDavTag = "webDav::" @Target(AnnotationTarget.VALUE_PARAMETER) @Retention(AnnotationRetention.SOURCE) - @IntDef(default, audio, image, file) + @IntDef(text, audio, image, webFile) annotation class Type } \ No newline at end of file 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 b9be414db..924992552 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 = 54, + version = 55, exportSchema = true, entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class, @@ -39,6 +39,7 @@ val appDb by lazy { AutoMigration(from = 51, to = 52), AutoMigration(from = 52, to = 53), AutoMigration(from = 53, to = 54), + AutoMigration(from = 54, to = 55, spec = DatabaseMigrations.Migration_44_45::class) ] ) abstract class AppDatabase : RoomDatabase() { diff --git a/app/src/main/java/io/legado/app/data/DatabaseMigrations.kt b/app/src/main/java/io/legado/app/data/DatabaseMigrations.kt index 4fc5fce39..e4c10dcd6 100644 --- a/app/src/main/java/io/legado/app/data/DatabaseMigrations.kt +++ b/app/src/main/java/io/legado/app/data/DatabaseMigrations.kt @@ -1,45 +1,24 @@ package io.legado.app.data +import androidx.room.migration.AutoMigrationSpec import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase import io.legado.app.constant.AppConst +import io.legado.app.constant.BookSourceType +import io.legado.app.constant.BookType object DatabaseMigrations { val migrations: Array by lazy { arrayOf( - migration_10_11, - migration_11_12, - migration_12_13, - migration_13_14, - migration_14_15, - migration_15_17, - migration_17_18, - migration_18_19, - migration_19_20, - migration_20_21, - migration_21_22, - migration_22_23, - migration_23_24, - migration_24_25, - migration_25_26, - migration_26_27, - migration_27_28, - migration_28_29, - migration_29_30, - migration_30_31, - migration_31_32, - migration_32_33, - migration_33_34, - migration_34_35, - migration_35_36, - migration_36_37, - migration_37_38, - migration_38_39, - migration_39_40, - migration_40_41, - migration_41_42, - migration_42_43 + migration_10_11, migration_11_12, migration_12_13, migration_13_14, + migration_14_15, migration_15_17, migration_17_18, migration_18_19, + migration_19_20, migration_20_21, migration_21_22, migration_22_23, + migration_23_24, migration_24_25, migration_25_26, migration_26_27, + migration_27_28, migration_28_29, migration_29_30, migration_30_31, + migration_31_32, migration_32_33, migration_33_34, migration_34_35, + migration_35_36, migration_36_37, migration_37_38, migration_38_39, + migration_39_40, migration_40_41, migration_41_42, migration_42_43, ) } @@ -343,4 +322,44 @@ object DatabaseMigrations { database.execSQL("ALTER TABLE `chapters` ADD `isVolume` INTEGER NOT NULL DEFAULT 0") } } + + + @Suppress("ClassName") + class Migration_44_45 : AutoMigrationSpec { + + override fun onPostMigrate(db: SupportSQLiteDatabase) { + db.execSQL( + """ + update books set type = ${BookType.audio} + where type = ${BookSourceType.audio} + """.trimIndent() + ) + db.execSQL( + """ + update books set type = ${BookType.image} + where type = ${BookSourceType.image} + """.trimIndent() + ) + db.execSQL( + """ + update books set type = ${BookType.webFile} + where type = ${BookSourceType.file} + """.trimIndent() + ) + db.execSQL( + """ + update books set type = ${BookType.text} + where type = ${BookSourceType.default} + """.trimIndent() + ) + db.execSQL( + """ + update books set type = type | ${BookType.local} + where origin = '${BookType.localTag}' or origin like '${BookType.webDavTag}%' + """.trimIndent() + ) + } + + } + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/dao/BookDao.kt b/app/src/main/java/io/legado/app/data/dao/BookDao.kt index 7c4de7d90..9a8f2f083 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookDao.kt @@ -11,8 +11,8 @@ interface BookDao { @Query( """ - select * from books where type != ${BookType.audio} - and origin != '${BookType.local}' and origin not like '${BookType.webDav}%' + select * from books where type & ${BookType.text} > 0 + and type & ${BookType.local} = 0 and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0 and (select show from book_groups where groupId = ${AppConst.bookGroupNetNoneId}) != 1 """ @@ -22,15 +22,15 @@ interface BookDao { @Query("SELECT * FROM books order by durChapterTime desc") fun flowAll(): Flow> - @Query("SELECT * FROM books WHERE type = ${BookType.audio}") + @Query("SELECT * FROM books WHERE type & ${BookType.audio} > 0") fun flowAudio(): Flow> - @Query("SELECT * FROM books WHERE origin = '${BookType.local}' or origin like '${BookType.webDav}%'") + @Query("SELECT * FROM books WHERE type & ${BookType.local} > 0") fun flowLocal(): Flow> @Query( """ - select * from books where type != ${BookType.audio} and origin != '${BookType.local}' and origin not like '${BookType.webDav}%' + select * from books where type & ${BookType.audio} = 0 and type & ${BookType.local} = 0 and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0 """ ) @@ -38,13 +38,13 @@ interface BookDao { @Query( """ - select * from books where origin = '${BookType.local}' or origin like '${BookType.webDav}%' + select * from books where type & ${BookType.local} > 0 and ((SELECT sum(groupId) FROM book_groups where groupId > 0) & `group`) = 0 """ ) fun flowLocalNoGroup(): Flow> - @Query("SELECT bookUrl FROM books WHERE origin = '${BookType.local}' or origin like '${BookType.webDav}%'") + @Query("SELECT bookUrl FROM books WHERE type & ${BookType.local} > 0") fun flowLocalUri(): Flow> @Query("SELECT * FROM books WHERE (`group` & :group) > 0") @@ -65,13 +65,13 @@ interface BookDao { @Query("SELECT * FROM books WHERE name = :name and author = :author") fun getBook(name: String, author: String): Book? - @get:Query("select count(bookUrl) from books where (SELECT sum(groupId) FROM book_groups) & `group` = 0") + @get:Query("select count(bookUrl) from books where (SELECT sum(groupId) FROM book_groups)") val noGroupSize: Int - @get:Query("SELECT * FROM books where origin <> '${BookType.local}' and type = 0") + @get:Query("SELECT * FROM books where type & ${BookType.local} = 0") val webBooks: List - @get:Query("SELECT * FROM books where origin <> '${BookType.local}' and canUpdate = 1") + @get:Query("SELECT * FROM books where type & ${BookType.local} = 0 and canUpdate = 1") val hasUpdateBooks: List @get:Query("SELECT * FROM books") diff --git a/app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt b/app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt index cfac470f0..e6c497df5 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookGroupDao.kt @@ -23,21 +23,21 @@ interface BookGroupDao { with const as (SELECT sum(groupId) sumGroupId FROM book_groups where groupId > 0) SELECT book_groups.* FROM book_groups, const where (groupId >= 0 and show > 0) or (groupId = -1 and show > 0) - or (groupId = -2 and show > 0 and (select count(bookUrl) from books where origin = '${BookType.local}') > 0) - or (groupId = -3 and show > 0 and (select count(bookUrl) from books where type = ${BookType.audio}) > 0) + or (groupId = -2 and show > 0 and (select count(bookUrl) from books where type & ${BookType.local} > 0) > 0) + or (groupId = -3 and show > 0 and (select count(bookUrl) from books where type & ${BookType.audio} > 0) > 0) or (groupId = -4 and show > 0 and ( select count(bookUrl) from books - where type != '${BookType.audio}' - and origin != '${BookType.local}' + where type & ${BookType.audio} = 0 + and type & ${BookType.local} = 0 and const.sumGroupId & `group` = 0 ) > 0 ) or (groupId = -5 and show > 0 and ( select count(bookUrl) from books - where type != '${BookType.audio}' - and origin = '${BookType.local}' + where type & ${BookType.audio} = 0 + and type & ${BookType.local} > 0 and const.sumGroupId & `group` = 0 ) > 0 ) diff --git a/app/src/main/java/io/legado/app/data/entities/Book.kt b/app/src/main/java/io/legado/app/data/entities/Book.kt index 426913043..bebecb0bc 100644 --- a/app/src/main/java/io/legado/app/data/entities/Book.kt +++ b/app/src/main/java/io/legado/app/data/entities/Book.kt @@ -10,11 +10,12 @@ import io.legado.app.help.BookHelp import io.legado.app.help.ContentProcessor import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig +import io.legado.app.help.isEpub +import io.legado.app.help.isImage import io.legado.app.model.ReadBook import io.legado.app.utils.GSON import io.legado.app.utils.MD5Utils import io.legado.app.utils.fromJsonObject -import io.legado.app.utils.isUri import kotlinx.coroutines.runBlocking import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize @@ -37,8 +38,8 @@ data class Book( @ColumnInfo(defaultValue = "") var tocUrl: String = "", // 书源URL(默认BookType.local) - @ColumnInfo(defaultValue = "") - var origin: String = BookType.local, + @ColumnInfo(defaultValue = BookType.localTag) + var origin: String = BookType.localTag, //书源名称 or 本地书籍文件名 @ColumnInfo(defaultValue = "") var originName: String = "", @@ -62,8 +63,8 @@ data class Book( var customIntro: String? = null, // 自定义字符集名称(仅适用于本地书籍) var charset: String? = null, - // 0:text 1:audio 3:image - @ColumnInfo(defaultValue = "0") + // 类型,详见BookType + @ColumnInfo(defaultValue = "1") var type: Int = 0, // 自定义分组索引号 @ColumnInfo(defaultValue = "0") @@ -108,29 +109,6 @@ data class Book( var readConfig: ReadConfig? = null ) : Parcelable, BaseBook { - fun isLocalBook(): Boolean { - //通过判断书籍链接来判断http* file:// content:// - //origin判断不可靠 http* BookType.local webDav:: - return origin == BookType.local || bookUrl.isUri() - } - - fun isLocalTxt(): Boolean { - return isLocalBook() && originName.endsWith(".txt", true) - } - - fun isEpub(): Boolean { - return originName.endsWith(".epub", true) - } - - fun isUmd(): Boolean { - return originName.endsWith(".umd", true) - } - - @Suppress("unused") - fun isOnLineTxt(): Boolean { - return !isLocalBook() && type == 0 - } - override fun equals(other: Any?): Boolean { if (other is Book) { return other.bookUrl == bookUrl @@ -206,7 +184,7 @@ data class Book( return useReplaceRule } //图片类书源 epub本地 默认关闭净化 - if (type == BookType.image || isEpub()) { + if (isImage || isEpub) { return false } return AppConfig.replaceEnableDefault @@ -226,7 +204,7 @@ data class Book( fun getPageAnim(): Int { var pageAnim = config.pageAnim - ?: if (type == BookType.image) PageAnim.scrollPageAnim else ReadBookConfig.pageAnim + ?: if (type and BookType.image > 0) PageAnim.scrollPageAnim else ReadBookConfig.pageAnim if (pageAnim < 0) { pageAnim = ReadBookConfig.pageAnim } @@ -239,7 +217,7 @@ data class Book( fun getImageStyle(): String? { return config.imageStyle - ?: if (type == BookType.image) imgStyleFull else null + ?: if (isImage) imgStyleFull else null } fun setTtsEngine(ttsEngine: String?) { @@ -358,4 +336,4 @@ data class Book( @TypeConverter fun stringToReadConfig(json: String?) = GSON.fromJsonObject(json).getOrNull() } -} +} \ No newline at end of file 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 bf7b4aa6d..3d5362c3f 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 @@ -4,7 +4,7 @@ import android.os.Parcelable import android.text.TextUtils import androidx.room.* import io.legado.app.constant.AppPattern -import io.legado.app.constant.BookType +import io.legado.app.constant.BookSourceType import io.legado.app.data.entities.rule.* import io.legado.app.help.source.SourceAnalyzer import io.legado.app.utils.GSON @@ -29,7 +29,7 @@ data class BookSource( // 分组 var bookSourceGroup: String? = null, // 类型,0 文本,1 音频, 2 图片, 3 文件(指的是类似知轩藏书只提供下载的网站) - @BookType.Type + @BookSourceType.Type var bookSourceType: Int = 0, // 详情页url正则 var bookUrlPattern: String? = null, diff --git a/app/src/main/java/io/legado/app/data/entities/SearchBook.kt b/app/src/main/java/io/legado/app/data/entities/SearchBook.kt index 7d0d1e026..2fc2a3a15 100644 --- a/app/src/main/java/io/legado/app/data/entities/SearchBook.kt +++ b/app/src/main/java/io/legado/app/data/entities/SearchBook.kt @@ -4,6 +4,7 @@ import android.content.Context import android.os.Parcelable import androidx.room.* import io.legado.app.R +import io.legado.app.constant.BookType import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonObject import kotlinx.parcelize.IgnoredOnParcel @@ -26,7 +27,7 @@ data class SearchBook( override var bookUrl: String = "", var origin: String = "", // 书源规则 var originName: String = "", - var type: Int = 0, // @BookType + var type: Int = BookType.text, // @BookType override var name: String = "", override var author: String = "", override var kind: String? = null, diff --git a/app/src/main/java/io/legado/app/help/BookExtensions.kt b/app/src/main/java/io/legado/app/help/BookExtensions.kt new file mode 100644 index 000000000..6af710c82 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/BookExtensions.kt @@ -0,0 +1,65 @@ +package io.legado.app.help + +import io.legado.app.constant.BookSourceType +import io.legado.app.constant.BookType +import io.legado.app.data.entities.Book +import io.legado.app.data.entities.BookSource + + +val Book.isAudio: Boolean + get() { + return type and BookType.audio > 0 + } + +val Book.isImage: Boolean + get() { + return type and BookType.image > 0 + } + +val Book.isLocal: Boolean + get() { + return type and BookType.local > 0 + } + +val Book.isLocalTxt: Boolean + get() { + return isLocal && originName.endsWith(".txt", true) + } + +val Book.isEpub: Boolean + get() { + return isLocal && originName.endsWith(".epub", true) + } + +val Book.isUmd: Boolean + get() { + return isLocal && originName.endsWith(".umd", true) + } + +val Book.isOnLineTxt: Boolean + get() { + return !isLocal && type and BookType.text > 0 + } + +fun Book.upType() { + if (type < 8) { + type = when (type) { + BookSourceType.image -> BookType.image + BookSourceType.audio -> BookType.audio + BookSourceType.file -> BookType.webFile + else -> BookType.text + } + if (origin == "loc_book" || origin.startsWith(BookType.webDavTag)) { + type = type or BookType.local + } + } +} + +fun BookSource.getBookType(): Int { + return when (bookSourceType) { + BookSourceType.file -> BookType.text or BookType.webFile + BookSourceType.image -> BookType.image + BookSourceType.audio -> BookType.audio + else -> BookType.text + } +} diff --git a/app/src/main/java/io/legado/app/help/BookHelp.kt b/app/src/main/java/io/legado/app/help/BookHelp.kt index 78c440b47..bfa3ce3e8 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -60,7 +60,7 @@ object BookHelp { val originNames = ArrayList() appDb.bookDao.all.forEach { bookFolderNames.add(it.getFolderName()) - if (it.isEpub()) originNames.add(it.originName) + if (it.isEpub) originNames.add(it.originName) } downloadDir.getFile(cacheFolderName) .listFiles()?.forEach { bookFile -> @@ -198,7 +198,7 @@ object BookHelp { fun getChapterFiles(book: Book): List { val fileNameList = arrayListOf() - if (book.isLocalTxt()) { + if (book.isLocalTxt) { return fileNameList } FileUtils.createFolderIfNotExist( @@ -214,7 +214,7 @@ object BookHelp { * 检测该章节是否下载 */ fun hasContent(book: Book, bookChapter: BookChapter): Boolean { - return if (book.isLocalTxt()) { + return if (book.isLocalTxt) { true } else { downloadDir.exists( @@ -258,9 +258,9 @@ object BookHelp { if (file.exists()) { return file.readText() } - if (book.isLocalBook()) { + if (book.isLocal) { val string = LocalBook.getContent(book, bookChapter) - if (string != null && book.isEpub()) { + if (string != null && book.isEpub) { saveText(book, bookChapter, string) } return string diff --git a/app/src/main/java/io/legado/app/help/source/SourceAnalyzer.kt b/app/src/main/java/io/legado/app/help/source/SourceAnalyzer.kt index 517bba282..5bcc9f7c8 100644 --- a/app/src/main/java/io/legado/app/help/source/SourceAnalyzer.kt +++ b/app/src/main/java/io/legado/app/help/source/SourceAnalyzer.kt @@ -4,13 +4,12 @@ import androidx.annotation.Keep import com.jayway.jsonpath.JsonPath import io.legado.app.constant.AppConst import io.legado.app.constant.AppLog -import io.legado.app.constant.BookType +import io.legado.app.constant.BookSourceType import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.rule.* import io.legado.app.exception.NoStackTraceException import io.legado.app.utils.* import java.io.InputStream - import java.util.regex.Pattern @Suppress("RegExpRedundantEscape") @@ -91,7 +90,7 @@ object SourceAnalyzer { searchUrl = toNewUrl(jsonItem.readString("ruleSearchUrl")) exploreUrl = toNewUrls(jsonItem.readString("ruleFindUrl")) bookSourceType = - if (jsonItem.readString("bookSourceType") == "AUDIO") BookType.audio else BookType.default + if (jsonItem.readString("bookSourceType") == "AUDIO") BookSourceType.audio else BookSourceType.default enabled = jsonItem.readBool("enable") ?: true if (exploreUrl.isNullOrBlank()) { enabledExplore = false @@ -226,7 +225,7 @@ object SourceAnalyzer { var bookSourceName: String = "", // 名称 var bookSourceGroup: String? = null, // 分组 var bookSourceUrl: String = "", // 地址,包括 http/https - var bookSourceType: Int = BookType.default, // 类型,0 文本,1 音频 + var bookSourceType: Int = BookSourceType.default, // 类型,0 文本,1 音频 var bookUrlPattern: String? = null, // 详情页url正则 var customOrder: Int = 0, // 手动排序编号 var enabled: Boolean = true, // 是否启用 diff --git a/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt b/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt index 6d4eda465..a29096e57 100644 --- a/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt +++ b/app/src/main/java/io/legado/app/help/storage/ImportOldData.kt @@ -3,6 +3,7 @@ package io.legado.app.help.storage import android.content.Context import android.net.Uri import androidx.documentfile.provider.DocumentFile +import io.legado.app.constant.BookType import io.legado.app.data.appDb import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookSource @@ -123,8 +124,9 @@ object ImportOldData { book.origin = jsonItem.readString("$.tag") ?: "" book.originName = jsonItem.readString("$.bookInfoBean.origin") ?: "" book.author = jsonItem.readString("$.bookInfoBean.author") ?: "" - book.type = - if (jsonItem.readString("$.bookInfoBean.bookSourceType") == "AUDIO") 1 else 0 + val local = if (book.origin == "loc_book") BookType.local else 0 + book.type = local or + if (jsonItem.readString("$.bookInfoBean.bookSourceType") == "AUDIO") BookType.audio else BookType.text book.tocUrl = jsonItem.readString("$.bookInfoBean.chapterUrl") ?: book.bookUrl book.coverUrl = jsonItem.readString("$.bookInfoBean.coverUrl") book.customCoverUrl = jsonItem.readString("$.customCoverPath") diff --git a/app/src/main/java/io/legado/app/help/storage/Restore.kt b/app/src/main/java/io/legado/app/help/storage/Restore.kt index 2290d25d5..ecab8e71a 100644 --- a/app/src/main/java/io/legado/app/help/storage/Restore.kt +++ b/app/src/main/java/io/legado/app/help/storage/Restore.kt @@ -16,6 +16,7 @@ import io.legado.app.help.LauncherIconHelp import io.legado.app.help.config.LocalConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.config.ThemeConfig +import io.legado.app.help.upType import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main @@ -65,6 +66,9 @@ object Restore { suspend fun restoreDatabase(path: String = Backup.backupPath) { withContext(IO) { fileToListT(path, "bookshelf.json")?.let { + it.forEach { book -> + book.upType() + } appDb.bookDao.insert(*it.toTypedArray()) } fileToListT(path, "bookmark.json")?.let { diff --git a/app/src/main/java/io/legado/app/model/BookCover.kt b/app/src/main/java/io/legado/app/model/BookCover.kt index c91d6cc0b..bf042e569 100644 --- a/app/src/main/java/io/legado/app/model/BookCover.kt +++ b/app/src/main/java/io/legado/app/model/BookCover.kt @@ -32,9 +32,13 @@ object BookCover { private set lateinit var defaultDrawable: Drawable private set - var coverRuleConfig: CoverRuleConfig = - GSON.fromJsonObject(CacheManager.get(coverRuleConfigKey)).getOrNull() - ?: DefaultData.coverRuleConfig + val coverRuleConfig: CoverRuleConfig + get() { + return GSON.fromJsonObject(CacheManager.get(coverRuleConfigKey)) + .getOrNull() + ?: DefaultData.coverRuleConfig + } + init { upDefaultCover() @@ -132,14 +136,12 @@ object BookCover { } fun saveCoverRuleConfig(config: CoverRuleConfig) { - coverRuleConfig = config val json = GSON.toJson(config) CacheManager.put(coverRuleConfigKey, json) } fun delCoverRuleConfig() { CacheManager.delete(coverRuleConfigKey) - coverRuleConfig = DefaultData.coverRuleConfig } data class CoverRuleConfig( diff --git a/app/src/main/java/io/legado/app/model/CacheBook.kt b/app/src/main/java/io/legado/app/model/CacheBook.kt index 2861b485b..f3ea48281 100644 --- a/app/src/main/java/io/legado/app/model/CacheBook.kt +++ b/app/src/main/java/io/legado/app/model/CacheBook.kt @@ -10,6 +10,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookSource import io.legado.app.exception.ConcurrentException import io.legado.app.help.BookHelp +import io.legado.app.help.isLocal import io.legado.app.model.webBook.WebBook import io.legado.app.service.CacheBookService import io.legado.app.utils.postEvent @@ -59,7 +60,7 @@ object CacheBook { } fun start(context: Context, book: Book, start: Int, end: Int) { - if (!book.isLocalBook()) { + if (!book.isLocal) { context.startService { action = IntentAction.start putExtra("bookUrl", book.bookUrl) diff --git a/app/src/main/java/io/legado/app/model/Debug.kt b/app/src/main/java/io/legado/app/model/Debug.kt index c2b3e70c6..2c4e4eaa3 100644 --- a/app/src/main/java/io/legado/app/model/Debug.kt +++ b/app/src/main/java/io/legado/app/model/Debug.kt @@ -240,7 +240,7 @@ object Debug { .onSuccess { log(debugSource, "︽详情页解析完成") log(debugSource, showTime = false) - if (book.type != BookType.file) { + if (book.type and BookType.webFile == 0) { tocDebug(scope, bookSource, book) } else { log(debugSource, "≡文件类书源跳过解析目录", state = 1000) diff --git a/app/src/main/java/io/legado/app/model/ReadBook.kt b/app/src/main/java/io/legado/app/model/ReadBook.kt index d1e4a1a43..bd5036b3f 100644 --- a/app/src/main/java/io/legado/app/model/ReadBook.kt +++ b/app/src/main/java/io/legado/app/model/ReadBook.kt @@ -1,7 +1,6 @@ package io.legado.app.model import io.legado.app.constant.AppLog -import io.legado.app.constant.BookType import io.legado.app.data.appDb import io.legado.app.data.entities.* import io.legado.app.help.AppWebDav @@ -10,6 +9,7 @@ import io.legado.app.help.ContentProcessor import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.isLocal import io.legado.app.model.webBook.WebBook import io.legado.app.service.BaseReadAloudService import io.legado.app.ui.book.read.page.entities.TextChapter @@ -50,7 +50,7 @@ object ReadBook : CoroutineScope by MainScope() { chapterSize = appDb.bookChapterDao.getChapterCount(book.bookUrl) durChapterIndex = book.durChapterIndex durChapterPos = book.durChapterPos - isLocalBook = book.origin == BookType.local + isLocalBook = book.isLocal clearTextChapter() callBack?.upMenuView() callBack?.upPageAnim() @@ -73,7 +73,7 @@ object ReadBook : CoroutineScope by MainScope() { } fun upWebBook(book: Book) { - if (book.origin == BookType.local) { + if (book.isLocal) { bookSource = null } else { appDb.bookSourceDao.getBookSource(book.origin)?.let { @@ -290,7 +290,7 @@ object ReadBook : CoroutineScope by MainScope() { return } book?.let { book -> - if (book.isLocalBook()) return + if (book.isLocal) return if (addLoading(index)) { Coroutine.async { appDb.bookChapterDao.getChapter(book.bookUrl, index)?.let { chapter -> @@ -318,7 +318,7 @@ object ReadBook : CoroutineScope by MainScope() { if (book != null && bookSource != null) { CacheBook.getOrCreate(bookSource, book).download(scope, chapter) } else if (book != null) { - val msg = if (book.isLocalBook()) "无内容" else "没有书源" + val msg = if (book.isLocal) "无内容" else "没有书源" contentLoadFinish( book, chapter, "加载正文失败\n$msg", resetPageOffset = resetPageOffset ) { 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 97e7e2cfe..0b1b9e0d9 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 @@ -14,17 +14,19 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.TocEmptyException +import io.legado.app.help.AppWebDav import io.legado.app.help.BookHelp import io.legado.app.help.config.AppConfig -import io.legado.app.help.AppWebDav +import io.legado.app.help.isEpub +import io.legado.app.help.isUmd import io.legado.app.lib.webdav.WebDav import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.utils.* +import kotlinx.coroutines.runBlocking import org.jsoup.nodes.Entities import splitties.init.appCtx import java.io.* import java.util.regex.Pattern -import kotlinx.coroutines.runBlocking /** * 书籍文件导入 目录正文解析 @@ -65,10 +67,10 @@ object LocalBook { @Throws(Exception::class) fun getChapterList(book: Book): ArrayList { val chapters = when { - book.isEpub() -> { + book.isEpub -> { EpubFile.getChapterList(book) } - book.isUmd() -> { + book.isUmd -> { UmdFile.getChapterList(book) } else -> { @@ -89,10 +91,10 @@ object LocalBook { fun getContent(book: Book, chapter: BookChapter): String? { val content = try { when { - book.isEpub() -> { + book.isEpub -> { EpubFile.getContent(book, chapter) } - book.isUmd() -> { + book.isUmd -> { UmdFile.getContent(book, chapter) } else -> { @@ -146,6 +148,7 @@ object LocalBook { if (book == null) { val nameAuthor = analyzeNameAuthor(fileName) book = Book( + type = BookType.text and BookType.local, bookUrl = bookUrl, name = nameAuthor.first, author = nameAuthor.second, @@ -158,8 +161,8 @@ object LocalBook { latestChapterTime = updateTime, order = appDb.bookDao.minOrder - 1 ) - if (book.isEpub()) EpubFile.upBookInfo(book) - if (book.isUmd()) UmdFile.upBookInfo(book) + if (book.isEpub) EpubFile.upBookInfo(book) + if (book.isUmd) UmdFile.upBookInfo(book) appDb.bookDao.insert(book) } else { //已有书籍说明是更新,删除原有目录 @@ -304,22 +307,20 @@ object LocalBook { //下载book.remoteUrl对应的远程文件并更新bookUrl 返回inputStream private fun downloadRemoteBook(localBook: Book): InputStream? { - if (localBook.origin == BookType.local) return null //webDav::${http} - val webDavUrl = localBook.origin.split("::").getOrNull(1) - webDavUrl ?: return null + if (!localBook.origin.startsWith(BookType.webDavTag)) return null + val webDavUrl = localBook.origin.substring(8) + if (webDavUrl.isBlank()) return null try { val uri = AppWebDav.authorization?.let { val webdav = WebDav(webDavUrl, it) runBlocking { - webdav.downloadInputStream().let { inputStream -> - saveBookFile(inputStream, localBook.originName) - } + saveBookFile(webdav.downloadInputStream(), localBook.originName) } } return uri?.let { localBook.bookUrl = if (it.isContentScheme()) it.toString() - else it.path!! + else it.path!! localBook.save() it.inputStream(appCtx) } diff --git a/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt b/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt index d7b87d8b3..63c5b3249 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookInfo.kt @@ -137,7 +137,7 @@ object BookInfo { Debug.log(bookSource.bookSourceUrl, "└${e.localizedMessage}") DebugLog.e("获取封面出错", e) } - if (book.type != BookType.file) { + if (book.type and BookType.webFile == 0) { coroutineContext.ensureActive() Debug.log(bookSource.bookSourceUrl, "┌获取目录链接") book.tocUrl = analyzeRule.getString(infoRule.tocUrl, isUrl = true) diff --git a/app/src/main/java/io/legado/app/model/webBook/BookList.kt b/app/src/main/java/io/legado/app/model/webBook/BookList.kt index e351ee3f3..5bb5e8935 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookList.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookList.kt @@ -7,6 +7,7 @@ import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.rule.BookListRule import io.legado.app.exception.NoStackTraceException import io.legado.app.help.BookHelp +import io.legado.app.help.getBookType import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeUrl @@ -138,7 +139,7 @@ object BookList { book.origin = bookSource.bookSourceUrl book.originName = bookSource.bookSourceName book.originOrder = bookSource.customOrder - book.type = bookSource.bookSourceType + book.type = bookSource.getBookType() analyzeRule.ruleData = book BookInfo.analyzeBookInfo( book, @@ -173,9 +174,9 @@ object BookList { ruleLastChapter: List ): SearchBook? { val searchBook = SearchBook(variable = variable) + searchBook.type = bookSource.getBookType() searchBook.origin = bookSource.bookSourceUrl searchBook.originName = bookSource.bookSourceName - searchBook.type = bookSource.bookSourceType searchBook.originOrder = bookSource.customOrder analyzeRule.ruleData = searchBook analyzeRule.setContent(item) 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 f80a4e0a7..d44726a28 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 @@ -6,6 +6,7 @@ import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.exception.NoStackTraceException import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.getBookType import io.legado.app.help.http.StrResponse import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeUrl @@ -134,7 +135,7 @@ object WebBook { book: Book, canReName: Boolean = true, ): Book { - book.type = bookSource.bookSourceType + book.type = bookSource.getBookType() if (!book.infoHtml.isNullOrEmpty()) { BookInfo.analyzeBookInfo( bookSource = bookSource, @@ -189,7 +190,7 @@ object WebBook { bookSource: BookSource, book: Book, ): Result> { - book.type = bookSource.bookSourceType + book.type = bookSource.getBookType() return kotlin.runCatching { if (book.bookUrl == book.tocUrl && !book.tocHtml.isNullOrEmpty()) { BookChapterList.analyzeChapterList( diff --git a/app/src/main/java/io/legado/app/service/CheckSourceService.kt b/app/src/main/java/io/legado/app/service/CheckSourceService.kt index 868c92d62..d34c83168 100644 --- a/app/src/main/java/io/legado/app/service/CheckSourceService.kt +++ b/app/src/main/java/io/legado/app/service/CheckSourceService.kt @@ -6,7 +6,7 @@ import com.script.ScriptException import io.legado.app.R import io.legado.app.base.BaseService import io.legado.app.constant.AppConst -import io.legado.app.constant.BookType +import io.legado.app.constant.BookSourceType import io.legado.app.constant.EventBus import io.legado.app.constant.IntentAction import io.legado.app.data.appDb @@ -214,7 +214,7 @@ class CheckSourceService : BaseService() { } //校验目录 if (CheckSource.checkCategory && - source.bookSourceType != BookType.file + source.bookSourceType != BookSourceType.file ) { val toc = WebBook.getChapterListAwait(source, mBook).getOrThrow() val nextChapterUrl = toc.getOrNull(1)?.url ?: toc.first().url diff --git a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt index 3ef09cbb2..9664348f4 100644 --- a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt @@ -12,7 +12,6 @@ import androidx.activity.viewModels import androidx.compose.runtime.mutableStateOf import io.legado.app.R import io.legado.app.base.VMBaseActivity -import io.legado.app.constant.BookType import io.legado.app.constant.EventBus import io.legado.app.constant.Status import io.legado.app.constant.Theme @@ -22,6 +21,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookSource import io.legado.app.databinding.ActivityAudioPlayBinding import io.legado.app.help.config.AppConfig +import io.legado.app.help.isAudio import io.legado.app.lib.dialogs.alert import io.legado.app.model.AudioPlay import io.legado.app.model.BookCover @@ -207,7 +207,7 @@ class AudioPlayActivity : get() = AudioPlay.book override fun changeTo(source: BookSource, book: Book, toc: List) { - if (book.type == BookType.audio) { + if (book.isAudio) { viewModel.changeTo(source, book, toc) } else { AudioPlay.stop(this) diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt index 2976801ed..cc8be4b35 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt @@ -10,7 +10,6 @@ import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst.charsets -import io.legado.app.constant.BookType import io.legado.app.constant.EventBus import io.legado.app.constant.PreferKey import io.legado.app.data.appDb @@ -21,6 +20,7 @@ import io.legado.app.databinding.ActivityCacheBookBinding import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.help.BookHelp import io.legado.app.help.config.AppConfig +import io.legado.app.help.isAudio import io.legado.app.lib.dialogs.SelectItem import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.selector @@ -166,7 +166,7 @@ class CacheActivity : VMBaseActivity() else -> appDb.bookDao.flowByGroup(groupId) }.conflate().map { books -> val booksDownload = books.filter { - it.type == BookType.default || it.type == BookType.image + !it.isAudio } when (getPrefInt(PreferKey.bookshelfSort)) { 1 -> booksDownload.sortedByDescending { it.latestChapterTime } diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt index 10d31a4cb..29a03f447 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt @@ -10,6 +10,7 @@ import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.data.entities.Book import io.legado.app.databinding.ItemDownloadBinding +import io.legado.app.help.isLocal import io.legado.app.model.CacheBook import io.legado.app.utils.gone import io.legado.app.utils.visible @@ -33,7 +34,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : if (payloads.isEmpty()) { tvName.text = item.name tvAuthor.text = context.getString(R.string.author_show, item.getRealAuthor()) - if (item.isLocalBook()) { + if (item.isLocal) { tvDownload.setText(R.string.local_book) } else { val cs = cacheChapters[item.bookUrl] @@ -49,7 +50,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : } } } else { - if (item.isLocalBook()) { + if (item.isLocal) { tvDownload.setText(R.string.local_book) } else { val cacheSize = cacheChapters[item.bookUrl]?.size ?: 0 @@ -84,7 +85,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : } private fun upDownloadIv(iv: ImageView, book: Book) { - if (book.isLocalBook()) { + if (book.isLocal) { iv.gone() } else { iv.visible() 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 b8571b3e3..f5a579200 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 @@ -2,7 +2,6 @@ package io.legado.app.ui.book.info import android.annotation.SuppressLint import android.content.Intent -import android.net.Uri import android.os.Bundle import android.view.Menu import android.view.MenuItem @@ -12,7 +11,6 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import io.legado.app.R import io.legado.app.base.VMBaseActivity -import io.legado.app.constant.BookType import io.legado.app.constant.EventBus import io.legado.app.constant.Theme import io.legado.app.data.appDb @@ -22,6 +20,9 @@ import io.legado.app.data.entities.BookSource import io.legado.app.databinding.ActivityBookInfoBinding import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.help.config.AppConfig +import io.legado.app.help.isAudio +import io.legado.app.help.isLocal +import io.legado.app.help.isLocalTxt import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.bottomBackground @@ -132,9 +133,9 @@ class BookInfoActivity : menu.findItem(R.id.menu_can_update)?.isVisible = viewModel.bookSource != null menu.findItem(R.id.menu_split_long_chapter)?.isVisible = - viewModel.bookData.value?.isLocalTxt() ?: false + viewModel.bookData.value?.isLocalTxt ?: false menu.findItem(R.id.menu_upload)?.isVisible = - viewModel.bookData.value?.isLocalBook() ?: false + viewModel.bookData.value?.isLocal ?: false return super.onMenuOpened(featureId, menu) } @@ -161,7 +162,7 @@ class BookInfoActivity : R.id.menu_refresh -> { upLoading(true) viewModel.bookData.value?.let { - if (it.isLocalBook()) { + if (it.isLocal) { it.tocUrl = "" } viewModel.loadBookInfo(it, false) @@ -437,7 +438,7 @@ class BookInfoActivity : @SuppressLint("InflateParams") private fun deleteBook() { viewModel.bookData.value?.let { - if (it.isLocalBook()) { + if (it.isLocal) { alert( titleResource = R.string.sure, messageResource = R.string.sure_del @@ -490,8 +491,8 @@ class BookInfoActivity : } private fun startReadActivity(book: Book) { - when (book.type) { - BookType.audio -> readBookResult.launch( + when { + book.isAudio -> readBookResult.launch( Intent(this, AudioPlayActivity::class.java) .putExtra("bookUrl", book.bookUrl) .putExtra("inBookshelf", viewModel.inBookshelf) diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt index c225a8882..7fcf16f7d 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt @@ -16,6 +16,7 @@ import io.legado.app.data.entities.BookSource import io.legado.app.exception.NoStackTraceException import io.legado.app.help.BookHelp import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.isLocal import io.legado.app.model.BookCover import io.legado.app.model.ReadBook import io.legado.app.model.analyzeRule.AnalyzeRule @@ -33,7 +34,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { var bookSource: BookSource? = null private var changeSourceCoroutine: Coroutine<*>? = null val isImportBookOnLine: Boolean - get() = (bookSource?.bookSourceType ?: BookType.local) == BookType.file + get() = (bookSource?.bookSourceType ?: BookType.local) == BookType.webFile fun initData(intent: Intent) { execute { @@ -75,7 +76,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { execute { bookData.postValue(book) upCoverByRule(book) - bookSource = if (book.isLocalBook()) null else + bookSource = if (book.isLocal) null else appDb.bookSourceDao.getBookSource(book.origin) if (book.tocUrl.isEmpty()) { loadBookInfo(book) @@ -112,7 +113,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { scope: CoroutineScope = viewModelScope ) { execute(scope) { - if (book.isLocalBook()) { + if (book.isLocal) { loadChapter(book, scope) } else { bookSource?.let { bookSource -> @@ -143,7 +144,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { scope: CoroutineScope = viewModelScope ) { execute(scope) { - if (book.isLocalBook()) { + if (book.isLocal) { LocalBook.getChapterList(book).let { appDb.bookDao.update(book) appDb.bookChapterDao.delByBook(book.bookUrl) @@ -277,7 +278,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { bookData.value?.let { it.delete() inBookshelf = false - if (it.isLocalBook()) { + if (it.isLocal) { LocalBook.deleteBook(it, deleteOriginal) } } diff --git a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt index c48954998..a16f70753 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt @@ -11,6 +11,9 @@ import io.legado.app.base.VMBaseActivity import io.legado.app.constant.BookType import io.legado.app.data.entities.Book import io.legado.app.databinding.ActivityBookInfoEditBinding +import io.legado.app.help.isAudio +import io.legado.app.help.isImage +import io.legado.app.help.isLocal import io.legado.app.ui.book.changecover.ChangeCoverDialog import io.legado.app.utils.* import io.legado.app.utils.viewbindingdelegate.viewBinding @@ -72,9 +75,9 @@ class BookInfoEditActivity : tieBookName.setText(book.name) tieBookAuthor.setText(book.author) spType.setSelection( - when (book.type) { - BookType.image -> 2 - BookType.audio -> 1 + when { + book.isImage -> 2 + book.isAudio -> 1 else -> 0 } ) @@ -93,10 +96,11 @@ class BookInfoEditActivity : viewModel.book?.let { book -> book.name = tieBookName.text?.toString() ?: "" book.author = tieBookAuthor.text?.toString() ?: "" + val local = if (book.isLocal) BookType.local else 0 book.type = when (spType.selectedItemPosition) { - 2 -> BookType.image - 1 -> BookType.audio - else -> BookType.default + 2 -> BookType.image or local + 1 -> BookType.audio or local + else -> BookType.text or local } val customCoverUrl = tieCoverUrl.text?.toString() book.customCoverUrl = if (customCoverUrl == book.coverUrl) null else customCoverUrl diff --git a/app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt b/app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt index 875832190..f4b7b408a 100644 --- a/app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/manage/BookAdapter.kt @@ -12,6 +12,7 @@ import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookGroup import io.legado.app.databinding.ItemArrangeBookBinding +import io.legado.app.help.isLocal import io.legado.app.lib.theme.backgroundColor import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.ItemTouchCallback @@ -53,7 +54,7 @@ class BookAdapter(context: Context, val callBack: CallBack) : tvAuthor.visibility = if (item.author.isEmpty()) View.GONE else View.VISIBLE tvGroupS.text = getGroupName(item.group) checkbox.isChecked = selectedBooks.contains(item) - if (item.isLocalBook()) { + if (item.isLocal) { tvOrigin.setText(R.string.local_book) } else { tvOrigin.text = item.originName diff --git a/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt b/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt index ff89934c1..59becf4e0 100644 --- a/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/manage/BookshelfManageViewModel.kt @@ -7,6 +7,7 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookSource import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.isLocal import io.legado.app.model.webBook.WebBook import io.legado.app.utils.toastOnUi @@ -45,7 +46,7 @@ class BookshelfManageViewModel(application: Application) : BaseViewModel(applica batchChangeSourceSize.value = books.size books.forEachIndexed { index, book -> batchChangeSourcePosition.value = index + 1 - if (book.isLocalBook()) return@forEachIndexed + if (book.isLocal) return@forEachIndexed if (book.origin == source.bookSourceUrl) return@forEachIndexed WebBook.preciseSearchAwait(this, source, book.name, book.author) .onFailure { diff --git a/app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt index 6a724470e..b53afd002 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ContentEditDialog.kt @@ -14,6 +14,7 @@ import io.legado.app.databinding.DialogContentEditBinding import io.legado.app.databinding.DialogEditTextBinding import io.legado.app.help.BookHelp import io.legado.app.help.ContentProcessor +import io.legado.app.help.isLocal import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.primaryColor import io.legado.app.model.ReadBook @@ -125,7 +126,7 @@ class ContentEditDialog : BaseDialogFragment(R.layout.dialog_content_edit) { if (reset) { content = null BookHelp.delContent(book, chapter) - if (!book.isLocalBook()) ReadBook.bookSource?.let { bookSource -> + if (!book.isLocal) ReadBook.bookSource?.let { bookSource -> WebBook.getContentAwait(bookSource, book, chapter) } } 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 7978b7ce7..5841ba80c 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 @@ -22,10 +22,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookProgress import io.legado.app.data.entities.BookSource import io.legado.app.exception.NoStackTraceException -import io.legado.app.help.AppWebDav -import io.legado.app.help.BookHelp -import io.legado.app.help.IntentData -import io.legado.app.help.TTS +import io.legado.app.help.* import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.config.ReadTipConfig @@ -248,13 +245,13 @@ class ReadBookActivity : BaseReadBookActivity(), val menu = menu val book = ReadBook.book if (menu != null && book != null) { - val onLine = !book.isLocalBook() + val onLine = !book.isLocal for (i in 0 until menu.size) { val item = menu[i] when (item.groupId) { R.id.menu_group_on_line -> item.isVisible = onLine R.id.menu_group_local -> item.isVisible = !onLine - R.id.menu_group_text -> item.isVisible = book.isLocalTxt() + R.id.menu_group_text -> item.isVisible = book.isLocalTxt else -> when (item.itemId) { R.id.menu_enable_replace -> item.isChecked = book.getUseReplaceRule() R.id.menu_re_segment -> item.isChecked = book.getReSegment() @@ -346,7 +343,7 @@ class ReadBookActivity : BaseReadBookActivity(), } R.id.menu_edit_content -> showDialogFragment(ContentEditDialog()) R.id.menu_update_toc -> ReadBook.book?.let { - if (it.isEpub()) { + if (it.isEpub) { BookHelp.clearCache(it) } loadChapterList(it) @@ -790,7 +787,7 @@ class ReadBookActivity : BaseReadBookActivity(), get() = ReadBook.book override fun changeTo(source: BookSource, book: Book, toc: List) { - if (book.type != BookType.audio) { + if (!book.isAudio) { viewModel.changeTo(book, toc) } else { ReadAloud.stop(this) @@ -986,7 +983,7 @@ class ReadBookActivity : BaseReadBookActivity(), override fun payAction() { ReadBook.book?.let { book -> - if (book.isLocalBook()) return + if (book.isLocal) return val chapter = appDb.bookChapterDao.getChapter(book.bookUrl, ReadBook.durChapterIndex) if (chapter == null) { toastOnUi("no chapter") diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index bfa935cd7..27ee29ac4 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -20,6 +20,7 @@ import io.legado.app.help.BookHelp import io.legado.app.help.ContentProcessor import io.legado.app.help.config.AppConfig import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.isLocal import io.legado.app.model.ReadAloud import io.legado.app.model.ReadBook import io.legado.app.model.analyzeRule.AnalyzeRule @@ -78,7 +79,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { } else { loadChapterList(book) } - } else if (book.isLocalBook() + } else if (book.isLocal && LocalBook.getLastModified(book).getOrDefault(0L) > book.latestChapterTime ) { loadChapterList(book) @@ -97,7 +98,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { if (!isSameBook || !BaseReadAloudService.isRun) { syncBookProgress(book) } - if (!book.isLocalBook() && ReadBook.bookSource == null) { + if (!book.isLocal && ReadBook.bookSource == null) { autoChangeSource(book.name, book.author) return } @@ -107,7 +108,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { * 加载详情页 */ private fun loadBookInfo(book: Book) { - if (book.isLocalBook()) { + if (book.isLocal) { loadChapterList(book) } else { ReadBook.bookSource?.let { source -> @@ -125,7 +126,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { * 加载目录 */ fun loadChapterList(book: Book) { - if (book.isLocalBook()) { + if (book.isLocal) { execute { LocalBook.getChapterList(book).let { book.latestChapterTime = System.currentTimeMillis() diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt index f4996dca5..77faf44be 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ImageProvider.kt @@ -13,6 +13,7 @@ import io.legado.app.exception.NoStackTraceException import io.legado.app.help.BookHelp import io.legado.app.help.config.AppConfig import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.isEpub import io.legado.app.model.ReadBook import io.legado.app.model.localBook.EpubFile import io.legado.app.utils.BitmapUtils @@ -71,7 +72,7 @@ object ImageProvider { return withContext(IO) { val vFile = BookHelp.getImage(book, src) if (!vFile.exists()) { - if (book.isEpub()) { + if (book.isEpub) { EpubFile.getImage(book, src)?.use { input -> val newFile = FileUtils.createFileIfNotExist(vFile.absolutePath) @Suppress("BlockingMethodInNonBlockingContext") diff --git a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt index 0e433b7fc..8a030dcfb 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/remote/RemoteBookViewModel.kt @@ -97,7 +97,7 @@ class RemoteBookViewModel(application: Application) : BaseViewModel(application) val downloadBookPath = RemoteBookWebDav.getRemoteBook(remoteBook) downloadBookPath?.let { val localBook = LocalBook.importFile(it) - localBook.origin = BookType.webDav + remoteBook.path + localBook.origin = BookType.webDavTag + remoteBook.path localBook.save() remoteBook.isOnBookShelf = true } diff --git a/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt b/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt index 49a6ab745..0489f15ef 100644 --- a/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt +++ b/app/src/main/java/io/legado/app/ui/book/remote/manager/RemoteBookWebDav.kt @@ -100,7 +100,7 @@ object RemoteBookWebDav : RemoteBookManager() { WebDav(putUrl, it).upload(localBookUri.path!!) } } - book.origin = BookType.webDav + putUrl + book.origin = BookType.webDavTag + putUrl book.save() return true } diff --git a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt index bc93b5311..3eca24466 100644 --- a/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt @@ -15,6 +15,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.databinding.ActivitySearchContentBinding import io.legado.app.help.BookHelp import io.legado.app.help.IntentData +import io.legado.app.help.isLocal import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.primaryTextColor @@ -193,7 +194,7 @@ class SearchContentActivity : } val isLocalBook: Boolean - get() = viewModel.book?.isLocalBook() == true + get() = viewModel.book?.isLocal == true override fun openSearchResult(searchResult: SearchResult, index: Int) { postEvent(EventBus.SEARCH_RESULT, viewModel.searchResultList as List) 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 78d66005a..381897a28 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 @@ -11,7 +11,7 @@ import com.google.android.material.tabs.TabLayout import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import io.legado.app.R import io.legado.app.base.VMBaseActivity -import io.legado.app.constant.BookType +import io.legado.app.constant.BookSourceType import io.legado.app.data.appDb import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.rule.* @@ -204,9 +204,9 @@ class BookSourceEditActivity : binding.cbIsEnableReview.isChecked = it.enabledReview ?: false binding.spType.setSelection( when (it.bookSourceType) { - BookType.file -> 3 - BookType.image -> 2 - BookType.audio -> 1 + BookSourceType.file -> 3 + BookSourceType.image -> 2 + BookSourceType.audio -> 1 else -> 0 } ) @@ -327,10 +327,10 @@ class BookSourceEditActivity : source.enabledCookieJar = binding.cbIsEnableCookie.isChecked source.enabledReview = binding.cbIsEnableReview.isChecked source.bookSourceType = when (binding.spType.selectedItemPosition) { - 3 -> BookType.file - 2 -> BookType.image - 1 -> BookType.audio - else -> BookType.default + 3 -> BookSourceType.file + 2 -> BookSourceType.image + 1 -> BookSourceType.audio + else -> BookSourceType.default } val searchRule = SearchRule() val exploreRule = ExploreRule() diff --git a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt index a6e561347..c0047bacc 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt @@ -14,6 +14,7 @@ import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.databinding.FragmentChapterListBinding import io.legado.app.help.BookHelp +import io.legado.app.help.isLocal import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.ui.widget.recycler.UpLinearLayoutManager @@ -152,7 +153,7 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragment_chapt get() = viewModel.bookData.value override val isLocalBook: Boolean - get() = viewModel.bookData.value?.isLocalBook() == true + get() = viewModel.bookData.value?.isLocal == true override fun durChapterIndex(): Int { return durChapterIndex diff --git a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt index c83f91280..57d401461 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt @@ -5,7 +5,6 @@ import androidx.lifecycle.viewModelScope import io.legado.app.base.BaseViewModel import io.legado.app.constant.AppConst import io.legado.app.constant.AppLog -import io.legado.app.constant.BookType import io.legado.app.constant.EventBus import io.legado.app.data.appDb import io.legado.app.data.entities.Book @@ -15,6 +14,7 @@ import io.legado.app.help.BookHelp import io.legado.app.help.DefaultData import io.legado.app.help.config.AppConfig import io.legado.app.help.config.LocalConfig +import io.legado.app.help.isLocal import io.legado.app.model.CacheBook import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.webBook.WebBook @@ -59,7 +59,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) { fun upToc(books: List) { execute(context = upTocPool) { books.filter { - it.origin != BookType.local && it.canUpdate + !it.isLocal && it.canUpdate }.let { addToWaitUp(it) } @@ -233,6 +233,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) { if (LocalConfig.needUpRssSources) { DefaultData.importDefaultRssSources() } + } } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterGrid.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterGrid.kt index b2c2211e0..b8b5ce81a 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterGrid.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterGrid.kt @@ -4,10 +4,10 @@ import android.content.Context import android.os.Bundle import android.view.ViewGroup import io.legado.app.base.adapter.ItemViewHolder -import io.legado.app.constant.BookType import io.legado.app.data.entities.Book import io.legado.app.databinding.ItemBookshelfGridBinding import io.legado.app.help.config.AppConfig +import io.legado.app.help.isLocal import io.legado.app.utils.invisible import splitties.views.onLongClick @@ -41,7 +41,7 @@ class BooksAdapterGrid(context: Context, private val callBack: CallBack) : } private fun upRefresh(binding: ItemBookshelfGridBinding, item: Book) { - if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) { + if (!item.isLocal && callBack.isUpdate(item.bookUrl)) { binding.bvUnread.invisible() binding.rlLoading.show() } else { diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterList.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterList.kt index 91f1173e1..c526b5b28 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterList.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksAdapterList.kt @@ -4,10 +4,10 @@ import android.content.Context import android.os.Bundle import android.view.ViewGroup import io.legado.app.base.adapter.ItemViewHolder -import io.legado.app.constant.BookType import io.legado.app.data.entities.Book import io.legado.app.databinding.ItemBookshelfListBinding import io.legado.app.help.config.AppConfig +import io.legado.app.help.isLocal import io.legado.app.utils.invisible import splitties.views.onLongClick @@ -47,7 +47,7 @@ class BooksAdapterList(context: Context, private val callBack: CallBack) : } private fun upRefresh(binding: ItemBookshelfListBinding, item: Book) { - if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) { + if (!item.isLocal && callBack.isUpdate(item.bookUrl)) { binding.bvUnread.invisible() binding.rlLoading.show() } else { diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt index a7f2002aa..1bbd3b99b 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style1/books/BooksFragment.kt @@ -10,11 +10,15 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import io.legado.app.R import io.legado.app.base.BaseFragment -import io.legado.app.constant.* +import io.legado.app.constant.AppConst +import io.legado.app.constant.AppLog +import io.legado.app.constant.EventBus +import io.legado.app.constant.PreferKey import io.legado.app.data.appDb import io.legado.app.data.entities.Book import io.legado.app.databinding.FragmentBooksBinding import io.legado.app.help.config.AppConfig +import io.legado.app.help.isAudio import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.book.audio.AudioPlayActivity @@ -187,8 +191,8 @@ class BooksFragment() : BaseFragment(R.layout.fragment_books), } override fun open(book: Book) { - when (book.type) { - BookType.audio -> + when { + book.isAudio -> startActivity { putExtra("bookUrl", book.bookUrl) } diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterGrid.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterGrid.kt index d62700156..cbe30a7df 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterGrid.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterGrid.kt @@ -5,12 +5,12 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import io.legado.app.constant.BookType import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookGroup import io.legado.app.databinding.ItemBookshelfGridBinding import io.legado.app.databinding.ItemBookshelfGridGroupBinding import io.legado.app.help.config.AppConfig +import io.legado.app.help.isLocal import io.legado.app.utils.invisible import splitties.views.onLongClick @@ -111,7 +111,7 @@ class BooksAdapterGrid(context: Context, callBack: CallBack) : } private fun upRefresh(binding: ItemBookshelfGridBinding, item: Book) { - if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) { + if (!item.isLocal && callBack.isUpdate(item.bookUrl)) { binding.bvUnread.invisible() binding.rlLoading.show() } else { diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterList.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterList.kt index 456f367e0..8088791b7 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterList.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BooksAdapterList.kt @@ -5,12 +5,12 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView -import io.legado.app.constant.BookType import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookGroup import io.legado.app.databinding.ItemBookshelfListBinding import io.legado.app.databinding.ItemBookshelfListGroupBinding import io.legado.app.help.config.AppConfig +import io.legado.app.help.isLocal import io.legado.app.utils.gone import io.legado.app.utils.invisible import io.legado.app.utils.visible @@ -126,7 +126,7 @@ class BooksAdapterList(context: Context, callBack: CallBack) : } private fun upRefresh(binding: ItemBookshelfListBinding, item: Book) { - if (item.origin != BookType.local && callBack.isUpdate(item.bookUrl)) { + if (!item.isLocal && callBack.isUpdate(item.bookUrl)) { binding.bvUnread.invisible() binding.rlLoading.show() } else { diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt index bb554a84e..6e4a0ea04 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt @@ -9,12 +9,16 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import io.legado.app.R -import io.legado.app.constant.* +import io.legado.app.constant.AppConst +import io.legado.app.constant.AppLog +import io.legado.app.constant.EventBus +import io.legado.app.constant.PreferKey import io.legado.app.data.appDb import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookGroup import io.legado.app.databinding.FragmentBookshelf1Binding import io.legado.app.help.config.AppConfig +import io.legado.app.help.isAudio import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.book.audio.AudioPlayActivity @@ -181,8 +185,8 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1), override fun onItemClick(position: Int) { when (val item = getItem(position)) { - is Book -> when (item.type) { - BookType.audio -> + is Book -> when { + item.isAudio -> startActivity { putExtra("bookUrl", item.bookUrl) }