Merge pull request #8 from gedoor/master

merge
pull/441/head
口口吕 4 years ago committed by GitHub
commit eae5ae2244
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      app/proguard-rules.pro
  2. 0
      app/src/main/assets/defaultData/httpTTS.json
  3. 0
      app/src/main/assets/defaultData/readConfig.json
  4. 0
      app/src/main/assets/defaultData/themeConfig.json
  5. 0
      app/src/main/assets/defaultData/txtTocRule.json
  6. 0
      app/src/main/assets/font/number.ttf
  7. 0
      app/src/main/assets/help/help.md
  8. 15
      app/src/main/assets/help/httpTts.md
  9. 4
      app/src/main/assets/updateLog.md
  10. 1
      app/src/main/java/io/legado/app/base/BaseFragment.kt
  11. 4
      app/src/main/java/io/legado/app/base/BaseService.kt
  12. 1
      app/src/main/java/io/legado/app/base/BaseViewModel.kt
  13. 1
      app/src/main/java/io/legado/app/base/adapter/CommonRecyclerAdapter.kt
  14. 1
      app/src/main/java/io/legado/app/base/adapter/InfiniteScrollListener.kt
  15. 1
      app/src/main/java/io/legado/app/base/adapter/ItemAnimation.kt
  16. 2
      app/src/main/java/io/legado/app/data/AppDatabase.kt
  17. 2
      app/src/main/java/io/legado/app/data/entities/rule/ContentRule.kt
  18. 1
      app/src/main/java/io/legado/app/help/ActivityHelp.kt
  19. 2
      app/src/main/java/io/legado/app/help/BlurTransformation.kt
  20. 27
      app/src/main/java/io/legado/app/help/BookHelp.kt
  21. 47
      app/src/main/java/io/legado/app/help/DefaultData.kt
  22. 19
      app/src/main/java/io/legado/app/help/DefaultValueHelp.kt
  23. 3
      app/src/main/java/io/legado/app/help/EventMessage.kt
  24. 1
      app/src/main/java/io/legado/app/help/IntentHelp.kt
  25. 1
      app/src/main/java/io/legado/app/help/LayoutManager.kt
  26. 8
      app/src/main/java/io/legado/app/help/ReadBookConfig.kt
  27. 7
      app/src/main/java/io/legado/app/help/ThemeConfig.kt
  28. 1
      app/src/main/java/io/legado/app/help/coroutine/CompositeCoroutine.kt
  29. 1
      app/src/main/java/io/legado/app/help/coroutine/Coroutine.kt
  30. 2
      app/src/main/java/io/legado/app/help/http/CookieStore.kt
  31. 6
      app/src/main/java/io/legado/app/help/http/HttpHelper.kt
  32. 1
      app/src/main/java/io/legado/app/help/http/SSLHelper.kt
  33. 1
      app/src/main/java/io/legado/app/help/permission/Permissions.kt
  34. 9
      app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt
  35. 9
      app/src/main/java/io/legado/app/help/storage/Backup.kt
  36. 2
      app/src/main/java/io/legado/app/help/storage/ImportOldData.kt
  37. 1
      app/src/main/java/io/legado/app/help/storage/OldRule.kt
  38. 23
      app/src/main/java/io/legado/app/help/storage/Restore.kt
  39. 1
      app/src/main/java/io/legado/app/lib/theme/ATH.kt
  40. 1
      app/src/main/java/io/legado/app/lib/theme/DrawableUtils.kt
  41. 2
      app/src/main/java/io/legado/app/lib/theme/MaterialValueHelper.kt
  42. 1
      app/src/main/java/io/legado/app/lib/theme/NavigationViewUtils.kt
  43. 6
      app/src/main/java/io/legado/app/lib/theme/Selector.kt
  44. 1
      app/src/main/java/io/legado/app/lib/theme/ThemeStore.kt
  45. 92
      app/src/main/java/io/legado/app/lib/theme/TintHelper.kt
  46. 1
      app/src/main/java/io/legado/app/lib/theme/ViewUtils.kt
  47. 5
      app/src/main/java/io/legado/app/lib/webdav/WebDav.kt
  48. 1
      app/src/main/java/io/legado/app/model/analyzeRule/AnalyzeByJSonPath.kt
  49. 20
      app/src/main/java/io/legado/app/model/localBook/AnalyzeTxtFile.kt
  50. 1
      app/src/main/java/io/legado/app/model/rss/RssParserDefault.kt
  51. 16
      app/src/main/java/io/legado/app/receiver/TimeBatteryReceiver.kt
  52. 25
      app/src/main/java/io/legado/app/service/help/CacheBook.kt
  53. 8
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineDialog.kt
  54. 12
      app/src/main/java/io/legado/app/ui/book/read/config/SpeakEngineViewModel.kt
  55. 6
      app/src/main/java/io/legado/app/ui/book/read/config/TocRegexViewModel.kt
  56. 1
      app/src/main/java/io/legado/app/ui/book/read/page/entities/TextLine.kt
  57. 4
      app/src/main/java/io/legado/app/ui/book/search/SearchViewModel.kt
  58. 2
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListActivity.kt
  59. 8
      app/src/main/java/io/legado/app/ui/filechooser/adapter/FileAdapter.kt
  60. 2
      app/src/main/java/io/legado/app/ui/filechooser/adapter/PathAdapter.kt
  61. 10
      app/src/main/java/io/legado/app/ui/filechooser/utils/FilePickerIcon.java
  62. 6
      app/src/main/java/io/legado/app/ui/main/MainViewModel.kt
  63. 2
      app/src/main/java/io/legado/app/ui/main/my/MyFragment.kt
  64. 2
      app/src/main/java/io/legado/app/ui/welcome/WelcomeActivity.kt
  65. 3
      app/src/main/java/io/legado/app/ui/widget/BatteryView.kt
  66. 2
      app/src/main/java/io/legado/app/utils/StringExtensions.kt

@ -54,6 +54,8 @@
# Android开发中一些需要保留的公共部分 # Android开发中一些需要保留的公共部分
# #
############################################# #############################################
# 屏蔽错误Unresolved class name
#noinspection ShrinkerUnresolvedReference
# 保留我们使用的四大组件,自定义的Application等等这些类不被混淆 # 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
# 因为这些子类都有可能被外部调用 # 因为这些子类都有可能被外部调用
@ -66,7 +68,6 @@
-keep public class * extends android.preference.Preference -keep public class * extends android.preference.Preference
-keep public class * extends android.view.View -keep public class * extends android.view.View
# 保留androidx下的所有类及其内部类 # 保留androidx下的所有类及其内部类
-keep class androidx.** {*;} -keep class androidx.** {*;}

@ -0,0 +1,15 @@
# 在线朗读规则说明
* 在线朗读规则为url规则,同书源url
* js参数
~~~
speakText //朗读文本
speakSpeed //朗读速度,0-45
~~~
* 例:
~~~
http://tts.baidu.com/text2audio,{
"method": "POST",
"body": "tex={{java.encodeURI(java.encodeURI(speakText))}}&spd={{String((speakSpeed + 5) / 10 + 4)}}&per=5003&cuid=baidu_speech_demo&idx=1&cod=2&lan=zh&ctp=1&pdt=1&vol=5&pit=5&_res_tag_=audio"
}
~~~

