From aaf262fb9dda88cbb31fb5674456793fa5f4b86e Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 14:50:26 +0800 Subject: [PATCH 01/90] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=9C=97=E8=AF=BB?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E8=87=AA=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/httpTTS.json | 62 +++++++ .../java/io/legado/app/constant/PreferKey.kt | 3 +- .../java/io/legado/app/data/AppDatabase.kt | 14 +- .../java/io/legado/app/data/dao/HttpTTSDao.kt | 28 +++ .../io/legado/app/data/entities/HttpTTS.kt | 12 ++ .../main/java/io/legado/app/help/AppConfig.kt | 3 - .../io/legado/app/help/http/HttpHelper.kt | 4 + .../io/legado/app/help/http/api/HttpGetApi.kt | 12 ++ .../legado/app/help/http/api/HttpPostApi.kt | 8 + .../app/model/analyzeRule/AnalyzeRule.kt | 2 +- .../app/model/analyzeRule/AnalyzeUrl.kt | 80 +++++++-- .../app/service/HttpReadAloudService.kt | 60 ++----- .../io/legado/app/service/help/ReadAloud.kt | 16 +- .../ui/book/changecover/ChangeCoverDialog.kt | 6 +- .../book/changesource/ChangeSourceDialog.kt | 9 +- .../app/ui/book/group/GroupManageDialog.kt | 7 +- .../app/ui/book/group/GroupSelectDialog.kt | 7 +- .../book/read/config/ReadAloudConfigDialog.kt | 35 ++-- .../ui/book/read/config/SpeakEngineDialog.kt | 161 ++++++++++++++++++ .../app/ui/book/read/config/TocRegexDialog.kt | 7 +- .../book/source/manage/GroupManageDialog.kt | 13 +- .../app/ui/replacerule/GroupManageDialog.kt | 7 +- .../ui/replacerule/edit/ReplaceEditDialog.kt | 3 +- .../ui/rss/source/manage/GroupManageDialog.kt | 5 +- .../image/photo/RotateGestureDetector.kt | 4 +- .../io/legado/app/utils/ContextExtensions.kt | 3 +- .../main/res/layout/dialog_change_cover.xml | 3 + .../main/res/layout/dialog_change_source.xml | 3 + .../main/res/layout/dialog_http_tts_edit.xml | 36 ++++ .../main/res/layout/dialog_recycler_view.xml | 16 +- .../main/res/layout/dialog_replace_edit.xml | 3 + app/src/main/res/layout/item_http_tts.xml | 37 ++++ app/src/main/res/menu/speak_engine.xml | 11 ++ app/src/main/res/values-zh-rHK/arrays.xml | 15 -- app/src/main/res/values-zh-rHK/strings.xml | 3 +- app/src/main/res/values-zh-rTW/arrays.xml | 15 -- app/src/main/res/values-zh-rTW/strings.xml | 3 +- app/src/main/res/values-zh/arrays.xml | 15 -- app/src/main/res/values-zh/strings.xml | 3 +- app/src/main/res/values/array_values.xml | 15 -- app/src/main/res/values/arrays.xml | 15 -- app/src/main/res/values/strings.xml | 3 +- app/src/main/res/xml/pref_config_aloud.xml | 15 +- 43 files changed, 571 insertions(+), 211 deletions(-) create mode 100644 app/src/main/assets/httpTTS.json create mode 100644 app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt create mode 100644 app/src/main/java/io/legado/app/data/entities/HttpTTS.kt create mode 100644 app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt create mode 100644 app/src/main/res/layout/dialog_http_tts_edit.xml create mode 100644 app/src/main/res/layout/item_http_tts.xml create mode 100644 app/src/main/res/menu/speak_engine.xml diff --git a/app/src/main/assets/httpTTS.json b/app/src/main/assets/httpTTS.json new file mode 100644 index 000000000..0d3c884f1 --- /dev/null +++ b/app/src/main/assets/httpTTS.json @@ -0,0 +1,62 @@ +[ + { + "id": 1, + "name": "度小美", + "url": "" + }, + { + "id": 2, + "name": "度小宇", + "url": "" + }, + { + "id": 3, + "name": "度逍遙", + "url": "" + }, + { + "id": 4, + "name": "度丫丫", + "url": "" + }, + { + "id": 5, + "name": "度小嬌", + "url": "" + }, + { + "id": 6, + "name": "度米朵", + "url": "" + }, + { + "id": 7, + "name": "度博文", + "url": "" + }, + { + "id": 8, + "name": "度小童", + "url": "" + }, + { + "id": 9, + "name": "度小萌", + "url": "" + }, + { + "id": 10, + "name": "百度騷男", + "url": "" + }, + { + "id": 11, + "name": "百度評書", + "url": "" + }, + { + "id": 12, + "name": "百度主持", + "url": "" + } +] \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/constant/PreferKey.kt b/app/src/main/java/io/legado/app/constant/PreferKey.kt index a4a9572bd..bf98afd11 100644 --- a/app/src/main/java/io/legado/app/constant/PreferKey.kt +++ b/app/src/main/java/io/legado/app/constant/PreferKey.kt @@ -9,10 +9,9 @@ object PreferKey { const val clickAllNext = "clickAllNext" const val hideNavigationBar = "hideNavigationBar" const val precisionSearch = "precisionSearch" - const val readAloudOnLine = "readAloudOnLine" + const val speakEngine = "speakEngine" const val readAloudByPage = "readAloudByPage" const val ttsSpeechRate = "ttsSpeechRate" - const val ttsSpeechPer = "ttsSpeechPer" const val prevKey = "prevKeyCode" const val nextKey = "nextKeyCode" const val showRss = "showRss" 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 71e6e453f..48770cefe 100644 --- a/app/src/main/java/io/legado/app/data/AppDatabase.kt +++ b/app/src/main/java/io/legado/app/data/AppDatabase.kt @@ -14,8 +14,8 @@ import io.legado.app.data.entities.* entities = [Book::class, BookGroup::class, BookSource::class, BookChapter::class, ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class, RssSource::class, Bookmark::class, RssArticle::class, RssReadRecord::class, - RssStar::class, TxtTocRule::class, ReadRecord::class], - version = 17, + RssStar::class, TxtTocRule::class, ReadRecord::class, HttpTTS::class], + version = 18, exportSchema = true ) abstract class AppDatabase : RoomDatabase() { @@ -33,7 +33,8 @@ abstract class AppDatabase : RoomDatabase() { migration_12_13, migration_13_14, migration_14_15, - migration_15_17 + migration_15_17, + migration_17_18 ) .allowMainThreadQueries() .build() @@ -94,6 +95,12 @@ abstract class AppDatabase : RoomDatabase() { database.execSQL("CREATE TABLE IF NOT EXISTS `readRecord` (`bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL, PRIMARY KEY(`bookName`))") } } + + private val migration_17_18 = object : Migration(17, 18) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("CREATE TABLE IF NOT EXISTS `httpTTS` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, PRIMARY KEY(`id`))") + } + } } abstract fun bookDao(): BookDao @@ -110,4 +117,5 @@ abstract class AppDatabase : RoomDatabase() { abstract fun cookieDao(): CookieDao abstract fun txtTocRule(): TxtTocRuleDao abstract fun readRecordDao(): ReadRecordDao + abstract fun httpTTSDao(): HttpTTSDao } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt b/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt new file mode 100644 index 000000000..971dc4896 --- /dev/null +++ b/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt @@ -0,0 +1,28 @@ +package io.legado.app.data.dao + +import androidx.lifecycle.LiveData +import androidx.room.* +import io.legado.app.data.entities.HttpTTS + +@Dao +interface HttpTTSDao { + + @get:Query("select * from httpTTS order by name") + val all: List + + @Query("select * from httpTTS order by name") + fun observeAll(): LiveData> + + @Query("select * from httpTTS where id = :id") + fun get(id: Long): HttpTTS? + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insert(vararg httpTTS: HttpTTS) + + @Delete + fun delete(vararg httpTTS: HttpTTS) + + @Update + fun update(vararg httpTTS: HttpTTS) + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/entities/HttpTTS.kt b/app/src/main/java/io/legado/app/data/entities/HttpTTS.kt new file mode 100644 index 000000000..2e5ad7df0 --- /dev/null +++ b/app/src/main/java/io/legado/app/data/entities/HttpTTS.kt @@ -0,0 +1,12 @@ +package io.legado.app.data.entities + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity(tableName = "httpTTS") +data class HttpTTS( + @PrimaryKey + val id: Long = System.currentTimeMillis(), + var name: String = "", + var url: String = "" +) \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/AppConfig.kt b/app/src/main/java/io/legado/app/help/AppConfig.kt index 8157af173..aebc822b7 100644 --- a/app/src/main/java/io/legado/app/help/AppConfig.kt +++ b/app/src/main/java/io/legado/app/help/AppConfig.kt @@ -81,9 +81,6 @@ object AppConfig { App.INSTANCE.putPrefInt(PreferKey.ttsSpeechRate, value) } - val ttsSpeechPer: String - get() = App.INSTANCE.getPrefString(PreferKey.ttsSpeechPer) ?: "0" - val clickAllNext: Boolean get() = App.INSTANCE.getPrefBoolean(PreferKey.clickAllNext, false) var chineseConverterType: Int diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index 51103b52e..9aa17e9c1 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -83,6 +83,10 @@ object HttpHelper { return getRetrofit(baseUrl, encode).create(T::class.java) } + inline fun getBytesApiService(baseUrl: String): T { + return getByteRetrofit(baseUrl).create(T::class.java) + } + fun getRetrofit(baseUrl: String, encode: String? = null): Retrofit { return Retrofit.Builder().baseUrl(baseUrl) //增加返回值为字符串的支持(以实体类返回) diff --git a/app/src/main/java/io/legado/app/help/http/api/HttpGetApi.kt b/app/src/main/java/io/legado/app/help/http/api/HttpGetApi.kt index 924361489..7138c8c20 100644 --- a/app/src/main/java/io/legado/app/help/http/api/HttpGetApi.kt +++ b/app/src/main/java/io/legado/app/help/http/api/HttpGetApi.kt @@ -32,6 +32,12 @@ interface HttpGetApi { @HeaderMap headers: Map ): Call + @GET + fun getByte( + @Url url: String, + @HeaderMap headers: Map + ): Call + @GET fun getMap( @Url url: String, @@ -46,6 +52,12 @@ interface HttpGetApi { @HeaderMap headers: Map ): Call + @GET + suspend fun getByteAsync( + @Url url: String, + @HeaderMap headers: Map + ): Response + @GET suspend fun getMapByteAsync( @Url url: String, diff --git a/app/src/main/java/io/legado/app/help/http/api/HttpPostApi.kt b/app/src/main/java/io/legado/app/help/http/api/HttpPostApi.kt index 9634b5b79..170894390 100644 --- a/app/src/main/java/io/legado/app/help/http/api/HttpPostApi.kt +++ b/app/src/main/java/io/legado/app/help/http/api/HttpPostApi.kt @@ -49,4 +49,12 @@ interface HttpPostApi { @FieldMap(encoded = true) fieldMap: Map, @HeaderMap headers: Map ): Response + + @POST + suspend fun postBodyByteAsync( + @Url url: String, + @Body body: RequestBody, + @HeaderMap headers: Map + ): Response + } diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt index 9b1e7d3b0..271eb5f68 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeRule.kt @@ -609,7 +609,7 @@ class AnalyzeRule(var book: BaseBook? = null) : JsExtensions { */ override fun ajax(urlStr: String): String? { return try { - val analyzeUrl = AnalyzeUrl(urlStr, null, null, null, baseUrl, book) + val analyzeUrl = AnalyzeUrl(urlStr, baseUrl = baseUrl, book = book) val call = analyzeUrl.getResponse(urlStr) val response = call.execute() response.body() diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 9cbf64f8f..2ed80701b 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -34,6 +34,8 @@ class AnalyzeUrl( var ruleUrl: String, key: String? = null, page: Int? = null, + speakText: String? = null, + speakSpeed: Int? = null, headerMapF: Map? = null, baseUrl: String? = null, book: BaseBook? = null, @@ -63,13 +65,19 @@ class AnalyzeUrl( } headerMapF?.let { headerMap.putAll(it) } //替换参数 - analyzeJs(key, page, book) - replaceKeyPageJs(key, page, book) + analyzeJs(key, page, speakText, speakSpeed, book) + replaceKeyPageJs(key, page, speakText, speakSpeed, book) //处理URL initUrl() } - private fun analyzeJs(key: String?, page: Int?, book: BaseBook?) { + private fun analyzeJs( + key: String?, + page: Int?, + speakText: String?, + speakSpeed: Int?, + book: BaseBook? + ) { val ruleList = arrayListOf() var start = 0 var tmp: String @@ -96,11 +104,13 @@ class AnalyzeUrl( when { ruleStr.startsWith("") -> { ruleStr = ruleStr.substring(4, ruleStr.lastIndexOf("<")) - ruleUrl = evalJS(ruleStr, ruleUrl, page, key, book) as String + ruleUrl = + evalJS(ruleStr, ruleUrl, page, key, speakText, speakSpeed, book) as String } ruleStr.startsWith("@js", true) -> { ruleStr = ruleStr.substring(4) - ruleUrl = evalJS(ruleStr, ruleUrl, page, key, book) as String + ruleUrl = + evalJS(ruleStr, ruleUrl, page, key, speakText, speakSpeed, book) as String } else -> ruleUrl = ruleStr.replace("@result", ruleUrl) } @@ -110,7 +120,13 @@ class AnalyzeUrl( /** * 替换关键字,页数,JS */ - private fun replaceKeyPageJs(key: String?, page: Int?, book: BaseBook?) { + private fun replaceKeyPageJs( + key: String?, + page: Int?, + speakText: String?, + speakSpeed: Int?, + book: BaseBook? + ) { //page page?.let { val matcher = pagePattern.matcher(ruleUrl) @@ -132,6 +148,8 @@ class AnalyzeUrl( simpleBindings["baseUrl"] = baseUrl simpleBindings["page"] = page simpleBindings["key"] = key + simpleBindings["speakText"] = speakText + simpleBindings["speakSpeed"] = speakSpeed simpleBindings["book"] = book val expMatcher = EXP_PATTERN.matcher(ruleUrl) while (expMatcher.find()) { @@ -242,12 +260,16 @@ class AnalyzeUrl( result: Any?, page: Int?, key: String?, + speakText: String?, + speakSpeed: Int?, book: BaseBook? ): Any { val bindings = SimpleBindings() bindings["java"] = this bindings["page"] = page bindings["key"] = key + bindings["speakText"] = speakText + bindings["speakSpeed"] = speakSpeed bindings["book"] = book bindings["result"] = result bindings["baseUrl"] = baseUrl @@ -332,23 +354,53 @@ class AnalyzeUrl( val cookie = CookieStore.getCookie(tag) NetworkUtils.getBaseUrl(url)?.let { val regex: Any - if(it.lastIndexOf(".") != it.indexOf(".")) { - regex = it.substring(it.indexOf(".")+1).toRegex() + regex = if (it.lastIndexOf(".") != it.indexOf(".")) { + it.substring(it.indexOf(".") + 1).toRegex() } else { - regex = it.substring(it.lastIndexOf("/")+1).toRegex() + it.substring(it.lastIndexOf("/") + 1).toRegex() } - if(regex.containsMatchIn(tag)) { + if (regex.containsMatchIn(tag)) { if (cookie.isNotEmpty()) { headerMap["Cookie"] += cookie } } } - headerMap[UA_NAME] = headerMap[UA_NAME] ?:userAgent - if(fieldMap.isEmpty()) { - return HttpHelper.getBytes(url, mapOf(), headerMap) + headerMap[UA_NAME] = headerMap[UA_NAME] ?: userAgent + return if (fieldMap.isEmpty()) { + HttpHelper.getBytes(url, mapOf(), headerMap) } else { - return HttpHelper.getBytes(url, fieldMap, headerMap) + HttpHelper.getBytes(url, fieldMap, headerMap) + } + } + + @Throws(Exception::class) + suspend fun getResponseBytes(tag: String? = null): ByteArray? { + if (tag != null) { + val cookie = CookieStore.getCookie(tag) + if (cookie.isNotEmpty()) { + headerMap["Cookie"] = cookie + } + } + val response = when { + method == RequestMethod.POST -> { + if (fieldMap.isNotEmpty()) { + HttpHelper + .getBytesApiService(baseUrl) + .postMapByteAsync(url, fieldMap, headerMap) + } else { + HttpHelper + .getBytesApiService(baseUrl) + .postBodyByteAsync(url, requestBody!!, headerMap) + } + } + fieldMap.isEmpty() -> HttpHelper + .getBytesApiService(baseUrl) + .getByteAsync(url, headerMap) + else -> HttpHelper + .getBytesApiService(baseUrl) + .getMapByteAsync(url, fieldMap, headerMap) } + return response.body() } data class UrlOption( diff --git a/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt b/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt index c70c06388..4fe576dcf 100644 --- a/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt +++ b/app/src/main/java/io/legado/app/service/HttpReadAloudService.kt @@ -7,8 +7,8 @@ import io.legado.app.constant.EventBus import io.legado.app.help.AppConfig import io.legado.app.help.IntentHelp import io.legado.app.help.coroutine.Coroutine -import io.legado.app.help.http.HttpHelper -import io.legado.app.help.http.api.HttpPostApi +import io.legado.app.model.analyzeRule.AnalyzeUrl +import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadBook import io.legado.app.utils.FileUtils import io.legado.app.utils.LogUtils @@ -17,7 +17,6 @@ import kotlinx.coroutines.isActive import java.io.File import java.io.FileDescriptor import java.io.FileInputStream -import java.net.URLEncoder class HttpReadAloudService : BaseReadAloudService(), MediaPlayer.OnPreparedListener, @@ -31,7 +30,7 @@ class HttpReadAloudService : BaseReadAloudService(), override fun onCreate() { super.onCreate() - ttsFolder = cacheDir.absolutePath + File.separator + "bdTts" + ttsFolder = externalCacheDir!!.absolutePath + File.separator + "httpTTS" mediaPlayer.setOnErrorListener(this) mediaPlayer.setOnPreparedListener(this) mediaPlayer.setOnCompletionListener(this) @@ -72,19 +71,21 @@ class HttpReadAloudService : BaseReadAloudService(), FileUtils.deleteFile(ttsFolder) for (index in 0 until contentList.size) { if (isActive) { - val bytes = HttpHelper.getByteRetrofit("http://tts.baidu.com") - .create(HttpPostApi::class.java) - .postMapByteAsync( - "http://tts.baidu.com/text2audio", - getAudioBody(contentList[index]), mapOf() - ).body() - if (bytes != null && isActive) { - val file = getSpeakFile(index) - file.writeBytes(bytes) - if (index == nowSpeak) { - @Suppress("BlockingMethodInNonBlockingContext") - val fis = FileInputStream(file) - playAudio(fis.fd) + ReadAloud.httpTTS?.let { + AnalyzeUrl( + it.url, + speakText = contentList[index], + speakSpeed = AppConfig.ttsSpeechRate + ).getResponseBytes()?.let { bytes -> + if (isActive) { + val file = getSpeakFile(index) + file.writeBytes(bytes) + if (index == nowSpeak) { + @Suppress("BlockingMethodInNonBlockingContext") + val fis = FileInputStream(file) + playAudio(fis.fd) + } + } } } } else { @@ -113,31 +114,6 @@ class HttpReadAloudService : BaseReadAloudService(), return FileUtils.createFileIfNotExist("${ttsFolder}${File.separator}${index}.mp3") } - private fun getAudioBody(content: String): Map { - return mapOf( - Pair("tex", encodeTwo(content)), - Pair("spd", ((AppConfig.ttsSpeechRate + 5) / 10 + 4).toString()), - Pair("per", AppConfig.ttsSpeechPer), - Pair("cuid", "baidu_speech_demo"), - Pair("idx", "1"), - Pair("cod", "2"), - Pair("lan", "zh"), - Pair("ctp", "1"), - Pair("pdt", "1"), - Pair("vol", "5"), - Pair("pit", "5"), - Pair("_res_tag_", "audio") - ) - } - - private fun encodeTwo(content: String): String { - return try { - URLEncoder.encode(URLEncoder.encode(content, "UTF-8"), "UTF-8") - } catch (e: Exception) { - " " - } - } - override fun pauseReadAloud(pause: Boolean) { super.pauseReadAloud(pause) mediaPlayer.pause() diff --git a/app/src/main/java/io/legado/app/service/help/ReadAloud.kt b/app/src/main/java/io/legado/app/service/help/ReadAloud.kt index b5c12a965..c7a812b8c 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadAloud.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadAloud.kt @@ -5,22 +5,30 @@ import android.content.Intent import io.legado.app.App import io.legado.app.constant.IntentAction import io.legado.app.constant.PreferKey +import io.legado.app.data.entities.HttpTTS import io.legado.app.service.BaseReadAloudService import io.legado.app.service.HttpReadAloudService import io.legado.app.service.TTSReadAloudService -import io.legado.app.utils.getPrefBoolean +import io.legado.app.utils.getPrefLong object ReadAloud { - var aloudClass: Class<*> = getReadAloudClass() + private var aloudClass: Class<*> = getReadAloudClass() + var httpTTS: HttpTTS? = null - fun getReadAloudClass(): Class<*> { - return if (App.INSTANCE.getPrefBoolean(PreferKey.readAloudOnLine)) { + private fun getReadAloudClass(): Class<*> { + val spId = App.INSTANCE.getPrefLong(PreferKey.speakEngine) + httpTTS = App.db.httpTTSDao().get(spId) + return if (httpTTS != null) { HttpReadAloudService::class.java } else { TTSReadAloudService::class.java } } + fun upReadAloudClass() { + aloudClass = getReadAloudClass() + } + fun play( context: Context, title: String, diff --git a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt index 10a683227..2539e6dc9 100644 --- a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt @@ -14,7 +14,7 @@ import androidx.recyclerview.widget.GridLayoutManager import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.constant.Theme -import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.primaryColor import io.legado.app.utils.applyTint import io.legado.app.utils.getViewModel import kotlinx.android.synthetic.main.dialog_change_source.* @@ -61,7 +61,7 @@ class ChangeCoverDialog : BaseDialogFragment(), } override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { - tool_bar.setBackgroundColor(bottomBackground) + tool_bar.setBackgroundColor(primaryColor) tool_bar.setTitle(R.string.change_cover_source) viewModel.initData(arguments) initMenu() @@ -70,7 +70,7 @@ class ChangeCoverDialog : BaseDialogFragment(), private fun initMenu() { tool_bar.inflateMenu(R.menu.change_cover) - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) } diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt index a4ca4244c..d27f8b756 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt @@ -16,10 +16,9 @@ import androidx.recyclerview.widget.RecyclerView import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.constant.PreferKey -import io.legado.app.constant.Theme import io.legado.app.data.entities.Book import io.legado.app.data.entities.SearchBook -import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.applyTint import io.legado.app.utils.getPrefBoolean @@ -69,7 +68,7 @@ class ChangeSourceDialog : BaseDialogFragment(), } override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { - tool_bar.setBackgroundColor(bottomBackground) + tool_bar.setBackgroundColor(primaryColor) viewModel.initData(arguments) showTitle() initMenu() @@ -86,7 +85,7 @@ class ChangeSourceDialog : BaseDialogFragment(), private fun initMenu() { tool_bar.inflateMenu(R.menu.change_source) - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) tool_bar.menu.findItem(R.id.menu_load_toc)?.isChecked = getPrefBoolean(PreferKey.changeSourceLoadToc) @@ -143,7 +142,7 @@ class ChangeSourceDialog : BaseDialogFragment(), } else { stopMenuItem?.setIcon(R.drawable.ic_refresh_black_24dp) } - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) }) viewModel.searchBooksLiveData.observe(viewLifecycleOwner, Observer { val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it)) diff --git a/app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt index 8a02ba06f..73bdd8595 100644 --- a/app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt @@ -20,7 +20,6 @@ import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter -import io.legado.app.constant.Theme import io.legado.app.data.entities.BookGroup import io.legado.app.help.AppConfig import io.legado.app.help.ItemTouchCallback @@ -30,7 +29,7 @@ import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.yesButton import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.backgroundColor -import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.applyTint import io.legado.app.utils.getViewModel @@ -65,7 +64,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener } override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { - tool_bar.setBackgroundColor(bottomBackground) + tool_bar.setBackgroundColor(primaryColor) tool_bar.title = getString(R.string.group_manage) initData() initMenu() @@ -94,7 +93,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener tool_bar.setOnMenuItemClickListener(this) tool_bar.inflateMenu(R.menu.book_group_manage) tool_bar.menu.let { - it.applyTint(requireContext(), Theme.getTheme()) + it.applyTint(requireContext()) it.findItem(R.id.menu_group_all) .isChecked = AppConfig.bookGroupAllShow it.findItem(R.id.menu_group_local) diff --git a/app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt b/app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt index a9bf52861..df058b901 100644 --- a/app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt @@ -20,7 +20,6 @@ import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter -import io.legado.app.constant.Theme import io.legado.app.data.entities.BookGroup import io.legado.app.help.ItemTouchCallback import io.legado.app.lib.dialogs.alert @@ -29,7 +28,7 @@ import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.yesButton import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.backgroundColor -import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.applyTint import io.legado.app.utils.getViewModel @@ -81,7 +80,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener } override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { - tool_bar.setBackgroundColor(bottomBackground) + tool_bar.setBackgroundColor(primaryColor) callBack = activity as? CallBack arguments?.let { groupId = it.getInt("groupId") @@ -94,7 +93,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener private fun initView() { tool_bar.title = getString(R.string.group_select) tool_bar.inflateMenu(R.menu.book_group_manage) - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) tool_bar.menu.setGroupVisible(R.id.menu_groups, false) adapter = GroupAdapter(requireContext()) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt index 16e7a39c2..d29bf1df8 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt @@ -10,16 +10,17 @@ import android.widget.LinearLayout import androidx.fragment.app.DialogFragment import androidx.preference.ListPreference import androidx.preference.Preference +import io.legado.app.App import io.legado.app.R import io.legado.app.base.BasePreferenceFragment import io.legado.app.constant.EventBus import io.legado.app.constant.PreferKey -import io.legado.app.help.AppConfig import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.backgroundColor import io.legado.app.service.BaseReadAloudService import io.legado.app.service.help.ReadAloud import io.legado.app.ui.book.read.Help +import io.legado.app.utils.getPrefLong import io.legado.app.utils.postEvent class ReadAloudConfigDialog : DialogFragment() { @@ -62,11 +63,18 @@ class ReadAloudConfigDialog : DialogFragment() { class ReadAloudPreferenceFragment : BasePreferenceFragment(), SharedPreferences.OnSharedPreferenceChangeListener { + private val speakEngineSummary: String + get() { + val eid = App.INSTANCE.getPrefLong(PreferKey.speakEngine) + val ht = App.db.httpTTSDao().get(eid) + return ht?.name ?: getString(R.string.local_tts) + } + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.pref_config_aloud) upPreferenceSummary( - findPreference(PreferKey.ttsSpeechPer), - AppConfig.ttsSpeechPer + findPreference(PreferKey.speakEngine), + speakEngineSummary ) } @@ -85,6 +93,14 @@ class ReadAloudConfigDialog : DialogFragment() { super.onPause() } + override fun onPreferenceTreeClick(preference: Preference?): Boolean { + when (preference?.key) { + PreferKey.speakEngine -> + SpeakEngineDialog().show(childFragmentManager, "speakEngine") + } + return super.onPreferenceTreeClick(preference) + } + override fun onSharedPreferenceChanged( sharedPreferences: SharedPreferences?, key: String? @@ -95,16 +111,9 @@ class ReadAloudConfigDialog : DialogFragment() { postEvent(EventBus.MEDIA_BUTTON, false) } } - PreferKey.readAloudOnLine -> { - ReadAloud.stop(requireContext()) - ReadAloud.aloudClass = ReadAloud.getReadAloudClass() - } - PreferKey.ttsSpeechPer -> { - upPreferenceSummary( - findPreference(PreferKey.ttsSpeechPer), - AppConfig.ttsSpeechPer - ) - ReadAloud.upTtsSpeechRate(requireContext()) + PreferKey.speakEngine -> { + upPreferenceSummary(findPreference(key), speakEngineSummary) + ReadAloud.upReadAloudClass() } } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt new file mode 100644 index 000000000..261aeb20e --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt @@ -0,0 +1,161 @@ +package io.legado.app.ui.book.read.config + +import android.annotation.SuppressLint +import android.content.Context +import android.os.Bundle +import android.util.DisplayMetrics +import android.view.LayoutInflater +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.widget.Toolbar +import androidx.lifecycle.LiveData +import androidx.recyclerview.widget.LinearLayoutManager +import io.legado.app.App +import io.legado.app.R +import io.legado.app.base.BaseDialogFragment +import io.legado.app.base.adapter.ItemViewHolder +import io.legado.app.base.adapter.SimpleRecyclerAdapter +import io.legado.app.constant.PreferKey +import io.legado.app.data.entities.HttpTTS +import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.dialogs.cancelButton +import io.legado.app.lib.dialogs.customView +import io.legado.app.lib.dialogs.okButton +import io.legado.app.lib.theme.primaryColor +import io.legado.app.service.help.ReadAloud +import io.legado.app.utils.* +import kotlinx.android.synthetic.main.dialog_http_tts_edit.view.* +import kotlinx.android.synthetic.main.dialog_recycler_view.* +import kotlinx.android.synthetic.main.item_http_tts.view.* +import org.jetbrains.anko.sdk27.listeners.onClick + +class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { + + override fun onStart() { + super.onStart() + val dm = DisplayMetrics() + activity?.windowManager?.defaultDisplay?.getMetrics(dm) + dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + return inflater.inflate(R.layout.dialog_recycler_view, container) + } + + lateinit var adapter: Adapter + private var httpTTSData: LiveData>? = null + var engineId = App.INSTANCE.getPrefLong(PreferKey.speakEngine) + + override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { + initView() + initMenu() + initData() + } + + private fun initView() { + tool_bar.setBackgroundColor(primaryColor) + tool_bar.setTitle(R.string.speak_engine) + recycler_view.layoutManager = LinearLayoutManager(requireContext()) + adapter = Adapter(requireContext()) + recycler_view.adapter = adapter + tv_footer_left.setText(R.string.local_tts) + tv_footer_left.visible() + tv_footer_left.onClick { + removePref(PreferKey.speakEngine) + dismiss() + } + tv_ok.visible() + tv_ok.onClick { + putPrefLong(PreferKey.speakEngine, engineId) + dismiss() + } + tv_cancel.visible() + tv_cancel.onClick { + dismiss() + } + } + + private fun initMenu() { + tool_bar.inflateMenu(R.menu.speak_engine) + tool_bar.menu.applyTint(requireContext()) + tool_bar.setOnMenuItemClickListener(this) + } + + private fun initData() { + httpTTSData?.removeObservers(this) + httpTTSData = App.db.httpTTSDao().observeAll() + httpTTSData?.observe(this, { + adapter.setItems(it) + }) + } + + override fun onMenuItemClick(item: MenuItem?): Boolean { + when (item?.itemId) { + R.id.menu_add -> editHttpTTS() + } + return true + } + + @SuppressLint("InflateParams") + private fun editHttpTTS(v: HttpTTS? = null) { + val httpTTS = v?.copy() ?: HttpTTS() + requireContext().alert(titleResource = R.string.speak_engine) { + var rootView: View? = null + customView { + LayoutInflater.from(requireContext()) + .inflate(R.layout.dialog_http_tts_edit, null).apply { + rootView = this + tv_name.setText(httpTTS.name) + tv_url.setText(httpTTS.url) + } + } + cancelButton() + okButton { + rootView?.apply { + httpTTS.name = tv_name.text.toString() + httpTTS.url = tv_url.text.toString() + App.db.httpTTSDao().insert(httpTTS) + ReadAloud.upReadAloudClass() + } + } + }.show().applyTint() + } + + inner class Adapter(context: Context) : + SimpleRecyclerAdapter(context, R.layout.item_http_tts) { + + override fun convert(holder: ItemViewHolder, item: HttpTTS, payloads: MutableList) { + holder.itemView.apply { + cb_name.text = item.name + cb_name.isChecked = item.id == engineId + } + } + + override fun registerListener(holder: ItemViewHolder) { + holder.itemView.apply { + cb_name.onClick { + getItem(holder.layoutPosition)?.let { httpTTS -> + engineId = httpTTS.id + notifyItemRangeChanged(0, getActualItemCount()) + } + } + iv_edit.onClick { + editHttpTTS(getItem(holder.layoutPosition)) + } + iv_menu_delete.onClick { + getItem(holder.layoutPosition)?.let { httpTTS -> + App.db.httpTTSDao().delete(httpTTS) + } + } + } + } + + + } + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt index a91e8cde4..22ae62c18 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt @@ -21,7 +21,6 @@ import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter -import io.legado.app.constant.Theme import io.legado.app.data.entities.TxtTocRule import io.legado.app.help.ItemTouchCallback import io.legado.app.lib.dialogs.alert @@ -29,7 +28,7 @@ import io.legado.app.lib.dialogs.cancelButton import io.legado.app.lib.dialogs.customView import io.legado.app.lib.dialogs.okButton import io.legado.app.lib.theme.backgroundColor -import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.text.AutoCompleteTextView import io.legado.app.utils.* @@ -68,11 +67,11 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { } override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { - tool_bar.setBackgroundColor(bottomBackground) + tool_bar.setBackgroundColor(primaryColor) durRegex = arguments?.getString("tocRegex") tool_bar.setTitle(R.string.txt_toc_regex) tool_bar.inflateMenu(R.menu.txt_toc_regex) - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) initView() initData() diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt index a926dbe55..b4c8f70d6 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt @@ -17,12 +17,12 @@ import io.legado.app.App import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter -import io.legado.app.constant.Theme import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.customView import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.yesButton import io.legado.app.lib.theme.backgroundColor +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.applyTint import io.legado.app.utils.getViewModelOfActivity @@ -56,18 +56,19 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) view.setBackgroundColor(backgroundColor) - initData() - } - - private fun initData() { + tool_bar.setBackgroundColor(primaryColor) tool_bar.title = getString(R.string.group_manage) tool_bar.inflateMenu(R.menu.group_manage) - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) adapter = GroupAdapter(requireContext()) recycler_view.layoutManager = LinearLayoutManager(requireContext()) recycler_view.addItemDecoration(VerticalDivider(requireContext())) recycler_view.adapter = adapter + initData() + } + + private fun initData() { App.db.bookSourceDao().liveGroup().observe(viewLifecycleOwner, Observer { val groups = linkedSetOf() it.map { group -> diff --git a/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt index c83d1f4b7..adc0d5cbb 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt @@ -17,13 +17,12 @@ import io.legado.app.App import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter -import io.legado.app.constant.Theme import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.customView import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.yesButton import io.legado.app.lib.theme.backgroundColor -import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.applyTint import io.legado.app.utils.getViewModelOfActivity @@ -57,14 +56,14 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) view.setBackgroundColor(backgroundColor) - tool_bar.setBackgroundColor(bottomBackground) + tool_bar.setBackgroundColor(primaryColor) initData() } private fun initData() { tool_bar.title = getString(R.string.group_manage) tool_bar.inflateMenu(R.menu.group_manage) - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) adapter = GroupAdapter(requireContext()) recycler_view.layoutManager = LinearLayoutManager(requireContext()) diff --git a/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt b/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt index 6b207cd0b..012a042a9 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt @@ -15,7 +15,6 @@ import androidx.lifecycle.Observer import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.constant.AppConst -import io.legado.app.constant.Theme import io.legado.app.data.entities.ReplaceRule import io.legado.app.lib.theme.bottomBackground import io.legado.app.ui.widget.KeyboardToolPop @@ -70,7 +69,7 @@ class ReplaceEditDialog : BaseDialogFragment(), tool_bar.setBackgroundColor(bottomBackground) mSoftKeyboardTool = KeyboardToolPop(requireContext(), AppConst.keyboardToolChars, this) tool_bar.inflateMenu(R.menu.replace_edit) - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) viewModel.replaceRuleData.observe(viewLifecycleOwner, Observer { upReplaceView(it) diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt index b5a92d099..5f78beeda 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt @@ -17,12 +17,12 @@ import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter -import io.legado.app.constant.Theme import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.customView import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.yesButton import io.legado.app.lib.theme.accentColor +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.utils.* import kotlinx.android.synthetic.main.dialog_edit_text.view.* @@ -51,9 +51,10 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener } override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { + tool_bar.setBackgroundColor(primaryColor) tool_bar.title = getString(R.string.group_manage) tool_bar.inflateMenu(R.menu.group_manage) - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) adapter = GroupAdapter(requireContext()) recycler_view.layoutManager = LinearLayoutManager(requireContext()) diff --git a/app/src/main/java/io/legado/app/ui/widget/image/photo/RotateGestureDetector.kt b/app/src/main/java/io/legado/app/ui/widget/image/photo/RotateGestureDetector.kt index e8d6ebf61..4bc309b56 100644 --- a/app/src/main/java/io/legado/app/ui/widget/image/photo/RotateGestureDetector.kt +++ b/app/src/main/java/io/legado/app/ui/widget/image/photo/RotateGestureDetector.kt @@ -4,12 +4,10 @@ import android.view.MotionEvent import kotlin.math.abs import kotlin.math.atan -class RotateGestureDetector(l: OnRotateListener) { +class RotateGestureDetector(private val mListener: OnRotateListener) { private val MAX_DEGREES_STEP = 120 - private val mListener: OnRotateListener? = null - private var mPrevSlope = 0f private var mCurrSlope = 0f diff --git a/app/src/main/java/io/legado/app/utils/ContextExtensions.kt b/app/src/main/java/io/legado/app/utils/ContextExtensions.kt index df9f457cd..1734997f2 100644 --- a/app/src/main/java/io/legado/app/utils/ContextExtensions.kt +++ b/app/src/main/java/io/legado/app/utils/ContextExtensions.kt @@ -24,6 +24,7 @@ import io.legado.app.App import io.legado.app.BuildConfig import io.legado.app.R import org.jetbrains.anko.defaultSharedPreferences +import org.jetbrains.anko.longToast import org.jetbrains.anko.toast import java.io.File import java.io.FileOutputStream @@ -138,7 +139,7 @@ fun Context.sendToClip(text: String) { val clipData = ClipData.newPlainText(null, text) clipboard?.let { clipboard.setPrimaryClip(clipData) - toast(R.string.copy_complete) + longToast(R.string.copy_complete) } } diff --git a/app/src/main/res/layout/dialog_change_cover.xml b/app/src/main/res/layout/dialog_change_cover.xml index cc7486b05..775b31f60 100644 --- a/app/src/main/res/layout/dialog_change_cover.xml +++ b/app/src/main/res/layout/dialog_change_cover.xml @@ -11,6 +11,9 @@ android:layout_height="wrap_content" android:background="@color/background_menu" android:elevation="5dp" + android:theme="?attr/actionBarStyle" + app:titleTextAppearance="@style/ToolbarTitle" + app:popupTheme="@style/AppTheme.PopupOverlay" app:displayHomeAsUp="false" app:fitStatusBar="false" /> diff --git a/app/src/main/res/layout/dialog_change_source.xml b/app/src/main/res/layout/dialog_change_source.xml index 4b8703b37..d72fab249 100644 --- a/app/src/main/res/layout/dialog_change_source.xml +++ b/app/src/main/res/layout/dialog_change_source.xml @@ -12,6 +12,9 @@ android:layout_height="wrap_content" android:background="@color/background_menu" android:elevation="5dp" + android:theme="?attr/actionBarStyle" + app:titleTextAppearance="@style/ToolbarTitle" + app:popupTheme="@style/AppTheme.PopupOverlay" app:displayHomeAsUp="false" app:fitStatusBar="false" /> diff --git a/app/src/main/res/layout/dialog_http_tts_edit.xml b/app/src/main/res/layout/dialog_http_tts_edit.xml new file mode 100644 index 000000000..0ab79c773 --- /dev/null +++ b/app/src/main/res/layout/dialog_http_tts_edit.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_recycler_view.xml b/app/src/main/res/layout/dialog_recycler_view.xml index c8e7c0944..e7ca72d9a 100644 --- a/app/src/main/res/layout/dialog_recycler_view.xml +++ b/app/src/main/res/layout/dialog_recycler_view.xml @@ -1,6 +1,7 @@ @@ -8,7 +9,10 @@ + android:layout_height="wrap_content" + android:theme="?attr/actionBarStyle" + app:titleTextAppearance="@style/ToolbarTitle" + app:popupTheme="@style/AppTheme.PopupOverlay" /> + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/speak_engine.xml b/app/src/main/res/menu/speak_engine.xml new file mode 100644 index 000000000..52bf86d0d --- /dev/null +++ b/app/src/main/res/menu/speak_engine.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rHK/arrays.xml b/app/src/main/res/values-zh-rHK/arrays.xml index a11c1cb68..346489faf 100644 --- a/app/src/main/res/values-zh-rHK/arrays.xml +++ b/app/src/main/res/values-zh-rHK/arrays.xml @@ -1,21 +1,6 @@ - - 度小美 - 度小宇 - 度逍遙 - 度丫丫 - 度小嬌 - 度米朵 - 度博文 - 度小童 - 度小萌 - 百度騷男 - 百度評書 - 百度主持 - - 跟隨系統 亮色主題 diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 2b3b4c2ef..279a4fe67 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -543,7 +543,7 @@ %d 分鐘 自動亮度 %s 按頁朗讀 - 在線朗讀 + 朗讀引擎 背景圖片 背景顏色 文字顏色 @@ -748,4 +748,5 @@ 公众号[开源阅读软件] 阅读记录 阅读时间记录 + 本地TTS diff --git a/app/src/main/res/values-zh-rTW/arrays.xml b/app/src/main/res/values-zh-rTW/arrays.xml index 837da7471..2b5966b66 100644 --- a/app/src/main/res/values-zh-rTW/arrays.xml +++ b/app/src/main/res/values-zh-rTW/arrays.xml @@ -5,21 +5,6 @@ @string/book_type_audio - - 度小美 - 度小宇 - 度逍遙 - 度丫丫 - 度小嬌 - 度米朵 - 度博文 - 度小童 - 度小萌 - 百度騷男 - 百度評書 - 百度主持 - - @string/indent_0 @string/indent_1 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 59e5fc685..50de2b25e 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -544,7 +544,7 @@ %d分鐘 自動亮度%s 按頁朗讀 - 線上朗讀 + 朗讀引擎 背景圖片 背景顏色 文字顏色 @@ -748,5 +748,6 @@ 公众号[开源阅读软件] 阅读记录 阅读时间记录 + 本地TTS diff --git a/app/src/main/res/values-zh/arrays.xml b/app/src/main/res/values-zh/arrays.xml index 3ac5c3cd4..146b90b4e 100644 --- a/app/src/main/res/values-zh/arrays.xml +++ b/app/src/main/res/values-zh/arrays.xml @@ -5,21 +5,6 @@ @string/book_type_audio - - 度小美 - 度小宇 - 度逍遥 - 度丫丫 - 度小娇 - 度米朵 - 度博文 - 度小童 - 度小萌 - 百度骚男 - 百度评书 - 百度主持 - - @string/indent_0 @string/indent_1 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 3e6402a56..c04e95f0a 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -545,7 +545,7 @@ %d分钟 自动亮度%s 按页朗读 - 在线朗读 + 朗读引擎 背景图片 背景颜色 文字颜色 @@ -748,4 +748,5 @@ 公众号[开源阅读软件] 阅读记录 阅读时间记录 + 本地TTS diff --git a/app/src/main/res/values/array_values.xml b/app/src/main/res/values/array_values.xml index bdaf1ef49..a545e3641 100644 --- a/app/src/main/res/values/array_values.xml +++ b/app/src/main/res/values/array_values.xml @@ -26,21 +26,6 @@ 3 - - 0 - 1 - 3 - 4 - 5 - 103 - 106 - 110 - 111 - 11 - 6 - 9 - - 0 1 diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 0ff78f4bf..33a99ef3e 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -5,21 +5,6 @@ @string/book_type_audio - - du Xiao Mei - du Xiao Yu - du Xiao Yao - du Ya Ya - du Xiao Jiao - du Mi Duo - du Bo Wen - du Xiao Tong - du Xiao Meng - baidu SaoNan - baidu PingShu - baidu ZhuChi - - @string/indent_0 @string/indent_1 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 585b95bd0..fd99b14df 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -547,7 +547,7 @@ %d min Auto-Brightness %s Speak by pages - Online Speech + Speak Engine Background images Background color Text color @@ -749,5 +749,6 @@ 公众号[开源阅读软件] 阅读记录 阅读时间记录 + 本地TTS \ No newline at end of file diff --git a/app/src/main/res/xml/pref_config_aloud.xml b/app/src/main/res/xml/pref_config_aloud.xml index a41fa79b1..95d5193d0 100644 --- a/app/src/main/res/xml/pref_config_aloud.xml +++ b/app/src/main/res/xml/pref_config_aloud.xml @@ -14,18 +14,11 @@ android:key="readAloudByPage" app:iconSpaceReserved="false" /> - - - From 9215bcf29fe54fade8b7700e7153a1ffefa69dd6 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 15:25:47 +0800 Subject: [PATCH 02/90] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=9C=97=E8=AF=BB?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E8=87=AA=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/storage/Backup.kt | 2 ++ app/src/main/java/io/legado/app/help/storage/Restore.kt | 3 +++ 2 files changed, 5 insertions(+) diff --git a/app/src/main/java/io/legado/app/help/storage/Backup.kt b/app/src/main/java/io/legado/app/help/storage/Backup.kt index c431de070..bec27b53a 100644 --- a/app/src/main/java/io/legado/app/help/storage/Backup.kt +++ b/app/src/main/java/io/legado/app/help/storage/Backup.kt @@ -32,6 +32,7 @@ object Backup { "replaceRule.json", "txtTocRule.json", "readRecord.json", + "httpTTS.json", ReadBookConfig.readConfigFileName, "config.xml" ) @@ -59,6 +60,7 @@ object Backup { writeListToJson(App.db.replaceRuleDao().all, "replaceRule.json", backupPath) writeListToJson(App.db.txtTocRule().all, "txtTocRule.json", backupPath) writeListToJson(App.db.readRecordDao().all, "readRecord.json", backupPath) + writeListToJson(App.db.httpTTSDao().all, "httpTTS.json", backupPath) GSON.toJson(ReadBookConfig.configList)?.let { FileUtils.createFileIfNotExist(backupPath + File.separator + ReadBookConfig.readConfigFileName) .writeText(it) 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 ca73c6df4..e8800f542 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 @@ -137,6 +137,9 @@ object Restore { fileToListT(path, "readRecord.json")?.let { App.db.readRecordDao().insert(*it.toTypedArray()) } + fileToListT(path, "httpTTS.json")?.let { + App.db.httpTTSDao().insert(*it.toTypedArray()) + } } } From 4ae244acab91fa4d467c875a3be7f73fbbee02f3 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 15:38:24 +0800 Subject: [PATCH 03/90] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=9C=97=E8=AF=BB?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E8=87=AA=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/httpTTS.json | 56 ++++++++++++++++---------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/app/src/main/assets/httpTTS.json b/app/src/main/assets/httpTTS.json index 0d3c884f1..22b9fcf47 100644 --- a/app/src/main/assets/httpTTS.json +++ b/app/src/main/assets/httpTTS.json @@ -1,62 +1,62 @@ [ { - "id": 1, + "id": 1598233029304, "name": "度小美", - "url": "" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 2, + "id": 1598233029305, "name": "度小宇", - "url": "" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 3, - "name": "度逍遙", - "url": "" + "id": 1598233029306, + "name": "度逍遥", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 4, + "id": 1598233029307, "name": "度丫丫", - "url": "" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 5, - "name": "度小嬌", - "url": "" + "id": 1598233029308, + "name": "度小娇", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 6, + "id": 1598233029309, "name": "度米朵", - "url": "" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 7, + "id": 1598233029310, "name": "度博文", - "url": "" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 8, + "id": 1598233029311, "name": "度小童", - "url": "" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 9, + "id": 1598233029312, "name": "度小萌", - "url": "" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 10, - "name": "百度騷男", - "url": "" + "id": 1598233029313, + "name": "百度骚男", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=11&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 11, - "name": "百度評書", - "url": "" + "id": 1598233029314, + "name": "百度评书", + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { - "id": 12, + "id": 1598233029315, "name": "百度主持", - "url": "" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" } ] \ No newline at end of file From c3461f78b465060bdd44eff61ee8142253d0039d Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 15:54:32 +0800 Subject: [PATCH 04/90] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=9C=97=E8=AF=BB?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E8=87=AA=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/data/dao/HttpTTSDao.kt | 3 +++ .../java/io/legado/app/ui/main/MainViewModel.kt | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt b/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt index 971dc4896..f71169bb1 100644 --- a/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/HttpTTSDao.kt @@ -13,6 +13,9 @@ interface HttpTTSDao { @Query("select * from httpTTS order by name") fun observeAll(): LiveData> + @get:Query("select count(*) from httpTTS") + val count: Int + @Query("select * from httpTTS where id = :id") fun get(id: Long): HttpTTS? 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 06fd049d3..ed2e070d8 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 @@ -6,15 +6,13 @@ import io.legado.app.base.BaseViewModel import io.legado.app.constant.BookType import io.legado.app.constant.EventBus import io.legado.app.data.entities.Book +import io.legado.app.data.entities.HttpTTS import io.legado.app.data.entities.RssSource import io.legado.app.help.AppConfig import io.legado.app.help.http.HttpHelper import io.legado.app.help.storage.Restore import io.legado.app.model.WebBook -import io.legado.app.utils.FileUtils -import io.legado.app.utils.GSON -import io.legado.app.utils.fromJsonObject -import io.legado.app.utils.postEvent +import io.legado.app.utils.* import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.delay @@ -97,6 +95,13 @@ class MainViewModel(application: Application) : BaseViewModel(application) { fun postLoad() { execute { FileUtils.deleteFile(FileUtils.getPath(context.cacheDir, "Fonts")) + if (App.db.httpTTSDao().count == 0) { + @Suppress("BlockingMethodInNonBlockingContext") + val json = String(App.INSTANCE.assets.open("httpTTS.json").readBytes()) + GSON.fromJsonArray(json)?.let { + App.db.httpTTSDao().insert(*it.toTypedArray()) + } + } } } } \ No newline at end of file From 275e1b9eeb5748f9796689f49382bd79d0108bbe Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 15:57:35 +0800 Subject: [PATCH 05/90] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=9C=97=E8=AF=BB?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E8=87=AA=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 159dcf354..6bfd5a555 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,11 +3,12 @@ * 关注合作公众号 **[小说拾遗]()** 获取好看的小说。 - 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 -**2020/08/23** +**2020/08/24** * 应用被杀死时停止朗读 * 默认封面添加删除操作 * 备份阅读记录 * 书源添加移除分组支持多选,多个分组以逗号(中英均可)隔开 +* 可以自定义在线朗读了 **2020/08/22** * 添加阅读时间记录 From 0c41a61de32b408e7ba5d7562d635141768e51fd Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 16:44:10 +0800 Subject: [PATCH 06/90] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=9C=97=E8=AF=BB?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E8=87=AA=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/service/help/ReadAloud.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/io/legado/app/service/help/ReadAloud.kt b/app/src/main/java/io/legado/app/service/help/ReadAloud.kt index c7a812b8c..b25c270c3 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadAloud.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadAloud.kt @@ -18,6 +18,7 @@ object ReadAloud { private fun getReadAloudClass(): Class<*> { val spId = App.INSTANCE.getPrefLong(PreferKey.speakEngine) httpTTS = App.db.httpTTSDao().get(spId) + stop(App.INSTANCE) return if (httpTTS != null) { HttpReadAloudService::class.java } else { From bb9e22f870672fa7f3b32afbdaa9048bdf42d433 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 17:40:41 +0800 Subject: [PATCH 07/90] =?UTF-8?q?=E9=98=85=E8=AF=BB=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 3 +++ .../io/legado/app/data/dao/ReadRecordDao.kt | 3 +++ .../legado/app/ui/about/ReadRecordActivity.kt | 19 ++++++++++++++++++- app/src/main/res/layout/item_read_record.xml | 15 +++++++++++++-- 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 6bfd5a555..bd4c7f43a 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,9 @@ * 关注合作公众号 **[小说拾遗]()** 获取好看的小说。 - 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2020/08/25** +* 阅读记录可以删除了 + **2020/08/24** * 应用被杀死时停止朗读 * 默认封面添加删除操作 diff --git a/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt b/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt index 88c785d0a..38eb5ead1 100644 --- a/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt @@ -21,4 +21,7 @@ interface ReadRecordDao { @Update fun update(vararg record: ReadRecord) + @Delete + fun delete(vararg record: ReadRecord) + } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt index 6ff52d229..6d34569af 100644 --- a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt +++ b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt @@ -9,6 +9,10 @@ import io.legado.app.base.BaseActivity import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.data.entities.ReadRecord +import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.dialogs.noButton +import io.legado.app.lib.dialogs.okButton +import io.legado.app.utils.applyTint import kotlinx.android.synthetic.main.activity_read_record.* import kotlinx.android.synthetic.main.item_read_record.* import kotlinx.android.synthetic.main.item_read_record.view.* @@ -16,6 +20,7 @@ import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.jetbrains.anko.sdk27.listeners.onClick class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) { @@ -57,7 +62,19 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) { } override fun registerListener(holder: ItemViewHolder) { - + holder.itemView.apply { + iv_remove.onClick { + alert(R.string.delete, R.string.sure_del) { + okButton { + getItem(holder.layoutPosition)?.let { + App.db.readRecordDao().delete(it) + initData() + } + } + noButton() + }.show().applyTint() + } + } } } diff --git a/app/src/main/res/layout/item_read_record.xml b/app/src/main/res/layout/item_read_record.xml index b28197be6..1437f0fdb 100644 --- a/app/src/main/res/layout/item_read_record.xml +++ b/app/src/main/res/layout/item_read_record.xml @@ -1,11 +1,13 @@ + android:orientation="horizontal" + android:gravity="center_vertical"> + + \ No newline at end of file From 72715eddbf039a6b95a26b7564cf0e63d9f11a98 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 18:17:29 +0800 Subject: [PATCH 08/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BF=BB=E9=A1=B5?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E9=80=89=E6=8B=A9=E9=A2=9C=E8=89=B2=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/lib/theme/view/ATERadioNoButton.kt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/lib/theme/view/ATERadioNoButton.kt b/app/src/main/java/io/legado/app/lib/theme/view/ATERadioNoButton.kt index 0a93266b6..1b6731098 100644 --- a/app/src/main/java/io/legado/app/lib/theme/view/ATERadioNoButton.kt +++ b/app/src/main/java/io/legado/app/lib/theme/view/ATERadioNoButton.kt @@ -34,7 +34,6 @@ class ATERadioNoButton(context: Context, attrs: AttributeSet) : isBottomBackground -> { val isLight = ColorUtils.isColorLight(context.bottomBackground) val textColor = context.getPrimaryTextColor(isLight) - setTextColor(textColor) background = Selector.shapeBuild() .setCornerRadius(2.dp) .setStrokeWidth(2.dp) @@ -42,15 +41,28 @@ class ATERadioNoButton(context: Context, attrs: AttributeSet) : .setCheckedStrokeColor(context.accentColor) .setDefaultStrokeColor(textColor) .create() + setTextColor( + Selector.colorBuild() + .setDefaultColor(textColor) + .setCheckedColor(context.getPrimaryTextColor(ColorUtils.isColorLight(context.accentColor))) + .create() + ) } else -> { + val textColor = context.getCompatColor(R.color.primaryText) background = Selector.shapeBuild() .setCornerRadius(2.dp) .setStrokeWidth(2.dp) .setCheckedBgColor(context.accentColor) .setCheckedStrokeColor(context.accentColor) - .setDefaultStrokeColor(context.getCompatColor(R.color.primaryText)) + .setDefaultStrokeColor(textColor) .create() + setTextColor( + Selector.colorBuild() + .setDefaultColor(textColor) + .setCheckedColor(context.getPrimaryTextColor(ColorUtils.isColorLight(context.accentColor))) + .create() + ) } } From e5b9fbb28e55136775923c0135e4e07b20795327 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 18:18:40 +0800 Subject: [PATCH 09/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BF=BB=E9=A1=B5?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E9=80=89=E6=8B=A9=E9=A2=9C=E8=89=B2=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index bd4c7f43a..646834fc6 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -5,6 +5,7 @@ **2020/08/25** * 阅读记录可以删除了 +* 修复翻页模式选择颜色问题 **2020/08/24** * 应用被杀死时停止朗读 From a88f5f29933bc1176ba8d9c42c69e682a8625fc9 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 18:21:17 +0800 Subject: [PATCH 10/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/ui/book/info/BookInfoActivity.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) 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 9f61755eb..d7c625c2f 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 @@ -25,6 +25,7 @@ import io.legado.app.help.IntentDataHelp import io.legado.app.lib.dialogs.alert import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.ui.audio.AudioPlayActivity import io.legado.app.ui.book.changecover.ChangeCoverDialog import io.legado.app.ui.book.changesource.ChangeSourceDialog @@ -35,10 +36,7 @@ import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.search.SearchActivity import io.legado.app.ui.book.source.edit.BookSourceEditActivity import io.legado.app.ui.widget.image.CoverImageView -import io.legado.app.utils.dp -import io.legado.app.utils.getViewModel -import io.legado.app.utils.gone -import io.legado.app.utils.visible +import io.legado.app.utils.* import kotlinx.android.synthetic.main.activity_book_info.* import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.startActivity @@ -66,6 +64,7 @@ class BookInfoActivity : ll_info.setBackgroundColor(backgroundColor) scroll_view.setBackgroundColor(backgroundColor) fl_action.setBackgroundColor(bottomBackground) + tv_shelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground))) viewModel.bookData.observe(this, Observer { showBook(it) }) viewModel.chapterListData.observe(this, Observer { upLoading(false, it) }) viewModel.initData(intent) From 5d5c61976df5d8e44315b1a0893fdfddc1e8f2f5 Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 20:30:00 +0800 Subject: [PATCH 11/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt | 2 ++ app/src/main/res/layout/item_read_record.xml | 1 + 2 files changed, 3 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt index 6d34569af..51e575dff 100644 --- a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt +++ b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt @@ -13,6 +13,7 @@ import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.okButton import io.legado.app.utils.applyTint +import io.legado.app.utils.visible import kotlinx.android.synthetic.main.activity_read_record.* import kotlinx.android.synthetic.main.item_read_record.* import kotlinx.android.synthetic.main.item_read_record.view.* @@ -58,6 +59,7 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) { holder.itemView.apply { tv_book_name.text = item.bookName tv_read_time.text = formatDuring(item.readTime) + iv_remove.visible() } } diff --git a/app/src/main/res/layout/item_read_record.xml b/app/src/main/res/layout/item_read_record.xml index 1437f0fdb..65f3894d4 100644 --- a/app/src/main/res/layout/item_read_record.xml +++ b/app/src/main/res/layout/item_read_record.xml @@ -31,6 +31,7 @@ android:layout_height="wrap_content" android:src="@drawable/ic_remove" android:contentDescription="@string/delete" + android:visibility="invisible" app:tint="@color/primaryText" /> \ No newline at end of file From b2ff27aa139701a6a1071b1931aa053a9b75b5b9 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 25 Aug 2020 13:00:59 +0800 Subject: [PATCH 12/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=BB=E9=A2=98bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/base/BaseActivity.kt | 7 +++--- .../java/io/legado/app/base/VMBaseActivity.kt | 5 ++-- .../main/java/io/legado/app/constant/Theme.kt | 9 ++++++++ .../legado/app/ui/audio/AudioPlayActivity.kt | 2 +- .../app/ui/book/info/BookInfoActivity.kt | 3 ++- .../java/io/legado/app/ui/widget/TitleBar.kt | 8 +++++-- .../res/layout-land/activity_book_info.xml | 3 ++- .../main/res/layout/activity_audio_play.xml | 23 ++++++++++--------- .../main/res/layout/activity_book_info.xml | 3 ++- .../main/res/layout/view_title_bar_dark.xml | 9 ++++++++ app/src/main/res/values/attrs.xml | 6 +++++ 11 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 app/src/main/res/layout/view_title_bar_dark.xml diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index 0574813a2..6e3b8ece2 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -25,6 +25,7 @@ abstract class BaseActivity( private val layoutID: Int, private val fullScreen: Boolean = true, private val theme: Theme = Theme.Auto, + private val toolBarTheme: Theme = Theme.Auto, private val transparent: Boolean = false ) : AppCompatActivity(), CoroutineScope by MainScope() { @@ -65,7 +66,7 @@ abstract class BaseActivity( final override fun onCreateOptionsMenu(menu: Menu?): Boolean { return menu?.let { val bool = onCompatCreateOptionsMenu(it) - it.applyTint(this, theme) + it.applyTint(this, toolBarTheme) bool } ?: super.onCreateOptionsMenu(menu) } @@ -129,9 +130,9 @@ abstract class BaseActivity( View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE } ATH.setStatusBarColorAuto(this, fullScreen) - if (theme == Theme.Dark) { + if (toolBarTheme == Theme.Dark) { ATH.setLightStatusBar(this, false) - } else if (theme == Theme.Light) { + } else if (toolBarTheme == Theme.Light) { ATH.setLightStatusBar(this, true) } upNavigationBarColor() diff --git a/app/src/main/java/io/legado/app/base/VMBaseActivity.kt b/app/src/main/java/io/legado/app/base/VMBaseActivity.kt index 3643588af..f8de615de 100644 --- a/app/src/main/java/io/legado/app/base/VMBaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/VMBaseActivity.kt @@ -6,8 +6,9 @@ import io.legado.app.constant.Theme abstract class VMBaseActivity( layoutID: Int, fullScreen: Boolean = true, - theme: Theme = Theme.Auto -) : BaseActivity(layoutID, fullScreen, theme) { + theme: Theme = Theme.Auto, + toolBarTheme: Theme = Theme.Auto +) : BaseActivity(layoutID, fullScreen, theme, toolBarTheme) { protected abstract val viewModel: VM diff --git a/app/src/main/java/io/legado/app/constant/Theme.kt b/app/src/main/java/io/legado/app/constant/Theme.kt index a4f313a80..720c339f9 100644 --- a/app/src/main/java/io/legado/app/constant/Theme.kt +++ b/app/src/main/java/io/legado/app/constant/Theme.kt @@ -1,6 +1,7 @@ package io.legado.app.constant import io.legado.app.help.AppConfig +import io.legado.app.utils.ColorUtils enum class Theme { Dark, Light, Auto, Transparent; @@ -11,5 +12,13 @@ enum class Theme { Dark } else Light } + + fun getTheme(backgroundColor: Int): Theme { + return if (ColorUtils.isColorLight(backgroundColor)) { + Light + } else { + Dark + } + } } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt index 2a339f46d..9ed2b173d 100644 --- a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt @@ -37,7 +37,7 @@ import org.jetbrains.anko.startActivityForResult class AudioPlayActivity : - VMBaseActivity(R.layout.activity_audio_play, theme = Theme.Dark), + VMBaseActivity(R.layout.activity_audio_play, toolBarTheme = Theme.Dark), ChangeSourceDialog.CallBack { override val viewModel: AudioPlayViewModel 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 d7c625c2f..906cacaf7 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 @@ -45,7 +45,7 @@ import org.jetbrains.anko.toast class BookInfoActivity : - VMBaseActivity(R.layout.activity_book_info, theme = Theme.Dark), + VMBaseActivity(R.layout.activity_book_info, toolBarTheme = Theme.Dark), GroupSelectDialog.CallBack, ChapterListAdapter.CallBack, ChangeSourceDialog.CallBack, @@ -58,6 +58,7 @@ class BookInfoActivity : override val viewModel: BookInfoViewModel get() = getViewModel(BookInfoViewModel::class.java) + @SuppressLint("PrivateResource") override fun onActivityCreated(savedInstanceState: Bundle?) { title_bar.transparent() arc_view.setBgColor(backgroundColor) diff --git a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt index 94d3b7be6..3b9d28757 100644 --- a/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt +++ b/app/src/main/java/io/legado/app/ui/widget/TitleBar.kt @@ -45,8 +45,6 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a private val attachToActivity: Boolean init { - inflate(context, R.layout.view_title_bar, this) - toolbar = findViewById(R.id.toolbar) val a = context.obtainStyledAttributes( attrs, R.styleable.TitleBar, R.attr.titleBarStyle, 0 @@ -62,6 +60,12 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a val titleText = a.getString(R.styleable.TitleBar_title) val subtitleText = a.getString(R.styleable.TitleBar_subtitle) + when (a.getInt(R.styleable.TitleBar_themeMode, 0)) { + 1 -> inflate(context, R.layout.view_title_bar_dark, this) + else -> inflate(context, R.layout.view_title_bar, this) + } + toolbar = findViewById(R.id.toolbar) + toolbar.apply { navigationIcon?.let { this.navigationIcon = it diff --git a/app/src/main/res/layout-land/activity_book_info.xml b/app/src/main/res/layout-land/activity_book_info.xml index d99efc484..05a4b316a 100644 --- a/app/src/main/res/layout-land/activity_book_info.xml +++ b/app/src/main/res/layout-land/activity_book_info.xml @@ -19,7 +19,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" - app:title="@string/book_info" /> + app:title="@string/book_info" + app:themeMode="dark" /> + app:layout_constraintTop_toTopOf="parent" + app:themeMode="dark" /> + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toBottomOf="@id/title_bar" /> + app:tint="@color/md_white_1000" /> + app:tint="@color/md_white_1000" /> + app:tint="@color/md_white_1000" /> + app:tint="@color/md_white_1000" /> + app:tint="@color/md_white_1000" /> + android:contentDescription="@string/chapter_list" + app:tint="@color/md_white_1000" /> diff --git a/app/src/main/res/layout/activity_book_info.xml b/app/src/main/res/layout/activity_book_info.xml index 02aaf18f3..e2d35458f 100644 --- a/app/src/main/res/layout/activity_book_info.xml +++ b/app/src/main/res/layout/activity_book_info.xml @@ -26,7 +26,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" - app:title="@string/book_info" /> + app:title="@string/book_info" + app:themeMode="dark" /> + diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 507cbc347..bdb8fd0b1 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -3,6 +3,11 @@ + + + + + @@ -25,6 +30,7 @@ + From 4993a51f7a4fb72043749746774ee337e8302631 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 25 Aug 2020 13:21:58 +0800 Subject: [PATCH 13/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/App.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index d14951cb1..e893bc64b 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -6,6 +6,7 @@ import android.content.Context import android.content.res.Configuration import android.graphics.Color import android.os.Build +import android.provider.Settings import androidx.annotation.RequiresApi import androidx.appcompat.app.AppCompatDelegate import androidx.multidex.MultiDexApplication @@ -34,6 +35,8 @@ class App : MultiDexApplication() { @JvmStatic lateinit var db: AppDatabase private set + + lateinit var androidId: String } var versionCode = 0 @@ -42,6 +45,7 @@ class App : MultiDexApplication() { override fun onCreate() { super.onCreate() INSTANCE = this + androidId = Settings.System.getString(contentResolver, Settings.Secure.ANDROID_ID) CrashHandler().init(this) LanguageUtils.setConfigurationOld(this) db = AppDatabase.createDatabase(INSTANCE) From 2f0d6fc2af050e082d63dd39de8bd07953b17f08 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 25 Aug 2020 13:23:23 +0800 Subject: [PATCH 14/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 646834fc6..14b14114f 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -6,6 +6,7 @@ **2020/08/25** * 阅读记录可以删除了 * 修复翻页模式选择颜色问题 +* 修复toolbar在一些情况下文字颜色不对的bug **2020/08/24** * 应用被杀死时停止朗读 From 0f8ee000faa0ea51f660407dd4328c94b9c0303f Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 25 Aug 2020 16:40:36 +0800 Subject: [PATCH 15/90] =?UTF-8?q?=E5=A4=9A=E8=AE=BE=E5=A4=87=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E8=AE=B0=E5=BD=95=E5=8F=A0=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/data/AppDatabase.kt | 15 +++++++++++++-- .../java/io/legado/app/data/dao/ReadRecordDao.kt | 2 +- .../io/legado/app/data/entities/ReadRecord.kt | 5 ++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/AppDatabase.kt b/app/src/main/java/io/legado/app/data/AppDatabase.kt index 48770cefe..7d0a81128 100644 --- a/app/src/main/java/io/legado/app/data/AppDatabase.kt +++ b/app/src/main/java/io/legado/app/data/AppDatabase.kt @@ -6,6 +6,7 @@ import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.migration.Migration import androidx.sqlite.db.SupportSQLiteDatabase +import io.legado.app.App import io.legado.app.data.dao.* import io.legado.app.data.entities.* @@ -15,7 +16,7 @@ import io.legado.app.data.entities.* ReplaceRule::class, SearchBook::class, SearchKeyword::class, Cookie::class, RssSource::class, Bookmark::class, RssArticle::class, RssReadRecord::class, RssStar::class, TxtTocRule::class, ReadRecord::class, HttpTTS::class], - version = 18, + version = 19, exportSchema = true ) abstract class AppDatabase : RoomDatabase() { @@ -34,7 +35,8 @@ abstract class AppDatabase : RoomDatabase() { migration_13_14, migration_14_15, migration_15_17, - migration_17_18 + migration_17_18, + migration_18_19 ) .allowMainThreadQueries() .build() @@ -101,6 +103,15 @@ abstract class AppDatabase : RoomDatabase() { database.execSQL("CREATE TABLE IF NOT EXISTS `httpTTS` (`id` INTEGER NOT NULL, `name` TEXT NOT NULL, `url` TEXT NOT NULL, PRIMARY KEY(`id`))") } } + + private val migration_18_19 = object : Migration(18, 19) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("CREATE TABLE IF NOT EXISTS `readRecordNew` (`androidId` TEXT NOT NULL, `bookName` TEXT NOT NULL, `readTime` INTEGER NOT NULL, PRIMARY KEY(`androidId`, `bookName`))") + database.execSQL("INSERT INTO readRecordNew(androidId, bookName, readTime) select '${App.androidId}' as androidId, bookName, readTime from readRecord") + database.execSQL("DROP TABLE readRecord") + database.execSQL("ALTER TABLE readRecordNew RENAME TO readRecord") + } + } } abstract fun bookDao(): BookDao diff --git a/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt b/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt index 38eb5ead1..d7619e9a8 100644 --- a/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt @@ -12,7 +12,7 @@ interface ReadRecordDao { @get:Query("select sum(readTime) from readRecord") val allTime: Long - @Query("select readTime from readRecord where bookName = :bookName") + @Query("select sum(readTime) from readRecord where bookName = :bookName") fun getReadTime(bookName: String): Long? @Insert(onConflict = OnConflictStrategy.REPLACE) diff --git a/app/src/main/java/io/legado/app/data/entities/ReadRecord.kt b/app/src/main/java/io/legado/app/data/entities/ReadRecord.kt index 488dc0205..60f577477 100644 --- a/app/src/main/java/io/legado/app/data/entities/ReadRecord.kt +++ b/app/src/main/java/io/legado/app/data/entities/ReadRecord.kt @@ -1,11 +1,10 @@ package io.legado.app.data.entities import androidx.room.Entity -import androidx.room.PrimaryKey -@Entity(tableName = "readRecord") +@Entity(tableName = "readRecord", primaryKeys = ["androidId", "bookName"]) data class ReadRecord( - @PrimaryKey + var androidId: String = "", var bookName: String = "", var readTime: Long = 0L ) \ No newline at end of file From 8ab9da21afeb498200309d05649ab6cd68d47bf0 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 25 Aug 2020 16:44:24 +0800 Subject: [PATCH 16/90] =?UTF-8?q?=E5=A4=9A=E8=AE=BE=E5=A4=87=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E8=AE=B0=E5=BD=95=E5=8F=A0=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 14b14114f..10bea623a 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -7,6 +7,7 @@ * 阅读记录可以删除了 * 修复翻页模式选择颜色问题 * 修复toolbar在一些情况下文字颜色不对的bug +* 多设备阅读记录叠加 **2020/08/24** * 应用被杀死时停止朗读 From 94cd21297ef18888af5425691e0bd8dfc4f93a83 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 25 Aug 2020 18:19:13 +0800 Subject: [PATCH 17/90] =?UTF-8?q?=E5=A4=9A=E8=AE=BE=E5=A4=87=E9=98=85?= =?UTF-8?q?=E8=AF=BB=E8=AE=B0=E5=BD=95=E5=8F=A0=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/item_read_record.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/item_read_record.xml b/app/src/main/res/layout/item_read_record.xml index 65f3894d4..41666c1af 100644 --- a/app/src/main/res/layout/item_read_record.xml +++ b/app/src/main/res/layout/item_read_record.xml @@ -14,7 +14,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="6dp" - android:gravity="right" + android:maxLength="10" android:textIsSelectable="true" tools:ignore="RtlHardcoded" /> From d6c344b5399cb11bade73d244887509a0faaec64 Mon Sep 17 00:00:00 2001 From: AndyBernie Date: Tue, 25 Aug 2020 19:01:01 +0800 Subject: [PATCH 18/90] =?UTF-8?q?=E5=B0=81=E9=9D=A2=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=BF=AE=E6=94=B9headers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/help/ImageLoader.kt | 3 ++- .../app/model/analyzeRule/AnalyzeUrl.kt | 20 +++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/ImageLoader.kt b/app/src/main/java/io/legado/app/help/ImageLoader.kt index 11f8dff21..9a58f45bf 100644 --- a/app/src/main/java/io/legado/app/help/ImageLoader.kt +++ b/app/src/main/java/io/legado/app/help/ImageLoader.kt @@ -9,6 +9,7 @@ import com.bumptech.glide.Glide import com.bumptech.glide.RequestBuilder import io.legado.app.utils.isAbsUrl import io.legado.app.utils.isContentPath +import io.legado.app.model.analyzeRule.AnalyzeUrl import java.io.File object ImageLoader { @@ -19,7 +20,7 @@ object ImageLoader { fun load(context: Context, path: String?): RequestBuilder { return when { path.isNullOrEmpty() -> Glide.with(context).load(path) - path.isAbsUrl() -> Glide.with(context).load(path) + path.isAbsUrl() -> Glide.with(context).load(AnalyzeUrl(path).getGlideUrl()) path.isContentPath() -> Glide.with(context).load(Uri.parse(path)) else -> try { Glide.with(context).load(File(path)) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 2ed80701b..56b1f1c0e 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -22,7 +22,8 @@ import java.net.URLEncoder import java.util.* import java.util.regex.Pattern import javax.script.SimpleBindings - +import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.load.model.LazyHeaders /** * Created by GKF on 2018/1/24. @@ -346,9 +347,7 @@ class AnalyzeUrl( } @Throws(Exception::class) - fun getImageBytes( - tag: String - ): ByteArray? { + fun getImageBytes(tag: String): ByteArray? { //资源为本站的资源,保留cookie //图片盗链的不保留当前的cookie,可由js生成图片源站的cookie val cookie = CookieStore.getCookie(tag) @@ -403,6 +402,19 @@ class AnalyzeUrl( return response.body() } + @Throws(Exception::class) + fun getGlideUrl(): Any? { + var glideUrl: Any = url + if(headerMap.isNotEmpty()) { + val Headers = LazyHeaders.Builder() + headerMap.forEach {(key, value) -> + Headers.addHeader(key, value) + } + glideUrl = GlideUrl(url, Headers.build()) + } + return glideUrl + } + data class UrlOption( val method: String?, val charset: String?, From 48559e63f87f1d030c8c9259f0c4be00dc75a603 Mon Sep 17 00:00:00 2001 From: AndyBernie Date: Tue, 25 Aug 2020 19:02:05 +0800 Subject: [PATCH 19/90] =?UTF-8?q?=E4=B9=A6=E7=B1=8D=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=B0=81=E9=9D=A2=E9=93=BE=E6=8E=A5=E4=B8=8D?= =?UTF-8?q?=E6=98=BE=E7=A4=BAheaders?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7315bdddc..ce8fe76fc 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 @@ -69,7 +69,7 @@ class BookInfoEditActivity : private fun upView(book: Book) { tie_book_name.setText(book.name) tie_book_author.setText(book.author) - tie_cover_url.setText(book.getDisplayCover()) + tie_cover_url.setText(book.getDisplayCover()?.substringBefore(",")) tie_book_intro.setText(book.getDisplayIntro()) upCover() } From df7af4617b3e323933025c66583fe4a9b1f77fec Mon Sep 17 00:00:00 2001 From: AndyBernie Date: Tue, 25 Aug 2020 19:02:40 +0800 Subject: [PATCH 20/90] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 10bea623a..c7d5926d7 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -8,6 +8,7 @@ * 修复翻页模式选择颜色问题 * 修复toolbar在一些情况下文字颜色不对的bug * 多设备阅读记录叠加 +* 封面链接支持修改headers **2020/08/24** * 应用被杀死时停止朗读 From 2f95f1ebb2ab1fff254223b19bd06329a674f659 Mon Sep 17 00:00:00 2001 From: gedoor Date: Tue, 25 Aug 2020 19:39:02 +0800 Subject: [PATCH 21/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/App.kt | 5 ++--- app/src/main/java/io/legado/app/ui/main/MainActivity.kt | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/legado/app/App.kt b/app/src/main/java/io/legado/app/App.kt index e893bc64b..a96db68fb 100644 --- a/app/src/main/java/io/legado/app/App.kt +++ b/app/src/main/java/io/legado/app/App.kt @@ -37,11 +37,10 @@ class App : MultiDexApplication() { private set lateinit var androidId: String + var versionCode = 0 + var versionName = "" } - var versionCode = 0 - var versionName = "" - override fun onCreate() { super.onCreate() INSTANCE = this diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index 0c02d5abd..1de002931 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -93,8 +93,8 @@ class MainActivity : VMBaseActivity(R.layout.activity_main), } private fun upVersion() { - if (getPrefInt(PreferKey.versionCode) != App.INSTANCE.versionCode) { - putPrefInt(PreferKey.versionCode, App.INSTANCE.versionCode) + if (getPrefInt(PreferKey.versionCode) != App.versionCode) { + putPrefInt(PreferKey.versionCode, App.versionCode) if (!BuildConfig.DEBUG) { val log = String(assets.open("updateLog.md").readBytes()) TextDialog.show(supportFragmentManager, log, TextDialog.MD, 5000, true) From 9c7bae52a5e63a6a967648790d6e24ff494bab45 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 09:36:48 +0800 Subject: [PATCH 22/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=98=85=E8=AF=BB?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/data/dao/ReadRecordDao.kt | 9 +++++++++ .../io/legado/app/data/entities/ReadRecordShow.kt | 6 ++++++ .../java/io/legado/app/help/storage/Restore.kt | 13 ++++++++++++- .../io/legado/app/ui/about/ReadRecordActivity.kt | 14 +++++++++----- 4 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/io/legado/app/data/entities/ReadRecordShow.kt diff --git a/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt b/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt index d7619e9a8..991eaf61c 100644 --- a/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt @@ -2,6 +2,7 @@ package io.legado.app.data.dao import androidx.room.* import io.legado.app.data.entities.ReadRecord +import io.legado.app.data.entities.ReadRecordShow @Dao interface ReadRecordDao { @@ -9,12 +10,18 @@ interface ReadRecordDao { @get:Query("select * from readRecord") val all: List + @get:Query("select bookName, sum(readTime) as readTime from readRecord group by bookName") + val allShow: List + @get:Query("select sum(readTime) from readRecord") val allTime: Long @Query("select sum(readTime) from readRecord where bookName = :bookName") fun getReadTime(bookName: String): Long? + @Query("select readTime from readRecord where androidId = :androidId and bookName = :bookName") + fun getReadTime(androidId: String, bookName: String): Long? + @Insert(onConflict = OnConflictStrategy.REPLACE) fun insert(vararg readRecord: ReadRecord) @@ -24,4 +31,6 @@ interface ReadRecordDao { @Delete fun delete(vararg record: ReadRecord) + @Query("delete from readRecord where bookName = :bookName") + fun deleteByName(bookName: String) } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/data/entities/ReadRecordShow.kt b/app/src/main/java/io/legado/app/data/entities/ReadRecordShow.kt new file mode 100644 index 000000000..79795b0d9 --- /dev/null +++ b/app/src/main/java/io/legado/app/data/entities/ReadRecordShow.kt @@ -0,0 +1,6 @@ +package io.legado.app.data.entities + +data class ReadRecordShow( + var bookName: String = "", + var readTime: Long = 0L +) \ No newline at end of file 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 e8800f542..63202a5c5 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 @@ -135,7 +135,18 @@ object Restore { App.db.txtTocRule().insert(*it.toTypedArray()) } fileToListT(path, "readRecord.json")?.let { - App.db.readRecordDao().insert(*it.toTypedArray()) + it.forEach { readRecord -> + //判断是不是本机记录 + if (readRecord.androidId != App.androidId) { + App.db.readRecordDao().insert(readRecord) + } else { + val time = App.db.readRecordDao() + .getReadTime(readRecord.androidId, readRecord.bookName) + if (time == null || time < readRecord.readTime) { + App.db.readRecordDao().insert(readRecord) + } + } + } } fileToListT(path, "httpTTS.json")?.let { App.db.httpTTSDao().insert(*it.toTypedArray()) diff --git a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt index 51e575dff..01a71f4ad 100644 --- a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt +++ b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt @@ -8,7 +8,7 @@ import io.legado.app.R import io.legado.app.base.BaseActivity import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter -import io.legado.app.data.entities.ReadRecord +import io.legado.app.data.entities.ReadRecordShow import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.noButton import io.legado.app.lib.dialogs.okButton @@ -45,7 +45,7 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) { withContext(Main) { tv_read_time.text = formatDuring(allTime) } - val readRecords = App.db.readRecordDao().all + val readRecords = App.db.readRecordDao().allShow withContext(Main) { adapter.setItems(readRecords) } @@ -53,9 +53,13 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) { } inner class RecordAdapter(context: Context) : - SimpleRecyclerAdapter(context, R.layout.item_read_record) { + SimpleRecyclerAdapter(context, R.layout.item_read_record) { - override fun convert(holder: ItemViewHolder, item: ReadRecord, payloads: MutableList) { + override fun convert( + holder: ItemViewHolder, + item: ReadRecordShow, + payloads: MutableList + ) { holder.itemView.apply { tv_book_name.text = item.bookName tv_read_time.text = formatDuring(item.readTime) @@ -69,7 +73,7 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) { alert(R.string.delete, R.string.sure_del) { okButton { getItem(holder.layoutPosition)?.let { - App.db.readRecordDao().delete(it) + App.db.readRecordDao().deleteByName(it.bookName) initData() } } From f3d68afe35110b85beb3322a16badfe545de919d Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 11:50:51 +0800 Subject: [PATCH 23/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E6=9C=97=E8=AF=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/httpTTS.json | 24 ++++++------- .../io/legado/app/help/DefaultValueHelp.kt | 19 +++++++++++ .../java/io/legado/app/help/JsExtensions.kt | 10 ++++++ .../ui/book/read/config/SpeakEngineDialog.kt | 11 +++--- .../book/read/config/SpeakEngineViewModel.kt | 34 +++++++++++++++++++ .../io/legado/app/ui/main/MainViewModel.kt | 13 ++++--- app/src/main/res/menu/speak_engine.xml | 11 ++++-- 7 files changed, 97 insertions(+), 25 deletions(-) create mode 100644 app/src/main/java/io/legado/app/help/DefaultValueHelp.kt create mode 100644 app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt diff --git a/app/src/main/assets/httpTTS.json b/app/src/main/assets/httpTTS.json index 22b9fcf47..29fda4c6f 100644 --- a/app/src/main/assets/httpTTS.json +++ b/app/src/main/assets/httpTTS.json @@ -2,61 +2,61 @@ { "id": 1598233029304, "name": "度小美", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=0&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029305, "name": "度小宇", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=1&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029306, "name": "度逍遥", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=3&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029307, "name": "度丫丫", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=4&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029308, "name": "度小娇", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029309, "name": "度米朵", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=103&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029310, "name": "度博文", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=106&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029311, "name": "度小童", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=110&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029312, "name": "度小萌", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=111&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029313, "name": "百度骚男", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=11&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=11&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029314, "name": "百度评书", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=6&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" }, { "id": 1598233029315, "name": "百度主持", - "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{encodeURIComponent(encodeURIComponent(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" + "url": "http://tts.baidu.com/text2audio,{\n \"method\": \"POST\",\n \"body\": \"tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=9&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio\"\n}" } ] \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/DefaultValueHelp.kt b/app/src/main/java/io/legado/app/help/DefaultValueHelp.kt new file mode 100644 index 000000000..49338e960 --- /dev/null +++ b/app/src/main/java/io/legado/app/help/DefaultValueHelp.kt @@ -0,0 +1,19 @@ +package io.legado.app.help + +import io.legado.app.App +import io.legado.app.data.entities.HttpTTS +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonArray + +object DefaultValueHelp { + + + fun initHttpTTS() { + val json = String(App.INSTANCE.assets.open("httpTTS.json").readBytes()) + GSON.fromJsonArray(json)?.let { + App.db.httpTTSDao().insert(*it.toTypedArray()) + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/help/JsExtensions.kt b/app/src/main/java/io/legado/app/help/JsExtensions.kt index d12fc07ea..cea6359e3 100644 --- a/app/src/main/java/io/legado/app/help/JsExtensions.kt +++ b/app/src/main/java/io/legado/app/help/JsExtensions.kt @@ -6,6 +6,7 @@ import io.legado.app.constant.AppConst.dateFormat import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.utils.EncoderUtils import io.legado.app.utils.MD5Utils +import java.net.URLEncoder import java.util.* @Keep @@ -52,10 +53,19 @@ interface JsExtensions { fun timeFormat(time: Long): String { return dateFormat.format(Date(time)) } + //utf8编码转gbk编码 fun utf8ToGbk(str: String): String { val utf8 = String(str.toByteArray(charset("UTF-8"))) val unicode = String(utf8.toByteArray(), charset("UTF-8")) return String(unicode.toByteArray(charset("GBK"))) } + + fun encodeURI(str: String): String { + return try { + URLEncoder.encode(str, "UTF-8") + } catch (e: Exception) { + "" + } + } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt index 261aeb20e..6ee1d5bda 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt @@ -39,18 +39,20 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener dialog?.window?.setLayout((dm.widthPixels * 0.9).toInt(), (dm.heightPixels * 0.9).toInt()) } + lateinit var adapter: Adapter + lateinit var viewModel: SpeakEngineViewModel + private var httpTTSData: LiveData>? = null + var engineId = App.INSTANCE.getPrefLong(PreferKey.speakEngine) + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { + viewModel = getViewModel(SpeakEngineViewModel::class.java) return inflater.inflate(R.layout.dialog_recycler_view, container) } - lateinit var adapter: Adapter - private var httpTTSData: LiveData>? = null - var engineId = App.INSTANCE.getPrefLong(PreferKey.speakEngine) - override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { initView() initMenu() @@ -97,6 +99,7 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener override fun onMenuItemClick(item: MenuItem?): Boolean { when (item?.itemId) { R.id.menu_add -> editHttpTTS() + R.id.menu_default -> viewModel.importDefault() } return true } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt new file mode 100644 index 000000000..490eb6efd --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt @@ -0,0 +1,34 @@ +package io.legado.app.ui.book.read.config + +import android.app.Application +import io.legado.app.App +import io.legado.app.base.BaseViewModel +import io.legado.app.data.entities.TxtTocRule +import io.legado.app.help.DefaultValueHelp +import io.legado.app.help.http.HttpHelper +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonArray + +class SpeakEngineViewModel(application: Application) : BaseViewModel(application) { + + fun importDefault() { + execute { + DefaultValueHelp.initHttpTTS() + } + } + + fun importOnLine(url: String, finally: (msg: String) -> Unit) { + execute { + HttpHelper.simpleGetAsync(url)?.let { json -> + GSON.fromJsonArray(json)?.let { + App.db.txtTocRule().insert(*it.toTypedArray()) + } + } + }.onSuccess { + finally("导入成功") + }.onError { + finally("导入失败") + } + } + +} \ No newline at end of file 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 ed2e070d8..b0122bc8b 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 @@ -6,13 +6,16 @@ import io.legado.app.base.BaseViewModel import io.legado.app.constant.BookType import io.legado.app.constant.EventBus import io.legado.app.data.entities.Book -import io.legado.app.data.entities.HttpTTS import io.legado.app.data.entities.RssSource import io.legado.app.help.AppConfig +import io.legado.app.help.DefaultValueHelp import io.legado.app.help.http.HttpHelper import io.legado.app.help.storage.Restore import io.legado.app.model.WebBook -import io.legado.app.utils.* +import io.legado.app.utils.FileUtils +import io.legado.app.utils.GSON +import io.legado.app.utils.fromJsonObject +import io.legado.app.utils.postEvent import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.asCoroutineDispatcher import kotlinx.coroutines.delay @@ -96,11 +99,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) { execute { FileUtils.deleteFile(FileUtils.getPath(context.cacheDir, "Fonts")) if (App.db.httpTTSDao().count == 0) { - @Suppress("BlockingMethodInNonBlockingContext") - val json = String(App.INSTANCE.assets.open("httpTTS.json").readBytes()) - GSON.fromJsonArray(json)?.let { - App.db.httpTTSDao().insert(*it.toTypedArray()) - } + DefaultValueHelp.initHttpTTS() } } } diff --git a/app/src/main/res/menu/speak_engine.xml b/app/src/main/res/menu/speak_engine.xml index 52bf86d0d..9ca269d05 100644 --- a/app/src/main/res/menu/speak_engine.xml +++ b/app/src/main/res/menu/speak_engine.xml @@ -1,11 +1,18 @@ - + app:showAsAction="always" + tools:ignore="AlwaysShowAction" /> + + \ No newline at end of file From 16e7898b405ed0c080a111de8b63d4348d44204a Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 11:54:00 +0800 Subject: [PATCH 24/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/about/AboutFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt index b9e1b2c60..faf676a10 100644 --- a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt +++ b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt @@ -34,7 +34,7 @@ class AboutFragment : PreferenceFragmentCompat() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { addPreferencesFromResource(R.xml.about) findPreference("check_update")?.summary = - "${getString(R.string.version)} ${App.INSTANCE.versionName}" + "${getString(R.string.version)} ${App.versionName}" } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { From b2630618f9423c32af8d393f2b68651b7b6710ae Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 12:25:03 +0800 Subject: [PATCH 25/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/model/webBook/BookList.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 474ed653c..85e5e87c0 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 @@ -11,6 +11,7 @@ import io.legado.app.model.analyzeRule.AnalyzeRule import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.utils.NetworkUtils import io.legado.app.utils.StringUtils.wordCountFormat +import io.legado.app.utils.htmlFormat import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.isActive @@ -161,7 +162,7 @@ object BookList { Debug.log(bookSource.bookSourceUrl, "└${searchBook.latestChapterTitle}") if (!scope.isActive) throw CancellationException() Debug.log(bookSource.bookSourceUrl, "┌获取简介") - searchBook.intro = analyzeRule.getString(intro) + searchBook.intro = analyzeRule.getString(intro).htmlFormat() Debug.log(bookSource.bookSourceUrl, "└${searchBook.intro}", true) if (!scope.isActive) throw CancellationException() Debug.log(bookSource.bookSourceUrl, "┌获取封面链接") @@ -221,7 +222,7 @@ object BookList { Debug.log(bookSource.bookSourceUrl, "└${searchBook.latestChapterTitle}", log) if (!scope.isActive) throw CancellationException() Debug.log(bookSource.bookSourceUrl, "┌获取简介", log) - searchBook.intro = analyzeRule.getString(ruleIntro) + searchBook.intro = analyzeRule.getString(ruleIntro).htmlFormat() Debug.log(bookSource.bookSourceUrl, "└${searchBook.intro}", log, true) if (!scope.isActive) throw CancellationException() Debug.log(bookSource.bookSourceUrl, "┌获取封面链接", log) From 73a69be4f54659b92791d3144ba2ec1ff2d6aca7 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 12:28:14 +0800 Subject: [PATCH 26/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/book/read/ReadBookActivity.kt | 1 + 1 file changed, 1 insertion(+) 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 7ad4008ac..3e665dd9e 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 @@ -128,6 +128,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo override fun onResume() { super.onResume() + ReadBook.readStartTime = System.currentTimeMillis() upSystemUiVisibility() timeBatteryReceiver = TimeBatteryReceiver.register(this) page_view.upTime() From bfc6d5f6669cf865fcd1748fa6d334c315b146c4 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 14:11:18 +0800 Subject: [PATCH 27/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/ui/book/read/ReadBookActivity.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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 3e665dd9e..a333d46d3 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 @@ -14,7 +14,6 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT import androidx.core.view.get import androidx.core.view.isVisible import androidx.core.view.size -import androidx.lifecycle.Observer import com.jaredrummler.android.colorpicker.ColorPickerDialogListener import io.legado.app.BuildConfig import io.legado.app.R @@ -108,11 +107,11 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo initView() upScreenTimeOut() ReadBook.callBack = this - ReadBook.titleDate.observe(this, Observer { + ReadBook.titleDate.observe(this) { title_bar.title = it upMenu() upView() - }) + } viewModel.initData(intent) } From aa49ef53e5b5a8851ee65ab82180eee243001d6e Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 14:12:33 +0800 Subject: [PATCH 28/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/main/MainActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index 1de002931..77a98460c 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -168,7 +168,7 @@ class MainActivity : VMBaseActivity(R.layout.activity_main), } } - private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) : + private inner class TabFragmentPageAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { override fun getItemPosition(`object`: Any): Int { From 4246bcd27d23ef7a4881065218481b8404da5459 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 14:13:54 +0800 Subject: [PATCH 29/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/ui/main/explore/ExploreFragment.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt index c8f93fc64..00e8c8da8 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt @@ -7,7 +7,6 @@ import android.view.SubMenu import android.view.View import androidx.appcompat.widget.SearchView import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -93,7 +92,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_find_ private fun initGroupData() { liveGroup?.removeObservers(viewLifecycleOwner) liveGroup = App.db.bookSourceDao().liveGroupExplore() - liveGroup?.observe(viewLifecycleOwner, Observer { + liveGroup?.observe(viewLifecycleOwner, { groups.clear() it.map { group -> groups.addAll(group.splitNotBlank(",", ";")) @@ -109,7 +108,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_find_ } else { App.db.bookSourceDao().liveExplore("%$key%") } - liveExplore?.observe(viewLifecycleOwner, Observer { + liveExplore?.observe(viewLifecycleOwner, { val diffResult = DiffUtil .calculateDiff(ExploreDiffCallBack(ArrayList(adapter.getItems()), it)) adapter.setItems(it) From fdd625cd333e9a3f08aeaa1a978ab4fb94b32b26 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 14:14:38 +0800 Subject: [PATCH 30/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/main/bookshelf/BookshelfFragment.kt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt index 1466f92f0..9abfddbd4 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt @@ -11,7 +11,6 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentStatePagerAdapter import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import com.google.android.material.tabs.TabLayout import io.legado.app.App import io.legado.app.R @@ -114,7 +113,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b private fun initBookGroupData() { bookGroupLiveData?.removeObservers(viewLifecycleOwner) bookGroupLiveData = App.db.bookGroupDao().liveDataAll() - bookGroupLiveData?.observe(viewLifecycleOwner, Observer { + bookGroupLiveData?.observe(viewLifecycleOwner, { viewModel.checkGroup(it) launch { synchronized(this) { @@ -152,7 +151,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b }) noGroupLiveData?.removeObservers(viewLifecycleOwner) noGroupLiveData = App.db.bookDao().observeNoGroupSize() - noGroupLiveData?.observe(viewLifecycleOwner, Observer { + noGroupLiveData?.observe(viewLifecycleOwner, { if (it > 0 && !showGroupNone && AppConfig.bookGroupNoneShow) { showGroupNone = true upGroup() @@ -270,7 +269,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b fragmentMap[selectedGroup?.groupId]?.gotoTop() } - private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) : + private inner class TabFragmentPageAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { override fun getPageTitle(position: Int): CharSequence? { From 21a792f209c62a69891e9516ef685c3c7459063c Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 15:40:34 +0800 Subject: [PATCH 31/90] =?UTF-8?q?=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/association/FileAssociationActivity.kt | 5 ++--- .../app/ui/association/ImportBookSourceActivity.kt | 5 ++--- .../app/ui/association/ImportReplaceRuleActivity.kt | 5 ++--- .../app/ui/association/ImportRssSourceActivity.kt | 5 ++--- .../java/io/legado/app/ui/audio/AudioPlayActivity.kt | 5 ++--- .../legado/app/ui/book/arrange/ArrangeBookActivity.kt | 5 ++--- .../app/ui/book/changecover/ChangeCoverDialog.kt | 5 ++--- .../app/ui/book/changesource/ChangeSourceDialog.kt | 5 ++--- .../app/ui/book/chapterlist/BookmarkFragment.kt | 5 ++--- .../app/ui/book/chapterlist/ChapterListFragment.kt | 5 ++--- .../legado/app/ui/book/download/DownloadActivity.kt | 5 ++--- .../legado/app/ui/book/explore/ExploreShowActivity.kt | 3 +-- .../io/legado/app/ui/book/group/GroupManageDialog.kt | 3 +-- .../io/legado/app/ui/book/group/GroupSelectDialog.kt | 3 +-- .../io/legado/app/ui/book/info/BookInfoActivity.kt | 5 ++--- .../app/ui/book/info/edit/BookInfoEditActivity.kt | 3 +-- .../io/legado/app/ui/book/local/ImportBookActivity.kt | 3 +-- .../legado/app/ui/book/read/config/TocRegexDialog.kt | 3 +-- .../io/legado/app/ui/book/search/SearchActivity.kt | 11 +++++------ .../app/ui/book/source/manage/BookSourceActivity.kt | 5 ++--- .../app/ui/book/source/manage/GroupManageDialog.kt | 3 +-- .../app/ui/main/bookshelf/books/BooksFragment.kt | 3 +-- .../java/io/legado/app/ui/main/rss/RssFragment.kt | 3 +-- .../io/legado/app/ui/replacerule/GroupManageDialog.kt | 3 +-- .../legado/app/ui/replacerule/ReplaceRuleActivity.kt | 5 ++--- .../app/ui/replacerule/edit/ReplaceEditDialog.kt | 3 +-- .../legado/app/ui/rss/article/RssArticlesFragment.kt | 5 ++--- .../io/legado/app/ui/rss/article/RssSortActivity.kt | 5 ++--- .../app/ui/rss/favorites/RssFavoritesActivity.kt | 3 +-- .../java/io/legado/app/ui/rss/read/ReadRssActivity.kt | 5 ++--- .../app/ui/rss/source/manage/GroupManageDialog.kt | 3 +-- .../app/ui/rss/source/manage/RssSourceActivity.kt | 5 ++--- 32 files changed, 54 insertions(+), 86 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt b/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt index bfd63c362..6c5741414 100644 --- a/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt +++ b/app/src/main/java/io/legado/app/ui/association/FileAssociationActivity.kt @@ -2,7 +2,6 @@ package io.legado.app.ui.association import android.content.Intent import android.os.Bundle -import androidx.lifecycle.Observer import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.constant.Theme @@ -23,12 +22,12 @@ class FileAssociationActivity : VMBaseActivity( override fun onActivityCreated(savedInstanceState: Bundle?) { rotate_loading.show() - viewModel.errorLiveData.observe(this, Observer { + viewModel.errorLiveData.observe(this, { rotate_loading.hide() toast(it) finish() }) - viewModel.successLiveData.observe(this, Observer { + viewModel.successLiveData.observe(this, { rotate_loading.hide() startActivity(it) finish() diff --git a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt index 874bb9e5e..0b74690f2 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportBookSourceActivity.kt @@ -9,7 +9,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.Toolbar -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R import io.legado.app.base.BaseDialogFragment @@ -41,11 +40,11 @@ class ImportBookSourceActivity : VMBaseActivity( override fun onActivityCreated(savedInstanceState: Bundle?) { rotate_loading.show() - viewModel.errorLiveData.observe(this, Observer { + viewModel.errorLiveData.observe(this, { rotate_loading.hide() errorDialog(it) }) - viewModel.successLiveData.observe(this, Observer { + viewModel.successLiveData.observe(this, { rotate_loading.hide() if (it > 0) { successDialog() diff --git a/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt index c5d757597..12ae447d1 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportReplaceRuleActivity.kt @@ -1,7 +1,6 @@ package io.legado.app.ui.association import android.os.Bundle -import androidx.lifecycle.Observer import io.legado.app.App import io.legado.app.R import io.legado.app.base.VMBaseActivity @@ -26,11 +25,11 @@ class ImportReplaceRuleActivity : VMBaseActivity( override fun onActivityCreated(savedInstanceState: Bundle?) { rotate_loading.show() - viewModel.errorLiveData.observe(this, Observer { + viewModel.errorLiveData.observe(this, { rotate_loading.hide() errorDialog(it) }) - viewModel.successLiveData.observe(this, Observer { + viewModel.successLiveData.observe(this, { rotate_loading.hide() if (it.size > 0) { successDialog(it) diff --git a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt index 35e3ca284..8862f2dbe 100644 --- a/app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/association/ImportRssSourceActivity.kt @@ -9,7 +9,6 @@ import android.view.MenuItem import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.Toolbar -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.R import io.legado.app.base.BaseDialogFragment @@ -41,11 +40,11 @@ class ImportRssSourceActivity : VMBaseActivity( override fun onActivityCreated(savedInstanceState: Bundle?) { rotate_loading.show() - viewModel.errorLiveData.observe(this, Observer { + viewModel.errorLiveData.observe(this, { rotate_loading.hide() errorDialog(it) }) - viewModel.successLiveData.observe(this, Observer { + viewModel.successLiveData.observe(this, { rotate_loading.hide() if (it > 0) { successDialog() diff --git a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt index 9ed2b173d..f1d2883fb 100644 --- a/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/audio/AudioPlayActivity.kt @@ -8,7 +8,6 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.widget.SeekBar -import androidx.lifecycle.Observer import com.bumptech.glide.RequestBuilder import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestOptions.bitmapTransform @@ -48,8 +47,8 @@ class AudioPlayActivity : override fun onActivityCreated(savedInstanceState: Bundle?) { title_bar.transparent() - AudioPlay.titleData.observe(this, Observer { title_bar.title = it }) - AudioPlay.coverData.observe(this, Observer { upCover(it) }) + AudioPlay.titleData.observe(this, { title_bar.title = it }) + AudioPlay.coverData.observe(this, { upCover(it) }) viewModel.initData(intent) initView() } diff --git a/app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt index 491922cb1..ab37c5fe1 100644 --- a/app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/arrange/ArrangeBookActivity.kt @@ -5,7 +5,6 @@ import android.view.Menu import android.view.MenuItem import androidx.appcompat.widget.PopupMenu import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App @@ -94,7 +93,7 @@ class ArrangeBookActivity : VMBaseActivity(R.layout.activi private fun initGroupData() { groupLiveData?.removeObservers(this) groupLiveData = App.db.bookGroupDao().liveDataAll() - groupLiveData?.observe(this, Observer { + groupLiveData?.observe(this, { groupList.clear() groupList.addAll(it) adapter.notifyDataSetChanged() @@ -112,7 +111,7 @@ class ArrangeBookActivity : VMBaseActivity(R.layout.activi AppConst.bookGroupNone.groupId -> App.db.bookDao().observeNoGroup() else -> App.db.bookDao().observeByGroup(groupId) } - booksLiveData?.observe(this, Observer { list -> + booksLiveData?.observe(this, { list -> val books = when (getPrefInt(PreferKey.bookshelfSort)) { 1 -> list.sortedByDescending { it.latestChapterTime } 2 -> list.sortedBy { it.name } diff --git a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt index 2539e6dc9..4a898fed4 100644 --- a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverDialog.kt @@ -8,7 +8,6 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.Toolbar import androidx.fragment.app.FragmentManager -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.GridLayoutManager import io.legado.app.R @@ -83,7 +82,7 @@ class ChangeCoverDialog : BaseDialogFragment(), override fun observeLiveBus() { super.observeLiveBus() - viewModel.searchStateData.observe(viewLifecycleOwner, Observer { + viewModel.searchStateData.observe(viewLifecycleOwner, { refresh_progress_bar.isAutoLoading = it if (it) { stopMenuItem?.setIcon(R.drawable.ic_stop_black_24dp) @@ -92,7 +91,7 @@ class ChangeCoverDialog : BaseDialogFragment(), } tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) }) - viewModel.searchBooksLiveData.observe(viewLifecycleOwner, Observer { + viewModel.searchBooksLiveData.observe(viewLifecycleOwner, { val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it)) adapter.setItems(it) diffResult.dispatchUpdatesTo(adapter) diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt index d27f8b756..7ebb4c0db 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceDialog.kt @@ -9,7 +9,6 @@ import android.view.ViewGroup import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.Toolbar import androidx.fragment.app.FragmentManager -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -135,7 +134,7 @@ class ChangeSourceDialog : BaseDialogFragment(), } private fun initLiveData() { - viewModel.searchStateData.observe(viewLifecycleOwner, Observer { + viewModel.searchStateData.observe(viewLifecycleOwner, { refresh_progress_bar.isAutoLoading = it if (it) { stopMenuItem?.setIcon(R.drawable.ic_stop_black_24dp) @@ -144,7 +143,7 @@ class ChangeSourceDialog : BaseDialogFragment(), } tool_bar.menu.applyTint(requireContext()) }) - viewModel.searchBooksLiveData.observe(viewLifecycleOwner, Observer { + viewModel.searchBooksLiveData.observe(viewLifecycleOwner, { val diffResult = DiffUtil.calculateDiff(DiffCallBack(adapter.getItems(), it)) adapter.setItems(it) diffResult.dispatchUpdatesTo(adapter) diff --git a/app/src/main/java/io/legado/app/ui/book/chapterlist/BookmarkFragment.kt b/app/src/main/java/io/legado/app/ui/book/chapterlist/BookmarkFragment.kt index ef47cd2c0..b24d438e8 100644 --- a/app/src/main/java/io/legado/app/ui/book/chapterlist/BookmarkFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/chapterlist/BookmarkFragment.kt @@ -8,7 +8,6 @@ import android.os.Bundle import android.view.View import android.widget.EditText import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.paging.LivePagedListBuilder import androidx.paging.PagedList import androidx.recyclerview.widget.LinearLayoutManager @@ -59,7 +58,7 @@ class BookmarkFragment : VMBaseFragment(R.layout.fragment_ LivePagedListBuilder( App.db.bookmarkDao().observeByBook(book.bookUrl, book.name, book.author), 20 ).build() - bookmarkLiveData?.observe(viewLifecycleOwner, Observer { adapter.submitList(it) }) + bookmarkLiveData?.observe(viewLifecycleOwner, { adapter.submitList(it) }) } } @@ -74,7 +73,7 @@ class BookmarkFragment : VMBaseFragment(R.layout.fragment_ newText ), 20 ).build() - bookmarkLiveData?.observe(viewLifecycleOwner, Observer { adapter.submitList(it) }) + bookmarkLiveData?.observe(viewLifecycleOwner, { adapter.submitList(it) }) } } diff --git a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt index 677d623e2..58d47efeb 100644 --- a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt @@ -6,7 +6,6 @@ import android.content.Intent import android.os.Bundle import android.view.View import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import io.legado.app.App import io.legado.app.R import io.legado.app.base.VMBaseFragment @@ -89,7 +88,7 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragme private fun initDoc() { tocLiveData?.removeObservers(this@ChapterListFragment) tocLiveData = App.db.bookChapterDao().observeByBook(viewModel.bookUrl) - tocLiveData?.observe(viewLifecycleOwner, Observer { + tocLiveData?.observe(viewLifecycleOwner, { adapter.setItems(it) if (!scrollToDurChapter) { mLayoutManager.scrollToPositionWithOffset(durChapterIndex, 0) @@ -124,7 +123,7 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragme } else { tocLiveData?.removeObservers(this) tocLiveData = App.db.bookChapterDao().liveDataSearch(viewModel.bookUrl, newText) - tocLiveData?.observe(viewLifecycleOwner, Observer { + tocLiveData?.observe(viewLifecycleOwner, { adapter.setItems(it) }) } diff --git a/app/src/main/java/io/legado/app/ui/book/download/DownloadActivity.kt b/app/src/main/java/io/legado/app/ui/book/download/DownloadActivity.kt index ecb9c6b67..d4c629381 100644 --- a/app/src/main/java/io/legado/app/ui/book/download/DownloadActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/download/DownloadActivity.kt @@ -6,7 +6,6 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.snackbar.Snackbar import io.legado.app.App @@ -129,7 +128,7 @@ class DownloadActivity : VMBaseActivity(R.layout.activity_dow AppConst.bookGroupNone.groupId -> App.db.bookDao().observeNoGroup() else -> App.db.bookDao().observeByGroup(groupId) } - booksLiveData?.observe(this, Observer { list -> + booksLiveData?.observe(this, { list -> val booksDownload = list.filter { it.isOnLineTxt() } @@ -147,7 +146,7 @@ class DownloadActivity : VMBaseActivity(R.layout.activity_dow private fun initGroupData() { groupLiveData?.removeObservers(this) groupLiveData = App.db.bookGroupDao().liveDataAll() - groupLiveData?.observe(this, Observer { + groupLiveData?.observe(this, { groupList.clear() groupList.addAll(it) adapter.notifyDataSetChanged() diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt index dbba6b63e..a447bb9e1 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowActivity.kt @@ -1,7 +1,6 @@ package io.legado.app.ui.book.explore import android.os.Bundle -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import io.legado.app.R @@ -27,7 +26,7 @@ class ExploreShowActivity : VMBaseActivity(R.layout.activi override fun onActivityCreated(savedInstanceState: Bundle?) { title_bar.title = intent.getStringExtra("exploreName") initRecyclerView() - viewModel.booksData.observe(this, Observer { upData(it) }) + viewModel.booksData.observe(this, { upData(it) }) viewModel.initData(intent) } diff --git a/app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt index 73bdd8595..d5efe8126 100644 --- a/app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt @@ -10,7 +10,6 @@ import android.view.View import android.view.ViewGroup import android.widget.EditText import androidx.appcompat.widget.Toolbar -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager @@ -78,7 +77,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener tv_ok.setTextColor(requireContext().accentColor) tv_ok.visible() tv_ok.onClick { dismiss() } - App.db.bookGroupDao().liveDataAll().observe(viewLifecycleOwner, Observer { + App.db.bookGroupDao().liveDataAll().observe(viewLifecycleOwner, { val diffResult = DiffUtil.calculateDiff(GroupDiffCallBack(ArrayList(adapter.getItems()), it)) adapter.setItems(it, diffResult) diff --git a/app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt b/app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt index df058b901..7a83ab140 100644 --- a/app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt @@ -11,7 +11,6 @@ import android.view.ViewGroup import android.widget.EditText import androidx.appcompat.widget.Toolbar import androidx.fragment.app.FragmentManager -import androidx.lifecycle.Observer import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -113,7 +112,7 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener } private fun initData() { - App.db.bookGroupDao().liveDataAll().observe(viewLifecycleOwner, Observer { + App.db.bookGroupDao().liveDataAll().observe(viewLifecycleOwner, { adapter.setItems(it) }) } 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 906cacaf7..2591a30c4 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 @@ -9,7 +9,6 @@ import android.view.Menu import android.view.MenuItem import android.widget.CheckBox import android.widget.LinearLayout -import androidx.lifecycle.Observer import com.bumptech.glide.RequestBuilder import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestOptions.bitmapTransform @@ -66,8 +65,8 @@ class BookInfoActivity : scroll_view.setBackgroundColor(backgroundColor) fl_action.setBackgroundColor(bottomBackground) tv_shelf.setTextColor(getPrimaryTextColor(ColorUtils.isColorLight(bottomBackground))) - viewModel.bookData.observe(this, Observer { showBook(it) }) - viewModel.chapterListData.observe(this, Observer { upLoading(false, it) }) + viewModel.bookData.observe(this, { showBook(it) }) + viewModel.chapterListData.observe(this, { upLoading(false, it) }) viewModel.initData(intent) initOnClick() } 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 ce8fe76fc..3e4986bde 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 @@ -7,7 +7,6 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import androidx.documentfile.provider.DocumentFile -import androidx.lifecycle.Observer import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.data.entities.Book @@ -30,7 +29,7 @@ class BookInfoEditActivity : get() = getViewModel(BookInfoEditViewModel::class.java) override fun onActivityCreated(savedInstanceState: Bundle?) { - viewModel.bookData.observe(this, Observer { upView(it) }) + viewModel.bookData.observe(this, { upView(it) }) if (viewModel.bookData.value == null) { intent.getStringExtra("bookUrl")?.let { viewModel.loadBook(it) diff --git a/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt b/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt index 994b7d8ca..86c5e5ecd 100644 --- a/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/local/ImportBookActivity.kt @@ -12,7 +12,6 @@ import android.view.View import androidx.appcompat.widget.PopupMenu import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R @@ -114,7 +113,7 @@ class ImportBookActivity : VMBaseActivity(R.layout.activity private fun initData() { localUriLiveData?.removeObservers(this) localUriLiveData = App.db.bookDao().observeLocalUri() - localUriLiveData?.observe(this, Observer { + localUriLiveData?.observe(this, { adapter.upBookHas(it) }) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt index 22ae62c18..4603a0d33 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/TocRegexDialog.kt @@ -11,7 +11,6 @@ import android.view.ViewGroup import androidx.appcompat.widget.Toolbar import androidx.fragment.app.FragmentManager import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -104,7 +103,7 @@ class TocRegexDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { private fun initData() { tocRegexLiveData?.removeObservers(viewLifecycleOwner) tocRegexLiveData = App.db.txtTocRule().observeAll() - tocRegexLiveData?.observe(viewLifecycleOwner, Observer { tocRules -> + tocRegexLiveData?.observe(viewLifecycleOwner, { tocRules -> initSelectedName(tocRules) adapter.setItems(tocRules) }) diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt index acf63099b..681e9aa9e 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt @@ -7,7 +7,6 @@ import android.view.View.GONE import android.view.View.VISIBLE import androidx.appcompat.widget.SearchView import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.flexbox.FlexboxLayoutManager @@ -176,17 +175,17 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se } private fun initLiveData() { - App.db.bookSourceDao().liveGroupEnabled().observe(this, Observer { + App.db.bookSourceDao().liveGroupEnabled().observe(this, { groups.clear() it.map { group -> groups.addAll(group.splitNotBlank(",", ";")) } upGroupMenu() }) - viewModel.searchBookLiveData.observe(this, Observer { + viewModel.searchBookLiveData.observe(this, { upSearchItems(it) }) - viewModel.isSearchLiveData.observe(this, Observer { + viewModel.isSearchLiveData.observe(this, { if (it) { startSearch() } else { @@ -254,7 +253,7 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se rv_bookshelf_search.gone() } else { bookData = App.db.bookDao().liveDataSearch(key) - bookData?.observe(this, Observer { + bookData?.observe(this, { if (it.isEmpty()) { tv_book_show.gone() rv_bookshelf_search.gone() @@ -272,7 +271,7 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se } else { App.db.searchKeywordDao().liveDataSearch(key) } - historyData?.observe(this, Observer { + historyData?.observe(this, { historyKeyAdapter.setItems(it) if (it.isEmpty()) { tv_clear_history.invisible() diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt index da57654f4..c06110f12 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt @@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.SearchView import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager @@ -164,7 +163,7 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity App.db.bookSourceDao().liveDataSearch("%$searchKey%") } } - bookSourceLiveDate?.observe(this, Observer { data -> + bookSourceLiveDate?.observe(this, { data -> val sourceList = when (sort) { 1 -> data.sortedBy { it.weight } 2 -> data.sortedBy { it.bookSourceName } @@ -179,7 +178,7 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity } private fun initLiveDataGroup() { - App.db.bookSourceDao().liveGroup().observe(this, Observer { + App.db.bookSourceDao().liveGroup().observe(this, { groups.clear() it.map { group -> groups.addAll(group.splitNotBlank(",", ";")) diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt index b4c8f70d6..3724694d4 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt @@ -11,7 +11,6 @@ import android.view.ViewGroup import android.widget.EditText import androidx.appcompat.widget.Toolbar import androidx.fragment.app.DialogFragment -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R @@ -69,7 +68,7 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener { } private fun initData() { - App.db.bookSourceDao().liveGroup().observe(viewLifecycleOwner, Observer { + App.db.bookSourceDao().liveGroup().observe(viewLifecycleOwner, { val groups = linkedSetOf() it.map { group -> groups.addAll(group.splitNotBlank(",", ";")) diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt index f0731f1ed..c03292011 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt @@ -3,7 +3,6 @@ package io.legado.app.ui.main.bookshelf.books import android.os.Bundle import android.view.View import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager @@ -106,7 +105,7 @@ class BooksFragment : BaseFragment(R.layout.fragment_books), AppConst.bookGroupNone.groupId -> App.db.bookDao().observeNoGroup() else -> App.db.bookDao().observeByGroup(groupId) } - bookshelfLiveData?.observe(this, Observer { list -> + bookshelfLiveData?.observe(this, { list -> val books = when (getPrefInt(PreferKey.bookshelfSort)) { 1 -> list.sortedByDescending { it.latestChapterTime } 2 -> list.sortedBy { it.name } diff --git a/app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt b/app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt index 334ce9e64..82ccf867f 100644 --- a/app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/rss/RssFragment.kt @@ -4,7 +4,6 @@ import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.view.View -import androidx.lifecycle.Observer import androidx.recyclerview.widget.GridLayoutManager import io.legado.app.App import io.legado.app.R @@ -56,7 +55,7 @@ class RssFragment : VMBaseFragment(R.layout.fragment_rss), } private fun initData() { - App.db.rssSourceDao().liveEnabled().observe(viewLifecycleOwner, Observer { + App.db.rssSourceDao().liveEnabled().observe(viewLifecycleOwner, { if (it.isEmpty()) { getViewModelOfActivity(MainViewModel::class.java).initRss() } diff --git a/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt index adc0d5cbb..17d5bcd53 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt @@ -11,7 +11,6 @@ import android.view.ViewGroup import android.widget.EditText import androidx.appcompat.widget.Toolbar import androidx.fragment.app.DialogFragment -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R @@ -69,7 +68,7 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener { recycler_view.layoutManager = LinearLayoutManager(requireContext()) recycler_view.addItemDecoration(VerticalDivider(requireContext())) recycler_view.adapter = adapter - App.db.replaceRuleDao().liveGroup().observe(viewLifecycleOwner, Observer { + App.db.replaceRuleDao().liveGroup().observe(viewLifecycleOwner, { val groups = linkedSetOf() it.map { group -> groups.addAll(group.splitNotBlank(",", ";")) diff --git a/app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt index 554bf635b..adf9fbb03 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt @@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.SearchView import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager @@ -133,7 +132,7 @@ class ReplaceRuleActivity : VMBaseActivity(R.layout.activi } else { App.db.replaceRuleDao().liveDataSearch(key) } - replaceRuleLiveData?.observe(this, Observer { + replaceRuleLiveData?.observe(this, { if (dataInit) { setResult(Activity.RESULT_OK) } @@ -146,7 +145,7 @@ class ReplaceRuleActivity : VMBaseActivity(R.layout.activi } private fun observeGroupData() { - App.db.replaceRuleDao().liveGroup().observe(this, Observer { + App.db.replaceRuleDao().liveGroup().observe(this, { groups.clear() it.map { group -> groups.addAll(group.splitNotBlank(",", ";")) diff --git a/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt b/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt index 012a042a9..1ee635f56 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt @@ -11,7 +11,6 @@ import android.widget.EditText import android.widget.PopupWindow import androidx.appcompat.widget.Toolbar import androidx.fragment.app.FragmentManager -import androidx.lifecycle.Observer import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.constant.AppConst @@ -71,7 +70,7 @@ class ReplaceEditDialog : BaseDialogFragment(), tool_bar.inflateMenu(R.menu.replace_edit) tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) - viewModel.replaceRuleData.observe(viewLifecycleOwner, Observer { + viewModel.replaceRuleData.observe(viewLifecycleOwner, { upReplaceView(it) }) arguments?.let { diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt index f2329cb84..f9b684592 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesFragment.kt @@ -3,7 +3,6 @@ package io.legado.app.ui.rss.article import android.os.Bundle import android.view.View import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -87,7 +86,7 @@ class RssArticlesFragment : VMBaseFragment(R.layout.fragme activityViewModel.url?.let { rssArticlesData?.removeObservers(this) rssArticlesData = App.db.rssArticleDao().liveByOriginSort(it, viewModel.sortName) - rssArticlesData?.observe(viewLifecycleOwner, Observer { list -> + rssArticlesData?.observe(viewLifecycleOwner, { list -> adapter.setItems(list) }) } @@ -104,7 +103,7 @@ class RssArticlesFragment : VMBaseFragment(R.layout.fragme } override fun observeLiveBus() { - viewModel.loadFinally.observe(viewLifecycleOwner, Observer { + viewModel.loadFinally.observe(viewLifecycleOwner, { refresh_recycler_view.stopLoading() if (it) { loadMoreView.startLoad() diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt index 41fad7292..307374f9f 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssSortActivity.kt @@ -8,7 +8,6 @@ import android.view.MenuItem import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentStatePagerAdapter -import androidx.lifecycle.Observer import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.ui.rss.source.edit.RssSourceEditActivity @@ -30,7 +29,7 @@ class RssSortActivity : VMBaseActivity(R.layout.activity_rss_a adapter = TabFragmentPageAdapter(supportFragmentManager) tab_layout.setupWithViewPager(view_pager) view_pager.adapter = adapter - viewModel.titleLiveData.observe(this, Observer { + viewModel.titleLiveData.observe(this, { title_bar.title = it }) viewModel.initData(intent) { @@ -85,7 +84,7 @@ class RssSortActivity : VMBaseActivity(R.layout.activity_rss_a } } - private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) : + private inner class TabFragmentPageAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { override fun getItemPosition(`object`: Any): Int { diff --git a/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt b/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt index f50329296..09f6d1549 100644 --- a/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/favorites/RssFavoritesActivity.kt @@ -2,7 +2,6 @@ package io.legado.app.ui.rss.favorites import android.os.Bundle import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R @@ -37,7 +36,7 @@ class RssFavoritesActivity : BaseActivity(R.layout.activity_rss_favorites), private fun initData() { liveData?.removeObservers(this) liveData = App.db.rssStarDao().liveAll() - liveData?.observe(this, Observer { + liveData?.observe(this, { adapter.setItems(it) }) } diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt index e11293cc4..908afa311 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssActivity.kt @@ -8,7 +8,6 @@ import android.os.Bundle import android.view.* import android.webkit.* import androidx.core.view.size -import androidx.lifecycle.Observer import io.legado.app.R import io.legado.app.base.VMBaseActivity import io.legado.app.lib.theme.DrawableUtils @@ -155,7 +154,7 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r @SuppressLint("SetJavaScriptEnabled") private fun initLiveData() { - viewModel.contentLiveData.observe(this, Observer { content -> + viewModel.contentLiveData.observe(this, { content -> viewModel.rssArticle?.let { upJavaScriptEnable() val url = NetworkUtils.getAbsoluteURL(it.origin, it.link) @@ -179,7 +178,7 @@ class ReadRssActivity : VMBaseActivity(R.layout.activity_rss_r } } }) - viewModel.urlLiveData.observe(this, Observer { + viewModel.urlLiveData.observe(this, { upJavaScriptEnable() web_view.loadUrl(it.url, it.headerMap) }) diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt index 5f78beeda..bfb876e0b 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt @@ -10,7 +10,6 @@ import android.view.View import android.view.ViewGroup import android.widget.EditText import androidx.appcompat.widget.Toolbar -import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R @@ -63,7 +62,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener tv_ok.setTextColor(requireContext().accentColor) tv_ok.visible() tv_ok.onClick { dismiss() } - App.db.rssSourceDao().liveGroup().observe(viewLifecycleOwner, Observer { + App.db.rssSourceDao().liveGroup().observe(viewLifecycleOwner, { val groups = linkedSetOf() it.map { group -> groups.addAll(group.splitNotBlank(",", ";")) diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt index d28ae94a8..2f9050f37 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt @@ -11,7 +11,6 @@ import androidx.appcompat.widget.PopupMenu import androidx.appcompat.widget.SearchView import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.LiveData -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager @@ -142,7 +141,7 @@ class RssSourceActivity : VMBaseActivity(R.layout.activity_r } private fun initLiveDataGroup() { - App.db.rssSourceDao().liveGroup().observe(this, Observer { + App.db.rssSourceDao().liveGroup().observe(this, { groups.clear() it.map { group -> groups.addAll(group.splitNotBlank(",", ";")) @@ -195,7 +194,7 @@ class RssSourceActivity : VMBaseActivity(R.layout.activity_r } else { App.db.rssSourceDao().liveSearch("%$key%") } - sourceLiveData?.observe(this, Observer { + sourceLiveData?.observe(this, { val diffResult = DiffUtil .calculateDiff(DiffCallBack(adapter.getItems(), it)) adapter.setItems(it, diffResult) From c23173f668592bdc6f9549f8c2f3d615ec1500cf Mon Sep 17 00:00:00 2001 From: AndyBernie Date: Wed, 26 Aug 2020 18:32:14 +0800 Subject: [PATCH 32/90] =?UTF-8?q?=E4=BF=9D=E5=AD=98Cookie=E6=97=B6?= =?UTF-8?q?=E4=BB=A5=E4=BA=8C=E7=BA=A7=E5=9F=9F=E5=90=8D=E4=B8=BAurl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/help/http/CookieStore.kt | 8 ++++---- .../legado/app/model/analyzeRule/AnalyzeUrl.kt | 16 ++-------------- .../java/io/legado/app/utils/NetworkUtils.kt | 8 ++++++++ 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/CookieStore.kt b/app/src/main/java/io/legado/app/help/http/CookieStore.kt index 3f40cfbe0..067435ddb 100644 --- a/app/src/main/java/io/legado/app/help/http/CookieStore.kt +++ b/app/src/main/java/io/legado/app/help/http/CookieStore.kt @@ -6,13 +6,13 @@ import com.franmontiel.persistentcookiejar.persistence.SerializableCookie import io.legado.app.App import io.legado.app.data.entities.Cookie import io.legado.app.help.coroutine.Coroutine - +import io.legado.app.utils.NetworkUtils object CookieStore : CookiePersistor { fun setCookie(url: String, cookie: String?) { Coroutine.async { - val cookieBean = Cookie(url, cookie ?: "") + val cookieBean = Cookie(NetworkUtils.getSubDomain(url), cookie ?: "") App.db.cookieDao().insert(cookieBean) } } @@ -33,12 +33,12 @@ object CookieStore : CookiePersistor { } fun getCookie(url: String): String { - val cookieBean = App.db.cookieDao().get(url) + val cookieBean = App.db.cookieDao().get(NetworkUtils.getSubDomain(url)) return cookieBean?.cookie ?: "" } fun removeCookie(url: String) { - App.db.cookieDao().delete(url) + App.db.cookieDao().delete(NetworkUtils.getSubDomain(url)) } private fun cookieToMap(cookie: String): MutableMap { diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 56b1f1c0e..561e3a320 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -348,21 +348,9 @@ class AnalyzeUrl( @Throws(Exception::class) fun getImageBytes(tag: String): ByteArray? { - //资源为本站的资源,保留cookie - //图片盗链的不保留当前的cookie,可由js生成图片源站的cookie val cookie = CookieStore.getCookie(tag) - NetworkUtils.getBaseUrl(url)?.let { - val regex: Any - regex = if (it.lastIndexOf(".") != it.indexOf(".")) { - it.substring(it.indexOf(".") + 1).toRegex() - } else { - it.substring(it.lastIndexOf("/") + 1).toRegex() - } - if (regex.containsMatchIn(tag)) { - if (cookie.isNotEmpty()) { - headerMap["Cookie"] += cookie - } - } + if (cookie.isNotEmpty()) { + headerMap["Cookie"] += cookie } headerMap[UA_NAME] = headerMap[UA_NAME] ?: userAgent return if (fieldMap.isEmpty()) { diff --git a/app/src/main/java/io/legado/app/utils/NetworkUtils.kt b/app/src/main/java/io/legado/app/utils/NetworkUtils.kt index b706a8d5e..4a3e236cb 100644 --- a/app/src/main/java/io/legado/app/utils/NetworkUtils.kt +++ b/app/src/main/java/io/legado/app/utils/NetworkUtils.kt @@ -98,6 +98,14 @@ object NetworkUtils { } else url.substring(0, index) } + fun getSubDomain(url: String?): String { + var baseUrl = getBaseUrl(url) + if (baseUrl == null) return "" + return if (baseUrl.indexOf(".") == baseUrl.lastIndexOf(".")) { + baseUrl.substring(baseUrl.lastIndexOf("/")+1) + } else baseUrl.substring(baseUrl.indexOf(".")+1) + } + /** * Get local Ip address. */ From cd4969c97df6b9a948bcc6a8b71a74ffbff2b445 Mon Sep 17 00:00:00 2001 From: AndyBernie Date: Wed, 26 Aug 2020 18:52:40 +0800 Subject: [PATCH 33/90] =?UTF-8?q?=E4=B8=BAjava.ajax(url)=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=BB=98=E8=AE=A4ua?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 561e3a320..3c75a20b3 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -191,6 +191,7 @@ class AnalyzeUrl( ?.let { headerMap.putAll(it) } } } + headerMap[UA_NAME] = headerMap[UA_NAME] ?: userAgent charset = option.charset body = if (option.body is String) { option.body @@ -352,7 +353,6 @@ class AnalyzeUrl( if (cookie.isNotEmpty()) { headerMap["Cookie"] += cookie } - headerMap[UA_NAME] = headerMap[UA_NAME] ?: userAgent return if (fieldMap.isEmpty()) { HttpHelper.getBytes(url, mapOf(), headerMap) } else { From f571b9d17633497334e9c233d82580883e349a02 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 21:27:52 +0800 Subject: [PATCH 34/90] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E4=B9=A6=E7=B1=8D=E7=BC=96=E7=A0=81=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 5 ++++ .../io/legado/app/service/help/ReadBook.kt | 9 ++++++ .../java/io/legado/app/ui/book/read/Help.kt | 29 ++++++++++++++++--- .../app/ui/book/read/ReadBookActivity.kt | 9 ++++-- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index c7d5926d7..3b7719f85 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,11 @@ * 关注合作公众号 **[小说拾遗]()** 获取好看的小说。 - 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2020/08/26** +* js添加java.encodeURI(speakText),用于解决js编码时有~的语句朗读不出来 +* 修复书名太长删除阅读记录按钮不显示的bug +* 完成本地书籍编码选择 + **2020/08/25** * 阅读记录可以删除了 * 修复翻页模式选择颜色问题 diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index 2827ba5ee..e15af105b 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -376,6 +376,14 @@ object ReadBook { private val imageStyle get() = webBook?.bookSource?.ruleContent?.imageStyle + fun setCharset(charset: String) { + book?.let { + it.charset = charset + callBack?.loadChapterList(it) + } + saveRead() + } + fun saveRead() { Coroutine.async { book?.let { book -> @@ -392,6 +400,7 @@ object ReadBook { } interface CallBack { + fun loadChapterList(book: Book) fun upContent(relativePosition: Int = 0, resetPageOffset: Boolean = true) fun upView() fun pageChanged() diff --git a/app/src/main/java/io/legado/app/ui/book/read/Help.kt b/app/src/main/java/io/legado/app/ui/book/read/Help.kt index ab86ed909..c789d6ae1 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/Help.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/Help.kt @@ -14,15 +14,13 @@ import io.legado.app.R import io.legado.app.data.entities.Bookmark import io.legado.app.help.AppConfig import io.legado.app.help.ReadBookConfig -import io.legado.app.lib.dialogs.alert -import io.legado.app.lib.dialogs.customView -import io.legado.app.lib.dialogs.noButton -import io.legado.app.lib.dialogs.yesButton +import io.legado.app.lib.dialogs.* import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ThemeStore import io.legado.app.lib.theme.backgroundColor import io.legado.app.service.help.Download import io.legado.app.service.help.ReadBook +import io.legado.app.ui.widget.text.AutoCompleteTextView import io.legado.app.utils.applyTint import io.legado.app.utils.requestInputMethod import kotlinx.android.synthetic.main.dialog_download_choice.view.* @@ -181,4 +179,27 @@ object Help { noButton() }.show().applyTint().requestInputMethod() } + + @SuppressLint("InflateParams") + fun showCharsetConfig(context: Context) = with(context) { + val charsets = + arrayListOf("UTF-8", "GB2312", "GBK", "Unicode", "UTF-16", "UTF-16LE", "ASCII") + alert(R.string.set_charset) { + var editText: AutoCompleteTextView? = null + customView { + layoutInflater.inflate(R.layout.dialog_edit_text, null).apply { + editText = edit_view + edit_view.setFilterValues(charsets) + edit_view.setText(ReadBook.book?.charset) + } + } + okButton { + val text = editText?.text?.toString() + text?.let { + ReadBook.setCharset(it) + } + } + cancelButton() + }.show().applyTint() + } } \ No newline at end of file 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 a333d46d3..8a872f1d8 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 @@ -251,8 +251,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo R.id.menu_copy_text -> TextDialog.show(supportFragmentManager, ReadBook.curTextChapter?.getContent()) R.id.menu_update_toc -> ReadBook.book?.let { - ReadBook.upMsg(getString(R.string.toc_updateing)) - viewModel.loadChapterList(it) + loadChapterList(it) } R.id.menu_enable_replace -> ReadBook.book?.let { it.useReplaceRule = !it.useReplaceRule @@ -275,6 +274,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo Pair("loginUrl", it.loginUrl) ) } + R.id.menu_set_charset -> Help.showCharsetConfig(this) } return super.onCompatOptionsItemSelected(item) } @@ -515,6 +515,11 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo return false } + override fun loadChapterList(book: Book) { + ReadBook.upMsg(getString(R.string.toc_updateing)) + viewModel.loadChapterList(book) + } + /** * 内容加载完成 */ From dcce2d864c0c8a16ce125dfa2f09a4f12383336b Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 21:45:27 +0800 Subject: [PATCH 35/90] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E4=B9=A6=E7=B1=8D=E7=BC=96=E7=A0=81=E9=80=89=E6=8B=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/model/localBook/AnalyzeTxtFile.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/model/localBook/AnalyzeTxtFile.kt b/app/src/main/java/io/legado/app/model/localBook/AnalyzeTxtFile.kt index c4bfb6ea6..41caca4a9 100644 --- a/app/src/main/java/io/legado/app/model/localBook/AnalyzeTxtFile.kt +++ b/app/src/main/java/io/legado/app/model/localBook/AnalyzeTxtFile.kt @@ -20,7 +20,9 @@ class AnalyzeTxtFile { @Throws(Exception::class) fun analyze(book: Book): ArrayList { val bookFile = getBookFile(book) - book.charset = EncodingDetect.getEncode(bookFile) + if (book.charset == null) { + book.charset = EncodingDetect.getEncode(bookFile) + } charset = book.fileCharset() val rulePattern = if (book.tocUrl.isNotEmpty()) { Pattern.compile(book.tocUrl, Pattern.MULTILINE) From cb64d0973e3dfc284c3d5407eb84499118770549 Mon Sep 17 00:00:00 2001 From: gedoor Date: Wed, 26 Aug 2020 22:21:56 +0800 Subject: [PATCH 36/90] =?UTF-8?q?=E5=B7=B2=E4=B8=8B=E8=BD=BD=E7=AB=A0?= =?UTF-8?q?=E8=8A=82=E6=B7=BB=E5=8A=A0=E6=9B=B4=E6=98=8E=E6=98=BE=E7=9A=84?= =?UTF-8?q?=E6=A0=87=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/book/chapterlist/ChapterListAdapter.kt | 11 ++++--- app/src/main/res/layout/item_chapter_list.xml | 31 +++++++++++++++---- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt index 6ea580b31..f1043a2a4 100644 --- a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt @@ -1,7 +1,7 @@ package io.legado.app.ui.book.chapterlist import android.content.Context -import android.widget.TextView +import android.view.View import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter @@ -33,12 +33,12 @@ class ChapterListAdapter(context: Context, val callback: Callback) : tv_tag.visible() } upHasCache( - tv_chapter_name, + this, cacheFileNames.contains(BookHelp.formatChapterName(item)) ) } else { upHasCache( - tv_chapter_name, + this, cacheFileNames.contains(BookHelp.formatChapterName(item)) ) } @@ -53,8 +53,9 @@ class ChapterListAdapter(context: Context, val callback: Callback) : } } - private fun upHasCache(textView: TextView, contains: Boolean) { - textView.paint.isFakeBoldText = contains + private fun upHasCache(itemView: View, contains: Boolean) = itemView.apply { + tv_chapter_name.paint.isFakeBoldText = contains + iv_checked.visible(contains) } interface Callback { diff --git a/app/src/main/res/layout/item_chapter_list.xml b/app/src/main/res/layout/item_chapter_list.xml index bd678b4fe..aea6a6cfd 100644 --- a/app/src/main/res/layout/item_chapter_list.xml +++ b/app/src/main/res/layout/item_chapter_list.xml @@ -1,5 +1,6 @@ - + android:singleLine="true" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toLeftOf="@+id/iv_checked" /> + android:singleLine="true" + app:layout_constraintTop_toBottomOf="@+id/tv_chapter_name" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toLeftOf="@+id/iv_checked" /> - \ No newline at end of file + + + \ No newline at end of file From 0139621aba0a1ada6b5efa2f1277d9b087822afb Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 27 Aug 2020 14:56:34 +0800 Subject: [PATCH 37/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 12 ++++++------ .../legado/app/ui/filechooser/FileChooserDialog.kt | 5 +++-- .../app/ui/replacerule/edit/ReplaceEditDialog.kt | 4 ++-- .../io/legado/app/ui/widget/font/FontSelectDialog.kt | 5 +++-- app/src/main/res/layout/dialog_file_chooser.xml | 7 +++++-- app/src/main/res/layout/dialog_font_select.xml | 7 +++++-- 6 files changed, 24 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 3c75a20b3..1a1077da0 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -3,6 +3,8 @@ package io.legado.app.model.analyzeRule import android.annotation.SuppressLint import android.text.TextUtils import androidx.annotation.Keep +import com.bumptech.glide.load.model.GlideUrl +import com.bumptech.glide.load.model.LazyHeaders import io.legado.app.constant.AppConst.SCRIPT_ENGINE import io.legado.app.constant.AppConst.UA_NAME import io.legado.app.constant.AppConst.userAgent @@ -22,8 +24,6 @@ import java.net.URLEncoder import java.util.* import java.util.regex.Pattern import javax.script.SimpleBindings -import com.bumptech.glide.load.model.GlideUrl -import com.bumptech.glide.load.model.LazyHeaders /** * Created by GKF on 2018/1/24. @@ -394,11 +394,11 @@ class AnalyzeUrl( fun getGlideUrl(): Any? { var glideUrl: Any = url if(headerMap.isNotEmpty()) { - val Headers = LazyHeaders.Builder() - headerMap.forEach {(key, value) -> - Headers.addHeader(key, value) + val headers = LazyHeaders.Builder() + headerMap.forEach {(key, value) -> + headers.addHeader(key, value) } - glideUrl = GlideUrl(url, Headers.build()) + glideUrl = GlideUrl(url, headers.build()) } return glideUrl } diff --git a/app/src/main/java/io/legado/app/ui/filechooser/FileChooserDialog.kt b/app/src/main/java/io/legado/app/ui/filechooser/FileChooserDialog.kt index f1e6a7bc9..fb2e5ac19 100644 --- a/app/src/main/java/io/legado/app/ui/filechooser/FileChooserDialog.kt +++ b/app/src/main/java/io/legado/app/ui/filechooser/FileChooserDialog.kt @@ -12,7 +12,7 @@ import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import io.legado.app.R -import io.legado.app.constant.Theme +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.filechooser.adapter.FileAdapter import io.legado.app.ui.filechooser.adapter.PathAdapter import io.legado.app.ui.widget.recycler.VerticalDivider @@ -93,6 +93,7 @@ class FileChooserDialog : DialogFragment(), override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + tool_bar.setBackgroundColor(primaryColor) view.setBackgroundResource(R.color.background_card) arguments?.let { requestCode = it.getInt("requestCode") @@ -129,7 +130,7 @@ class FileChooserDialog : DialogFragment(), tool_bar.menu.add(menuTitle) } } - tool_bar.menu.applyTint(requireContext(), Theme.getTheme()) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) } diff --git a/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt b/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt index 1ee635f56..4bbfb44be 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/edit/ReplaceEditDialog.kt @@ -15,7 +15,7 @@ import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.constant.AppConst import io.legado.app.data.entities.ReplaceRule -import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.widget.KeyboardToolPop import io.legado.app.utils.applyTint import io.legado.app.utils.getViewModel @@ -65,7 +65,7 @@ class ReplaceEditDialog : BaseDialogFragment(), } override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { - tool_bar.setBackgroundColor(bottomBackground) + tool_bar.setBackgroundColor(primaryColor) mSoftKeyboardTool = KeyboardToolPop(requireContext(), AppConst.keyboardToolChars, this) tool_bar.inflateMenu(R.menu.replace_edit) tool_bar.menu.applyTint(requireContext()) diff --git a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt index 57611e8ad..b10371864 100644 --- a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt +++ b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt @@ -22,7 +22,7 @@ import io.legado.app.help.AppConfig import io.legado.app.help.permission.Permissions import io.legado.app.help.permission.PermissionsCompat import io.legado.app.lib.dialogs.alert -import io.legado.app.lib.theme.bottomBackground +import io.legado.app.lib.theme.primaryColor import io.legado.app.ui.filechooser.FileChooserDialog import io.legado.app.ui.filechooser.FilePicker import io.legado.app.utils.* @@ -59,9 +59,10 @@ class FontSelectDialog : BaseDialogFragment(), } override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) { - tool_bar.setBackgroundColor(requireContext().bottomBackground) + tool_bar.setBackgroundColor(primaryColor) tool_bar.setTitle(R.string.select_font) tool_bar.inflateMenu(R.menu.font_select) + tool_bar.menu.applyTint(requireContext()) tool_bar.setOnMenuItemClickListener(this) adapter = FontAdapter(requireContext(), this) recycler_view.layoutManager = LinearLayoutManager(context) diff --git a/app/src/main/res/layout/dialog_file_chooser.xml b/app/src/main/res/layout/dialog_file_chooser.xml index 7615ba752..efe1db737 100644 --- a/app/src/main/res/layout/dialog_file_chooser.xml +++ b/app/src/main/res/layout/dialog_file_chooser.xml @@ -1,5 +1,6 @@ + android:layout_height="wrap_content" + android:theme="?attr/actionBarStyle" + app:titleTextAppearance="@style/ToolbarTitle" + app:popupTheme="@style/AppTheme.PopupOverlay" /> + android:layout_height="wrap_content" + android:theme="?attr/actionBarStyle" + app:titleTextAppearance="@style/ToolbarTitle" + app:popupTheme="@style/AppTheme.PopupOverlay" /> Date: Thu, 27 Aug 2020 15:04:11 +0800 Subject: [PATCH 38/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 1a1077da0..65d513831 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -50,7 +50,7 @@ class AnalyzeUrl( private var baseUrl: String = "" lateinit var url: String private set - var path: String? = null + lateinit var urlHasQuery: String private set val headerMap = HashMap() private var queryStr: String? = null @@ -174,6 +174,7 @@ class AnalyzeUrl( private fun initUrl() { var urlArray = ruleUrl.split(",[^\\{]*".toRegex(), 2) url = urlArray[0] + urlHasQuery = urlArray[0] NetworkUtils.getBaseUrl(url)?.let { baseUrl = it } @@ -392,13 +393,13 @@ class AnalyzeUrl( @Throws(Exception::class) fun getGlideUrl(): Any? { - var glideUrl: Any = url + var glideUrl: Any = urlHasQuery if(headerMap.isNotEmpty()) { val headers = LazyHeaders.Builder() headerMap.forEach {(key, value) -> headers.addHeader(key, value) } - glideUrl = GlideUrl(url, headers.build()) + glideUrl = GlideUrl(urlHasQuery, headers.build()) } return glideUrl } From ea5e975d08514a705183668b47759a1344bf5c29 Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 27 Aug 2020 15:09:05 +0800 Subject: [PATCH 39/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/layout/dialog_book_group_picker.xml | 7 +++++-- app/src/main/res/layout/dialog_change_cover.xml | 1 - app/src/main/res/layout/dialog_toc_regex.xml | 7 +++++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/layout/dialog_book_group_picker.xml b/app/src/main/res/layout/dialog_book_group_picker.xml index dbf0e1310..95317f693 100644 --- a/app/src/main/res/layout/dialog_book_group_picker.xml +++ b/app/src/main/res/layout/dialog_book_group_picker.xml @@ -1,15 +1,18 @@ + android:layout_height="wrap_content" + android:theme="?attr/actionBarStyle" + app:titleTextAppearance="@style/ToolbarTitle" + app:popupTheme="@style/AppTheme.PopupOverlay" /> + android:layout_height="wrap_content" + android:theme="?attr/actionBarStyle" + app:titleTextAppearance="@style/ToolbarTitle" + app:popupTheme="@style/AppTheme.PopupOverlay" /> Date: Thu, 27 Aug 2020 15:21:42 +0800 Subject: [PATCH 40/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 65d513831..4ac7227d8 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -59,10 +59,11 @@ class AnalyzeUrl( private var body: String? = null private var requestBody: RequestBody? = null private var method = RequestMethod.GET + private val splitUrlRegex = Regex(",[^\\{]*") init { baseUrl?.let { - this.baseUrl = it.split(",[^\\{]*".toRegex(), 1)[0] + this.baseUrl = it.split(splitUrlRegex, 1)[0] } headerMapF?.let { headerMap.putAll(it) } //替换参数 @@ -172,7 +173,7 @@ class AnalyzeUrl( * 处理URL */ private fun initUrl() { - var urlArray = ruleUrl.split(",[^\\{]*".toRegex(), 2) + var urlArray = ruleUrl.split(splitUrlRegex, 2) url = urlArray[0] urlHasQuery = urlArray[0] NetworkUtils.getBaseUrl(url)?.let { From 912688069875dd2da2b863df6dc082a525dd453a Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 27 Aug 2020 15:22:44 +0800 Subject: [PATCH 41/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 3b7719f85..650696a06 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,10 @@ * 关注合作公众号 **[小说拾遗]()** 获取好看的小说。 - 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2020/08/27** +* 修复主题bug +* 修复封面bug + **2020/08/26** * js添加java.encodeURI(speakText),用于解决js编码时有~的语句朗读不出来 * 修复书名太长删除阅读记录按钮不显示的bug From ef504403b081d474786ebd6cc2fff22f9511e0fe Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 27 Aug 2020 17:14:52 +0800 Subject: [PATCH 42/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B0=8F=E8=AF=B4?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/constant/EventBus.kt | 2 +- .../io/legado/app/ui/main/MainActivity.kt | 2 +- .../io/legado/app/ui/main/MainViewModel.kt | 63 ++++++++++++++----- .../ui/main/bookshelf/BookshelfFragment.kt | 2 +- .../ui/main/bookshelf/books/BooksFragment.kt | 2 +- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/EventBus.kt b/app/src/main/java/io/legado/app/constant/EventBus.kt index e24ba8000..6fe8b5cea 100644 --- a/app/src/main/java/io/legado/app/constant/EventBus.kt +++ b/app/src/main/java/io/legado/app/constant/EventBus.kt @@ -3,7 +3,7 @@ package io.legado.app.constant object EventBus { const val MEDIA_BUTTON = "mediaButton" const val RECREATE = "RECREATE" - const val UP_BOOK = "sourceDebugLog" + const val UP_BOOK = "upBookToc" const val ALOUD_STATE = "aloud_state" const val TTS_PROGRESS = "ttsStart" const val TTS_DS = "ttsDs" diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt index 77a98460c..7d6c71134 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt @@ -62,7 +62,7 @@ class MainActivity : VMBaseActivity(R.layout.activity_main), //自动更新书籍 if (AppConfig.autoRefreshBook) { view_pager_main.postDelayed({ - viewModel.upChapterList() + viewModel.upAllBookToc() }, 1000) } view_pager_main.postDelayed({ 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 b0122bc8b..3917769b0 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 @@ -18,13 +18,18 @@ import io.legado.app.utils.fromJsonObject import io.legado.app.utils.postEvent import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.asCoroutineDispatcher -import kotlinx.coroutines.delay +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.Executors class MainViewModel(application: Application) : BaseViewModel(application) { - private var upTocPool = - Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher() - val updateList = hashSetOf() + val threadCount = AppConfig.threadCount + private var upTocPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher() + val updateList = CopyOnWriteArraySet() + private val bookMap = ConcurrentHashMap() + + @Volatile + private var usePoolCount = 0 override fun onCleared() { super.onCleared() @@ -36,18 +41,31 @@ class MainViewModel(application: Application) : BaseViewModel(application) { upTocPool = Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher() } - fun upChapterList() { + fun upAllBookToc() { execute { - upChapterList(App.db.bookDao().hasUpdateBooks) + upToc(App.db.bookDao().hasUpdateBooks) + } + } + + fun upToc(books: List) { + books.filter { + it.origin != BookType.local && it.canUpdate + }.forEach { + bookMap[it.bookUrl] = it + } + for (i in 0 until threadCount) { + if (usePoolCount < threadCount) { + usePoolCount++ + updateToc() + } } } - fun upChapterList(books: List) { + private fun updateToc() { execute { - books.filter { - it.origin != BookType.local && it.canUpdate - }.forEach { book -> - if (!updateList.contains(book.bookUrl)) { + bookMap.forEach { bookEntry -> + if (!updateList.contains(bookEntry.key)) { + val book = bookEntry.value App.db.bookSourceDao().getBookSource(book.origin)?.let { bookSource -> synchronized(this) { updateList.add(book.bookUrl) @@ -56,28 +74,39 @@ class MainViewModel(application: Application) : BaseViewModel(application) { WebBook(bookSource).getChapterList(book, context = upTocPool) .timeout(300000) .onSuccess(IO) { - synchronized(this) { - updateList.remove(book.bookUrl) - postEvent(EventBus.UP_BOOK, book.bookUrl) - } App.db.bookDao().update(book) App.db.bookChapterDao().delByBook(book.bookUrl) App.db.bookChapterDao().insert(*it.toTypedArray()) } .onError { + it.printStackTrace() + } + .onFinally { synchronized(this) { + bookMap.remove(bookEntry.key) updateList.remove(book.bookUrl) postEvent(EventBus.UP_BOOK, book.bookUrl) + upNext() } - it.printStackTrace() } + } ?: synchronized(this) { + bookMap.remove(bookEntry.key) + upNext() } + return@forEach } - delay(50) } } } + private fun upNext() { + if (bookMap.size > updateList.size) { + updateToc() + } else { + usePoolCount-- + } + } + fun initRss() { execute { val url = "https://gitee.com/alanskycn/yuedu/raw/master/JS/RSS/rssSource" diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt index 9abfddbd4..4444f33d7 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfFragment.kt @@ -78,7 +78,7 @@ class BookshelfFragment : VMBaseFragment(R.layout.fragment_b val group = bookGroups[tab_layout.selectedTabPosition] val fragment = fragmentMap[group.groupId] fragment?.getBooks()?.let { - activityViewModel.upChapterList(it) + activityViewModel.upToc(it) } } R.id.menu_bookshelf_layout -> configBookshelf() diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt index c03292011..ebbe310e8 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/books/BooksFragment.kt @@ -66,7 +66,7 @@ class BooksFragment : BaseFragment(R.layout.fragment_books), refresh_layout.setColorSchemeColors(accentColor) refresh_layout.setOnRefreshListener { refresh_layout.isRefreshing = false - activityViewModel.upChapterList(booksAdapter.getItems()) + activityViewModel.upToc(booksAdapter.getItems()) } val bookshelfLayout = getPrefInt(PreferKey.bookshelfLayout) if (bookshelfLayout == 0) { From c4303af5749a48dfa745981947cc946b70545c2b Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 27 Aug 2020 17:37:31 +0800 Subject: [PATCH 43/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=B0=8F=E8=AF=B4?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/main/MainViewModel.kt | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) 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 3917769b0..fbacdd448 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 @@ -48,29 +48,31 @@ class MainViewModel(application: Application) : BaseViewModel(application) { } fun upToc(books: List) { - books.filter { - it.origin != BookType.local && it.canUpdate - }.forEach { - bookMap[it.bookUrl] = it - } - for (i in 0 until threadCount) { - if (usePoolCount < threadCount) { - usePoolCount++ - updateToc() + execute { + books.filter { + it.origin != BookType.local && it.canUpdate + }.forEach { + bookMap[it.bookUrl] = it + } + for (i in 0 until threadCount) { + if (usePoolCount < threadCount) { + usePoolCount++ + updateToc() + } } } } private fun updateToc() { - execute { + synchronized(this) { bookMap.forEach { bookEntry -> if (!updateList.contains(bookEntry.key)) { val book = bookEntry.value + synchronized(this) { + updateList.add(book.bookUrl) + postEvent(EventBus.UP_BOOK, book.bookUrl) + } App.db.bookSourceDao().getBookSource(book.origin)?.let { bookSource -> - synchronized(this) { - updateList.add(book.bookUrl) - postEvent(EventBus.UP_BOOK, book.bookUrl) - } WebBook(bookSource).getChapterList(book, context = upTocPool) .timeout(300000) .onSuccess(IO) { @@ -91,6 +93,8 @@ class MainViewModel(application: Application) : BaseViewModel(application) { } } ?: synchronized(this) { bookMap.remove(bookEntry.key) + updateList.remove(book.bookUrl) + postEvent(EventBus.UP_BOOK, book.bookUrl) upNext() } return@forEach From 1496927823df3235c86110c0542988a31c9f4b52 Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 27 Aug 2020 22:05:19 +0800 Subject: [PATCH 44/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8D=A2=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../changesource/ChangeSourceViewModel.kt | 100 +++++++++++------- 1 file changed, 63 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt index da58200c5..2997b0780 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt @@ -10,30 +10,35 @@ import io.legado.app.base.BaseViewModel import io.legado.app.constant.AppPattern import io.legado.app.constant.PreferKey import io.legado.app.data.entities.Book +import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.help.AppConfig -import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.coroutine.CompositeCoroutine import io.legado.app.model.WebBook import io.legado.app.utils.getPrefBoolean import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.ExecutorCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher import org.jetbrains.anko.debug +import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.Executors class ChangeSourceViewModel(application: Application) : BaseViewModel(application) { - private var searchPool = - Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher() + val threadCount = AppConfig.threadCount + private lateinit var searchPool: ExecutorCoroutineDispatcher val handler = Handler() val searchStateData = MutableLiveData() val searchBooksLiveData = MutableLiveData>() var name: String = "" var author: String = "" - private var task: Coroutine<*>? = null + private var tasks = CompositeCoroutine() private var screenKey: String = "" - private val searchBooks = hashSetOf() + private var bookSourceList = arrayListOf() + private val searchBooks = CopyOnWriteArraySet() private var postTime = 0L private val sendRunnable = Runnable { upAdapter() } - + @Volatile + private var searchIndex = -1 fun initData(arguments: Bundle?) { arguments?.let { bundle -> @@ -46,13 +51,17 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio } } + private fun initSearchPool() { + searchPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher() + } + fun loadDbSearchBook() { execute { App.db.searchBookDao().getByNameAuthorEnable(name, author).let { searchBooks.addAll(it) if (it.size <= 1) { upAdapter() - search() + startSearch() } else { upAdapter() } @@ -83,38 +92,53 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio upAdapter() } - fun search() { - task = execute { - val bookSourceList = App.db.bookSourceDao().allEnabled - for (item in bookSourceList) { - //task取消时自动取消 by (scope = this@execute) - WebBook(item).searchBook(name, scope = this@execute, context = searchPool) - .timeout(30000L) - .onSuccess(IO) { - it.forEach { searchBook -> - if (searchBook.name == name && searchBook.author == author) { - if (context.getPrefBoolean(PreferKey.changeSourceLoadToc)) { - if (searchBook.tocUrl.isEmpty()) { - loadBookInfo(searchBook.toBook()) - } else { - loadChapter(searchBook.toBook()) - } + private fun startSearch() { + execute { + bookSourceList.clear() + bookSourceList.addAll(App.db.bookSourceDao().allEnabled) + searchStateData.postValue(true) + initSearchPool() + for (i in 0 until threadCount) { + search() + } + } + } + + private fun search() { + synchronized(this) { + searchIndex++ + val source = bookSourceList[searchIndex] + val task = WebBook(source).searchBook(name, scope = this, context = searchPool) + .timeout(60000L) + .onSuccess(IO) { + it.forEach { searchBook -> + if (searchBook.name == name && searchBook.author == author) { + if (context.getPrefBoolean(PreferKey.changeSourceLoadToc)) { + if (searchBook.tocUrl.isEmpty()) { + loadBookInfo(searchBook.toBook()) } else { - searchFinish(searchBook) + loadChapter(searchBook.toBook()) } - return@onSuccess + } else { + searchFinish(searchBook) } + return@forEach } } - } - }.onStart { - searchStateData.postValue(true) - }.onCancel { - searchStateData.postValue(false) - } - - task?.invokeOnCompletion { - searchStateData.postValue(false) + } + .onFinally { + synchronized(this) { + if (searchIndex < bookSourceList.lastIndex) { + search() + } else { + searchIndex++ + } + if (searchIndex >= bookSourceList.lastIndex + threadCount) { + searchStateData.postValue(false) + } + } + } + tasks.add(task) } } @@ -166,10 +190,12 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio } fun stopSearch() { - if (task?.isActive == true) { - task?.cancel() + if (tasks.isEmpty) { + startSearch() } else { - search() + tasks.clear() + searchPool.close() + searchStateData.postValue(false) } } From 2442e747d387ba94887a775397188149411beb2e Mon Sep 17 00:00:00 2001 From: gedoor Date: Thu, 27 Aug 2020 22:10:23 +0800 Subject: [PATCH 45/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/model/Debug.kt | 2 ++ app/src/main/java/io/legado/app/model/{ => rss}/Rss.kt | 2 +- .../io/legado/app/model/{ => webBook}/SearchBookModel.kt | 2 +- .../main/java/io/legado/app/model/{ => webBook}/WebBook.kt | 7 ++----- app/src/main/java/io/legado/app/service/DownloadService.kt | 2 +- app/src/main/java/io/legado/app/service/help/AudioPlay.kt | 2 +- .../main/java/io/legado/app/service/help/CheckSource.kt | 2 +- app/src/main/java/io/legado/app/service/help/ReadBook.kt | 2 +- .../main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt | 2 +- .../legado/app/ui/book/changecover/ChangeCoverViewModel.kt | 2 +- .../app/ui/book/changesource/ChangeSourceViewModel.kt | 2 +- .../io/legado/app/ui/book/explore/ExploreShowViewModel.kt | 2 +- .../java/io/legado/app/ui/book/info/BookInfoViewModel.kt | 2 +- .../java/io/legado/app/ui/book/read/ReadBookViewModel.kt | 2 +- .../java/io/legado/app/ui/book/search/SearchViewModel.kt | 2 +- .../app/ui/book/source/debug/BookSourceDebugModel.kt | 2 +- app/src/main/java/io/legado/app/ui/main/MainViewModel.kt | 2 +- .../io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt | 2 +- .../io/legado/app/ui/rss/article/RssArticlesViewModel.kt | 2 +- .../java/io/legado/app/ui/rss/read/ReadRssViewModel.kt | 2 +- .../io/legado/app/web/controller/BookshelfController.kt | 2 +- .../io/legado/app/web/controller/SourceDebugWebSocket.kt | 2 +- 22 files changed, 24 insertions(+), 25 deletions(-) rename app/src/main/java/io/legado/app/model/{ => rss}/Rss.kt (98%) rename app/src/main/java/io/legado/app/model/{ => webBook}/SearchBookModel.kt (98%) rename app/src/main/java/io/legado/app/model/{ => webBook}/WebBook.kt (96%) 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 85c87812c..795170985 100644 --- a/app/src/main/java/io/legado/app/model/Debug.kt +++ b/app/src/main/java/io/legado/app/model/Debug.kt @@ -6,6 +6,8 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssSource import io.legado.app.help.coroutine.CompositeCoroutine +import io.legado.app.model.rss.Rss +import io.legado.app.model.webBook.WebBook import io.legado.app.utils.htmlFormat import io.legado.app.utils.isAbsUrl import java.text.SimpleDateFormat diff --git a/app/src/main/java/io/legado/app/model/Rss.kt b/app/src/main/java/io/legado/app/model/rss/Rss.kt similarity index 98% rename from app/src/main/java/io/legado/app/model/Rss.kt rename to app/src/main/java/io/legado/app/model/rss/Rss.kt index 7b6d2e266..f9ea78195 100644 --- a/app/src/main/java/io/legado/app/model/Rss.kt +++ b/app/src/main/java/io/legado/app/model/rss/Rss.kt @@ -1,4 +1,4 @@ -package io.legado.app.model +package io.legado.app.model.rss import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssSource diff --git a/app/src/main/java/io/legado/app/model/SearchBookModel.kt b/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt similarity index 98% rename from app/src/main/java/io/legado/app/model/SearchBookModel.kt rename to app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt index 1f6cac065..0cb36d1c7 100644 --- a/app/src/main/java/io/legado/app/model/SearchBookModel.kt +++ b/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt @@ -1,4 +1,4 @@ -package io.legado.app.model +package io.legado.app.model.webBook import io.legado.app.App import io.legado.app.data.entities.SearchBook diff --git a/app/src/main/java/io/legado/app/model/WebBook.kt b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt similarity index 96% rename from app/src/main/java/io/legado/app/model/WebBook.kt rename to app/src/main/java/io/legado/app/model/webBook/WebBook.kt index cb1742132..cdf5553ee 100644 --- a/app/src/main/java/io/legado/app/model/WebBook.kt +++ b/app/src/main/java/io/legado/app/model/webBook/WebBook.kt @@ -1,15 +1,12 @@ -package io.legado.app.model +package io.legado.app.model.webBook import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.help.coroutine.Coroutine +import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeUrl -import io.legado.app.model.webBook.BookChapterList -import io.legado.app.model.webBook.BookContent -import io.legado.app.model.webBook.BookInfo -import io.legado.app.model.webBook.BookList import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlin.coroutines.CoroutineContext diff --git a/app/src/main/java/io/legado/app/service/DownloadService.kt b/app/src/main/java/io/legado/app/service/DownloadService.kt index b21d4e36e..047e8d643 100644 --- a/app/src/main/java/io/legado/app/service/DownloadService.kt +++ b/app/src/main/java/io/legado/app/service/DownloadService.kt @@ -16,7 +16,7 @@ import io.legado.app.help.BookHelp import io.legado.app.help.IntentHelp import io.legado.app.help.coroutine.CompositeCoroutine import io.legado.app.help.coroutine.Coroutine -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.service.help.Download import io.legado.app.utils.postEvent import kotlinx.coroutines.Dispatchers.IO diff --git a/app/src/main/java/io/legado/app/service/help/AudioPlay.kt b/app/src/main/java/io/legado/app/service/help/AudioPlay.kt index 7c8d120b3..06bb6b5a9 100644 --- a/app/src/main/java/io/legado/app/service/help/AudioPlay.kt +++ b/app/src/main/java/io/legado/app/service/help/AudioPlay.kt @@ -6,7 +6,7 @@ import androidx.lifecycle.MutableLiveData import io.legado.app.constant.IntentAction import io.legado.app.constant.Status import io.legado.app.data.entities.Book -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.service.AudioPlayService object AudioPlay { diff --git a/app/src/main/java/io/legado/app/service/help/CheckSource.kt b/app/src/main/java/io/legado/app/service/help/CheckSource.kt index c387e526c..7ae99e667 100644 --- a/app/src/main/java/io/legado/app/service/help/CheckSource.kt +++ b/app/src/main/java/io/legado/app/service/help/CheckSource.kt @@ -7,7 +7,7 @@ import io.legado.app.R import io.legado.app.constant.IntentAction import io.legado.app.data.entities.BookSource import io.legado.app.help.coroutine.Coroutine -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.service.CheckSourceService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index e15af105b..0d7c4c982 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -13,7 +13,7 @@ import io.legado.app.help.AppConfig import io.legado.app.help.BookHelp import io.legado.app.help.IntentDataHelp import io.legado.app.help.coroutine.Coroutine -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.service.BaseReadAloudService import io.legado.app.ui.book.read.page.entities.TextChapter import io.legado.app.ui.book.read.page.provider.ChapterProvider diff --git a/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt b/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt index 124fd710f..4c1a5a85b 100644 --- a/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/audio/AudioPlayViewModel.kt @@ -8,7 +8,7 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.help.BookHelp -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.service.help.AudioPlay import kotlinx.coroutines.Dispatchers diff --git a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt index 0c91fe0f9..835c3a885 100644 --- a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt @@ -9,7 +9,7 @@ import io.legado.app.constant.AppPattern import io.legado.app.data.entities.SearchBook import io.legado.app.help.AppConfig import io.legado.app.help.coroutine.Coroutine -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.asCoroutineDispatcher import java.util.concurrent.Executors diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt index 2997b0780..4b50151ef 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt @@ -14,7 +14,7 @@ import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.help.AppConfig import io.legado.app.help.coroutine.CompositeCoroutine -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.utils.getPrefBoolean import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.ExecutorCoroutineDispatcher diff --git a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt index bd22b3968..9e7b8dd11 100644 --- a/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/explore/ExploreShowViewModel.kt @@ -7,7 +7,7 @@ import io.legado.app.App import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import kotlinx.coroutines.Dispatchers.IO class ExploreShowViewModel(application: Application) : BaseViewModel(application) { 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 3a36170e4..8f2ed64c2 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 @@ -9,7 +9,7 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.help.BookHelp -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.model.localBook.LocalBook import io.legado.app.service.help.ReadBook import kotlinx.coroutines.Dispatchers.IO 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 d7fb413f0..249141890 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 @@ -10,7 +10,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.help.AppConfig import io.legado.app.help.BookHelp import io.legado.app.help.IntentDataHelp -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.model.localBook.LocalBook import io.legado.app.service.BaseReadAloudService import io.legado.app.service.help.ReadAloud diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt index 318937697..e06c6f81a 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt @@ -8,7 +8,7 @@ import io.legado.app.base.BaseViewModel import io.legado.app.constant.PreferKey import io.legado.app.data.entities.SearchBook import io.legado.app.data.entities.SearchKeyword -import io.legado.app.model.SearchBookModel +import io.legado.app.model.webBook.SearchBookModel import io.legado.app.utils.getPrefBoolean import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.isActive diff --git a/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt b/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt index b17ec5e9f..c7755401d 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/debug/BookSourceDebugModel.kt @@ -4,7 +4,7 @@ import android.app.Application import io.legado.app.App import io.legado.app.base.BaseViewModel import io.legado.app.model.Debug -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook class BookSourceDebugModel(application: Application) : BaseViewModel(application), Debug.Callback { 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 fbacdd448..452e77c18 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 @@ -11,7 +11,7 @@ import io.legado.app.help.AppConfig import io.legado.app.help.DefaultValueHelp import io.legado.app.help.http.HttpHelper import io.legado.app.help.storage.Restore -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.utils.FileUtils import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonObject diff --git a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt index dda342015..ae1287842 100644 --- a/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/bookshelf/BookshelfViewModel.kt @@ -7,7 +7,7 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookSource -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.utils.NetworkUtils import kotlinx.coroutines.Dispatchers.IO diff --git a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt index 8ab79c861..44f125ef2 100644 --- a/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/article/RssArticlesViewModel.kt @@ -7,7 +7,7 @@ import io.legado.app.App import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssSource -import io.legado.app.model.Rss +import io.legado.app.model.rss.Rss import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext diff --git a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt index f5fa3f97b..11b4ba940 100644 --- a/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/rss/read/ReadRssViewModel.kt @@ -17,7 +17,7 @@ import io.legado.app.data.entities.RssArticle import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssStar import io.legado.app.help.http.HttpHelper -import io.legado.app.model.Rss +import io.legado.app.model.rss.Rss import io.legado.app.model.analyzeRule.AnalyzeUrl import io.legado.app.utils.DocumentUtils import io.legado.app.utils.FileUtils diff --git a/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt b/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt index 9871ff72a..203bb37da 100644 --- a/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt +++ b/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt @@ -4,7 +4,7 @@ import io.legado.app.App import io.legado.app.constant.PreferKey import io.legado.app.data.entities.Book import io.legado.app.help.BookHelp -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.service.help.ReadBook import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonObject diff --git a/app/src/main/java/io/legado/app/web/controller/SourceDebugWebSocket.kt b/app/src/main/java/io/legado/app/web/controller/SourceDebugWebSocket.kt index 77b4384c1..ae3172d2f 100644 --- a/app/src/main/java/io/legado/app/web/controller/SourceDebugWebSocket.kt +++ b/app/src/main/java/io/legado/app/web/controller/SourceDebugWebSocket.kt @@ -6,7 +6,7 @@ import fi.iki.elonen.NanoWSD import io.legado.app.App import io.legado.app.R import io.legado.app.model.Debug -import io.legado.app.model.WebBook +import io.legado.app.model.webBook.WebBook import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonObject import io.legado.app.utils.isJson From 757d01a6990a2ca6c73ef87578ca2a413d5509a8 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 10:47:40 +0800 Subject: [PATCH 46/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/model/webBook/SearchBookModel.kt | 111 +++++++++++------- .../changesource/ChangeSourceViewModel.kt | 16 ++- .../app/ui/book/search/SearchViewModel.kt | 3 +- 3 files changed, 80 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt b/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt index 0cb36d1c7..c252c567f 100644 --- a/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt +++ b/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt @@ -1,86 +1,109 @@ package io.legado.app.model.webBook import io.legado.app.App +import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.help.AppConfig -import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.coroutine.CompositeCoroutine import io.legado.app.utils.getPrefString import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.ExecutorCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher import java.util.concurrent.Executors +import kotlin.math.min class SearchBookModel(private val scope: CoroutineScope, private val callBack: CallBack) { - private var searchPool = - Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher() - private var mSearchId = System.currentTimeMillis() + val threadCount = AppConfig.threadCount + private var searchPool: ExecutorCoroutineDispatcher? = null + private var mSearchId = 0L private var searchPage = 1 private var searchKey: String = "" - private var task: Coroutine<*>? = null + private var tasks = CompositeCoroutine() + private var bookSourceList = arrayListOf() + + @Volatile + private var searchIndex = -1 private fun initSearchPool() { - searchPool = - Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher() + searchPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher() } fun search(searchId: Long, key: String) { + callBack.onSearchStart() if (searchId != mSearchId) { - task?.cancel() - searchPool.close() - initSearchPool() - mSearchId = searchId - searchPage = 1 if (key.isEmpty()) { + callBack.onSearchCancel() return } else { this.searchKey = key } - } else { - searchPage++ - } - task = Coroutine.async(scope, searchPool) { + if (mSearchId != 0L) { + close() + } + initSearchPool() + mSearchId = searchId + searchPage = 1 val searchGroup = App.INSTANCE.getPrefString("searchGroup") ?: "" - val bookSourceList = if (searchGroup.isBlank()) { - App.db.bookSourceDao().allEnabled + bookSourceList.clear() + if (searchGroup.isBlank()) { + bookSourceList.addAll(App.db.bookSourceDao().allEnabled) } else { - App.db.bookSourceDao().getEnabledByGroup(searchGroup) + bookSourceList.addAll(App.db.bookSourceDao().getEnabledByGroup(searchGroup)) } - for (item in bookSourceList) { - //task取消时自动取消 by (scope = this@execute) - WebBook(item).searchBook( - searchKey, - searchPage, - scope = this, - context = searchPool - ) - .timeout(30000L) - .onSuccess(IO) { - if (searchId == mSearchId) { - callBack.onSearchSuccess(it) - } - } - } - }.onStart { - callBack.onSearchStart() + } else { + searchPage++ + } + for (i in 0 until threadCount) { + search(searchId) } + } - task?.invokeOnCompletion { - if (searchId == mSearchId) { - callBack.onSearchFinish() + private fun search(searchId: Long) { + synchronized(this) { + if (searchIndex >= bookSourceList.lastIndex) { + return } + searchIndex++ + val source = bookSourceList[searchIndex] + val task = WebBook(source).searchBook( + searchKey, + searchPage, + scope = scope, + context = searchPool!! + ).timeout(30000L) + .onSuccess(IO) { + if (searchId == mSearchId) { + callBack.onSearchSuccess(it) + } + } + .onFinally { + synchronized(this) { + if (searchIndex < bookSourceList.lastIndex) { + search(searchId) + } else { + searchIndex++ + } + if (searchIndex >= bookSourceList.lastIndex + min(bookSourceList.size, + threadCount) + ) { + callBack.onSearchFinish() + } + } + } + tasks.add(task) } } fun cancelSearch() { - task?.cancel() - mSearchId = 0 + close() callBack.onSearchCancel() } fun close() { - task?.cancel() - mSearchId = 0 - searchPool.close() + tasks.clear() + searchPool?.close() + mSearchId = 0L } interface CallBack { diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt index 4b50151ef..8efb57093 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt @@ -22,10 +22,11 @@ import kotlinx.coroutines.asCoroutineDispatcher import org.jetbrains.anko.debug import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.Executors +import kotlin.math.min class ChangeSourceViewModel(application: Application) : BaseViewModel(application) { val threadCount = AppConfig.threadCount - private lateinit var searchPool: ExecutorCoroutineDispatcher + private var searchPool: ExecutorCoroutineDispatcher? = null val handler = Handler() val searchStateData = MutableLiveData() val searchBooksLiveData = MutableLiveData>() @@ -106,9 +107,12 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio private fun search() { synchronized(this) { + if (searchIndex >= bookSourceList.lastIndex) { + return + } searchIndex++ val source = bookSourceList[searchIndex] - val task = WebBook(source).searchBook(name, scope = this, context = searchPool) + val task = WebBook(source).searchBook(name, scope = this, context = searchPool!!) .timeout(60000L) .onSuccess(IO) { it.forEach { searchBook -> @@ -133,7 +137,9 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio } else { searchIndex++ } - if (searchIndex >= bookSourceList.lastIndex + threadCount) { + if (searchIndex >= bookSourceList.lastIndex + min(bookSourceList.size, + threadCount) + ) { searchStateData.postValue(false) } } @@ -194,14 +200,14 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio startSearch() } else { tasks.clear() - searchPool.close() + searchPool?.close() searchStateData.postValue(false) } } override fun onCleared() { super.onCleared() - searchPool.close() + searchPool?.close() } fun disableSource(searchBook: SearchBook) { diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt index e06c6f81a..564b2bb3e 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt @@ -30,7 +30,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application), * 开始搜索 */ fun search(key: String) { - if (searchKey != key && key.isNotEmpty()) { + if ((searchKey != key && key.isEmpty()) || key.isNotEmpty()) { searchBookModel.cancelSearch() searchBooks.clear() searchBookLiveData.postValue(searchBooks) @@ -54,6 +54,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application), override fun onSearchStart() { isSearchLiveData.postValue(true) + isLoading = true } override fun onSearchSuccess(searchBooks: ArrayList) { From 949c789f9e1b2a5f29eb7ebdb57ccf56b65ab78a Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 11:05:16 +0800 Subject: [PATCH 47/90] update log --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 650696a06..7723f7189 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -6,6 +6,7 @@ **2020/08/27** * 修复主题bug * 修复封面bug +* 优化书籍更新,搜索,换源 **2020/08/26** * js添加java.encodeURI(speakText),用于解决js编码时有~的语句朗读不出来 From 0e88541771bab20b8632cf06599f58d4a3e6b780 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 11:50:05 +0800 Subject: [PATCH 48/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8DFile=20name=20too=20lon?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/BookHelp.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) 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 7925fccf8..4f25f85ed 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -90,20 +90,28 @@ object BookHelp { analyzeUrl.getImageBytes(book.origin)?.let { FileUtils.createFileIfNotExist( downloadDir, - "${MD5Utils.md5Encode16(src)}${src.substringAfterLast(".").substringBefore(",")}", + "${MD5Utils.md5Encode16(src)}${getImageSuffix(src)}", subDirs = arrayOf(cacheFolderName, bookFolderName(book), cacheImageFolderName) ).writeBytes(it) } } - - fun getImage(book:Book, src:String): File { + + fun getImage(book: Book, src: String): File { return FileUtils.getFile( downloadDir, - "${MD5Utils.md5Encode16(src)}${src.substringAfterLast(".").substringBefore(",")}", + "${MD5Utils.md5Encode16(src)}${getImageSuffix(src)}", subDirs = arrayOf(cacheFolderName, bookFolderName(book), cacheImageFolderName) ) } + private fun getImageSuffix(src: String): String { + var suffix = src.substringAfterLast(".").substringBefore(",") + if (suffix.length > 5) { + suffix = ".jpg" + } + return suffix + } + fun getChapterFiles(book: Book): List { val fileNameList = arrayListOf() FileUtils.createFolderIfNotExist( From c0cad75f9fa01b254b4f5af5a7d7c59aefc42e82 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 12:45:20 +0800 Subject: [PATCH 49/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/constant/AppPattern.kt | 5 +- .../app/ui/book/search/SearchActivity.kt | 3 +- .../book/source/manage/BookSourceActivity.kt | 3 +- .../book/source/manage/BookSourceViewModel.kt | 57 ++++++++++--------- .../book/source/manage/GroupManageDialog.kt | 3 +- .../app/ui/main/explore/ExploreFragment.kt | 3 +- .../app/ui/replacerule/GroupManageDialog.kt | 3 +- .../app/ui/replacerule/ReplaceRuleActivity.kt | 3 +- .../ui/rss/source/manage/GroupManageDialog.kt | 3 +- .../ui/rss/source/manage/RssSourceActivity.kt | 3 +- 10 files changed, 49 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/AppPattern.kt b/app/src/main/java/io/legado/app/constant/AppPattern.kt index 396edb73d..e9a508939 100644 --- a/app/src/main/java/io/legado/app/constant/AppPattern.kt +++ b/app/src/main/java/io/legado/app/constant/AppPattern.kt @@ -3,8 +3,11 @@ package io.legado.app.constant import java.util.regex.Pattern object AppPattern { - val JS_PATTERN: Pattern = Pattern.compile("([\\w\\W]*?|@js:[\\w\\W]*$)", Pattern.CASE_INSENSITIVE) + val JS_PATTERN: Pattern = + Pattern.compile("([\\w\\W]*?|@js:[\\w\\W]*$)", Pattern.CASE_INSENSITIVE) val EXP_PATTERN: Pattern = Pattern.compile("\\{\\{([\\w\\W]*?)\\}\\}") val authorRegex = "作\\s*者\\s*[::]".toRegex() + + val splitGroupRegex = Regex("[,;]") } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt index 681e9aa9e..2870818c2 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchActivity.kt @@ -13,6 +13,7 @@ import com.google.android.flexbox.FlexboxLayoutManager import io.legado.app.App import io.legado.app.R import io.legado.app.base.VMBaseActivity +import io.legado.app.constant.AppPattern import io.legado.app.constant.PreferKey import io.legado.app.data.entities.Book import io.legado.app.data.entities.SearchBook @@ -178,7 +179,7 @@ class SearchActivity : VMBaseActivity(R.layout.activity_book_se App.db.bookSourceDao().liveGroupEnabled().observe(this, { groups.clear() it.map { group -> - groups.addAll(group.splitNotBlank(",", ";")) + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) } upGroupMenu() }) diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt index c06110f12..7fb8855b3 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt @@ -17,6 +17,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R import io.legado.app.base.VMBaseActivity +import io.legado.app.constant.AppPattern import io.legado.app.data.entities.BookSource import io.legado.app.help.IntentDataHelp import io.legado.app.help.ItemTouchCallback @@ -181,7 +182,7 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity App.db.bookSourceDao().liveGroup().observe(this, { groups.clear() it.map { group -> - groups.addAll(group.splitNotBlank(",", ";")) + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) } upGroupMenu() }) diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt index 8038cf0db..29be62163 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt @@ -5,6 +5,7 @@ import android.text.TextUtils import androidx.documentfile.provider.DocumentFile import io.legado.app.App import io.legado.app.base.BaseViewModel +import io.legado.app.constant.AppPattern import io.legado.app.data.entities.BookSource import io.legado.app.utils.FileUtils import io.legado.app.utils.GSON @@ -94,41 +95,41 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application) } fun selectionAddToGroups(sources: List, groups: String) { - execute { - val list = arrayListOf() - sources.forEach { - val newGroupList = arrayListOf() - it.bookSourceGroup?.splitNotBlank(",", ";")?.forEach { - newGroupList.add(it) - } - groups.splitNotBlank(",", ";", ",").forEach { - newGroupList.add(it) - } - val lh = LinkedHashSet(newGroupList) - val newGroup = ArrayList(lh).joinToString(separator = ",") - list.add(it.copy(bookSourceGroup = newGroup)) + execute { + val list = arrayListOf() + sources.forEach { source -> + val newGroupList = arrayListOf() + source.bookSourceGroup?.splitNotBlank(AppPattern.splitGroupRegex)?.forEach { + newGroupList.add(it) } - App.db.bookSourceDao().update(*list.toTypedArray()) + groups.splitNotBlank(",", ";", ",").forEach { + newGroupList.add(it) + } + val lh = LinkedHashSet(newGroupList) + val newGroup = ArrayList(lh).joinToString(separator = ",") + list.add(source.copy(bookSourceGroup = newGroup)) } + App.db.bookSourceDao().update(*list.toTypedArray()) + } } fun selectionRemoveFromGroups(sources: List, groups: String) { - execute { - val list = arrayListOf() - sources.forEach { - val newGroupList = arrayListOf() - it.bookSourceGroup?.splitNotBlank(",", ";")?.forEach { - newGroupList.add(it) - } - groups.splitNotBlank(",", ";", ",").forEach { - newGroupList.remove(it) - } - val lh = LinkedHashSet(newGroupList) - val newGroup = ArrayList(lh).joinToString(separator = ",") - list.add(it.copy(bookSourceGroup = newGroup)) + execute { + val list = arrayListOf() + sources.forEach { source -> + val newGroupList = arrayListOf() + source.bookSourceGroup?.splitNotBlank(AppPattern.splitGroupRegex)?.forEach { + newGroupList.add(it) } - App.db.bookSourceDao().update(*list.toTypedArray()) + groups.splitNotBlank(",", ";", ",").forEach { + newGroupList.remove(it) + } + val lh = LinkedHashSet(newGroupList) + val newGroup = ArrayList(lh).joinToString(separator = ",") + list.add(source.copy(bookSourceGroup = newGroup)) } + App.db.bookSourceDao().update(*list.toTypedArray()) + } } fun delSelection(sources: List) { diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt index 3724694d4..5c7136691 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/GroupManageDialog.kt @@ -16,6 +16,7 @@ import io.legado.app.App import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter +import io.legado.app.constant.AppPattern import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.customView import io.legado.app.lib.dialogs.noButton @@ -71,7 +72,7 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener { App.db.bookSourceDao().liveGroup().observe(viewLifecycleOwner, { val groups = linkedSetOf() it.map { group -> - groups.addAll(group.splitNotBlank(",", ";")) + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) } adapter.setItems(groups.toList()) }) diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt index 00e8c8da8..6aa870ee7 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreFragment.kt @@ -13,6 +13,7 @@ import androidx.recyclerview.widget.RecyclerView import io.legado.app.App import io.legado.app.R import io.legado.app.base.VMBaseFragment +import io.legado.app.constant.AppPattern import io.legado.app.data.entities.BookSource import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.primaryTextColor @@ -95,7 +96,7 @@ class ExploreFragment : VMBaseFragment(R.layout.fragment_find_ liveGroup?.observe(viewLifecycleOwner, { groups.clear() it.map { group -> - groups.addAll(group.splitNotBlank(",", ";")) + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) } upGroupsMenu() }) diff --git a/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt index 17d5bcd53..bf9cb5409 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/GroupManageDialog.kt @@ -16,6 +16,7 @@ import io.legado.app.App import io.legado.app.R import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter +import io.legado.app.constant.AppPattern import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.customView import io.legado.app.lib.dialogs.noButton @@ -71,7 +72,7 @@ class GroupManageDialog : DialogFragment(), Toolbar.OnMenuItemClickListener { App.db.replaceRuleDao().liveGroup().observe(viewLifecycleOwner, { val groups = linkedSetOf() it.map { group -> - groups.addAll(group.splitNotBlank(",", ";")) + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) } adapter.setItems(groups.toList()) }) diff --git a/app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt b/app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt index adf9fbb03..52fec9244 100644 --- a/app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt +++ b/app/src/main/java/io/legado/app/ui/replacerule/ReplaceRuleActivity.kt @@ -17,6 +17,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R import io.legado.app.base.VMBaseActivity +import io.legado.app.constant.AppPattern import io.legado.app.data.entities.ReplaceRule import io.legado.app.help.BookHelp import io.legado.app.help.IntentDataHelp @@ -148,7 +149,7 @@ class ReplaceRuleActivity : VMBaseActivity(R.layout.activi App.db.replaceRuleDao().liveGroup().observe(this, { groups.clear() it.map { group -> - groups.addAll(group.splitNotBlank(",", ";")) + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) } upGroupMenu() }) diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt index bfb876e0b..48180951f 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/GroupManageDialog.kt @@ -16,6 +16,7 @@ import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.base.adapter.SimpleRecyclerAdapter +import io.legado.app.constant.AppPattern import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.customView import io.legado.app.lib.dialogs.noButton @@ -65,7 +66,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener App.db.rssSourceDao().liveGroup().observe(viewLifecycleOwner, { val groups = linkedSetOf() it.map { group -> - groups.addAll(group.splitNotBlank(",", ";")) + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) } adapter.setItems(groups.toList()) }) diff --git a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt index 2f9050f37..64fc6a849 100644 --- a/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/rss/source/manage/RssSourceActivity.kt @@ -17,6 +17,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import io.legado.app.App import io.legado.app.R import io.legado.app.base.VMBaseActivity +import io.legado.app.constant.AppPattern import io.legado.app.data.entities.RssSource import io.legado.app.help.IntentDataHelp import io.legado.app.help.ItemTouchCallback @@ -144,7 +145,7 @@ class RssSourceActivity : VMBaseActivity(R.layout.activity_r App.db.rssSourceDao().liveGroup().observe(this, { groups.clear() it.map { group -> - groups.addAll(group.splitNotBlank(",", ";")) + groups.addAll(group.splitNotBlank(AppPattern.splitGroupRegex)) } upGroupMenu() }) From f65f553d836f701ec4546ca84d032c9e9579500c Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 14:12:07 +0800 Subject: [PATCH 50/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/book/chapterlist/ChapterListAdapter.kt | 25 ++++++++++--------- .../main/res/drawable/ic_outline_cloud_24.xml | 10 ++++++++ app/src/main/res/layout/item_chapter_list.xml | 2 +- 3 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 app/src/main/res/drawable/ic_outline_cloud_24.xml diff --git a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt index f1043a2a4..17970bc65 100644 --- a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt @@ -21,8 +21,10 @@ class ChapterListAdapter(context: Context, val callback: Callback) : override fun convert(holder: ItemViewHolder, item: BookChapter, payloads: MutableList) { with(holder.itemView) { + val isDur = callback.durChapterIndex() == item.index + val cached = cacheFileNames.contains(BookHelp.formatChapterName(item)) if (payloads.isEmpty()) { - if (callback.durChapterIndex() == item.index) { + if (isDur) { tv_chapter_name.setTextColor(context.accentColor) } else { tv_chapter_name.setTextColor(context.getCompatColor(R.color.primaryText)) @@ -32,15 +34,9 @@ class ChapterListAdapter(context: Context, val callback: Callback) : tv_tag.text = item.tag tv_tag.visible() } - upHasCache( - this, - cacheFileNames.contains(BookHelp.formatChapterName(item)) - ) + upHasCache(this, isDur, cached) } else { - upHasCache( - this, - cacheFileNames.contains(BookHelp.formatChapterName(item)) - ) + upHasCache(this, isDur, cached) } } } @@ -53,9 +49,14 @@ class ChapterListAdapter(context: Context, val callback: Callback) : } } - private fun upHasCache(itemView: View, contains: Boolean) = itemView.apply { - tv_chapter_name.paint.isFakeBoldText = contains - iv_checked.visible(contains) + private fun upHasCache(itemView: View, isDur: Boolean, cached: Boolean) = itemView.apply { + tv_chapter_name.paint.isFakeBoldText = cached + iv_checked.setImageResource(R.drawable.ic_outline_cloud_24) + iv_checked.visible(!cached) + if (isDur) { + iv_checked.setImageResource(R.drawable.ic_check) + iv_checked.visible() + } } interface Callback { diff --git a/app/src/main/res/drawable/ic_outline_cloud_24.xml b/app/src/main/res/drawable/ic_outline_cloud_24.xml new file mode 100644 index 000000000..c8b092ead --- /dev/null +++ b/app/src/main/res/drawable/ic_outline_cloud_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/item_chapter_list.xml b/app/src/main/res/layout/item_chapter_list.xml index aea6a6cfd..b0e9d4f23 100644 --- a/app/src/main/res/layout/item_chapter_list.xml +++ b/app/src/main/res/layout/item_chapter_list.xml @@ -34,7 +34,7 @@ android:src="@drawable/ic_check" android:visibility="invisible" android:contentDescription="@string/success" - app:tint="@color/primaryText" + app:tint="@color/secondaryText" app:layout_constraintTop_toTopOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" /> From 95e7ce34794caf0e222ac2fd2da62f9c10f229b3 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 14:43:43 +0800 Subject: [PATCH 51/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/model/webBook/SearchBookModel.kt | 1 + .../java/io/legado/app/ui/book/search/SearchViewModel.kt | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt b/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt index c252c567f..1224979af 100644 --- a/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt +++ b/app/src/main/java/io/legado/app/model/webBook/SearchBookModel.kt @@ -54,6 +54,7 @@ class SearchBookModel(private val scope: CoroutineScope, private val callBack: C } else { searchPage++ } + searchIndex = -1 for (i in 0 until threadCount) { search(searchId) } diff --git a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt index 564b2bb3e..179b2cd9b 100644 --- a/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt @@ -30,13 +30,16 @@ class SearchViewModel(application: Application) : BaseViewModel(application), * 开始搜索 */ fun search(key: String) { - if ((searchKey != key && key.isEmpty()) || key.isNotEmpty()) { + if ((searchKey == key) || key.isNotEmpty()) { searchBookModel.cancelSearch() searchBooks.clear() searchBookLiveData.postValue(searchBooks) searchID = System.currentTimeMillis() searchKey = key } + if (searchKey.isEmpty()) { + return + } searchBookModel.search(searchID, searchKey) } @@ -111,7 +114,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application), && item.author == searchBook.author ) { hasSame = true - searchBook.addOrigin(item.bookUrl) + searchBook.addOrigin(item.origin) break } } From 12ee46ec5cf31b1686363cdfe54b02745387bb74 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 14:49:08 +0800 Subject: [PATCH 52/90] =?UTF-8?q?e-ink=E6=A8=A1=E5=BC=8F=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/help/ReadBookConfig.kt | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/ReadBookConfig.kt b/app/src/main/java/io/legado/app/help/ReadBookConfig.kt index 73e344393..74f8617df 100644 --- a/app/src/main/java/io/legado/app/help/ReadBookConfig.kt +++ b/app/src/main/java/io/legado/app/help/ReadBookConfig.kt @@ -77,16 +77,11 @@ object ReadBookConfig { val dm = resources.displayMetrics val width = dm.widthPixels val height = dm.heightPixels - if (AppConfig.isEInkMode && !AppConfig.isNightTheme) { - bg = ColorDrawable(Color.WHITE) - bgMeanColor = Color.WHITE - } else { - bg = durConfig.bgDrawable(width, height).apply { - if (this is BitmapDrawable) { - bgMeanColor = BitmapUtils.getMeanColor(bitmap) - } else if (this is ColorDrawable) { - bgMeanColor = color - } + bg = durConfig.bgDrawable(width, height).apply { + if (this is BitmapDrawable) { + bgMeanColor = BitmapUtils.getMeanColor(bitmap) + } else if (this is ColorDrawable) { + bgMeanColor = color } } isScroll = pageAnim == 3 From 15b39157d922cab63f6e616e1252648e8b85a98c Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 14:50:01 +0800 Subject: [PATCH 53/90] =?UTF-8?q?e-ink=E6=A8=A1=E5=BC=8F=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/ReadBookConfig.kt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/ReadBookConfig.kt b/app/src/main/java/io/legado/app/help/ReadBookConfig.kt index 74f8617df..c6c71598c 100644 --- a/app/src/main/java/io/legado/app/help/ReadBookConfig.kt +++ b/app/src/main/java/io/legado/app/help/ReadBookConfig.kt @@ -29,13 +29,7 @@ object ReadBookConfig { var bg: Drawable? = null var bgMeanColor: Int = 0 - val textColor: Int - get() = - if (AppConfig.isEInkMode && !AppConfig.isNightTheme) { - Color.BLACK - } else { - durConfig.textColor() - } + val textColor: Int get() = durConfig.textColor() init { upConfig() From 3206d4ac9cc7f67b0d7010286ca2c4d7bd8ac818 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 14:53:38 +0800 Subject: [PATCH 54/90] =?UTF-8?q?e-ink=E6=A8=A1=E5=BC=8F=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 7723f7189..d2465782e 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -7,6 +7,7 @@ * 修复主题bug * 修复封面bug * 优化书籍更新,搜索,换源 +* e-ink模式不再固定背景 **2020/08/26** * js添加java.encodeURI(speakText),用于解决js编码时有~的语句朗读不出来 From b25e00ea862fd79f329e97148f3d12caddbc135b Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 15:13:35 +0800 Subject: [PATCH 55/90] =?UTF-8?q?e-ink=E6=A8=A1=E5=BC=8F=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E8=83=8C=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt index 50824ff50..db1b658c1 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt @@ -13,7 +13,6 @@ import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.constant.EventBus import io.legado.app.constant.PreferKey -import io.legado.app.help.AppConfig import io.legado.app.help.ReadBookConfig import io.legado.app.lib.dialogs.alert import io.legado.app.lib.dialogs.selector @@ -209,9 +208,6 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack { upBg() postEvent(EventBus.UP_CONFIG, true) } - if (AppConfig.isEInkMode) { - toast(R.string.e_ink_change_bg) - } } private fun showBgTextConfig(index: Int): Boolean { From fa471e879986df23315c6308bd67a026b35398d7 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 15:32:29 +0800 Subject: [PATCH 56/90] =?UTF-8?q?=E6=B8=85=E7=90=86=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=A1=AE=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/ui/config/OtherConfigFragment.kt | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt b/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt index bf130b50e..c0efd5698 100644 --- a/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt +++ b/app/src/main/java/io/legado/app/ui/config/OtherConfigFragment.kt @@ -20,6 +20,9 @@ import io.legado.app.help.AppConfig import io.legado.app.help.BookHelp import io.legado.app.help.permission.Permissions import io.legado.app.help.permission.PermissionsCompat +import io.legado.app.lib.dialogs.alert +import io.legado.app.lib.dialogs.noButton +import io.legado.app.lib.dialogs.okButton import io.legado.app.lib.dialogs.selector import io.legado.app.lib.theme.ATH import io.legado.app.receiver.SharedReceiverActivity @@ -79,11 +82,7 @@ class OtherConfigFragment : BasePreferenceFragment(), .show { putPrefInt(PreferKey.webPort, it) } - PreferKey.cleanCache -> { - BookHelp.clearCache() - FileUtils.deleteFile(requireActivity().cacheDir.absolutePath) - toast(R.string.clear_cache_success) - } + PreferKey.cleanCache -> clearCache() PreferKey.defaultCover -> if (getPrefString(PreferKey.defaultCover).isNullOrEmpty()) { selectDefaultCover() } else { @@ -145,6 +144,18 @@ class OtherConfigFragment : BasePreferenceFragment(), } } + private fun clearCache() { + requireContext().alert(titleResource = R.string.clear_cache, + messageResource = R.string.sure_del) { + okButton { + BookHelp.clearCache() + FileUtils.deleteFile(requireActivity().cacheDir.absolutePath) + toast(R.string.clear_cache_success) + } + noButton() + }.show().applyTint() + } + private fun selectDefaultCover() { val intent = Intent(Intent.ACTION_GET_CONTENT) intent.addCategory(Intent.CATEGORY_OPENABLE) From b2f7eb45a56bd2bd0a785fa09e1985dc690286bf Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 15:43:06 +0800 Subject: [PATCH 57/90] =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E7=94=B5=E6=B1=A0?= =?UTF-8?q?=E5=AD=97=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/widget/BatteryView.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt b/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt index d9725f019..3141c5a86 100644 --- a/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt +++ b/app/src/main/java/io/legado/app/ui/widget/BatteryView.kt @@ -5,6 +5,7 @@ import android.content.Context import android.graphics.Canvas import android.graphics.Paint import android.graphics.Rect +import android.graphics.Typeface import android.util.AttributeSet import androidx.annotation.ColorInt import androidx.appcompat.widget.AppCompatTextView @@ -21,6 +22,7 @@ class BatteryView(context: Context, attrs: AttributeSet?) : AppCompatTextView(co batteryPaint.strokeWidth = 1.dp.toFloat() batteryPaint.isAntiAlias = true batteryPaint.color = paint.color + typeface = Typeface.createFromAsset(context.assets, "number.ttf") } fun setColor(@ColorInt color: Int) { From c360afbbd114c593a8ef9432f80ed830aaf28894 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 15:49:47 +0800 Subject: [PATCH 58/90] cover --- .../io/legado/app/ui/book/info/edit/BookInfoEditActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 3e4986bde..06a149ca1 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 @@ -68,7 +68,7 @@ class BookInfoEditActivity : private fun upView(book: Book) { tie_book_name.setText(book.name) tie_book_author.setText(book.author) - tie_cover_url.setText(book.getDisplayCover()?.substringBefore(",")) + tie_cover_url.setText(book.getDisplayCover()) tie_book_intro.setText(book.getDisplayIntro()) upCover() } From 1de396327b16637b5a64feb8733e9fc073d3e332 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 16:44:01 +0800 Subject: [PATCH 59/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Durl=E6=8B=86=E5=88=86bu?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 4ac7227d8..bf0244883 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -50,8 +50,7 @@ class AnalyzeUrl( private var baseUrl: String = "" lateinit var url: String private set - lateinit var urlHasQuery: String - private set + private lateinit var urlHasQuery: String val headerMap = HashMap() private var queryStr: String? = null private val fieldMap = LinkedHashMap() @@ -59,7 +58,7 @@ class AnalyzeUrl( private var body: String? = null private var requestBody: RequestBody? = null private var method = RequestMethod.GET - private val splitUrlRegex = Regex(",[^\\{]*") + private val splitUrlRegex = Regex(",[\\s]*(?=\\{)") init { baseUrl?.let { From c3fb4f0bb0421fc2afe72c551a3f5c452d7562e1 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 16:44:51 +0800 Subject: [PATCH 60/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Durl=E6=8B=86=E5=88=86bu?= =?UTF-8?q?g?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index bf0244883..e892bf073 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -58,7 +58,7 @@ class AnalyzeUrl( private var body: String? = null private var requestBody: RequestBody? = null private var method = RequestMethod.GET - private val splitUrlRegex = Regex(",[\\s]*(?=\\{)") + private val splitUrlRegex = Regex(",\\s*(?=\\{)") init { baseUrl?.let { From 5b0afc70bed102f81c83a0ad922aeaeca7e380a8 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 17:09:25 +0800 Subject: [PATCH 61/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/main/MainViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 452e77c18..098edef57 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 @@ -97,7 +97,7 @@ class MainViewModel(application: Application) : BaseViewModel(application) { postEvent(EventBus.UP_BOOK, book.bookUrl) upNext() } - return@forEach + return } } } From 2a412944c981c112f4e2c03b73d904187bfa4776 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 17:39:41 +0800 Subject: [PATCH 62/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/base/BaseActivity.kt | 4 ++-- app/src/main/java/io/legado/app/lib/theme/ATH.kt | 11 ++++++----- app/src/main/java/io/legado/app/ui/book/read/Help.kt | 10 +++++----- .../io/legado/app/ui/book/read/ReadBookActivity.kt | 2 +- .../legado/app/ui/book/read/config/AutoReadDialog.kt | 2 +- .../app/ui/book/read/config/BgTextConfigDialog.kt | 4 ++-- .../app/ui/book/read/config/MoreConfigDialog.kt | 2 +- .../app/ui/book/read/config/PaddingConfigDialog.kt | 2 +- .../app/ui/book/read/config/ReadAloudConfigDialog.kt | 2 +- .../app/ui/book/read/config/ReadAloudDialog.kt | 2 +- .../app/ui/book/read/config/ReadStyleDialog.kt | 2 +- .../app/ui/book/read/config/TipConfigDialog.kt | 12 ++++++------ 12 files changed, 28 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/io/legado/app/base/BaseActivity.kt b/app/src/main/java/io/legado/app/base/BaseActivity.kt index 6e3b8ece2..3ca496783 100644 --- a/app/src/main/java/io/legado/app/base/BaseActivity.kt +++ b/app/src/main/java/io/legado/app/base/BaseActivity.kt @@ -131,9 +131,9 @@ abstract class BaseActivity( } ATH.setStatusBarColorAuto(this, fullScreen) if (toolBarTheme == Theme.Dark) { - ATH.setLightStatusBar(this, false) + ATH.setLightStatusBar(window, false) } else if (toolBarTheme == Theme.Light) { - ATH.setLightStatusBar(this, true) + ATH.setLightStatusBar(window, true) } upNavigationBarColor() } diff --git a/app/src/main/java/io/legado/app/lib/theme/ATH.kt b/app/src/main/java/io/legado/app/lib/theme/ATH.kt index d9ee9e2a2..f69c5d40a 100644 --- a/app/src/main/java/io/legado/app/lib/theme/ATH.kt +++ b/app/src/main/java/io/legado/app/lib/theme/ATH.kt @@ -9,6 +9,7 @@ import android.graphics.drawable.GradientDrawable import android.os.Build import android.view.View import android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR +import android.view.Window import android.widget.EdgeEffect import android.widget.ScrollView import androidx.annotation.ColorInt @@ -63,16 +64,16 @@ object ATH { } else { activity.window.statusBarColor = color } - setLightStatusBarAuto(activity, color) + setLightStatusBarAuto(activity.window, color) } - fun setLightStatusBarAuto(activity: Activity, bgColor: Int) { - setLightStatusBar(activity, ColorUtils.isColorLight(bgColor)) + fun setLightStatusBarAuto(window: Window, bgColor: Int) { + setLightStatusBar(window, ColorUtils.isColorLight(bgColor)) } - fun setLightStatusBar(activity: Activity, enabled: Boolean) { + fun setLightStatusBar(window: Window, enabled: Boolean) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - val decorView = activity.window.decorView + val decorView = window.decorView val systemUiVisibility = decorView.systemUiVisibility if (enabled) { decorView.systemUiVisibility = diff --git a/app/src/main/java/io/legado/app/ui/book/read/Help.kt b/app/src/main/java/io/legado/app/ui/book/read/Help.kt index c789d6ae1..6a6a59912 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/Help.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/Help.kt @@ -35,7 +35,7 @@ object Help { /** * 更新状态栏,导航栏 */ - fun upSystemUiVisibility(activity: Activity, toolBarHide: Boolean = true) { + fun upSystemUiVisibility(window: Window, toolBarHide: Boolean = true) { var flag = (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_IMMERSIVE @@ -51,13 +51,13 @@ object Help { flag = flag or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION } } - activity.window.decorView.systemUiVisibility = flag + window.decorView.systemUiVisibility = flag if (toolBarHide) { - ATH.setLightStatusBar(activity, ReadBookConfig.durConfig.statusIconDark()) + ATH.setLightStatusBar(window, ReadBookConfig.durConfig.statusIconDark()) } else { ATH.setLightStatusBarAuto( - activity, - ThemeStore.statusBarColor(activity, AppConfig.isTransparentStatusBar) + window, + ThemeStore.statusBarColor(App.INSTANCE, AppConfig.isTransparentStatusBar) ) } } 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 8a872f1d8..3e1c82259 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 @@ -691,7 +691,7 @@ class ReadBookActivity : VMBaseActivity(R.layout.activity_boo * 更新状态栏,导航栏 */ override fun upSystemUiVisibility() { - Help.upSystemUiVisibility(this, !read_menu.isVisible) + Help.upSystemUiVisibility(window, !read_menu.isVisible) upNavigationBarColor() } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt index 610fa3dde..cb697be77 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt @@ -26,10 +26,10 @@ class AutoReadDialog : BaseDialogFragment() { super.onStart() val dm = DisplayMetrics() activity?.let { - Help.upSystemUiVisibility(it) it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { + Help.upSystemUiVisibility(it) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 0, 0, 0) val attr = it.attributes diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt index 99c951643..d859d7685 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt @@ -47,10 +47,10 @@ class BgTextConfigDialog : BaseDialogFragment() { super.onStart() val dm = DisplayMetrics() activity?.let { - Help.upSystemUiVisibility(it) it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { + Help.upSystemUiVisibility(it) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 5, 0, 0) val attr = it.attributes @@ -102,7 +102,7 @@ class BgTextConfigDialog : BaseDialogFragment() { sw_dark_status_icon.onCheckedChange { buttonView, isChecked -> if (buttonView?.isPressed == true) { setStatusIconDark(isChecked) - activity?.let { + dialog?.window?.let { Help.upSystemUiVisibility(it) } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt index 2c2df5bbf..e17cb808a 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt @@ -30,10 +30,10 @@ class MoreConfigDialog : DialogFragment() { super.onStart() val dm = DisplayMetrics() activity?.let { - Help.upSystemUiVisibility(it) it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { + Help.upSystemUiVisibility(it) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 0, 0, 0) val attr = it.attributes diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt index a37d7e91b..808306ed6 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt @@ -20,10 +20,10 @@ class PaddingConfigDialog : BaseDialogFragment() { super.onStart() val dm = DisplayMetrics() activity?.let { - Help.upSystemUiVisibility(it) it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { + Help.upSystemUiVisibility(it) val attr = it.attributes attr.dimAmount = 0.0f it.attributes = attr diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt index d29bf1df8..be79b46f7 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt @@ -30,10 +30,10 @@ class ReadAloudConfigDialog : DialogFragment() { super.onStart() val dm = DisplayMetrics() activity?.let { - Help.upSystemUiVisibility(it) it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { + Help.upSystemUiVisibility(it) it.setBackgroundDrawableResource(R.color.transparent) it.setLayout((dm.widthPixels * 0.9).toInt(), ViewGroup.LayoutParams.WRAP_CONTENT) } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt index 8c5c4e6a9..1886837d1 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt @@ -31,10 +31,10 @@ class ReadAloudDialog : BaseDialogFragment() { super.onStart() val dm = DisplayMetrics() activity?.let { - Help.upSystemUiVisibility(it) it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { + Help.upSystemUiVisibility(it) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 0, 0, 0) val attr = it.attributes diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt index db1b658c1..4c3897d06 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt @@ -39,10 +39,10 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack { super.onStart() val dm = DisplayMetrics() activity?.let { - Help.upSystemUiVisibility(it) it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { + Help.upSystemUiVisibility(it) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 0, 0, 0) val attr = it.attributes diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/TipConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/TipConfigDialog.kt index 65bcfc7b6..2a6f414cb 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/TipConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/TipConfigDialog.kt @@ -22,19 +22,19 @@ class TipConfigDialog : BaseDialogFragment() { super.onStart() val dm = DisplayMetrics() activity?.let { - Help.upSystemUiVisibility(it) it.windowManager?.defaultDisplay?.getMetrics(dm) } - dialog?.window?.setLayout( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT - ) + dialog?.window?.let { + Help.upSystemUiVisibility(it) + it.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT) + } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? + savedInstanceState: Bundle?, ): View? { return inflater.inflate(R.layout.dialog_tip_config, container) } From 42830f372978cc75daf0bc7e19ae884542aec2db Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 17:44:49 +0800 Subject: [PATCH 63/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/about/AboutFragment.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt index faf676a10..44a85a7fe 100644 --- a/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt +++ b/app/src/main/java/io/legado/app/ui/about/AboutFragment.kt @@ -11,6 +11,7 @@ import io.legado.app.App import io.legado.app.R import io.legado.app.lib.dialogs.alert import io.legado.app.ui.widget.dialog.TextDialog +import io.legado.app.utils.applyTint import io.legado.app.utils.openUrl import io.legado.app.utils.sendToClip import io.legado.app.utils.toast @@ -92,7 +93,7 @@ class AboutFragment : PreferenceFragmentCompat() { } } } - }.show() + }.show().applyTint() } private fun joinQQGroup(key: String): Boolean { From 99246d48ee0e1244312708b131711baa8e6105cb Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 17:52:13 +0800 Subject: [PATCH 64/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=98=85=E8=AF=BB?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E7=95=8C=E9=9D=A2=E7=8A=B6=E6=80=81=E6=A0=8F?= =?UTF-8?q?=E9=A2=9C=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/book/read/config/AutoReadDialog.kt | 8 ++------ .../legado/app/ui/book/read/config/BgTextConfigDialog.kt | 9 +++------ .../legado/app/ui/book/read/config/MoreConfigDialog.kt | 7 ++----- .../app/ui/book/read/config/PaddingConfigDialog.kt | 4 ++-- .../app/ui/book/read/config/ReadAloudConfigDialog.kt | 5 ++--- .../io/legado/app/ui/book/read/config/ReadAloudDialog.kt | 8 ++------ .../io/legado/app/ui/book/read/config/ReadStyleDialog.kt | 8 ++------ 7 files changed, 15 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt index cb697be77..11c2fed44 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/AutoReadDialog.kt @@ -2,10 +2,7 @@ package io.legado.app.ui.book.read.config import android.os.Bundle import android.util.DisplayMetrics -import android.view.Gravity -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.SeekBar import io.legado.app.R import io.legado.app.base.BaseDialogFragment @@ -14,7 +11,6 @@ import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.service.BaseReadAloudService import io.legado.app.service.help.ReadAloud -import io.legado.app.ui.book.read.Help import io.legado.app.utils.ColorUtils import kotlinx.android.synthetic.main.dialog_auto_read.* import org.jetbrains.anko.sdk27.listeners.onClick @@ -29,7 +25,7 @@ class AutoReadDialog : BaseDialogFragment() { it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { - Help.upSystemUiVisibility(it) + it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 0, 0, 0) val attr = it.attributes diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt index d859d7685..eaaf2f4d4 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/BgTextConfigDialog.kt @@ -9,10 +9,7 @@ import android.graphics.Color import android.net.Uri import android.os.Bundle import android.util.DisplayMetrics -import android.view.Gravity -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import androidx.documentfile.provider.DocumentFile import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView @@ -50,7 +47,7 @@ class BgTextConfigDialog : BaseDialogFragment() { it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { - Help.upSystemUiVisibility(it) + it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 5, 0, 0) val attr = it.attributes @@ -102,7 +99,7 @@ class BgTextConfigDialog : BaseDialogFragment() { sw_dark_status_icon.onCheckedChange { buttonView, isChecked -> if (buttonView?.isPressed == true) { setStatusIconDark(isChecked) - dialog?.window?.let { + activity?.window?.let { Help.upSystemUiVisibility(it) } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt index e17cb808a..1e7aa8d1c 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/MoreConfigDialog.kt @@ -4,10 +4,7 @@ import android.annotation.SuppressLint import android.content.SharedPreferences import android.os.Bundle import android.util.DisplayMetrics -import android.view.Gravity -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.LinearLayout import androidx.fragment.app.DialogFragment import androidx.preference.Preference @@ -33,7 +30,7 @@ class MoreConfigDialog : DialogFragment() { it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { - Help.upSystemUiVisibility(it) + it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 0, 0, 0) val attr = it.attributes diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt index 808306ed6..dda13716a 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/PaddingConfigDialog.kt @@ -6,11 +6,11 @@ import android.util.DisplayMetrics import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.WindowManager import io.legado.app.R import io.legado.app.base.BaseDialogFragment import io.legado.app.constant.EventBus import io.legado.app.help.ReadBookConfig -import io.legado.app.ui.book.read.Help import io.legado.app.utils.postEvent import kotlinx.android.synthetic.main.dialog_read_padding.* @@ -23,7 +23,7 @@ class PaddingConfigDialog : BaseDialogFragment() { it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { - Help.upSystemUiVisibility(it) + it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) val attr = it.attributes attr.dimAmount = 0.0f it.attributes = attr diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt index be79b46f7..3ae466454 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudConfigDialog.kt @@ -19,7 +19,6 @@ import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.backgroundColor import io.legado.app.service.BaseReadAloudService import io.legado.app.service.help.ReadAloud -import io.legado.app.ui.book.read.Help import io.legado.app.utils.getPrefLong import io.legado.app.utils.postEvent @@ -33,8 +32,8 @@ class ReadAloudConfigDialog : DialogFragment() { it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { - Help.upSystemUiVisibility(it) - it.setBackgroundDrawableResource(R.color.transparent) + + it.setBackgroundDrawableResource(R.color.transparent) it.setLayout((dm.widthPixels * 0.9).toInt(), ViewGroup.LayoutParams.WRAP_CONTENT) } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt index 1886837d1..7fcd0f26d 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadAloudDialog.kt @@ -2,10 +2,7 @@ package io.legado.app.ui.book.read.config import android.os.Bundle import android.util.DisplayMetrics -import android.view.Gravity -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import android.widget.SeekBar import io.legado.app.R import io.legado.app.base.BaseDialogFragment @@ -16,7 +13,6 @@ import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.service.BaseReadAloudService import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadBook -import io.legado.app.ui.book.read.Help import io.legado.app.utils.ColorUtils import io.legado.app.utils.getPrefBoolean import io.legado.app.utils.observeEvent @@ -34,7 +30,7 @@ class ReadAloudDialog : BaseDialogFragment() { it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { - Help.upSystemUiVisibility(it) + it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 0, 0, 0) val attr = it.attributes diff --git a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt index 4c3897d06..77b789b24 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/config/ReadStyleDialog.kt @@ -4,10 +4,7 @@ import android.annotation.SuppressLint import android.content.DialogInterface import android.os.Bundle import android.util.DisplayMetrics -import android.view.Gravity -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup +import android.view.* import androidx.core.view.get import io.legado.app.R import io.legado.app.base.BaseDialogFragment @@ -20,7 +17,6 @@ import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.lib.theme.primaryColor -import io.legado.app.ui.book.read.Help import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.widget.font.FontSelectDialog import io.legado.app.utils.* @@ -42,7 +38,7 @@ class ReadStyleDialog : BaseDialogFragment(), FontSelectDialog.CallBack { it.windowManager?.defaultDisplay?.getMetrics(dm) } dialog?.window?.let { - Help.upSystemUiVisibility(it) + it.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND) it.setBackgroundDrawableResource(R.color.background) it.decorView.setPadding(0, 0, 0, 0) val attr = it.attributes From 41b120c0a6c72a77d576c473a7b84411069c6746 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 21:35:21 +0800 Subject: [PATCH 65/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=B9=A6=E7=B1=8D?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/main/MainViewModel.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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 098edef57..c9fc9066a 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 @@ -23,7 +23,7 @@ import java.util.concurrent.CopyOnWriteArraySet import java.util.concurrent.Executors class MainViewModel(application: Application) : BaseViewModel(application) { - val threadCount = AppConfig.threadCount + private var threadCount = AppConfig.threadCount private var upTocPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher() val updateList = CopyOnWriteArraySet() private val bookMap = ConcurrentHashMap() @@ -37,8 +37,9 @@ class MainViewModel(application: Application) : BaseViewModel(application) { } fun upPool() { + threadCount = AppConfig.threadCount upTocPool.close() - upTocPool = Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher() + upTocPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher() } fun upAllBookToc() { From 09a097eb5765d72a2394db248de70ab75c62d7a8 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 21:46:14 +0800 Subject: [PATCH 66/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=81=A2=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/storage/Restore.kt | 9 +++++++-- app/src/main/res/values-zh-rHK/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 5 files changed, 11 insertions(+), 2 deletions(-) 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 63202a5c5..5deeac5dd 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 @@ -39,7 +39,8 @@ object Restore { "readConfig", PreferKey.themeMode, PreferKey.bookshelfLayout, - PreferKey.showRss + PreferKey.showRss, + PreferKey.threadCount ) //忽略标题 @@ -47,7 +48,8 @@ object Restore { App.INSTANCE.getString(R.string.read_config), App.INSTANCE.getString(R.string.theme_mode), App.INSTANCE.getString(R.string.bookshelf_layout), - App.INSTANCE.getString(R.string.show_rss) + App.INSTANCE.getString(R.string.show_rss), + App.INSTANCE.getString(R.string.thread_count) ) //默认忽略keys @@ -219,6 +221,7 @@ object Restore { PreferKey.themeMode == key && ignoreThemeMode -> false PreferKey.bookshelfLayout == key && ignoreBookshelfLayout -> false PreferKey.showRss == key && ignoreShowRss -> false + PreferKey.threadCount == key && ignoreThreadCount -> false else -> true } } @@ -231,6 +234,8 @@ object Restore { get() = ignoreConfig[PreferKey.bookshelfLayout] == true private val ignoreShowRss: Boolean get() = ignoreConfig[PreferKey.showRss] == true + private val ignoreThreadCount: Boolean + get() = ignoreConfig[PreferKey.threadCount] == true fun saveIgnoreConfig() { val json = GSON.toJson(ignoreConfig) diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 640e5c4cc..083f92787 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -750,4 +750,5 @@ 阅读记录 阅读时间记录 本地TTS + 线程数 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index f7aed74c5..01c999ac7 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -750,5 +750,6 @@ 阅读记录 阅读时间记录 本地TTS + 线程数 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 8082cb605..b41d0c84c 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -750,4 +750,5 @@ 阅读记录 阅读时间记录 本地TTS + 线程数 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 991d4e9ca..610f079a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -751,5 +751,6 @@ 阅读记录 阅读时间记录 本地TTS + 线程数 \ No newline at end of file From f8701a88d6e15e9f48cd8c2068657813797e7696 Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 22:24:43 +0800 Subject: [PATCH 67/90] =?UTF-8?q?=E7=AC=AC1=E4=B8=AA=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E9=BB=91=E7=99=BD=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/readConfig.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/assets/readConfig.json b/app/src/main/assets/readConfig.json index 301a75705..968141a0c 100644 --- a/app/src/main/assets/readConfig.json +++ b/app/src/main/assets/readConfig.json @@ -1,9 +1,9 @@ [ { - "bgStr": "#EBD9BB", - "bgStrNight": "#1E2021", - "textColor": "#63543C", - "textColorNight": "#DCDFE1", + "bgStr": "#FFFFFF", + "bgStrNight": "#000000", + "textColor": "#000000", + "textColorNight": "#FFFFFF", "bgType": 0, "bgTypeNight": 0, "darkStatusIcon": true, From 280f2f0a3d7e9f332a94f4dbc75683a0a6893a1e Mon Sep 17 00:00:00 2001 From: gedoor Date: Fri, 28 Aug 2020 22:53:46 +0800 Subject: [PATCH 68/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/constant/AppPattern.kt | 7 ++-- .../java/io/legado/app/data/entities/Book.kt | 5 +++ .../main/java/io/legado/app/help/BookHelp.kt | 34 +++++++------------ .../read/page/provider/ChapterProvider.kt | 6 ++-- 4 files changed, 24 insertions(+), 28 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/AppPattern.kt b/app/src/main/java/io/legado/app/constant/AppPattern.kt index e9a508939..d31e69f23 100644 --- a/app/src/main/java/io/legado/app/constant/AppPattern.kt +++ b/app/src/main/java/io/legado/app/constant/AppPattern.kt @@ -6,8 +6,11 @@ object AppPattern { val JS_PATTERN: Pattern = Pattern.compile("([\\w\\W]*?|@js:[\\w\\W]*$)", Pattern.CASE_INSENSITIVE) val EXP_PATTERN: Pattern = Pattern.compile("\\{\\{([\\w\\W]*?)\\}\\}") + val imgPattern = + Pattern.compile("", Pattern.CASE_INSENSITIVE) - val authorRegex = "作\\s*者\\s*[::]".toRegex() - + val nameRegex = Regex("\\s+作\\s*者.*") + val authorRegex = Regex(".*?作\\s*?者[::]") + val fileNameRegex = Regex("[\\\\/:*?\"<>|.]") val splitGroupRegex = Regex("[,;]") } \ No newline at end of file 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 33d5d309b..c6759c237 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 @@ -11,6 +11,7 @@ import io.legado.app.constant.BookType import io.legado.app.help.AppConfig import io.legado.app.service.help.ReadBook import io.legado.app.utils.GSON +import io.legado.app.utils.MD5Utils import io.legado.app.utils.fromJsonObject import kotlinx.android.parcel.IgnoredOnParcel import kotlinx.android.parcel.Parcelize @@ -115,6 +116,10 @@ data class Book( return charset(charset ?: "UTF-8") } + fun getFolderName(): String { + return name.replace(AppPattern.fileNameRegex, "") + MD5Utils.md5Encode16(bookUrl) + } + fun toSearchBook(): SearchBook { return SearchBook( name = name, 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 4f25f85ed..b0e5575f8 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -2,6 +2,7 @@ package io.legado.app.help import com.hankcs.hanlp.HanLP import io.legado.app.App +import io.legado.app.constant.AppPattern import io.legado.app.constant.EventBus import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter @@ -16,19 +17,12 @@ import kotlinx.coroutines.withContext import org.apache.commons.text.similarity.JaccardSimilarity import org.jetbrains.anko.toast import java.io.File -import java.util.regex.Pattern import kotlin.math.min object BookHelp { private const val cacheFolderName = "book_cache" private const val cacheImageFolderName = "images" private val downloadDir: File = App.INSTANCE.externalFilesDir - private val srcPattern = - Pattern.compile("", Pattern.CASE_INSENSITIVE) - - fun bookFolderName(book: Book): String { - return formatFolderName(book.name) + MD5Utils.md5Encode16(book.bookUrl) - } fun formatChapterName(bookChapter: BookChapter): String { return String.format( @@ -51,7 +45,7 @@ object BookHelp { Coroutine.async { val bookFolderNames = arrayListOf() App.db.bookDao().all.forEach { - bookFolderNames.add(bookFolderName(it)) + bookFolderNames.add(it.getFolderName()) } val file = FileUtils.getDirFile(downloadDir, cacheFolderName) file.listFiles()?.forEach { bookFile -> @@ -69,11 +63,11 @@ object BookHelp { FileUtils.createFileIfNotExist( downloadDir, formatChapterName(bookChapter), - subDirs = arrayOf(cacheFolderName, bookFolderName(book)) + subDirs = arrayOf(cacheFolderName, book.getFolderName()) ).writeText(content) //保存图片 content.split("\n").forEach { - val matcher = srcPattern.matcher(it) + val matcher = AppPattern.imgPattern.matcher(it) if (matcher.find()) { var src = matcher.group(1) src = NetworkUtils.getAbsoluteURL(bookChapter.url, src) @@ -91,7 +85,7 @@ object BookHelp { FileUtils.createFileIfNotExist( downloadDir, "${MD5Utils.md5Encode16(src)}${getImageSuffix(src)}", - subDirs = arrayOf(cacheFolderName, bookFolderName(book), cacheImageFolderName) + subDirs = arrayOf(cacheFolderName, book.getFolderName(), cacheImageFolderName) ).writeBytes(it) } } @@ -100,7 +94,7 @@ object BookHelp { return FileUtils.getFile( downloadDir, "${MD5Utils.md5Encode16(src)}${getImageSuffix(src)}", - subDirs = arrayOf(cacheFolderName, bookFolderName(book), cacheImageFolderName) + subDirs = arrayOf(cacheFolderName, book.getFolderName(), cacheImageFolderName) ) } @@ -116,7 +110,7 @@ object BookHelp { val fileNameList = arrayListOf() FileUtils.createFolderIfNotExist( downloadDir, - subDirs = arrayOf(cacheFolderName, bookFolderName(book)) + subDirs = arrayOf(cacheFolderName, book.getFolderName()) ).list()?.let { fileNameList.addAll(it) } @@ -130,7 +124,7 @@ object BookHelp { FileUtils.exists( downloadDir, formatChapterName(bookChapter), - subDirs = arrayOf(cacheFolderName, bookFolderName(book)) + subDirs = arrayOf(cacheFolderName, book.getFolderName()) ) } } @@ -142,7 +136,7 @@ object BookHelp { val file = FileUtils.getFile( downloadDir, formatChapterName(bookChapter), - subDirs = arrayOf(cacheFolderName, bookFolderName(book)) + subDirs = arrayOf(cacheFolderName, book.getFolderName()) ) if (file.exists()) { return file.readText() @@ -158,24 +152,20 @@ object BookHelp { FileUtils.createFileIfNotExist( downloadDir, formatChapterName(bookChapter), - subDirs = arrayOf(cacheFolderName, bookFolderName(book)) + subDirs = arrayOf(cacheFolderName, book.getFolderName()) ).delete() } } - private fun formatFolderName(folderName: String): String { - return folderName.replace("[\\\\/:*?\"<>|.]".toRegex(), "") - } - fun formatBookName(name: String): String { return name - .replace("\\s+作\\s*者.*".toRegex(), "") + .replace(AppPattern.nameRegex, "") .trim { it <= ' ' } } fun formatBookAuthor(author: String): String { return author - .replace(".*?作\\s*?者[::]".toRegex(), "") + .replace(AppPattern.authorRegex, "") .trim { it <= ' ' } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt index 3dbc0a5e1..849c69b84 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/provider/ChapterProvider.kt @@ -7,6 +7,7 @@ import android.text.StaticLayout import android.text.TextPaint import android.text.TextUtils import io.legado.app.App +import io.legado.app.constant.AppPattern import io.legado.app.constant.PreferKey import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter @@ -18,7 +19,6 @@ import io.legado.app.ui.book.read.page.entities.TextLine import io.legado.app.ui.book.read.page.entities.TextPage import io.legado.app.utils.* import java.util.* -import java.util.regex.Pattern @Suppress("DEPRECATION") @@ -38,8 +38,6 @@ object ChapterProvider { var typeface: Typeface = Typeface.SANS_SERIF lateinit var titlePaint: TextPaint lateinit var contentPaint: TextPaint - private val srcPattern = - Pattern.compile("", Pattern.CASE_INSENSITIVE) init { upStyle() @@ -62,7 +60,7 @@ object ChapterProvider { var durY = 0f textPages.add(TextPage()) contents.forEachIndexed { index, text -> - val matcher = srcPattern.matcher(text) + val matcher = AppPattern.imgPattern.matcher(text) if (matcher.find()) { var src = matcher.group(1) if (!book.isEpub()) { From 0f0bd505848104560b7f8b084539fbf564ec63df Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 09:36:27 +0800 Subject: [PATCH 69/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/BookHelp.kt | 3 +++ .../io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt | 4 +++- .../io/legado/app/ui/book/chapterlist/ChapterListFragment.kt | 3 +++ app/src/main/res/layout/item_chapter_list.xml | 4 ++-- 4 files changed, 11 insertions(+), 3 deletions(-) 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 b0e5575f8..85d5aaa87 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -108,6 +108,9 @@ object BookHelp { fun getChapterFiles(book: Book): List { val fileNameList = arrayListOf() + if (book.isLocalBook()) { + return fileNameList + } FileUtils.createFolderIfNotExist( downloadDir, subDirs = arrayOf(cacheFolderName, book.getFolderName()) diff --git a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt index 17970bc65..5d4b3621b 100644 --- a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListAdapter.kt @@ -22,7 +22,8 @@ class ChapterListAdapter(context: Context, val callback: Callback) : override fun convert(holder: ItemViewHolder, item: BookChapter, payloads: MutableList) { with(holder.itemView) { val isDur = callback.durChapterIndex() == item.index - val cached = cacheFileNames.contains(BookHelp.formatChapterName(item)) + val cached = callback.isLocalBook + || cacheFileNames.contains(BookHelp.formatChapterName(item)) if (payloads.isEmpty()) { if (isDur) { tv_chapter_name.setTextColor(context.accentColor) @@ -60,6 +61,7 @@ class ChapterListAdapter(context: Context, val callback: Callback) : } interface Callback { + val isLocalBook: Boolean fun openChapter(bookChapter: BookChapter) fun durChapterIndex(): Int } diff --git a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt index 58d47efeb..d4339bb23 100644 --- a/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/chapterlist/ChapterListFragment.kt @@ -129,6 +129,9 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragme } } + override val isLocalBook: Boolean + get() = viewModel.book?.isLocalBook() == true + override fun durChapterIndex(): Int { return durChapterIndex } diff --git a/app/src/main/res/layout/item_chapter_list.xml b/app/src/main/res/layout/item_chapter_list.xml index b0e9d4f23..285af05ba 100644 --- a/app/src/main/res/layout/item_chapter_list.xml +++ b/app/src/main/res/layout/item_chapter_list.xml @@ -29,8 +29,8 @@ Date: Sat, 29 Aug 2020 17:11:29 +0800 Subject: [PATCH 70/90] =?UTF-8?q?=E6=9F=90=E4=BA=9B=E4=B9=A6=E6=BA=90?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=AE=BE=E7=BD=AE=E4=BB=A3=E7=90=86=E8=AE=BF?= =?UTF-8?q?=E9=97=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/http/HttpHelper.kt | 66 +++++++++++++++++++ .../app/model/analyzeRule/AnalyzeUrl.kt | 60 +++++++++++++---- 2 files changed, 115 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index 9aa17e9c1..79abae41f 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -8,7 +8,10 @@ import okhttp3.ConnectionSpec import okhttp3.Interceptor import okhttp3.OkHttpClient import okhttp3.Protocol +import okhttp3.Credentials import retrofit2.Retrofit +import java.net.InetSocketAddress +import java.net.Proxy import java.util.concurrent.TimeUnit import kotlin.coroutines.resume @@ -83,6 +86,14 @@ object HttpHelper { return getRetrofit(baseUrl, encode).create(T::class.java) } + inline fun getApiServiceWithProxy( + baseUrl: String, + encode: String? = null, + proxy: String? = null + ): T { + return getRetrofitWithProxy(baseUrl, encode, proxy).create(T::class.java) + } + inline fun getBytesApiService(baseUrl: String): T { return getByteRetrofit(baseUrl).create(T::class.java) } @@ -95,6 +106,61 @@ object HttpHelper { .build() } + fun getRetrofitWithProxy( + baseUrl: String, + encode: String? = null, + proxy: String? = null + ): Retrofit { + val r = + Regex( + """ + (http|socks4|socks5)://(.*):(\d{2,5})(@.*@.*)? + """.trimIndent() + ) + val ms = proxy?.let { r.findAll(it) }; + val group = ms?.first() + var type: String = "direct" //直接连接 + var host: String = "127.0.0.1" //代理服务器hostname + var port: Int = 1080 //代理服务器port + var username: String = "" //代理服务器验证用户名 + var password: String = "" //代理服务器验证密码 + if (group != null) { + type = if (group.groupValues[1] == "http") { + "http" + } else { + "socks" + } + host = group.groupValues[2] + port = group.groupValues[3].toInt() + if (group.groupValues[4] != "") { + username = group.groupValues[4].split("@")[1]; + password = group.groupValues[4].split("@")[2]; + } + } + val builder = client.newBuilder(); + if (type != "direct" && host != "") { + if (type == "http") { + builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))); + } else { + builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))); + } + if (username != "" && password != "") { + builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 + val credential: String = Credentials.basic(username, password) + response.request().newBuilder() + .header("Proxy-Authorization", credential) + .build() + } + } + + } + return Retrofit.Builder().baseUrl(baseUrl) + //增加返回值为字符串的支持(以实体类返回) + .addConverterFactory(EncodeConverter(encode)) + .client(builder.build()) + .build() + } + fun getByteRetrofit(baseUrl: String): Retrofit { return Retrofit.Builder().baseUrl(baseUrl) .addConverterFactory(ByteConverter()) diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index e892bf073..97a9149a0 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -59,12 +59,19 @@ class AnalyzeUrl( private var requestBody: RequestBody? = null private var method = RequestMethod.GET private val splitUrlRegex = Regex(",\\s*(?=\\{)") + private var proxy: String? = null init { baseUrl?.let { this.baseUrl = it.split(splitUrlRegex, 1)[0] } - headerMapF?.let { headerMap.putAll(it) } + headerMapF?.let { + headerMap.putAll(it) + if (it.containsKey("proxy")) { + proxy = it["proxy"]; + headerMap.remove("proxy") + } + } //替换参数 analyzeJs(key, page, speakText, speakSpeed, book) replaceKeyPageJs(key, page, speakText, speakSpeed, book) @@ -329,21 +336,52 @@ class AnalyzeUrl( val res = when { method == RequestMethod.POST -> { if (fieldMap.isNotEmpty()) { + if (proxy == null) { + HttpHelper + .getApiService(baseUrl, charset) + .postMapAsync(url, fieldMap, headerMap) + } else { + HttpHelper + .getApiServiceWithProxy(baseUrl, charset, proxy) + .postMapAsync(url, fieldMap, headerMap) + } + } else { + if (proxy == null) { + HttpHelper + .getApiService(baseUrl, charset) + .postBodyAsync(url, requestBody!!, headerMap) + } else { + HttpHelper + .getApiServiceWithProxy(baseUrl, charset, proxy) + .postBodyAsync(url, requestBody!!, headerMap) + } + } + } + fieldMap.isEmpty() -> { + if (proxy == null) { HttpHelper - .getApiService(baseUrl, charset) - .postMapAsync(url, fieldMap, headerMap) + .getApiService(baseUrl, charset) + .getAsync(url, headerMap) + } else { HttpHelper - .getApiService(baseUrl, charset) - .postBodyAsync(url, requestBody!!, headerMap) + .getApiServiceWithProxy(baseUrl, charset, proxy) + .getAsync(url, headerMap) } + + } + else -> { + if (proxy == null) { + HttpHelper + .getApiService(baseUrl, charset) + .getMapAsync(url, fieldMap, headerMap) + } else { + HttpHelper + .getApiServiceWithProxy(baseUrl, charset, proxy) + .getMapAsync(url, fieldMap, headerMap) + } + } - fieldMap.isEmpty() -> HttpHelper - .getApiService(baseUrl, charset) - .getAsync(url, headerMap) - else -> HttpHelper - .getApiService(baseUrl, charset) - .getMapAsync(url, fieldMap, headerMap) } return Res(NetworkUtils.getUrl(res), res.body()) } From b992edd5fb53be867b0a5456243a9f59dc2d5944 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 17:21:41 +0800 Subject: [PATCH 71/90] =?UTF-8?q?web=E9=98=85=E8=AF=BB=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/web/controller/BookshelfController.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt b/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt index 203bb37da..dba45d4c1 100644 --- a/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt +++ b/app/src/main/java/io/legado/app/web/controller/BookshelfController.kt @@ -94,6 +94,7 @@ object BookshelfController { App.db.bookDao().update(book) if (ReadBook.book?.bookUrl == book.bookUrl) { ReadBook.book = book + ReadBook.durChapterIndex = index } } } From aac445c4d6d44eeca28b86ced77b125622033a60 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 17:26:43 +0800 Subject: [PATCH 72/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=98=85=E8=AF=BB?= =?UTF-8?q?=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/service/BaseReadAloudService.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt b/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt index dbfebd323..2fd69506e 100644 --- a/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt +++ b/app/src/main/java/io/legado/app/service/BaseReadAloudService.kt @@ -336,6 +336,7 @@ abstract class BaseReadAloudService : BaseService(), abstract fun aloudServicePendingIntent(actionStr: String): PendingIntent? open fun nextChapter() { + ReadBook.upReadStartTime() if (!ReadBook.moveToNextChapter(true)) { stopSelf() } From 64e55854f72eb7c51642655957cf0f258e0d212f Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 17:52:20 +0800 Subject: [PATCH 73/90] =?UTF-8?q?WebDav=E6=81=A2=E5=A4=8D=E5=87=BA?= =?UTF-8?q?=E9=94=99=E6=97=B6=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/storage/WebDavHelp.kt | 22 ++++++-------- .../legado/app/ui/config/BackupRestoreUi.kt | 29 ++++++++++--------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/storage/WebDavHelp.kt b/app/src/main/java/io/legado/app/help/storage/WebDavHelp.kt index 190ec2176..e728c28de 100644 --- a/app/src/main/java/io/legado/app/help/storage/WebDavHelp.kt +++ b/app/src/main/java/io/legado/app/help/storage/WebDavHelp.kt @@ -51,28 +51,25 @@ object WebDavHelp { return false } + @Throws(Exception::class) private fun getWebDavFileNames(): ArrayList { val url = rootWebDavUrl val names = arrayListOf() if (initWebDav()) { - try { - var files = WebDav(url).listFiles() - files = files.reversed() - for (index: Int in 0 until min(10, files.size)) { - files[index].displayName?.let { - names.add(it) - } + var files = WebDav(url).listFiles() + files = files.reversed() + for (index: Int in 0 until min(10, files.size)) { + files[index].displayName?.let { + names.add(it) } - } catch (e: Exception) { - return names } } return names } - suspend fun showRestoreDialog(context: Context): Boolean { + suspend fun showRestoreDialog(context: Context) { val names = withContext(IO) { getWebDavFileNames() } - return if (names.isNotEmpty()) { + if (names.isNotEmpty()) { withContext(Main) { context.selector( title = context.getString(R.string.select_restore_file), @@ -83,9 +80,8 @@ object WebDavHelp { } } } - true } else { - false + throw Exception("Web dav no back up file") } } diff --git a/app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt b/app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt index 391a76ddf..39939e8cf 100644 --- a/app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt +++ b/app/src/main/java/io/legado/app/ui/config/BackupRestoreUi.kt @@ -19,6 +19,7 @@ import io.legado.app.help.storage.WebDavHelp import io.legado.app.ui.filechooser.FilePicker import io.legado.app.utils.getPrefString import io.legado.app.utils.isContentPath +import io.legado.app.utils.longToast import io.legado.app.utils.toast import kotlinx.coroutines.Dispatchers.Main import org.jetbrains.anko.toast @@ -77,24 +78,24 @@ object BackupRestoreUi { fun restore(fragment: Fragment) { Coroutine.async(context = Main) { - val restoreFromWebDav = WebDavHelp.showRestoreDialog(fragment.requireContext()) - if (!restoreFromWebDav) { - val backupPath = fragment.getPrefString(PreferKey.backupPath) - if (backupPath?.isNotEmpty() == true) { - if (backupPath.isContentPath()) { - val uri = Uri.parse(backupPath) - val doc = DocumentFile.fromTreeUri(fragment.requireContext(), uri) - if (doc?.canWrite() == true) { - Restore.restore(fragment.requireContext(), backupPath) - } else { - selectBackupFolder(fragment, restoreSelectRequestCode) - } + WebDavHelp.showRestoreDialog(fragment.requireContext()) + }.onError { + fragment.longToast("WebDavError:${it.localizedMessage},将从本地备份恢复。") + val backupPath = fragment.getPrefString(PreferKey.backupPath) + if (backupPath?.isNotEmpty() == true) { + if (backupPath.isContentPath()) { + val uri = Uri.parse(backupPath) + val doc = DocumentFile.fromTreeUri(fragment.requireContext(), uri) + if (doc?.canWrite() == true) { + Restore.restore(fragment.requireContext(), backupPath) } else { - restoreUsePermission(fragment, backupPath) + selectBackupFolder(fragment, restoreSelectRequestCode) } } else { - selectBackupFolder(fragment, restoreSelectRequestCode) + restoreUsePermission(fragment, backupPath) } + } else { + selectBackupFolder(fragment, restoreSelectRequestCode) } } } From 6ea1cba8c05c11aaf673e212d4d8d13a924ad249 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 18:01:29 +0800 Subject: [PATCH 74/90] =?UTF-8?q?=E6=8D=A2=E6=BA=90=E4=B8=8D=E5=9C=A8?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E4=B9=A6=E5=90=8D=E5=92=8C=E4=BD=9C=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/model/webBook/BookInfo.kt | 14 +++++++++----- .../java/io/legado/app/model/webBook/WebBook.kt | 5 +++-- .../legado/app/ui/book/read/ReadBookViewModel.kt | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) 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 ce588c5cd..37ff4b5e7 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 @@ -2,7 +2,6 @@ package io.legado.app.model.webBook import io.legado.app.App import io.legado.app.R -import io.legado.app.constant.AppPattern import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookSource import io.legado.app.help.BookHelp @@ -19,7 +18,8 @@ object BookInfo { book: Book, body: String?, bookSource: BookSource, - baseUrl: String + baseUrl: String, + canReName: Boolean, ) { body ?: throw Exception( App.INSTANCE.getString(R.string.error_get_web_content, baseUrl) @@ -35,13 +35,17 @@ object BookInfo { } } Debug.log(bookSource.bookSourceUrl, "┌获取书名") - BookHelp.formatBookName(analyzeRule.getString(infoRule.name)).trim { it <= ' ' }.let { - if (it.isNotEmpty()) book.name = it + BookHelp.formatBookName(analyzeRule.getString(infoRule.name)).let { + if (it.isNotEmpty() && canReName) { + book.name = it + } } Debug.log(bookSource.bookSourceUrl, "└${book.name}") Debug.log(bookSource.bookSourceUrl, "┌获取作者") BookHelp.formatBookAuthor(analyzeRule.getString(infoRule.author)).let { - if (it.isNotEmpty()) book.author = it.replace(AppPattern.authorRegex, "") + if (it.isNotEmpty() && canReName) { + book.author = it + } } Debug.log(bookSource.bookSourceUrl, "└${book.author}") Debug.log(bookSource.bookSourceUrl, "┌获取分类") 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 cdf5553ee..22b75ed84 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 @@ -90,7 +90,8 @@ class WebBook(val bookSource: BookSource) { fun getBookInfo( book: Book, scope: CoroutineScope = Coroutine.DEFAULT, - context: CoroutineContext = Dispatchers.IO + context: CoroutineContext = Dispatchers.IO, + canReName: Boolean = true, ): Coroutine { return Coroutine.async(scope, context) { book.type = bookSource.bookSourceType @@ -106,7 +107,7 @@ class WebBook(val bookSource: BookSource) { ) analyzeUrl.getResponseAwait(bookSource.bookSourceUrl).body } - BookInfo.analyzeBookInfo(book, body, bookSource, book.bookUrl) + BookInfo.analyzeBookInfo(book, body, bookSource, book.bookUrl, canReName) book } } 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 249141890..5ba4625bd 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 @@ -10,8 +10,8 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.help.AppConfig import io.legado.app.help.BookHelp import io.legado.app.help.IntentDataHelp -import io.legado.app.model.webBook.WebBook import io.legado.app.model.localBook.LocalBook +import io.legado.app.model.webBook.WebBook import io.legado.app.service.BaseReadAloudService import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadBook @@ -95,7 +95,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { if (book.isLocalBook()) { loadChapterList(book, changeDruChapterIndex) } else { - ReadBook.webBook?.getBookInfo(book, this) + ReadBook.webBook?.getBookInfo(book, this, canReName = false) ?.onSuccess { loadChapterList(book, changeDruChapterIndex) } From 58902371210f99c4d3b86691fe6779d2e30883ae Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 18:07:55 +0800 Subject: [PATCH 75/90] =?UTF-8?q?=E6=8D=A2=E6=BA=90=E4=B8=8D=E5=9C=A8?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E4=B9=A6=E5=90=8D=E5=92=8C=E4=BD=9C=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/book/info/BookInfoViewModel.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 8f2ed64c2..71f046826 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 @@ -9,8 +9,8 @@ import io.legado.app.base.BaseViewModel import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.help.BookHelp -import io.legado.app.model.webBook.WebBook import io.legado.app.model.localBook.LocalBook +import io.legado.app.model.webBook.WebBook import io.legado.app.service.help.ReadBook import kotlinx.coroutines.Dispatchers.IO @@ -49,15 +49,15 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { } fun loadBookInfo( - book: Book, - changeDruChapterIndex: ((chapters: List) -> Unit)? = null + book: Book, canReName: Boolean = true, + changeDruChapterIndex: ((chapters: List) -> Unit)? = null, ) { execute { if (book.isLocalBook()) { loadChapter(book, changeDruChapterIndex) } else { App.db.bookSourceDao().getBookSource(book.origin)?.let { bookSource -> - WebBook(bookSource).getBookInfo(book, this) + WebBook(bookSource).getBookInfo(book, this, canReName = canReName) .onSuccess(IO) { bookData.postValue(book) if (inBookshelf) { @@ -138,7 +138,7 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { } bookData.postValue(newBook) if (newBook.tocUrl.isEmpty()) { - loadBookInfo(newBook) { upChangeDurChapterIndex(newBook, it) } + loadBookInfo(newBook, false) { upChangeDurChapterIndex(newBook, it) } } else { loadChapter(newBook) { upChangeDurChapterIndex(newBook, it) } } From f461474928a855908ae2c55a179cb6718e15b18a Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 18:11:49 +0800 Subject: [PATCH 76/90] =?UTF-8?q?=E6=8D=A2=E6=BA=90=E4=B8=8D=E5=9C=A8?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E4=B9=A6=E5=90=8D=E5=92=8C=E4=BD=9C=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/assets/updateLog.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index d2465782e..4b5b8223c 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,10 @@ * 关注合作公众号 **[小说拾遗]()** 获取好看的小说。 - 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2020/08/28** +* 修复一些bug +* 换源不再改变书名和作者,防止换到一些错误的书源后不能再换源 + **2020/08/27** * 修复主题bug * 修复封面bug From 90bc9df2f450358f29d4c6e8132fbed12cd694b0 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 18:13:09 +0800 Subject: [PATCH 77/90] =?UTF-8?q?=E6=8D=A2=E6=BA=90=E4=B8=8D=E5=9C=A8?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E4=B9=A6=E5=90=8D=E5=92=8C=E4=BD=9C=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/io/legado/app/ui/book/info/BookInfoActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2591a30c4..74c9c1acf 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 @@ -96,7 +96,7 @@ class BookInfoActivity : if (it.isLocalBook()) { it.tocUrl = "" } - viewModel.loadBookInfo(it) + viewModel.loadBookInfo(it, false) } } R.id.menu_can_update -> { From fcf7f3720ef594840e43327181d135d071938d35 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 18:22:33 +0800 Subject: [PATCH 78/90] =?UTF-8?q?=E6=8D=A2=E6=BA=90=E4=B8=8D=E5=9C=A8?= =?UTF-8?q?=E6=94=B9=E5=8F=98=E4=B9=A6=E5=90=8D=E5=92=8C=E4=BD=9C=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/model/webBook/BookInfo.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 37ff4b5e7..7d6c3a94c 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 @@ -36,14 +36,14 @@ object BookInfo { } Debug.log(bookSource.bookSourceUrl, "┌获取书名") BookHelp.formatBookName(analyzeRule.getString(infoRule.name)).let { - if (it.isNotEmpty() && canReName) { + if (it.isNotEmpty() && (canReName || book.name.isEmpty())) { book.name = it } } Debug.log(bookSource.bookSourceUrl, "└${book.name}") Debug.log(bookSource.bookSourceUrl, "┌获取作者") BookHelp.formatBookAuthor(analyzeRule.getString(infoRule.author)).let { - if (it.isNotEmpty() && canReName) { + if (it.isNotEmpty() && (canReName || book.name.isEmpty())) { book.author = it } } From 4a359c48a854ea1be3b4599ae9c3de8c50d41420 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sat, 29 Aug 2020 19:43:37 +0800 Subject: [PATCH 79/90] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8D=A2=E6=BA=90,?= =?UTF-8?q?=E6=8D=A2=E5=B0=81=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../book/changecover/ChangeCoverViewModel.kt | 104 ++++++++++++------ .../changesource/ChangeSourceViewModel.kt | 3 +- 2 files changed, 70 insertions(+), 37 deletions(-) diff --git a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt index 835c3a885..8a9e7ebe0 100644 --- a/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changecover/ChangeCoverViewModel.kt @@ -6,24 +6,31 @@ import androidx.lifecycle.MutableLiveData import io.legado.app.App import io.legado.app.base.BaseViewModel import io.legado.app.constant.AppPattern +import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.help.AppConfig -import io.legado.app.help.coroutine.Coroutine +import io.legado.app.help.coroutine.CompositeCoroutine import io.legado.app.model.webBook.WebBook import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExecutorCoroutineDispatcher import kotlinx.coroutines.asCoroutineDispatcher import java.util.concurrent.Executors +import kotlin.math.min class ChangeCoverViewModel(application: Application) : BaseViewModel(application) { - private var searchPool = - Executors.newFixedThreadPool(AppConfig.threadCount).asCoroutineDispatcher() + private val threadCount = AppConfig.threadCount + private var searchPool: ExecutorCoroutineDispatcher? = null var name: String = "" var author: String = "" - private var task: Coroutine<*>? = null + private var tasks = CompositeCoroutine() + private var bookSourceList = arrayListOf() val searchStateData = MutableLiveData() val searchBooksLiveData = MutableLiveData>() private val searchBooks = ArrayList() + @Volatile + private var searchIndex = -1 + fun initData(arguments: Bundle?) { arguments?.let { bundle -> bundle.getString("name")?.let { @@ -35,13 +42,18 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application } } + private fun initSearchPool() { + searchPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher() + searchIndex = -1 + } + fun loadDbSearchBook() { execute { App.db.searchBookDao().getEnableHasCover(name, author).let { searchBooks.addAll(it) if (it.size <= 1) { searchBooksLiveData.postValue(searchBooks) - search() + startSearch() } else { searchBooksLiveData.postValue(searchBooks) } @@ -49,50 +61,70 @@ class ChangeCoverViewModel(application: Application) : BaseViewModel(application } } - fun search() { - task = execute { - val bookSourceList = App.db.bookSourceDao().allEnabled - for (item in bookSourceList) { - //task取消时自动取消 by (scope = this@execute) - WebBook(item).searchBook(name, scope = this@execute, context = searchPool) - .timeout(30000L) - .onSuccess(Dispatchers.IO) { - if (it.isNotEmpty()) { - val searchBook = it[0] - if (searchBook.name == name && searchBook.author == author - && !searchBook.coverUrl.isNullOrEmpty() - ) { - App.db.searchBookDao().insert(searchBook) - if (!searchBooks.contains(searchBook)) { - searchBooks.add(searchBook) - searchBooksLiveData.postValue(searchBooks) - } - } - } - } - } - }.onStart { + private fun startSearch() { + execute { + bookSourceList.clear() + bookSourceList.addAll(App.db.bookSourceDao().allEnabled) searchStateData.postValue(true) - }.onCancel { - searchStateData.postValue(false) + initSearchPool() + for (i in 0 until threadCount) { + search() + } } + } - task?.invokeOnCompletion { - searchStateData.postValue(false) + private fun search() { + synchronized(this) { + if (searchIndex >= bookSourceList.lastIndex) { + return + } + searchIndex++ + val source = bookSourceList[searchIndex] + val task = WebBook(source).searchBook(name, scope = this, context = searchPool!!) + .timeout(60000L) + .onSuccess(Dispatchers.IO) { + if (it.isNotEmpty()) { + val searchBook = it[0] + if (searchBook.name == name && searchBook.author == author + && !searchBook.coverUrl.isNullOrEmpty() + ) { + App.db.searchBookDao().insert(searchBook) + if (!searchBooks.contains(searchBook)) { + searchBooks.add(searchBook) + searchBooksLiveData.postValue(searchBooks) + } + } + } + } + .onFinally { + synchronized(this) { + if (searchIndex < bookSourceList.lastIndex) { + search() + } else { + searchIndex++ + } + if (searchIndex >= bookSourceList.lastIndex + min(bookSourceList.size, + threadCount) + ) { + searchStateData.postValue(false) + } + } + } + tasks.add(task) } } fun stopSearch() { - if (task?.isActive == true) { - task?.cancel() + if (tasks.isEmpty) { + startSearch() } else { - search() + tasks.clear() } } override fun onCleared() { super.onCleared() - searchPool.close() + searchPool?.close() } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt index 8efb57093..6ce62b9f2 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeSourceViewModel.kt @@ -25,7 +25,7 @@ import java.util.concurrent.Executors import kotlin.math.min class ChangeSourceViewModel(application: Application) : BaseViewModel(application) { - val threadCount = AppConfig.threadCount + private val threadCount = AppConfig.threadCount private var searchPool: ExecutorCoroutineDispatcher? = null val handler = Handler() val searchStateData = MutableLiveData() @@ -54,6 +54,7 @@ class ChangeSourceViewModel(application: Application) : BaseViewModel(applicatio private fun initSearchPool() { searchPool = Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher() + searchIndex = -1 } fun loadDbSearchBook() { From 63b33012c9c40b96def2eda65b95c590e7d9a113 Mon Sep 17 00:00:00 2001 From: Mupceet Date: Sun, 30 Aug 2020 14:34:01 +0800 Subject: [PATCH 80/90] feat: support slide slection - BookSourceActivity In order to enhance the interactive experience, we introduced the function of sliding selection. Currently, this function is only enabled in the BookSourceActivity --- .../book/source/manage/BookSourceActivity.kt | 8 + .../book/source/manage/BookSourceAdapter.kt | 26 + .../recycler/DragSelectTouchHelper.java | 983 ++++++++++++++++++ 3 files changed, 1017 insertions(+) create mode 100644 app/src/main/java/io/legado/app/ui/widget/recycler/DragSelectTouchHelper.java diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt index 7fb8855b3..b673fe729 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceActivity.kt @@ -31,6 +31,7 @@ import io.legado.app.ui.filechooser.FileChooserDialog import io.legado.app.ui.filechooser.FilePicker import io.legado.app.ui.qrcode.QrCodeActivity import io.legado.app.ui.widget.SelectActionBar +import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.text.AutoCompleteTextView import io.legado.app.utils.* @@ -137,6 +138,13 @@ class BookSourceActivity : VMBaseActivity(R.layout.activity val itemTouchCallback = ItemTouchCallback() itemTouchCallback.onItemTouchCallbackListener = adapter itemTouchCallback.isCanDrag = true + val dragSelectTouchHelper: DragSelectTouchHelper = + DragSelectTouchHelper(adapter.initDragSelectTouchHelperCallback()).setSlideArea(16, 50) + dragSelectTouchHelper.attachToRecyclerView(recycler_view) + // When this page is opened, it is in selection mode + dragSelectTouchHelper.activeSlideSelect() + + // Note: need judge selection first, so add ItemTouchHelper after it. ItemTouchHelper(itemTouchCallback).attachToRecyclerView(recycler_view) } diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt index a035341ee..7bdb34018 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceAdapter.kt @@ -14,6 +14,7 @@ import io.legado.app.base.adapter.SimpleRecyclerAdapter import io.legado.app.data.entities.BookSource import io.legado.app.help.ItemTouchCallback.OnItemTouchCallbackListener import io.legado.app.lib.theme.backgroundColor +import io.legado.app.ui.widget.recycler.DragSelectTouchHelper import io.legado.app.utils.invisible import io.legado.app.utils.visible import kotlinx.android.synthetic.main.item_book_source.view.* @@ -193,6 +194,31 @@ class BookSourceAdapter(context: Context, val callBack: CallBack) : } } + fun initDragSelectTouchHelperCallback(): DragSelectTouchHelper.Callback { + return object : DragSelectTouchHelper.AdvanceCallback(Mode.ToggleAndReverse) { + override fun currentSelectedId(): MutableSet { + return selected + } + + override fun getItemId(position: Int): BookSource { + return getItem(position)!! + } + + override fun updateSelectState(position: Int, isSelected: Boolean): Boolean { + getItem(position)?.let { + if (isSelected) { + selected.add(it) + } else { + selected.remove(it) + } + notifyItemChanged(position, bundleOf(Pair("selected", null))) + return true + } + return false + } + } + } + interface CallBack { fun del(bookSource: BookSource) fun edit(bookSource: BookSource) diff --git a/app/src/main/java/io/legado/app/ui/widget/recycler/DragSelectTouchHelper.java b/app/src/main/java/io/legado/app/ui/widget/recycler/DragSelectTouchHelper.java new file mode 100644 index 000000000..a8291897e --- /dev/null +++ b/app/src/main/java/io/legado/app/ui/widget/recycler/DragSelectTouchHelper.java @@ -0,0 +1,983 @@ +/* + * Copyright 2020 Mupceet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.legado.app.ui.widget.recycler; + +import android.content.res.Resources; +import android.text.TextUtils; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; +import android.view.MotionEvent; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.view.ViewCompat; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Set; + +import io.legado.app.BuildConfig; + +/** + * @author mupceet + */ +public class DragSelectTouchHelper { + private static final String TAG = "DSTH"; + private static final float MAX_HOTSPOT_RATIO = 0.5f; + private static final EdgeType DEFAULT_EDGE_TYPE = EdgeType.INSIDE_EXTEND; + private static final float DEFAULT_HOTSPOT_RATIO = 0.2f; + private static final int DEFAULT_HOTSPOT_OFFSET = 0; + private static final int DEFAULT_MAX_SCROLL_VELOCITY = 10; + private static final int SELECT_STATE_NORMAL = 0x00; + + /* + * !autoChangeMode +-------------------+ inactiveSelect() + * +------------------------------------> | | <--------------------+ + * | | Normal | | + * | activeDragSelect(position) | | activeSlideSelect() | + * | +------------------------------ | | ----------+ | + * | v +-------------------+ v | + * +-------------------+ autoChangeMode +-----------------------+ + * | Drag From Disable | ----------------------------------------------> | | + * +-------------------+ | | + * | | | | + * | | activeDragSelect(position) && allowDragInSlide | Slide | + * | | <---------------------------------------------- | | + * | Drag From Slide | | | + * | | | | + * | | ----------------------------------------------> | | + * +-------------------+ +-----------------------+ + */ + + private static final int SELECT_STATE_SLIDE = 0x01; + private static final int SELECT_STATE_DRAG_FROM_NORMAL = 0x10; + private static final int SELECT_STATE_DRAG_FROM_SLIDE = 0x11; + private final DisplayMetrics mDisplayMetrics; + /** + * Start of the slide area. + */ + private float mSlideAreaLeft; + /** + * End of the slide area. + */ + private float mSlideAreaRight; + /** + * The hotspot height by the ratio of RecyclerView. + */ + private float mHotspotHeightRatio; + /** + * The hotspot height. + */ + private float mHotspotHeight = 0f; + /** + * The hotspot offset. + */ + private float mHotspotOffset; + /** + * Whether should continue scrolling when move outside top hotspot region. + */ + private boolean mScrollAboveTopRegion; + /** + * Whether should continue scrolling when move outside bottom hotspot region. + */ + private boolean mScrollBelowBottomRegion; + /** + * The maximum velocity of auto scrolling. + */ + private int mMaximumVelocity; + /** + * Whether should auto enter slide mode after drag select finished. + */ + private boolean mShouldAutoChangeState; + /** + * Whether can drag selection in slide select mode. + */ + private boolean mIsAllowDragInSlideState; + private RecyclerView mRecyclerView = null; + /** + * The coordinate of hotspot area. + */ + private float mTopRegionFrom = -1f; + private float mTopRegionTo = -1f; + private float mBottomRegionFrom = -1f; + private float mBottomRegionTo = -1f; + private final View.OnLayoutChangeListener mOnLayoutChangeListener = new View.OnLayoutChangeListener() { + @Override + public void onLayoutChange(View v, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + if (oldLeft != left || oldRight != right || oldTop != top || oldBottom != bottom) { + if (v == mRecyclerView) { + Logger.i("onLayoutChange:new: " + + left + " " + top + " " + right + " " + bottom); + Logger.i("onLayoutChange:old: " + + oldLeft + " " + oldTop + " " + oldRight + " " + oldBottom); + init(bottom - top); + } + } + } + }; + /** + * The current mode of selection. + */ + private int mSelectState = SELECT_STATE_NORMAL; + /** + * Whether is in top hotspot area. + */ + private boolean mIsInTopHotspot = false; + /** + * Whether is in bottom hotspot area. + */ + private boolean mIsInBottomHotspot = false; + /** + * Indicates automatically scroll. + */ + private boolean mIsScrolling; + /** + * The actual speed of the current moment. + */ + private int mScrollDistance = 0; + /** + * The reference coordinate for the action start, used to avoid reverse scrolling. + */ + private float mDownY = Float.MIN_VALUE; + /** + * The reference coordinates for the last action. + */ + private float mLastX = Float.MIN_VALUE; + private float mLastY = Float.MIN_VALUE; + /** + * The selected items position. + */ + private int mStart = RecyclerView.NO_POSITION; + private int mEnd = RecyclerView.NO_POSITION; + private int mLastRealStart = RecyclerView.NO_POSITION; + private int mLastRealEnd = RecyclerView.NO_POSITION; + private int mSlideStateStartPosition = RecyclerView.NO_POSITION; + private boolean mHaveCalledSelectStart = false; + /** + * Developer callback which controls the behavior of DragSelectTouchHelper. + */ + @NonNull + private Callback mCallback; + private Runnable mScrollRunnable = new Runnable() { + @Override + public void run() { + if (mIsScrolling) { + scrollBy(mScrollDistance); + ViewCompat.postOnAnimation(mRecyclerView, mScrollRunnable); + } + } + }; + private final RecyclerView.OnItemTouchListener mOnItemTouchListener = new RecyclerView.OnItemTouchListener() { + @Override + public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + Logger.d("onInterceptTouchEvent: x:" + e.getX() + ",y:" + e.getY() + + ", " + MotionEvent.actionToString(e.getAction())); + RecyclerView.Adapter adapter = rv.getAdapter(); + if (adapter == null || adapter.getItemCount() == 0) { + return false; + } + boolean intercept = false; + int action = e.getAction(); + int actionMask = action & MotionEvent.ACTION_MASK; + // It seems that it's unnecessary to process multiple pointers. + switch (actionMask) { + case MotionEvent.ACTION_DOWN: + mDownY = e.getY(); + // call the selection start's callback before moving + if (mSelectState == SELECT_STATE_SLIDE && isInSlideArea(e)) { + mSlideStateStartPosition = getItemPosition(rv, e); + if (mSlideStateStartPosition != RecyclerView.NO_POSITION) { + mCallback.onSelectStart(mSlideStateStartPosition); + mHaveCalledSelectStart = true; + } + intercept = true; + } + break; + case MotionEvent.ACTION_MOVE: + if (mSelectState == SELECT_STATE_DRAG_FROM_NORMAL + || mSelectState == SELECT_STATE_DRAG_FROM_SLIDE) { + Logger.i("onInterceptTouchEvent: drag mode move"); + intercept = true; + } + break; + case MotionEvent.ACTION_UP: + if (mSelectState == SELECT_STATE_DRAG_FROM_NORMAL + || mSelectState == SELECT_STATE_DRAG_FROM_SLIDE) { + intercept = true; + } + // fall through + case MotionEvent.ACTION_CANCEL: + // finger is lifted before moving + if (mSlideStateStartPosition != RecyclerView.NO_POSITION) { + selectFinished(mSlideStateStartPosition); + mSlideStateStartPosition = RecyclerView.NO_POSITION; + } + // selection has triggered + if (mStart != RecyclerView.NO_POSITION) { + selectFinished(mEnd); + } + break; + default: + // do nothing + } + // Intercept only when the selection is triggered + Logger.d("intercept result: " + intercept); + return intercept; + } + + @Override + public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) { + if (!isActivated()) { + return; + } + Logger.d("onTouchEvent: x:" + e.getX() + ",y:" + e.getY() + + ", " + MotionEvent.actionToString(e.getAction())); + int action = e.getAction(); + int actionMask = action & MotionEvent.ACTION_MASK; + switch (actionMask) { + case MotionEvent.ACTION_MOVE: + if (mSlideStateStartPosition != RecyclerView.NO_POSITION) { + selectFirstItem(mSlideStateStartPosition); + // selection is triggered + mSlideStateStartPosition = RecyclerView.NO_POSITION; + Logger.i("onTouchEvent: after slide mode down"); + } + processAutoScroll(e); + if (!mIsInTopHotspot && !mIsInBottomHotspot) { + updateSelectedRange(rv, e); + } + break; + case MotionEvent.ACTION_CANCEL: + case MotionEvent.ACTION_UP: + selectFinished(mEnd); + break; + default: + // do nothing + } + } + + @Override + public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { + if (disallowIntercept) { + inactiveSelect(); + } + } + }; + + public DragSelectTouchHelper(@NonNull Callback callback) { + mCallback = callback; + mDisplayMetrics = Resources.getSystem().getDisplayMetrics(); + setHotspotRatio(DEFAULT_HOTSPOT_RATIO); + setHotspotOffset(DEFAULT_HOTSPOT_OFFSET); + setMaximumVelocity(DEFAULT_MAX_SCROLL_VELOCITY); + setEdgeType(DEFAULT_EDGE_TYPE); + setAutoEnterSlideState(false); + setAllowDragInSlideState(false); + setSlideArea(0, 0); + } + + /** + * Attaches the DragSelectTouchHelper to the provided RecyclerView. If TouchHelper is already + * attached to a RecyclerView, it will first detach from the previous one. You can call this + * method with {@code null} to detach it from the current RecyclerView. + * + * @param recyclerView The RecyclerView instance to which you want to add this helper or + * {@code null} if you want to remove DragSelectTouchHelper from the + * current RecyclerView. + */ + public void attachToRecyclerView(@Nullable RecyclerView recyclerView) { + if (mRecyclerView == recyclerView) { + return; // nothing to do + } + if (mRecyclerView != null) { + mRecyclerView.removeOnItemTouchListener(mOnItemTouchListener); + } + mRecyclerView = recyclerView; + if (mRecyclerView != null) { + mRecyclerView.addOnItemTouchListener(mOnItemTouchListener); + mRecyclerView.addOnLayoutChangeListener(mOnLayoutChangeListener); + } + } + + /** + * Activate the slide selection mode. + */ + public void activeSlideSelect() { + activeSelectInternal(RecyclerView.NO_POSITION); + } + + /** + * Activate the selection mode with selected item position. Normally called on long press. + * + * @param position Indicates the position of selected item. + */ + public void activeDragSelect(int position) { + activeSelectInternal(position); + } + + /** + * Exit the selection mode. + */ + public void inactiveSelect() { + if (isActivated()) { + selectFinished(mEnd); + } else { + selectFinished(RecyclerView.NO_POSITION); + } + Logger.logSelectStateChange(mSelectState, SELECT_STATE_NORMAL); + mSelectState = SELECT_STATE_NORMAL; + } + + /** + * To determine whether it is in the selection mode. + * + * @return true if is in the selection mode. + */ + public boolean isActivated() { + return (mSelectState != SELECT_STATE_NORMAL); + } + + /** + * Sets hotspot height by ratio of RecyclerView. + * + * @param ratio range (0, 0.5). + * @return The select helper, which may used to chain setter calls. + */ + public DragSelectTouchHelper setHotspotRatio(float ratio) { + mHotspotHeightRatio = ratio; + return this; + } + + /** + * Sets hotspot height. + * + * @param hotspotHeight hotspot height which unit is dp. + * @return The select helper, which may used to chain setter calls. + */ + public DragSelectTouchHelper setHotspotHeight(int hotspotHeight) { + mHotspotHeight = dp2px(hotspotHeight); + return this; + } + + /** + * Sets hotspot offset. It don't need to be set if no special requirement. + * + * @param hotspotOffset hotspot offset which unit is dp. + * @return The select helper, which may used to chain setter calls. + */ + public DragSelectTouchHelper setHotspotOffset(int hotspotOffset) { + mHotspotOffset = dp2px(hotspotOffset); + return this; + } + + /** + * Sets the activation edge type, one of: + *
    + *
  • {@link EdgeType#INSIDE} for edges that respond to touches inside + * the bounds of the host view. If touch moves outside the bounds, scrolling + * will stop. + *
  • {@link EdgeType#INSIDE_EXTEND} for inside edges that continued to + * scroll when touch moves outside the bounds of the host view. + *
+ * + * @param type The type of edge to use. + * @return The select helper, which may used to chain setter calls. + */ + public DragSelectTouchHelper setEdgeType(EdgeType type) { + switch (type) { + case INSIDE: + mScrollAboveTopRegion = false; + mScrollBelowBottomRegion = false; + break; + case INSIDE_EXTEND: + default: + mScrollAboveTopRegion = true; + mScrollBelowBottomRegion = true; + break; + } + return this; + } + + /** + * Sets sliding area's start and end, has been considered RTL situation + * + * @param startDp The start of the sliding area + * @param endDp The end of the sliding area + * @return The select helper, which may used to chain setter calls. + */ + public DragSelectTouchHelper setSlideArea(int startDp, int endDp) { + if (!isRtl()) { + mSlideAreaLeft = dp2px(startDp); + mSlideAreaRight = dp2px(endDp); + } else { + int displayWidth = mDisplayMetrics.widthPixels; + mSlideAreaLeft = displayWidth - dp2px(endDp); + mSlideAreaRight = displayWidth - dp2px(startDp); + } + return this; + } + + /** + * Sets the maximum velocity for scrolling + * + * @param velocity maximum velocity + * @return The select helper, which may used to chain setter calls. + */ + public DragSelectTouchHelper setMaximumVelocity(int velocity) { + mMaximumVelocity = (int) (velocity * mDisplayMetrics.density + 0.5f); + return this; + } + + /** + * Sets whether should auto enter slide mode after drag select finished. + * It's usefully for LinearLayout RecyclerView. + * + * @param autoEnterSlideState should auto enter slide mode + * @return The select helper, which may used to chain setter calls. + */ + public DragSelectTouchHelper setAutoEnterSlideState(boolean autoEnterSlideState) { + mShouldAutoChangeState = autoEnterSlideState; + return this; + } + + /** + * Sets whether can drag selection in slide select mode. + * It's usefully for LinearLayout RecyclerView. + * + * @param allowDragInSlideState allow drag selection in slide select mode + * @return The select helper, which may used to chain setter calls. + */ + public DragSelectTouchHelper setAllowDragInSlideState(boolean allowDragInSlideState) { + mIsAllowDragInSlideState = allowDragInSlideState; + return this; + } + + private void init(int rvHeight) { + if (mHotspotOffset >= rvHeight * MAX_HOTSPOT_RATIO) { + mHotspotOffset = rvHeight * MAX_HOTSPOT_RATIO; + } + // The height of hotspot area is not set, using (RV height x ratio) + if (mHotspotHeight <= 0) { + if (mHotspotHeightRatio <= 0 || mHotspotHeightRatio >= MAX_HOTSPOT_RATIO) { + mHotspotHeightRatio = DEFAULT_HOTSPOT_RATIO; + } + mHotspotHeight = rvHeight * mHotspotHeightRatio; + } else { + if (mHotspotHeight >= rvHeight * MAX_HOTSPOT_RATIO) { + mHotspotHeight = rvHeight * MAX_HOTSPOT_RATIO; + } + } + + mTopRegionFrom = mHotspotOffset; + mTopRegionTo = mTopRegionFrom + mHotspotHeight; + mBottomRegionTo = rvHeight - mHotspotOffset; + mBottomRegionFrom = mBottomRegionTo - mHotspotHeight; + + if (mTopRegionTo > mBottomRegionFrom) { + mTopRegionTo = mBottomRegionFrom = rvHeight >> 1; + } + + Logger.d("Hotspot: [" + mTopRegionFrom + ", " + mTopRegionTo + "], [" + + mBottomRegionFrom + ", " + mBottomRegionTo + "]"); + } + + private void activeSelectInternal(int position) { + // We should initialize the hotspot here, because its data may be delayed load + if (mRecyclerView != null) { + init(mRecyclerView.getHeight()); + } + if (position == RecyclerView.NO_POSITION) { + Logger.logSelectStateChange(mSelectState, SELECT_STATE_SLIDE); + mSelectState = SELECT_STATE_SLIDE; + } else { + if (!mHaveCalledSelectStart) { + mCallback.onSelectStart(position); + mHaveCalledSelectStart = true; + } + if (mSelectState == SELECT_STATE_SLIDE) { + if (mIsAllowDragInSlideState && selectFirstItem(position)) { + Logger.logSelectStateChange(mSelectState, SELECT_STATE_DRAG_FROM_SLIDE); + mSelectState = SELECT_STATE_DRAG_FROM_SLIDE; + } + } else if (mSelectState == SELECT_STATE_NORMAL) { + if (selectFirstItem(position)) { + Logger.logSelectStateChange(mSelectState, SELECT_STATE_DRAG_FROM_NORMAL); + mSelectState = SELECT_STATE_DRAG_FROM_NORMAL; + } + } else { + Logger.e("activeSelect in unexpected state: " + mSelectState); + } + } + } + + private boolean selectFirstItem(int position) { + boolean selectFirstItemSucceed = mCallback.onSelectChange(position, true); + // The drag select feature is only available if the first item is available for selection + if (selectFirstItemSucceed) { + mStart = position; + mEnd = position; + mLastRealStart = position; + mLastRealEnd = position; + } + return selectFirstItemSucceed; + } + + private void updateSelectedRange(RecyclerView rv, MotionEvent e) { + updateSelectedRange(rv, e.getX(), e.getY()); + } + + private void updateSelectedRange(RecyclerView rv, float x, float y) { + int position = getItemPosition(rv, x, y); + if (position != RecyclerView.NO_POSITION && mEnd != position) { + mEnd = position; + notifySelectRangeChange(); + } + } + + private void notifySelectRangeChange() { + if (mStart == RecyclerView.NO_POSITION || mEnd == RecyclerView.NO_POSITION) { + return; + } + + int newStart, newEnd; + newStart = Math.min(mStart, mEnd); + newEnd = Math.max(mStart, mEnd); + if (mLastRealStart == RecyclerView.NO_POSITION || mLastRealEnd == RecyclerView.NO_POSITION) { + if (newEnd - newStart == 1) { + notifySelectChange(newStart, newStart, true); + } else { + notifySelectChange(newStart, newEnd, true); + } + } else { + if (newStart > mLastRealStart) { + notifySelectChange(mLastRealStart, newStart - 1, false); + } else if (newStart < mLastRealStart) { + notifySelectChange(newStart, mLastRealStart - 1, true); + } + + if (newEnd > mLastRealEnd) { + notifySelectChange(mLastRealEnd + 1, newEnd, true); + } else if (newEnd < mLastRealEnd) { + notifySelectChange(newEnd + 1, mLastRealEnd, false); + } + } + + mLastRealStart = newStart; + mLastRealEnd = newEnd; + } + + private void notifySelectChange(int start, int end, boolean newState) { + for (int i = start; i <= end; i++) { + mCallback.onSelectChange(i, newState); + } + } + + private void selectFinished(int lastItem) { + if (lastItem != RecyclerView.NO_POSITION) { + mCallback.onSelectEnd(lastItem); + } + mStart = RecyclerView.NO_POSITION; + mEnd = RecyclerView.NO_POSITION; + mLastRealStart = RecyclerView.NO_POSITION; + mLastRealEnd = RecyclerView.NO_POSITION; + mHaveCalledSelectStart = false; + mIsInTopHotspot = false; + mIsInBottomHotspot = false; + stopAutoScroll(); + switch (mSelectState) { + case SELECT_STATE_DRAG_FROM_NORMAL: + if (mShouldAutoChangeState) { + Logger.logSelectStateChange(mSelectState, SELECT_STATE_SLIDE); + mSelectState = SELECT_STATE_SLIDE; + } else { + Logger.logSelectStateChange(mSelectState, SELECT_STATE_NORMAL); + mSelectState = SELECT_STATE_NORMAL; + } + break; + case SELECT_STATE_DRAG_FROM_SLIDE: + Logger.logSelectStateChange(mSelectState, SELECT_STATE_SLIDE); + mSelectState = SELECT_STATE_SLIDE; + break; + default: + // doesn't change the selection state + break; + } + } + + /** + * Process motion event, according to the location to determine whether to scroll + */ + private void processAutoScroll(MotionEvent e) { + float y = e.getY(); + if (y >= mTopRegionFrom && y <= mTopRegionTo && y < mDownY) { + mLastX = e.getX(); + mLastY = e.getY(); + float scrollDistanceFactor = (y - mTopRegionTo) / mHotspotHeight; + mScrollDistance = (int) (mMaximumVelocity * scrollDistanceFactor); + if (!mIsInTopHotspot) { + mIsInTopHotspot = true; + startAutoScroll(); + mDownY = mTopRegionTo; + } + } else if (mScrollAboveTopRegion && y < mTopRegionFrom && mIsInTopHotspot) { + mLastX = e.getX(); + mLastY = mTopRegionFrom; + // Use the maximum speed + mScrollDistance = mMaximumVelocity * -1; + startAutoScroll(); + } else if (y >= mBottomRegionFrom && y <= mBottomRegionTo && y > mDownY) { + mLastX = e.getX(); + mLastY = e.getY(); + float scrollDistanceFactor = (y - mBottomRegionFrom) / mHotspotHeight; + mScrollDistance = (int) (mMaximumVelocity * scrollDistanceFactor); + if (!mIsInBottomHotspot) { + mIsInBottomHotspot = true; + startAutoScroll(); + mDownY = mBottomRegionFrom; + } + } else if (mScrollBelowBottomRegion && y > mBottomRegionTo && mIsInBottomHotspot) { + mLastX = e.getX(); + mLastY = mBottomRegionTo; + // Use the maximum speed + mScrollDistance = mMaximumVelocity; + startAutoScroll(); + } else { + mIsInTopHotspot = false; + mIsInBottomHotspot = false; + mLastX = Float.MIN_VALUE; + mLastY = Float.MIN_VALUE; + stopAutoScroll(); + } + + } + + private void startAutoScroll() { + if (!mIsScrolling) { + mIsScrolling = true; + mRecyclerView.removeCallbacks(mScrollRunnable); + ViewCompat.postOnAnimation(mRecyclerView, mScrollRunnable); + } + } + + private void stopAutoScroll() { + if (mIsScrolling) { + mIsScrolling = false; + mRecyclerView.removeCallbacks(mScrollRunnable); + } + } + + private void scrollBy(int distance) { + int scrollDistance; + if (distance > 0) { + scrollDistance = Math.min(distance, mMaximumVelocity); + } else { + scrollDistance = Math.max(distance, -mMaximumVelocity); + } + mRecyclerView.scrollBy(0, scrollDistance); + if (mLastX != Float.MIN_VALUE && mLastY != Float.MIN_VALUE) { + updateSelectedRange(mRecyclerView, mLastX, mLastY); + } + } + + private int dp2px(float dpVal) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + dpVal, mDisplayMetrics); + } + + private boolean isRtl() { + return TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) + == View.LAYOUT_DIRECTION_RTL; + } + + private boolean isInSlideArea(MotionEvent e) { + float x = e.getX(); + return (x > mSlideAreaLeft && x < mSlideAreaRight); + } + + private int getItemPosition(RecyclerView rv, MotionEvent e) { + return getItemPosition(rv, e.getX(), e.getY()); + } + + private int getItemPosition(RecyclerView rv, float x, float y) { + final View v = rv.findChildViewUnder(x, y); + if (v == null) { + RecyclerView.LayoutManager layoutManager = rv.getLayoutManager(); + if (layoutManager instanceof GridLayoutManager) { + int lastVisibleItemPosition = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition(); + int lastItemPosition = layoutManager.getItemCount() - 1; + if (lastItemPosition == lastVisibleItemPosition) { + return lastItemPosition; + } + } + return RecyclerView.NO_POSITION; + } + return rv.getChildAdapterPosition(v); + } + + /** + * Edge type that specifies an activation area starting at the view bounds and extending inward. + */ + public enum EdgeType { + /** + * After activation begins, moving outside the view bounds will stop scrolling. + */ + INSIDE, + + /** + * After activation begins, moving outside the view bounds will continue scrolling. + */ + INSIDE_EXTEND + } + + /** + * This class is the contract between DragSelectTouchHelper and your application. It lets you + * update adapter when selection start/end and state changed. + */ + public abstract static class Callback { + /** + * Called when changing item state. + * + * @param position this item want to change the state to new state. + * @param isSelected true if the position should be selected, false otherwise. + * @return Whether to set the new state successfully. + */ + public abstract boolean onSelectChange(int position, boolean isSelected); + + /** + * Called when selection start. + * + * @param start the first selected item. + */ + public void onSelectStart(int start) { + + } + + /** + * Called when selection end. + * + * @param end the last selected item. + */ + public void onSelectEnd(int end) { + + } + } + + /** + * An advance Callback which provide 4 useful selection modes {@link Mode}. + *

+ * Note: Since the state of item may be repeatedly set, in order to improve efficiency, + * please process it in the Adapter + */ + public abstract static class AdvanceCallback extends Callback { + private Mode mMode; + private Set mOriginalSelection; + private boolean mFirstWasSelected; + + /** + * Creates a SimpleCallback with default {@link Mode#SelectAndReverse}# mode. + * + * @see Mode + */ + public AdvanceCallback() { + setMode(Mode.SelectAndReverse); + } + + /** + * Creates a SimpleCallback with select mode. + * + * @param mode the initial select mode + * @see Mode + */ + public AdvanceCallback(Mode mode) { + setMode(mode); + } + + /** + * Sets the select mode. + * + * @param mode The type of select mode. + * @see Mode + */ + public void setMode(Mode mode) { + mMode = mode; + } + + @Override + public void onSelectStart(int start) { + mOriginalSelection = new HashSet<>(); + Set selected = currentSelectedId(); + if (selected != null) { + mOriginalSelection.addAll(selected); + } + mFirstWasSelected = mOriginalSelection.contains(getItemId(start)); + } + + @Override + public void onSelectEnd(int end) { + mOriginalSelection = null; + } + + @Override + public boolean onSelectChange(int position, boolean isSelected) { + boolean stateChanged; + switch (mMode) { + case SelectAndKeep: { + stateChanged = updateSelectState(position, true); + break; + } + case SelectAndReverse: { + stateChanged = updateSelectState(position, isSelected); + break; + } + case SelectAndUndo: { + if (isSelected) { + stateChanged = updateSelectState(position, true); + } else { + stateChanged = updateSelectState(position, mOriginalSelection.contains(getItemId(position))); + } + break; + } + case ToggleAndKeep: { + stateChanged = updateSelectState(position, !mFirstWasSelected); + break; + } + case ToggleAndReverse: { + if (isSelected) { + stateChanged = updateSelectState(position, !mFirstWasSelected); + } else { + stateChanged = updateSelectState(position, mFirstWasSelected); + } + break; + } + case ToggleAndUndo: { + if (isSelected) { + stateChanged = updateSelectState(position, !mFirstWasSelected); + } else { + stateChanged = updateSelectState(position, mOriginalSelection.contains(getItemId(position))); + } + break; + } + default: + // SelectAndReverse Mode + stateChanged = updateSelectState(position, isSelected); + } + return stateChanged; + } + + /** + * Get the currently selected items when selecting first item. + * + * @return the currently selected item's id set. + */ + public abstract Set currentSelectedId(); + + /** + * Get the ID of the item. + * + * @param position item position to be judged. + * @return item's identity. + */ + public abstract T getItemId(int position); + + /** + * Update the selection status of the position. + * + * @param position the position who's selection state changed. + * @param isSelected true if the position should be selected, false otherwise. + * @return Whether to set the state successfully. + */ + public abstract boolean updateSelectState(int position, boolean isSelected); + + /** + * Different existing selection modes + */ + public enum Mode { + /** + * Selects the first item and applies the same state to each item you go by + * and keep the state on move back + */ + SelectAndKeep, + /** + * Selects the first item and applies the same state to each item you go by + * and applies inverted state on move back + */ + SelectAndReverse, + /** + * Selects the first item and applies the same state to each item you go by + * and reverts to the original state on move back + */ + SelectAndUndo, + /** + * Toggles the first item and applies the same state to each item you go by + * and keep the state on move back + */ + ToggleAndKeep, + /** + * Toggles the first item and applies the same state to each item you go by + * and applies inverted state on move back + */ + ToggleAndReverse, + /** + * Toggles the first item and applies the same state to each item you go by + * and reverts to the original state on move back + */ + ToggleAndUndo, + } + } + + private static class Logger { + private static boolean DEBUG = BuildConfig.DEBUG; + + private static void d(String msg) { + if (DEBUG) { + Log.d(TAG, msg); + } + } + + private static void e(String msg) { + Log.e(TAG, msg); + } + + private static void i(String msg) { + Log.i(TAG, msg); + } + + private static void logSelectStateChange(int before, int after) { + i("Select state changed: " + stateName(before) + " --> " + stateName(after)); + } + + private static String stateName(int state) { + switch (state) { + case SELECT_STATE_NORMAL: + return "NormalState"; + case SELECT_STATE_SLIDE: + return "SlideState"; + case SELECT_STATE_DRAG_FROM_NORMAL: + return "DragFromNormal"; + case SELECT_STATE_DRAG_FROM_SLIDE: + return "DragFromSlide"; + default: + return "Unknown"; + } + } + } +} \ No newline at end of file From 6f22da2c41b3a3325886dd036d9925409a495dbf Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 15:21:24 +0800 Subject: [PATCH 81/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=8E=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E9=A1=B5=E7=9B=AE=E5=BD=95=E6=89=93=E5=BC=80=E7=AB=A0?= =?UTF-8?q?=E8=8A=82=E5=86=85=E5=AE=B9=E4=B8=8D=E5=AF=B9=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/ui/book/read/ReadBookViewModel.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) 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 5ba4625bd..a23b56bb1 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 @@ -64,10 +64,17 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { ReadBook.loadContent(resetPageOffset = true) } } else { - isInitFinish = true + if (ReadBook.durChapterIndex != book.durChapterIndex) { + ReadBook.durChapterIndex = book.durChapterIndex + ReadBook.durPageIndex = book.durChapterPos + ReadBook.prevTextChapter = null + ReadBook.curTextChapter = null + ReadBook.nextTextChapter = null + } ReadBook.book!!.group = book.group ReadBook.titleDate.postValue(book.name) ReadBook.upWebBook(book) + isInitFinish = true if (!book.isLocalBook() && ReadBook.webBook == null) { autoChangeSource(book.name, book.author) return @@ -82,6 +89,8 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { } else { if (ReadBook.curTextChapter != null) { ReadBook.callBack?.upContent(resetPageOffset = false) + } else { + ReadBook.loadContent(resetPageOffset = true) } } } From 0e48bca78f3abc533c448705036d4c82a29be42f Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 15:35:26 +0800 Subject: [PATCH 82/90] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9C=A8=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=A4=B4=E9=87=8C=E8=AE=BE=E7=BD=AE=E4=BB=A3=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/help/http/HttpHelper.kt | 29 +++++++------------ 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt index 79abae41f..6364e9ed8 100644 --- a/app/src/main/java/io/legado/app/help/http/HttpHelper.kt +++ b/app/src/main/java/io/legado/app/help/http/HttpHelper.kt @@ -4,11 +4,7 @@ import io.legado.app.constant.AppConst import io.legado.app.help.http.api.HttpGetApi import io.legado.app.utils.NetworkUtils import kotlinx.coroutines.suspendCancellableCoroutine -import okhttp3.ConnectionSpec -import okhttp3.Interceptor -import okhttp3.OkHttpClient -import okhttp3.Protocol -import okhttp3.Credentials +import okhttp3.* import retrofit2.Retrofit import java.net.InetSocketAddress import java.net.Proxy @@ -111,19 +107,14 @@ object HttpHelper { encode: String? = null, proxy: String? = null ): Retrofit { - val r = - Regex( - """ - (http|socks4|socks5)://(.*):(\d{2,5})(@.*@.*)? - """.trimIndent() - ) + val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") val ms = proxy?.let { r.findAll(it) }; val group = ms?.first() - var type: String = "direct" //直接连接 - var host: String = "127.0.0.1" //代理服务器hostname - var port: Int = 1080 //代理服务器port - var username: String = "" //代理服务器验证用户名 - var password: String = "" //代理服务器验证密码 + var type = "direct" //直接连接 + var host = "127.0.0.1" //代理服务器hostname + var port = 1080 //代理服务器port + var username = "" //代理服务器验证用户名 + var password = "" //代理服务器验证密码 if (group != null) { type = if (group.groupValues[1] == "http") { "http" @@ -133,11 +124,11 @@ object HttpHelper { host = group.groupValues[2] port = group.groupValues[3].toInt() if (group.groupValues[4] != "") { - username = group.groupValues[4].split("@")[1]; - password = group.groupValues[4].split("@")[2]; + username = group.groupValues[4].split("@")[1] + password = group.groupValues[4].split("@")[2] } } - val builder = client.newBuilder(); + val builder = client.newBuilder() if (type != "direct" && host != "") { if (type == "http") { builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))); From e88fbc12bd0268e1d7779b014f273cae67478ad4 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 15:43:34 +0800 Subject: [PATCH 83/90] update log --- app/src/main/assets/updateLog.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 4b5b8223c..f65a1992b 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -3,6 +3,26 @@ * 关注合作公众号 **[小说拾遗]()** 获取好看的小说。 - 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 +**2020/08/29** +* 修复从详情页目录打开章节内容不对的bug +* 书源选择增加滑动选择, 选择框区域滑动时进行选择 +* 请求头,支持http代理,socks4 socks5代理设置 +``` +socks5代理 +{ + "proxy":"socks5://127.0.0.1:1080" +} +http代理 +{ + "proxy":"http://127.0.0.1:1080" +} +支持代理服务器验证 +{ + "proxy":"socks5://127.0.0.1:1080@用户名@密码" +} +注意:这些请求头是无意义的,会被忽略掉 +``` + **2020/08/28** * 修复一些bug * 换源不再改变书名和作者,防止换到一些错误的书源后不能再换源 From cd1766507733fb1a42dc34e5c4497922c9025771 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 15:45:16 +0800 Subject: [PATCH 84/90] update log --- app/src/main/assets/updateLog.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index f65a1992b..914003ee5 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -5,8 +5,8 @@ **2020/08/29** * 修复从详情页目录打开章节内容不对的bug -* 书源选择增加滑动选择, 选择框区域滑动时进行选择 -* 请求头,支持http代理,socks4 socks5代理设置 +* 书源选择增加滑动选择, 选择框区域滑动时进行选择 by [Mupceet](https://github.com/Mupceet) +* 请求头,支持http代理,socks4 socks5代理设置 by [10bits](https://github.com/10bits) ``` socks5代理 { From 8f7369d6909bf3c0d38e5b921b5f64293a643461 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 16:00:40 +0800 Subject: [PATCH 85/90] =?UTF-8?q?=E5=A4=9A=E7=AB=A0=E8=8A=82=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E5=9B=BE=E7=89=87=E5=90=8C=E6=AD=A5=E8=BF=9B=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/help/BookHelp.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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 85d5aaa87..94e7fdde1 100644 --- a/app/src/main/java/io/legado/app/help/BookHelp.kt +++ b/app/src/main/java/io/legado/app/help/BookHelp.kt @@ -56,7 +56,6 @@ object BookHelp { } } - @Synchronized fun saveContent(book: Book, bookChapter: BookChapter, content: String) { if (content.isEmpty()) return //保存文本 @@ -80,7 +79,7 @@ object BookHelp { } fun saveImage(book: Book, src:String) { - val analyzeUrl = AnalyzeUrl(src, null, null, null, null) + val analyzeUrl = AnalyzeUrl(src) analyzeUrl.getImageBytes(book.origin)?.let { FileUtils.createFileIfNotExist( downloadDir, From fb97833526c8c3af6bd38fed2c41735157920f47 Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 17:23:45 +0800 Subject: [PATCH 86/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dnull=E5=B4=A9=E6=BA=83b?= =?UTF-8?q?ug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/io/legado/app/constant/AppPattern.kt | 2 +- .../app/model/analyzeRule/AnalyzeUrl.kt | 22 ++++++++++--------- .../io/legado/app/service/help/ReadBook.kt | 3 ++- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/io/legado/app/constant/AppPattern.kt b/app/src/main/java/io/legado/app/constant/AppPattern.kt index d31e69f23..2faf70daf 100644 --- a/app/src/main/java/io/legado/app/constant/AppPattern.kt +++ b/app/src/main/java/io/legado/app/constant/AppPattern.kt @@ -6,7 +6,7 @@ object AppPattern { val JS_PATTERN: Pattern = Pattern.compile("([\\w\\W]*?|@js:[\\w\\W]*$)", Pattern.CASE_INSENSITIVE) val EXP_PATTERN: Pattern = Pattern.compile("\\{\\{([\\w\\W]*?)\\}\\}") - val imgPattern = + val imgPattern: Pattern = Pattern.compile("", Pattern.CASE_INSENSITIVE) val nameRegex = Regex("\\s+作\\s*者.*") diff --git a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt index 97a9149a0..3fa15df00 100644 --- a/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt +++ b/app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeUrl.kt @@ -40,7 +40,7 @@ class AnalyzeUrl( headerMapF: Map? = null, baseUrl: String? = null, book: BaseBook? = null, - var useWebView: Boolean = false + var useWebView: Boolean = false, ) : JsExtensions { companion object { private val pagePattern = Pattern.compile("<(.*?)>") @@ -68,7 +68,7 @@ class AnalyzeUrl( headerMapF?.let { headerMap.putAll(it) if (it.containsKey("proxy")) { - proxy = it["proxy"]; + proxy = it["proxy"] headerMap.remove("proxy") } } @@ -84,7 +84,7 @@ class AnalyzeUrl( page: Int?, speakText: String?, speakSpeed: Int?, - book: BaseBook? + book: BaseBook?, ) { val ruleList = arrayListOf() var start = 0 @@ -133,7 +133,7 @@ class AnalyzeUrl( page: Int?, speakText: String?, speakSpeed: Int?, - book: BaseBook? + book: BaseBook?, ) { //page page?.let { @@ -161,7 +161,9 @@ class AnalyzeUrl( simpleBindings["book"] = book val expMatcher = EXP_PATTERN.matcher(ruleUrl) while (expMatcher.find()) { - jsEval = SCRIPT_ENGINE.eval(expMatcher.group(1), simpleBindings) + jsEval = expMatcher.group(1)?.let { + SCRIPT_ENGINE.eval(it, simpleBindings) + } ?: "" if (jsEval is String) { expMatcher.appendReplacement(sb, jsEval) } else if (jsEval is Double && jsEval % 1.0 == 0.0) { @@ -272,7 +274,7 @@ class AnalyzeUrl( key: String?, speakText: String?, speakSpeed: Int?, - book: BaseBook? + book: BaseBook?, ): Any { val bindings = SimpleBindings() bindings["java"] = this @@ -317,7 +319,7 @@ class AnalyzeUrl( suspend fun getResponseAwait( tag: String, jsStr: String? = null, - sourceRegex: String? = null + sourceRegex: String? = null, ): Res { if (useWebView) { val params = AjaxWebView.AjaxParams(url) @@ -432,9 +434,9 @@ class AnalyzeUrl( @Throws(Exception::class) fun getGlideUrl(): Any? { var glideUrl: Any = urlHasQuery - if(headerMap.isNotEmpty()) { + if (headerMap.isNotEmpty()) { val headers = LazyHeaders.Builder() - headerMap.forEach {(key, value) -> + headerMap.forEach { (key, value) -> headers.addHeader(key, value) } glideUrl = GlideUrl(urlHasQuery, headers.build()) @@ -447,7 +449,7 @@ class AnalyzeUrl( val charset: String?, val webView: Any?, val headers: Any?, - val body: Any? + val body: Any?, ) } diff --git a/app/src/main/java/io/legado/app/service/help/ReadBook.kt b/app/src/main/java/io/legado/app/service/help/ReadBook.kt index 0d7c4c982..25858c022 100644 --- a/app/src/main/java/io/legado/app/service/help/ReadBook.kt +++ b/app/src/main/java/io/legado/app/service/help/ReadBook.kt @@ -22,6 +22,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import org.jetbrains.anko.getStackTraceString import org.jetbrains.anko.toast @@ -370,7 +371,7 @@ object ReadBook { } }.onError { it.printStackTrace() - App.INSTANCE.toast(it.localizedMessage ?: "ChapterProvider ERROR") + App.INSTANCE.toast("ChapterProvider ERROR:\n${it.getStackTraceString()}") } } From 5da31b25a2bbbff5bed2d4e26080c58525d9ac8b Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 18:01:39 +0800 Subject: [PATCH 87/90] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=BB=9A=E5=8A=A8?= =?UTF-8?q?=E6=97=B6=E6=88=91=E7=9A=84=E7=95=8C=E9=9D=A2=E5=9B=BE=E6=A0=87?= =?UTF-8?q?=E6=B6=88=E5=A4=B1=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/widget/prefs/Preference.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/widget/prefs/Preference.kt b/app/src/main/java/io/legado/app/ui/widget/prefs/Preference.kt index 7ce8c9dfb..042b03868 100644 --- a/app/src/main/java/io/legado/app/ui/widget/prefs/Preference.kt +++ b/app/src/main/java/io/legado/app/ui/widget/prefs/Preference.kt @@ -66,7 +66,7 @@ class Preference(context: Context, attrs: AttributeSet) : } val iconView = it.findViewById(R.id.preference_icon) if (iconView is ImageView) { - iconView.isVisible = icon != null && icon.isVisible + iconView.isVisible = icon != null iconView.setImageDrawable(icon) iconView.setColorFilter(context.accentColor) } From 1847fcb5ad7e75b86d54d13a37ea5609e534234b Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 18:04:04 +0800 Subject: [PATCH 88/90] update log --- app/src/main/assets/updateLog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/assets/updateLog.md b/app/src/main/assets/updateLog.md index 914003ee5..355fe1364 100644 --- a/app/src/main/assets/updateLog.md +++ b/app/src/main/assets/updateLog.md @@ -4,6 +4,8 @@ - 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 **2020/08/29** +* 修复一个null引起的崩溃bug +* 修复我的界面滚动时图标消失的bug * 修复从详情页目录打开章节内容不对的bug * 书源选择增加滑动选择, 选择框区域滑动时进行选择 by [Mupceet](https://github.com/Mupceet) * 请求头,支持http代理,socks4 socks5代理设置 by [10bits](https://github.com/10bits) From d1626ee5d65433459ac5c8c74224584e8e1e42ec Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 19:27:57 +0800 Subject: [PATCH 89/90] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8E=92=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/legado/app/data/dao/ReadRecordDao.kt | 2 +- .../app/ui/widget/font/FontSelectDialog.kt | 70 ++++++++++--------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt b/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt index 991eaf61c..311194cf0 100644 --- a/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/ReadRecordDao.kt @@ -10,7 +10,7 @@ interface ReadRecordDao { @get:Query("select * from readRecord") val all: List - @get:Query("select bookName, sum(readTime) as readTime from readRecord group by bookName") + @get:Query("select bookName, sum(readTime) as readTime from readRecord group by bookName order by bookName") val allShow: List @get:Query("select sum(readTime) from readRecord") diff --git a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt index b10371864..697c3f68c 100644 --- a/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt +++ b/app/src/main/java/io/legado/app/ui/widget/font/FontSelectDialog.kt @@ -1,6 +1,5 @@ package io.legado.app.ui.widget.font -import android.annotation.SuppressLint import android.app.Activity.RESULT_OK import android.content.Intent import android.net.Uri @@ -38,6 +37,7 @@ class FontSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener, FontAdapter.CallBack { private val fontFolderRequestCode = 35485 + private val fontRegex = Regex(".*\\.[ot]tf") private val fontFolder by lazy { FileUtils.createFolderIfNotExist(App.INSTANCE.filesDir, "Fonts") } @@ -75,12 +75,12 @@ class FontSelectDialog : BaseDialogFragment(), if (fontPath.isContentPath()) { val doc = DocumentFile.fromTreeUri(requireContext(), Uri.parse(fontPath)) if (doc?.canRead() == true) { - getFontFiles(doc) + loadFontFiles(doc) } else { openFolder() } } else { - getFontFilesByPermission(fontPath) + loadFontFilesByPermission(fontPath) } } } @@ -111,22 +111,21 @@ class FontSelectDialog : BaseDialogFragment(), FilePicker.selectFolder(this@FontSelectDialog, fontFolderRequestCode) { val path = "${FileUtils.getSdCardPath()}${File.separator}Fonts" putPrefString(PreferKey.fontFolder, path) - getFontFilesByPermission(path) + loadFontFilesByPermission(path) } } } - @SuppressLint("DefaultLocale") - private fun getFontFiles(doc: DocumentFile) { + private fun loadFontFiles(doc: DocumentFile) { execute { val fontItems = arrayListOf() val docItems = DocumentUtils.listFiles(App.INSTANCE, doc.uri) docItems.forEach { item -> - if (item.name.toLowerCase().matches(".*\\.[ot]tf".toRegex())) { + if (item.name.toLowerCase(Locale.getDefault()).matches(fontRegex)) { fontItems.add(item) } } - fontItems + fontItems.sortedBy { it.name } }.onSuccess { adapter?.setItems(it) }.onError { @@ -134,36 +133,41 @@ class FontSelectDialog : BaseDialogFragment(), } } - @SuppressLint("DefaultLocale") - private fun getFontFilesByPermission(path: String) { + private fun loadFontFilesByPermission(path: String) { PermissionsCompat.Builder(this@FontSelectDialog) .addPermissions(*Permissions.Group.STORAGE) .rationale(R.string.tip_perm_request_storage) .onGranted { - try { - val fontItems = arrayListOf() - val file = File(path) - file.listFiles { pathName -> - pathName.name.toLowerCase().matches(".*\\.[ot]tf".toRegex()) - }?.forEach { - fontItems.add( - DocItem( - it.name, - it.extension, - it.length(), - Date(it.lastModified()), - Uri.parse(it.absolutePath) - ) - ) - } - adapter?.setItems(fontItems) - } catch (e: Exception) { - toast(e.localizedMessage ?: "") - } + loadFontFiles(path) } .request() } + private fun loadFontFiles(path: String) { + execute { + val fontItems = arrayListOf() + val file = File(path) + file.listFiles { pathName -> + pathName.name.toLowerCase(Locale.getDefault()).matches(fontRegex) + }?.forEach { + fontItems.add( + DocItem( + it.name, + it.extension, + it.length(), + Date(it.lastModified()), + Uri.parse(it.absolutePath) + ) + ) + } + fontItems.sortedBy { it.name } + }.onSuccess { + adapter?.setItems(it) + }.onError { + toast("getFontFiles:${it.localizedMessage}") + } + } + override fun onClick(docItem: DocItem) { execute { fontFolder.listFiles()?.forEach { @@ -198,7 +202,7 @@ class FontSelectDialog : BaseDialogFragment(), when (requestCode) { fontFolderRequestCode -> { putPrefString(PreferKey.fontFolder, currentPath) - getFontFilesByPermission(currentPath) + loadFontFilesByPermission(currentPath) } } } @@ -215,10 +219,10 @@ class FontSelectDialog : BaseDialogFragment(), uri, Intent.FLAG_GRANT_READ_URI_PERMISSION ) - getFontFiles(doc) + loadFontFiles(doc) } else { RealPathUtil.getPath(requireContext(), uri)?.let { - getFontFilesByPermission(it) + loadFontFilesByPermission(it) } } } From e6bc38b3bb1f9bb684410e25eeee0536a994308c Mon Sep 17 00:00:00 2001 From: gedoor Date: Sun, 30 Aug 2020 19:36:32 +0800 Subject: [PATCH 90/90] =?UTF-8?q?=E5=AD=97=E7=AC=A6=E4=B8=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt | 2 +- app/src/main/res/values-zh-rHK/strings.xml | 1 + app/src/main/res/values-zh-rTW/strings.xml | 1 + app/src/main/res/values-zh/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt index 01a71f4ad..5a1b3b75d 100644 --- a/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt +++ b/app/src/main/java/io/legado/app/ui/about/ReadRecordActivity.kt @@ -33,7 +33,7 @@ class ReadRecordActivity : BaseActivity(R.layout.activity_read_record) { } private fun initView() { - tv_book_name.text = "总阅读时间" + tv_book_name.setText(R.string.all_read_time) recycler_view.layoutManager = LinearLayoutManager(this) adapter = RecordAdapter(this) recycler_view.adapter = adapter diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml index 083f92787..b13efd3e8 100644 --- a/app/src/main/res/values-zh-rHK/strings.xml +++ b/app/src/main/res/values-zh-rHK/strings.xml @@ -751,4 +751,5 @@ 阅读时间记录 本地TTS 线程数 + 总阅读时间 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 01c999ac7..62c626a3f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -751,5 +751,6 @@ 阅读时间记录 本地TTS 线程数 + 总阅读时间 diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index b41d0c84c..c6877a404 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -751,4 +751,5 @@ 阅读时间记录 本地TTS 线程数 + 总阅读时间 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 610f079a5..88f3b7760 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -752,5 +752,6 @@ 阅读时间记录 本地TTS 线程数 + 总阅读时间 \ No newline at end of file