From aaf262fb9dda88cbb31fb5674456793fa5f4b86e Mon Sep 17 00:00:00 2001 From: gedoor Date: Mon, 24 Aug 2020 14:50:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8=E7=BA=BF=E6=9C=97=E8=AF=BB=E6=94=B9?= =?UTF-8?q?=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" /> - - -