@ -3,6 +3,10 @@
* 关注合作公众号 **[小说拾遗]()** 获取好看的小说。 * 关注合作公众号 **[小说拾遗]()** 获取好看的小说。
* 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。 * 旧版数据导入教程:先在旧版阅读(2.x)中进行备份,然后在新版阅读(3.x)【我的】->【备份与恢复】,选择【导入旧版本数据】。
**2020/10/19**
* 优化分组管理
* 修复预下载没有保存的bug
**2020/10/18** **2020/10/18**
* 优化分组管理,默认分组可以重命名了 * 优化分组管理,默认分组可以重命名了
* 修复书架空白的bug,是constraintlayout库新版本的bug * 修复书架空白的bug,是constraintlayout库新版本的bug

@ -15,6 +15,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@Suppress("MemberVisibilityCanBePrivate")
abstract class BaseFragment(layoutID: Int) : Fragment(layoutID), abstract class BaseFragment(layoutID: Int) : Fragment(layoutID),
CoroutineScope { CoroutineScope {
lateinit var job: Job lateinit var job: Job

@ -18,7 +18,9 @@ abstract class BaseService : Service(), CoroutineScope by MainScope() {
block: suspend CoroutineScope.() -> T block: suspend CoroutineScope.() -> T
) = Coroutine.async(scope, context) { block() } ) = Coroutine.async(scope, context) { block() }
override fun onBind(intent: Intent?) = null override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()

@ -11,6 +11,7 @@ import org.jetbrains.anko.AnkoLogger
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@Suppress("unused")
open class BaseViewModel(application: Application) : AndroidViewModel(application), open class BaseViewModel(application: Application) : AndroidViewModel(application),
CoroutineScope by MainScope(), CoroutineScope by MainScope(),
AnkoLogger { AnkoLogger {

@ -15,6 +15,7 @@ import java.util.*
* *
* 通用的adapter 可添加headerfooter以及不同类型item * 通用的adapter 可添加headerfooter以及不同类型item
*/ */
@Suppress("unused", "MemberVisibilityCanBePrivate")
abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) : abstract class CommonRecyclerAdapter<ITEM>(protected val context: Context) :
RecyclerView.Adapter<ItemViewHolder>() { RecyclerView.Adapter<ItemViewHolder>() {

@ -8,6 +8,7 @@ import androidx.recyclerview.widget.RecyclerView
* *
* 上拉加载更多 * 上拉加载更多
*/ */
@Suppress("unused")
abstract class InfiniteScrollListener() : RecyclerView.OnScrollListener() { abstract class InfiniteScrollListener() : RecyclerView.OnScrollListener() {
private val loadMoreRunnable = Runnable { onLoadMore() } private val loadMoreRunnable = Runnable { onLoadMore() }

@ -7,6 +7,7 @@ import io.legado.app.base.adapter.animations.*
/** /**
* Created by Invincible on 2017/12/15. * Created by Invincible on 2017/12/15.
*/ */
@Suppress("unused")
class ItemAnimation private constructor() { class ItemAnimation private constructor() {
var itemAnimEnabled = false var itemAnimEnabled = false

@ -49,12 +49,10 @@ abstract class AppDatabase: RoomDatabase() {
private val dbCallback = object : Callback() { private val dbCallback = object : Callback() {
override fun onCreate(db: SupportSQLiteDatabase) { override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
db.setLocale(Locale.CHINESE) db.setLocale(Locale.CHINESE)
} }
override fun onOpen(db: SupportSQLiteDatabase) { override fun onOpen(db: SupportSQLiteDatabase) {
db.setLocale(Locale.CHINESE)
db.execSQL( db.execSQL(
""" """
insert into book_groups(groupId, groupName, 'order', show) select ${AppConst.bookGroupAllId}, '全部', -10, 1 insert into book_groups(groupId, groupName, 'order', show) select ${AppConst.bookGroupAllId}, '全部', -10, 1

@ -10,5 +10,5 @@ data class ContentRule(
var webJs: String? = null, var webJs: String? = null,
var sourceRegex: String? = null, var sourceRegex: String? = null,
var replaceRegex: String? = null, var replaceRegex: String? = null,
var imageStyle: String? = null //默认大小居中,1最大宽度 var imageStyle: String? = null //默认大小居中,FULL最大宽度
) : Parcelable ) : Parcelable

@ -10,6 +10,7 @@ import java.util.*
/** /**
* Activity管理器,管理项目中Activity的状态 * Activity管理器,管理项目中Activity的状态
*/ */
@Suppress("unused")
object ActivityHelp : Application.ActivityLifecycleCallbacks { object ActivityHelp : Application.ActivityLifecycleCallbacks {
private val activities: MutableList<WeakReference<Activity>> = arrayListOf() private val activities: MutableList<WeakReference<Activity>> = arrayListOf()

@ -28,7 +28,7 @@ class BlurTransformation(context: Context, private val radius: Int) : CenterCrop
//图片缩小1/2 //图片缩小1/2
val width = (min(outWidth, transform.width) / 2f).roundToInt() val width = (min(outWidth, transform.width) / 2f).roundToInt()
val height = (min(outHeight, transform.height) / 2f).roundToInt() val height = (min(outHeight, transform.height) / 2f).roundToInt()
val blurredBitmap = Bitmap.createScaledBitmap(transform, width, height, false); val blurredBitmap = Bitmap.createScaledBitmap(transform, width, height, false)
// Allocate memory for Renderscript to work with // Allocate memory for Renderscript to work with
//分配用于渲染脚本的内存 //分配用于渲染脚本的内存
val input = Allocation.createFromBitmap( val input = Allocation.createFromBitmap(

@ -267,8 +267,9 @@ object BookHelp {
} }
} }
private val chapterNamePattern = private val chapterNamePattern by lazy {
Pattern.compile("^(.*?第([\\d零〇一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟0-9\\s]+)[章节篇回集])[、,。 ::.\\s]*") Pattern.compile("^(.*?第([\\d零〇一二两三四五六七八九十百千万壹贰叁肆伍陆柒捌玖拾佰仟0-9\\s]+)[章节篇回集])[、,。 ::.\\s]*")
}
private fun getChapterNum(chapterName: String?): Int { private fun getChapterNum(chapterName: String?): Int {
if (chapterName != null) { if (chapterName != null) {
@ -280,15 +281,25 @@ object BookHelp {
return -1 return -1
} }
private fun getPureChapterName(chapterName: String?): String { @Suppress("SpellCheckingInspection")
private val regexOther by lazy {
// 所有非字母数字中日韩文字 CJK区+扩展A-F区 // 所有非字母数字中日韩文字 CJK区+扩展A-F区
return@lazy "[^\\w\\u4E00-\\u9FEF〇\\u3400-\\u4DBF\\u20000-\\u2A6DF\\u2A700-\\u2EBEF]".toRegex()
}
private val regexA by lazy {
return@lazy "\\s".toRegex()
}
private val regexB by lazy {
return@lazy "^第.*?章|[(\\[][^()\\[\\]]{2,}[)\\]]$".toRegex()
}
private fun getPureChapterName(chapterName: String?): String {
return if (chapterName == null) "" else StringUtils.fullToHalf(chapterName) return if (chapterName == null) "" else StringUtils.fullToHalf(chapterName)
.replace("\\s".toRegex(), "") .replace(regexA, "")
.replace("^第.*?章|[(\\[][^()\\[\\]]{2,}[)\\]]$".toRegex(), "") .replace(regexB, "")
.replace( .replace(regexOther, "")
"[^\\w\\u4E00-\\u9FEF〇\\u3400-\\u4DBF\\u20000-\\u2A6DF\\u2A700-\\u2EBEF]".toRegex(),
""
)
} }
private var bookName: String? = null private var bookName: String? = null

@ -0,0 +1,47 @@
package io.legado.app.help
import io.legado.app.App
import io.legado.app.data.entities.HttpTTS
import io.legado.app.data.entities.TxtTocRule
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray
import java.io.File
object DefaultData {
const val httpTtsFileName = "httpTTS.json"
const val txtTocRuleFileName = "txtTocRule.json"
val defaultHttpTTS by lazy {
val json =
String(
App.INSTANCE.assets.open("defaultData${File.separator}$httpTtsFileName")
.readBytes()
)
GSON.fromJsonArray<HttpTTS>(json)!!
}
val defaultReadConfigs by lazy {
val json = String(
App.INSTANCE.assets.open("defaultData${File.separator}${ReadBookConfig.configFileName}")
.readBytes()
)
GSON.fromJsonArray<ReadBookConfig.Config>(json)!!
}
val defaultTxtTocRules by lazy {
val json = String(
App.INSTANCE.assets.open("defaultData${File.separator}$txtTocRuleFileName")
.readBytes()
)
GSON.fromJsonArray<TxtTocRule>(json)!!
}
val defaultThemeConfigs by lazy {
val json = String(
App.INSTANCE.assets.open("defaultData${File.separator}${ThemeConfig.configFileName}")
.readBytes()
)
GSON.fromJsonArray<ThemeConfig.Config>(json)!!
}
}

@ -1,19 +0,0 @@
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<HttpTTS>(json)?.let {
App.db.httpTTSDao().insert(*it.toTypedArray())
}
}
}

@ -2,8 +2,7 @@ package io.legado.app.help
import android.text.TextUtils import android.text.TextUtils
import java.util.Arrays @Suppress("unused")
class EventMessage { class EventMessage {
var what: Int?=null var what: Int?=null

@ -7,6 +7,7 @@ import android.os.Bundle
import io.legado.app.R import io.legado.app.R
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
@Suppress("unused")
object IntentHelp { object IntentHelp {

@ -6,6 +6,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager import androidx.recyclerview.widget.StaggeredGridLayoutManager
@Suppress("unused")
object LayoutManager { object LayoutManager {
interface LayoutManagerFactory { interface LayoutManagerFactory {

@ -26,10 +26,6 @@ object ReadBookConfig {
val shareConfigFilePath = FileUtils.getPath(App.INSTANCE.filesDir, shareConfigFileName) val shareConfigFilePath = FileUtils.getPath(App.INSTANCE.filesDir, shareConfigFileName)
val configList: ArrayList<Config> = arrayListOf() val configList: ArrayList<Config> = arrayListOf()
lateinit var shareConfig: Config lateinit var shareConfig: Config
private val defaultConfigs by lazy {
val json = String(App.INSTANCE.assets.open(configFileName).readBytes())
GSON.fromJsonArray<Config>(json)!!
}
var durConfig var durConfig
get() = getConfig(styleSelect) get() = getConfig(styleSelect)
set(value) { set(value) {
@ -68,7 +64,7 @@ object ReadBookConfig {
e.printStackTrace() e.printStackTrace()
} }
} }
(configs ?: defaultConfigs).let { (configs ?: DefaultData.defaultReadConfigs).let {
configList.clear() configList.clear()
configList.addAll(it) configList.addAll(it)
} }
@ -131,7 +127,7 @@ object ReadBookConfig {
} }
private fun resetAll() { private fun resetAll() {
defaultConfigs.let { DefaultData.defaultReadConfigs.let {
configList.clear() configList.clear()
configList.addAll(it) configList.addAll(it)
save() save()

@ -13,10 +13,7 @@ import java.io.File
object ThemeConfig { object ThemeConfig {
const val configFileName = "themeConfig.json" const val configFileName = "themeConfig.json"
val configFilePath = FileUtils.getPath(App.INSTANCE.filesDir, configFileName) val configFilePath = FileUtils.getPath(App.INSTANCE.filesDir, configFileName)
private val defaultConfigs by lazy {
val json = String(App.INSTANCE.assets.open(configFileName).readBytes())
GSON.fromJsonArray<Config>(json)!!
}
val configList = arrayListOf<Config>() val configList = arrayListOf<Config>()
init { init {
@ -24,7 +21,7 @@ object ThemeConfig {
} }
fun upConfig() { fun upConfig() {
(getConfigs() ?: defaultConfigs).let { (getConfigs() ?: DefaultData.defaultThemeConfigs).let {
configList.clear() configList.clear()
configList.addAll(it) configList.addAll(it)
} }

@ -1,5 +1,6 @@
package io.legado.app.help.coroutine package io.legado.app.help.coroutine
@Suppress("unused")
class CompositeCoroutine : CoroutineContainer { class CompositeCoroutine : CoroutineContainer {
private var resources: HashSet<Coroutine<*>>? = null private var resources: HashSet<Coroutine<*>>? = null

@ -5,6 +5,7 @@ import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext import kotlin.coroutines.CoroutineContext
@Suppress("unused")
class Coroutine<T>( class Coroutine<T>(
val scope: CoroutineScope, val scope: CoroutineScope,
context: CoroutineContext = Dispatchers.IO, context: CoroutineContext = Dispatchers.IO,

@ -1,3 +1,5 @@
@file:Suppress("unused")
package io.legado.app.help.http package io.legado.app.help.http
import android.text.TextUtils import android.text.TextUtils

@ -112,7 +112,7 @@ object HttpHelper {
proxy: String? = null proxy: String? = null
): Retrofit { ): Retrofit {
val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?") val r = Regex("(http|socks4|socks5)://(.*):(\\d{2,5})(@.*@.*)?")
val ms = proxy?.let { r.findAll(it) }; val ms = proxy?.let { r.findAll(it) }
val group = ms?.first() val group = ms?.first()
var type = "direct" //直接连接 var type = "direct" //直接连接
var host = "127.0.0.1" //代理服务器hostname var host = "127.0.0.1" //代理服务器hostname
@ -135,9 +135,9 @@ object HttpHelper {
val builder = client.newBuilder() val builder = client.newBuilder()
if (type != "direct" && host != "") { if (type != "direct" && host != "") {
if (type == "http") { if (type == "http") {
builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port))); builder.proxy(Proxy(Proxy.Type.HTTP, InetSocketAddress(host, port)))
} else { } else {
builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port))); builder.proxy(Proxy(Proxy.Type.SOCKS, InetSocketAddress(host, port)))
} }
if (username != "" && password != "") { if (username != "" && password != "") {
builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码 builder.proxyAuthenticator { _, response -> //设置代理服务器账号密码

@ -12,6 +12,7 @@ import java.security.cert.CertificateFactory
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
import javax.net.ssl.* import javax.net.ssl.*
@Suppress("unused")
object SSLHelper { object SSLHelper {
/** /**

@ -1,5 +1,6 @@
package io.legado.app.help.permission package io.legado.app.help.permission
@Suppress("unused")
object Permissions { object Permissions {
const val READ_CALENDAR = "android.permission.READ_CALENDAR" const val READ_CALENDAR = "android.permission.READ_CALENDAR"

@ -5,6 +5,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import java.util.* import java.util.*
@Suppress("unused")
class PermissionsCompat private constructor() { class PermissionsCompat private constructor() {
private var request: Request? = null private var request: Request? = null
@ -16,11 +17,11 @@ class PermissionsCompat private constructor() {
companion object { companion object {
// 检查权限, 如果已经拥有返回 true // 检查权限, 如果已经拥有返回 true
fun check(activity: AppCompatActivity, vararg permissions: String): Boolean { fun check(activity: AppCompatActivity, vararg permissions: String): Boolean {
var request = Request(activity) val request = Request(activity)
var pers = ArrayList<String>() val pers = ArrayList<String>()
pers.addAll(listOf(*permissions)) pers.addAll(listOf(*permissions))
var data = request.getDeniedPermissions(pers.toTypedArray()) val data = request.getDeniedPermissions(pers.toTypedArray())
return data == null; return data == null
} }
} }

@ -5,6 +5,7 @@ import android.net.Uri
import androidx.documentfile.provider.DocumentFile import androidx.documentfile.provider.DocumentFile
import io.legado.app.App import io.legado.app.App
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.help.DefaultData
import io.legado.app.help.ReadBookConfig import io.legado.app.help.ReadBookConfig
import io.legado.app.help.ThemeConfig import io.legado.app.help.ThemeConfig
import io.legado.app.help.coroutine.Coroutine import io.legado.app.help.coroutine.Coroutine
@ -31,9 +32,9 @@ object Backup {
"rssSource.json", "rssSource.json",
"rssStar.json", "rssStar.json",
"replaceRule.json", "replaceRule.json",
"txtTocRule.json",
"readRecord.json", "readRecord.json",
"httpTTS.json", DefaultData.txtTocRuleFileName,
DefaultData.httpTtsFileName,
ReadBookConfig.configFileName, ReadBookConfig.configFileName,
ReadBookConfig.shareConfigFileName, ReadBookConfig.shareConfigFileName,
ThemeConfig.configFileName, ThemeConfig.configFileName,
@ -62,9 +63,9 @@ object Backup {
writeListToJson(App.db.rssSourceDao().all, "rssSource.json", backupPath) writeListToJson(App.db.rssSourceDao().all, "rssSource.json", backupPath)
writeListToJson(App.db.rssStarDao().all, "rssStar.json", backupPath) writeListToJson(App.db.rssStarDao().all, "rssStar.json", backupPath)
writeListToJson(App.db.replaceRuleDao().all, "replaceRule.json", backupPath) 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.readRecordDao().all, "readRecord.json", backupPath)
writeListToJson(App.db.httpTTSDao().all, "httpTTS.json", backupPath) writeListToJson(App.db.txtTocRule().all, DefaultData.txtTocRuleFileName, backupPath)
writeListToJson(App.db.httpTTSDao().all, DefaultData.httpTtsFileName, backupPath)
GSON.toJson(ReadBookConfig.configList).let { GSON.toJson(ReadBookConfig.configList).let {
FileUtils.createFileIfNotExist(backupPath + File.separator + ReadBookConfig.configFileName) FileUtils.createFileIfNotExist(backupPath + File.separator + ReadBookConfig.configFileName)
.writeText(it) .writeText(it)

@ -100,7 +100,7 @@ object ImportOldData {
return bookSources.size return bookSources.size
} }
fun importOldReplaceRule(json: String): Int { private fun importOldReplaceRule(json: String): Int {
val rules = OldReplace.jsonToReplaceRules(json) val rules = OldReplace.jsonToReplaceRules(json)
App.db.replaceRuleDao().insert(*rules.toTypedArray()) App.db.replaceRuleDao().insert(*rules.toTypedArray())
return rules.size return rules.size

@ -9,6 +9,7 @@ import io.legado.app.help.storage.Restore.jsonPath
import io.legado.app.utils.* import io.legado.app.utils.*
import java.util.regex.Pattern import java.util.regex.Pattern
@Suppress("RegExpRedundantEscape")
object OldRule { object OldRule {
private val headerPattern = Pattern.compile("@Header:\\{.+?\\}", Pattern.CASE_INSENSITIVE) private val headerPattern = Pattern.compile("@Header:\\{.+?\\}", Pattern.CASE_INSENSITIVE)
private val jsPattern = Pattern.compile("\\{\\{.+?\\}\\}", Pattern.CASE_INSENSITIVE) private val jsPattern = Pattern.compile("\\{\\{.+?\\}\\}", Pattern.CASE_INSENSITIVE)

@ -13,10 +13,7 @@ import io.legado.app.R
import io.legado.app.constant.EventBus import io.legado.app.constant.EventBus
import io.legado.app.constant.PreferKey import io.legado.app.constant.PreferKey
import io.legado.app.data.entities.* import io.legado.app.data.entities.*
import io.legado.app.help.AppConfig import io.legado.app.help.*
import io.legado.app.help.LauncherIconHelp
import io.legado.app.help.ReadBookConfig
import io.legado.app.help.ThemeConfig
import io.legado.app.service.help.ReadBook import io.legado.app.service.help.ReadBook
import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ChapterProvider
import io.legado.app.utils.* import io.legado.app.utils.*
@ -81,7 +78,7 @@ object Restore {
for (fileName in Backup.backupFileNames) { for (fileName in Backup.backupFileNames) {
if (doc.name == fileName) { if (doc.name == fileName) {
DocumentUtils.readText(context, doc.uri)?.let { DocumentUtils.readText(context, doc.uri)?.let {
FileUtils.createFileIfNotExist(Backup.backupPath + File.separator + fileName) FileUtils.createFileIfNotExist("${Backup.backupPath}${File.separator}$fileName")
.writeText(it) .writeText(it)
} }
} }
@ -94,7 +91,7 @@ object Restore {
FileUtils.getFile(file, fileName).let { FileUtils.getFile(file, fileName).let {
if (it.exists()) { if (it.exists()) {
it.copyTo( it.copyTo(
FileUtils.createFileIfNotExist(Backup.backupPath + File.separator + fileName), FileUtils.createFileIfNotExist("${Backup.backupPath}${File.separator}$fileName"),
true true
) )
} }
@ -132,9 +129,12 @@ object Restore {
fileToListT<ReplaceRule>(path, "replaceRule.json")?.let { fileToListT<ReplaceRule>(path, "replaceRule.json")?.let {
App.db.replaceRuleDao().insert(*it.toTypedArray()) App.db.replaceRuleDao().insert(*it.toTypedArray())
} }
fileToListT<TxtTocRule>(path, "txtTocRule.json")?.let { fileToListT<TxtTocRule>(path, DefaultData.txtTocRuleFileName)?.let {
App.db.txtTocRule().insert(*it.toTypedArray()) App.db.txtTocRule().insert(*it.toTypedArray())
} }
fileToListT<HttpTTS>(path, DefaultData.httpTtsFileName)?.let {
App.db.httpTTSDao().insert(*it.toTypedArray())
}
fileToListT<ReadRecord>(path, "readRecord.json")?.let { fileToListT<ReadRecord>(path, "readRecord.json")?.let {
it.forEach { readRecord -> it.forEach { readRecord ->
//判断是不是本机记录 //判断是不是本机记录
@ -149,9 +149,6 @@ object Restore {
} }
} }
} }
fileToListT<HttpTTS>(path, "httpTTS.json")?.let {
App.db.httpTTSDao().insert(*it.toTypedArray())
}
} }
} }
@ -159,7 +156,7 @@ object Restore {
withContext(IO) { withContext(IO) {
try { try {
val file = val file =
FileUtils.createFileIfNotExist(path + File.separator + ThemeConfig.configFileName) FileUtils.createFileIfNotExist("$path${File.separator}${ThemeConfig.configFileName}")
if (file.exists()) { if (file.exists()) {
FileUtils.deleteFile(ThemeConfig.configFilePath) FileUtils.deleteFile(ThemeConfig.configFilePath)
file.copyTo(File(ThemeConfig.configFilePath)) file.copyTo(File(ThemeConfig.configFilePath))
@ -171,7 +168,7 @@ object Restore {
if (!ignoreReadConfig) { if (!ignoreReadConfig) {
try { try {
val file = val file =
FileUtils.createFileIfNotExist(path + File.separator + ReadBookConfig.configFileName) FileUtils.createFileIfNotExist("$path${File.separator}${ReadBookConfig.configFileName}")
if (file.exists()) { if (file.exists()) {
FileUtils.deleteFile(ReadBookConfig.configFilePath) FileUtils.deleteFile(ReadBookConfig.configFilePath)
file.copyTo(File(ReadBookConfig.configFilePath)) file.copyTo(File(ReadBookConfig.configFilePath))
@ -182,7 +179,7 @@ object Restore {
} }
try { try {
val file = val file =
FileUtils.createFileIfNotExist(path + File.separator + ReadBookConfig.shareConfigFileName) FileUtils.createFileIfNotExist("$path${File.separator}${ReadBookConfig.shareConfigFileName}")
if (file.exists()) { if (file.exists()) {
FileUtils.deleteFile(ReadBookConfig.shareConfigFilePath) FileUtils.deleteFile(ReadBookConfig.shareConfigFilePath)
file.copyTo(File(ReadBookConfig.shareConfigFilePath)) file.copyTo(File(ReadBookConfig.shareConfigFilePath))

@ -30,6 +30,7 @@ import org.jetbrains.anko.backgroundColor
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
@Suppress("unused", "MemberVisibilityCanBePrivate")
object ATH { object ATH {
@SuppressLint("CommitPrefEdits") @SuppressLint("CommitPrefEdits")

@ -11,6 +11,7 @@ import androidx.core.graphics.drawable.DrawableCompat
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
@Suppress("unused")
object DrawableUtils { object DrawableUtils {
fun createTransitionDrawable(@ColorInt startColor: Int, @ColorInt endColor: Int): TransitionDrawable { fun createTransitionDrawable(@ColorInt startColor: Int, @ColorInt endColor: Int): TransitionDrawable {

@ -1,3 +1,5 @@
@file:Suppress("unused")
package io.legado.app.lib.theme package io.legado.app.lib.theme
import android.annotation.SuppressLint import android.annotation.SuppressLint

@ -8,6 +8,7 @@ import com.google.android.material.navigation.NavigationView
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
@Suppress("unused")
object NavigationViewUtils { object NavigationViewUtils {
fun setItemIconColors(navigationView: NavigationView, @ColorInt normalColor: Int, @ColorInt selectedColor: Int) { fun setItemIconColors(navigationView: NavigationView, @ColorInt normalColor: Int, @ColorInt selectedColor: Int) {

@ -13,6 +13,7 @@ import androidx.annotation.DrawableRes
import androidx.annotation.IntDef import androidx.annotation.IntDef
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
@Suppress("unused")
object Selector { object Selector {
fun shapeBuild(): ShapeSelector { fun shapeBuild(): ShapeSelector {
return ShapeSelector() return ShapeSelector()
@ -260,7 +261,8 @@ object Selector {
* @author hjy * @author hjy
* created at 2017/12/11 22:34 * created at 2017/12/11 22:34
*/ */
class DrawableSelector constructor() { @Suppress("MemberVisibilityCanBePrivate")
class DrawableSelector {
private var mDefaultDrawable: Drawable? = null private var mDefaultDrawable: Drawable? = null
private var mDisabledDrawable: Drawable? = null private var mDisabledDrawable: Drawable? = null
@ -355,7 +357,7 @@ object Selector {
* @author hjy * @author hjy
* created at 2017/12/11 22:26 * created at 2017/12/11 22:26
*/ */
class ColorSelector constructor() { class ColorSelector {
private var mDefaultColor: Int = 0 private var mDefaultColor: Int = 0
private var mDisabledColor: Int = 0 private var mDisabledColor: Int = 0

@ -16,6 +16,7 @@ import io.legado.app.utils.ColorUtils
/** /**
* @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid) * @author Aidan Follestad (afollestad), Karim Abou Zeid (kabouzeid)
*/ */
@Suppress("unused")
class ThemeStore @SuppressLint("CommitPrefEdits") class ThemeStore @SuppressLint("CommitPrefEdits")
private constructor(private val mContext: Context) : ThemeStoreInterface { private constructor(private val mContext: Context) : ThemeStoreInterface {
private val mEditor: SharedPreferences.Editor private val mEditor: SharedPreferences.Editor

@ -23,6 +23,7 @@ import io.legado.app.utils.ColorUtils
/** /**
* @author afollestad, plusCubed * @author afollestad, plusCubed
*/ */
@Suppress("MemberVisibilityCanBePrivate")
object TintHelper { object TintHelper {
@SuppressLint("PrivateResource") @SuppressLint("PrivateResource")
@ -37,7 +38,10 @@ object TintHelper {
) )
} }
private fun getDisabledColorStateList(@ColorInt normal: Int, @ColorInt disabled: Int): ColorStateList { private fun getDisabledColorStateList(
@ColorInt normal: Int,
@ColorInt disabled: Int
): ColorStateList {
return ColorStateList( return ColorStateList(
arrayOf( arrayOf(
intArrayOf(-android.R.attr.state_enabled), intArrayOf(-android.R.attr.state_enabled),
@ -61,48 +65,52 @@ object TintHelper {
) )
val sl: ColorStateList val sl: ColorStateList
if (view is Button) { when (view) {
sl = getDisabledColorStateList(color, disabled) is Button -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && view.getBackground() is RippleDrawable) { sl = getDisabledColorStateList(color, disabled)
val rd = view.getBackground() as RippleDrawable if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && view.getBackground() is RippleDrawable) {
rd.setColor(ColorStateList.valueOf(rippleColor)) val rd = view.getBackground() as RippleDrawable
} rd.setColor(ColorStateList.valueOf(rippleColor))
}
// Disabled text color state for buttons, may get overridden later by ATE tags // Disabled text color state for buttons, may get overridden later by ATE tags
view.setTextColor( view.setTextColor(
getDisabledColorStateList( getDisabledColorStateList(
textColor, textColor,
ContextCompat.getColor( ContextCompat.getColor(
view.getContext(), view.getContext(),
if (useDarkTheme) R.color.ate_button_text_disabled_dark else R.color.ate_button_text_disabled_light if (useDarkTheme) R.color.ate_button_text_disabled_dark else R.color.ate_button_text_disabled_light
)
) )
) )
) }
} else if (view is FloatingActionButton) { is FloatingActionButton -> {
// FloatingActionButton doesn't support disabled state? // FloatingActionButton doesn't support disabled state?
sl = ColorStateList( sl = ColorStateList(
arrayOf( arrayOf(
intArrayOf(-android.R.attr.state_pressed), intArrayOf(-android.R.attr.state_pressed),
intArrayOf(android.R.attr.state_pressed) intArrayOf(android.R.attr.state_pressed)
), intArrayOf(color, pressed) ), intArrayOf(color, pressed)
) )
view.rippleColor = rippleColor view.rippleColor = rippleColor
view.backgroundTintList = sl view.backgroundTintList = sl
if (view.drawable != null) if (view.drawable != null)
view.setImageDrawable(createTintedDrawable(view.drawable, textColor)) view.setImageDrawable(createTintedDrawable(view.drawable, textColor))
return return
} else { }
sl = ColorStateList( else -> {
arrayOf( sl = ColorStateList(
intArrayOf(-android.R.attr.state_enabled), arrayOf(
intArrayOf(android.R.attr.state_enabled), intArrayOf(-android.R.attr.state_enabled),
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed), intArrayOf(android.R.attr.state_enabled),
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_activated), intArrayOf(android.R.attr.state_enabled, android.R.attr.state_pressed),
intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked) intArrayOf(android.R.attr.state_enabled, android.R.attr.state_activated),
), intArrayOf(android.R.attr.state_enabled, android.R.attr.state_checked)
intArrayOf(disabled, color, pressed, activated, activated) ),
) intArrayOf(disabled, color, pressed, activated, activated)
)
}
} }
var drawable: Drawable? = view.background var drawable: Drawable? = view.background
@ -386,7 +394,11 @@ object TintHelper {
return createTintedDrawable(from, sl) return createTintedDrawable(from, sl)
} }
fun setTint(switchView: Switch, @ColorInt color: Int, useDarker: Boolean) { fun setTint(
@SuppressLint("UseSwitchCompatOrMaterialCode") switchView: Switch,
@ColorInt color: Int,
useDarker: Boolean
) {
if (switchView.trackDrawable != null) { if (switchView.trackDrawable != null) {
switchView.trackDrawable = modifySwitchDrawable( switchView.trackDrawable = modifySwitchDrawable(
switchView.context, switchView.context,

@ -10,6 +10,7 @@ import androidx.annotation.ColorInt
/** /**
* @author Karim Abou Zeid (kabouzeid) * @author Karim Abou Zeid (kabouzeid)
*/ */
@Suppress("unused")
object ViewUtils { object ViewUtils {
fun removeOnGlobalLayoutListener(v: View, listener: ViewTreeObserver.OnGlobalLayoutListener) { fun removeOnGlobalLayoutListener(v: View, listener: ViewTreeObserver.OnGlobalLayoutListener) {

@ -14,6 +14,7 @@ import java.net.URL
import java.net.URLEncoder import java.net.URLEncoder
import java.util.* import java.util.*
@Suppress("unused")
class WebDav(urlStr: String) { class WebDav(urlStr: String) {
companion object { companion object {
// 指定返回哪些属性 // 指定返回哪些属性
@ -60,9 +61,9 @@ class WebDav(urlStr: String) {
return field return field
} }
fun getPath() = url.toString() val path get() = url.toString()
fun getHost() = url.host val host: String? get() = url.host
/** /**
* 填充文件信息实例化WebDAVFile对象时并没有将远程文件的信息填充到实例中需要手动填充 * 填充文件信息实例化WebDAVFile对象时并没有将远程文件的信息填充到实例中需要手动填充

@ -8,6 +8,7 @@ import io.legado.app.utils.splitNotBlank
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
@Suppress("RegExpRedundantEscape")
@Keep @Keep
class AnalyzeByJSonPath { class AnalyzeByJSonPath {
private lateinit var ctx: ReadContext private lateinit var ctx: ReadContext

@ -5,6 +5,7 @@ import io.legado.app.App
import io.legado.app.data.entities.Book import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookChapter
import io.legado.app.data.entities.TxtTocRule import io.legado.app.data.entities.TxtTocRule
import io.legado.app.help.DefaultData
import io.legado.app.utils.* import io.legado.app.utils.*
import java.io.File import java.io.File
import java.io.RandomAccessFile import java.io.RandomAccessFile
@ -281,24 +282,17 @@ class AnalyzeTxtFile {
} }
private fun getTocRules(): List<TxtTocRule> { private fun getTocRules(): List<TxtTocRule> {
val rules = App.db.txtTocRule().enabled var rules = App.db.txtTocRule().enabled
if (rules.isEmpty()) { if (rules.isEmpty()) {
return getDefaultEnabledRules() rules = DefaultData.defaultTxtTocRules.apply {
App.db.txtTocRule().insert(*this.toTypedArray())
}.filter {
it.enable
}
} }
return rules return rules
} }
fun getDefaultEnabledRules(): List<TxtTocRule> {
App.INSTANCE.assets.open("txtTocRule.json").readBytes().let { byteArray ->
GSON.fromJsonArray<TxtTocRule>(String(byteArray))?.let { txtTocRules ->
App.db.txtTocRule().insert(*txtTocRules.toTypedArray())
return txtTocRules.filter {
it.enable
}
}
}
return emptyList()
}
} }
} }

@ -8,6 +8,7 @@ import org.xmlpull.v1.XmlPullParserFactory
import java.io.IOException import java.io.IOException
import java.io.StringReader import java.io.StringReader
@Suppress("unused")
object RssParserDefault { object RssParserDefault {
@Throws(XmlPullParserException::class, IOException::class) @Throws(XmlPullParserException::class, IOException::class)

@ -25,15 +25,13 @@ class TimeBatteryReceiver : BroadcastReceiver() {
} }
override fun onReceive(context: Context?, intent: Intent?) { override fun onReceive(context: Context?, intent: Intent?) {
intent?.action?.let { when (intent?.action) {
when (it) { Intent.ACTION_TIME_TICK -> {
Intent.ACTION_TIME_TICK -> { postEvent(EventBus.TIME_CHANGED, "")
postEvent(EventBus.TIME_CHANGED, "") }
} Intent.ACTION_BATTERY_CHANGED -> {
Intent.ACTION_BATTERY_CHANGED -> { val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) postEvent(EventBus.BATTERY_CHANGED, level)
postEvent(EventBus.BATTERY_CHANGED, level)
}
} }
} }
} }

@ -77,23 +77,16 @@ object CacheBook {
downloadMap[book.bookUrl]?.add(chapter.index) downloadMap[book.bookUrl]?.add(chapter.index)
webBook.getContent(book, chapter) webBook.getContent(book, chapter)
.onSuccess(IO) { content -> .onSuccess(IO) { content ->
if (content.isNotBlank()) {
BookHelp.saveContent(book, chapter, content)
}
if (ReadBook.book?.bookUrl == book.bookUrl) { if (ReadBook.book?.bookUrl == book.bookUrl) {
if (content.isEmpty()) { ReadBook.contentLoadFinish(
ReadBook.contentLoadFinish( book,
book, chapter,
chapter, content.ifBlank { App.INSTANCE.getString(R.string.content_empty) },
App.INSTANCE.getString(R.string.content_empty), resetPageOffset = resetPageOffset
resetPageOffset = resetPageOffset )
)
} else {
BookHelp.saveContent(book, chapter, content)
ReadBook.contentLoadFinish(
book,
chapter,
content,
resetPageOffset = resetPageOffset
)
}
} }
}.onError { }.onError {
if (ReadBook.book?.bookUrl == book.bookUrl) { if (ReadBook.book?.bookUrl == book.bookUrl) {

@ -24,11 +24,13 @@ import io.legado.app.lib.dialogs.customView
import io.legado.app.lib.dialogs.okButton import io.legado.app.lib.dialogs.okButton
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.service.help.ReadAloud import io.legado.app.service.help.ReadAloud
import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.* import io.legado.app.utils.*
import kotlinx.android.synthetic.main.dialog_http_tts_edit.view.* import kotlinx.android.synthetic.main.dialog_http_tts_edit.view.*
import kotlinx.android.synthetic.main.dialog_recycler_view.* import kotlinx.android.synthetic.main.dialog_recycler_view.*
import kotlinx.android.synthetic.main.item_http_tts.view.* import kotlinx.android.synthetic.main.item_http_tts.view.*
import org.jetbrains.anko.sdk27.listeners.onClick import org.jetbrains.anko.sdk27.listeners.onClick
import java.io.File
class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener { class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener {
@ -126,6 +128,12 @@ class SpeakEngineDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
ReadAloud.upReadAloudClass() ReadAloud.upReadAloudClass()
} }
} }
neutralButton(R.string.help) {
val helpStr = String(
requireContext().assets.open("help${File.separator}httpTts.md").readBytes()
)
TextDialog.show(childFragmentManager, helpStr, TextDialog.MD)
}
}.show().applyTint() }.show().applyTint()
} }

@ -3,8 +3,8 @@ package io.legado.app.ui.book.read.config
import android.app.Application import android.app.Application
import io.legado.app.App import io.legado.app.App
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.TxtTocRule import io.legado.app.data.entities.HttpTTS
import io.legado.app.help.DefaultValueHelp import io.legado.app.help.DefaultData
import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.HttpHelper
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray import io.legado.app.utils.fromJsonArray
@ -13,15 +13,17 @@ class SpeakEngineViewModel(application: Application) : BaseViewModel(application
fun importDefault() { fun importDefault() {
execute { execute {
DefaultValueHelp.initHttpTTS() DefaultData.defaultHttpTTS.let {
App.db.httpTTSDao().insert(*it.toTypedArray())
}
} }
} }
fun importOnLine(url: String, finally: (msg: String) -> Unit) { fun importOnLine(url: String, finally: (msg: String) -> Unit) {
execute { execute {
HttpHelper.simpleGetAsync(url)?.let { json -> HttpHelper.simpleGetAsync(url)?.let { json ->
GSON.fromJsonArray<TxtTocRule>(json)?.let { GSON.fromJsonArray<HttpTTS>(json)?.let {
App.db.txtTocRule().insert(*it.toTypedArray()) App.db.httpTTSDao().insert(*it.toTypedArray())
} }
} }
}.onSuccess { }.onSuccess {

@ -4,8 +4,8 @@ import android.app.Application
import io.legado.app.App import io.legado.app.App
import io.legado.app.base.BaseViewModel import io.legado.app.base.BaseViewModel
import io.legado.app.data.entities.TxtTocRule import io.legado.app.data.entities.TxtTocRule
import io.legado.app.help.DefaultData
import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.HttpHelper
import io.legado.app.model.localBook.AnalyzeTxtFile
import io.legado.app.utils.GSON import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonArray import io.legado.app.utils.fromJsonArray
@ -23,7 +23,9 @@ class TocRegexViewModel(application: Application) : BaseViewModel(application) {
fun importDefault() { fun importDefault() {
execute { execute {
App.db.txtTocRule().deleteDefault() App.db.txtTocRule().deleteDefault()
AnalyzeTxtFile.getDefaultEnabledRules() DefaultData.defaultTxtTocRules.let {
App.db.txtTocRule().insert(*it.toTypedArray())
}
} }
} }

@ -4,6 +4,7 @@ import android.text.TextPaint
import io.legado.app.ui.book.read.page.provider.ChapterProvider import io.legado.app.ui.book.read.page.provider.ChapterProvider
import io.legado.app.ui.book.read.page.provider.ChapterProvider.textHeight import io.legado.app.ui.book.read.page.provider.ChapterProvider.textHeight
@Suppress("unused")
data class TextLine( data class TextLine(
var text: String = "", var text: String = "",
val textChars: ArrayList<TextChar> = arrayListOf(), val textChars: ArrayList<TextChar> = arrayListOf(),

@ -144,7 +144,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application),
} }
} }
if (!scope.isActive) return if (!scope.isActive) return
searchBooks.sortWith(Comparator { o1, o2 -> searchBooks.sortWith { o1, o2 ->
if (o1.name == searchKey && o2.name != searchKey) { if (o1.name == searchKey && o2.name != searchKey) {
1 1
} else if (o1.name != searchKey && o2.name == searchKey) { } else if (o1.name != searchKey && o2.name == searchKey) {
@ -168,7 +168,7 @@ class SearchViewModel(application: Application) : BaseViewModel(application),
} else { } else {
0 0
} }
}) }
if (!scope.isActive) return if (!scope.isActive) return
searchBooks = copyDataS searchBooks = copyDataS
upAdapter() upAdapter()

@ -65,7 +65,7 @@ class ChapterListActivity : VMBaseActivity<ChapterListViewModel>(R.layout.activi
return super.onCompatCreateOptionsMenu(menu) return super.onCompatCreateOptionsMenu(menu)
} }
private inner class TabFragmentPageAdapter internal constructor(fm: FragmentManager) : private inner class TabFragmentPageAdapter(fm: FragmentManager) :
FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) { FragmentPagerAdapter(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
override fun getItem(position: Int): Fragment { override fun getItem(position: Int): Fragment {
return when (position) { return when (position) {

@ -23,10 +23,10 @@ class FileAdapter(context: Context, val callBack: CallBack) :
private var rootPath: String? = null private var rootPath: String? = null
var currentPath: String? = null var currentPath: String? = null
private set private set
private val homeIcon = ConvertUtils.toDrawable(FilePickerIcon.getHOME()) private val homeIcon = ConvertUtils.toDrawable(FilePickerIcon.getHome())
private val upIcon = ConvertUtils.toDrawable(FilePickerIcon.getUPDIR()) private val upIcon = ConvertUtils.toDrawable(FilePickerIcon.getUpDir())
private val folderIcon = ConvertUtils.toDrawable(FilePickerIcon.getFOLDER()) private val folderIcon = ConvertUtils.toDrawable(FilePickerIcon.getFolder())
private val fileIcon = ConvertUtils.toDrawable(FilePickerIcon.getFILE()) private val fileIcon = ConvertUtils.toDrawable(FilePickerIcon.getFile())
private val primaryTextColor = context.getPrimaryTextColor(!AppConfig.isNightTheme) private val primaryTextColor = context.getPrimaryTextColor(!AppConfig.isNightTheme)
private val disabledTextColor = context.getPrimaryDisabledTextColor(!AppConfig.isNightTheme) private val disabledTextColor = context.getPrimaryDisabledTextColor(!AppConfig.isNightTheme)

@ -17,7 +17,7 @@ class PathAdapter(context: Context, val callBack: CallBack) :
private val paths = LinkedList<String>() private val paths = LinkedList<String>()
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
private val sdCardDirectory = Environment.getExternalStorageDirectory().absolutePath private val sdCardDirectory = Environment.getExternalStorageDirectory().absolutePath
private val arrowIcon = ConvertUtils.toDrawable(FilePickerIcon.getARROW()) private val arrowIcon = ConvertUtils.toDrawable(FilePickerIcon.getArrow())
fun getPath(position: Int): String { fun getPath(position: Int): String {
val tmp = StringBuilder("$sdCardDirectory/") val tmp = StringBuilder("$sdCardDirectory/")

@ -8,23 +8,23 @@ package io.legado.app.ui.filechooser.utils;
*/ */
public class FilePickerIcon { public class FilePickerIcon {
public static byte[] getFILE() { public static byte[] getFile() {
return FILE; return FILE;
} }
public static byte[] getFOLDER() { public static byte[] getFolder() {
return FOLDER; return FOLDER;
} }
public static byte[] getHOME() { public static byte[] getHome() {
return HOME; return HOME;
} }
public static byte[] getUPDIR() { public static byte[] getUpDir() {
return UPDIR; return UPDIR;
} }
public static byte[] getARROW() { public static byte[] getArrow() {
return ARROW; return ARROW;
} }

@ -9,7 +9,7 @@ import io.legado.app.data.entities.Book
import io.legado.app.data.entities.RssSource import io.legado.app.data.entities.RssSource
import io.legado.app.help.AppConfig import io.legado.app.help.AppConfig
import io.legado.app.help.BookHelp import io.legado.app.help.BookHelp
import io.legado.app.help.DefaultValueHelp import io.legado.app.help.DefaultData
import io.legado.app.help.http.HttpHelper import io.legado.app.help.http.HttpHelper
import io.legado.app.help.storage.Restore import io.legado.app.help.storage.Restore
import io.legado.app.model.webBook.WebBook import io.legado.app.model.webBook.WebBook
@ -162,7 +162,9 @@ class MainViewModel(application: Application) : BaseViewModel(application) {
execute { execute {
FileUtils.deleteFile(FileUtils.getPath(context.cacheDir, "Fonts")) FileUtils.deleteFile(FileUtils.getPath(context.cacheDir, "Fonts"))
if (App.db.httpTTSDao().count == 0) { if (App.db.httpTTSDao().count == 0) {
DefaultValueHelp.initHttpTTS() DefaultData.defaultHttpTTS.let {
App.db.httpTTSDao().insert(*it.toTypedArray())
}
} }
} }
} }

@ -54,7 +54,7 @@ class MyFragment : BaseFragment(R.layout.fragment_my_config), FileChooserDialog.
override fun onCompatOptionsItemSelected(item: MenuItem) { override fun onCompatOptionsItemSelected(item: MenuItem) {
when (item.itemId) { when (item.itemId) {
R.id.menu_help -> { R.id.menu_help -> {
val text = String(requireContext().assets.open("help.md").readBytes()) val text = String(requireContext().assets.open("help/help.md").readBytes())
TextDialog.show(childFragmentManager, text, TextDialog.MD) TextDialog.show(childFragmentManager, text, TextDialog.MD)
} }
} }

@ -32,7 +32,7 @@ open class WelcomeActivity : BaseActivity(R.layout.activity_welcome) {
private fun init() { private fun init() {
Coroutine.async { Coroutine.async {
//清过期数据 //清过期数据
App.db.searchBookDao() App.db.searchBookDao()
.clearExpired(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1)) .clearExpired(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1))
//初始化简繁转换引擎 //初始化简繁转换引擎

@ -10,6 +10,7 @@ import android.util.AttributeSet
import androidx.annotation.ColorInt import androidx.annotation.ColorInt
import androidx.appcompat.widget.AppCompatTextView import androidx.appcompat.widget.AppCompatTextView
import io.legado.app.utils.dp import io.legado.app.utils.dp
import java.io.File
class BatteryView(context: Context, attrs: AttributeSet?) : AppCompatTextView(context, attrs) { class BatteryView(context: Context, attrs: AttributeSet?) : AppCompatTextView(context, attrs) {
private val batteryPaint = Paint() private val batteryPaint = Paint()
@ -22,7 +23,7 @@ class BatteryView(context: Context, attrs: AttributeSet?) : AppCompatTextView(co
batteryPaint.strokeWidth = 1.dp.toFloat() batteryPaint.strokeWidth = 1.dp.toFloat()
batteryPaint.isAntiAlias = true batteryPaint.isAntiAlias = true
batteryPaint.color = paint.color batteryPaint.color = paint.color
typeface = Typeface.createFromAsset(context.assets, "number.ttf") typeface = Typeface.createFromAsset(context.assets, "font${File.separator}number.ttf")
} }
fun setColor(@ColorInt color: Int) { fun setColor(@ColorInt color: Int) {

@ -1,3 +1,5 @@
@file:Suppress("unused")
package io.legado.app.utils package io.legado.app.utils
import android.net.Uri import android.net.Uri

Loading…
Cancel
Save