mirror of
https://github.com/gedoor/legado.git
synced 2024-07-06 23:47:49 +08:00
优化
This commit is contained in:
parent
4ad32a3291
commit
d8023474ed
@ -63,11 +63,11 @@ class ReaderProvider : ContentProvider() {
|
||||
selectionArgs: Array<String>?
|
||||
): Int {
|
||||
if (sMatcher.match(uri) < 0) return -1
|
||||
when (RequestCode.values()[sMatcher.match(uri)]) {
|
||||
when (RequestCode.entries[sMatcher.match(uri)]) {
|
||||
RequestCode.DeleteBookSources -> BookSourceController.deleteSources(selection)
|
||||
RequestCode.DeleteRssSources -> BookSourceController.deleteSources(selection)
|
||||
else -> throw IllegalStateException(
|
||||
"Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name
|
||||
"Unexpected value: " + RequestCode.entries[sMatcher.match(uri)].name
|
||||
)
|
||||
}
|
||||
return 0
|
||||
@ -78,7 +78,7 @@ class ReaderProvider : ContentProvider() {
|
||||
override fun insert(uri: Uri, values: ContentValues?): Uri? {
|
||||
if (sMatcher.match(uri) < 0) return null
|
||||
runBlocking {
|
||||
when (RequestCode.values()[sMatcher.match(uri)]) {
|
||||
when (RequestCode.entries[sMatcher.match(uri)]) {
|
||||
RequestCode.SaveBookSource -> values?.let {
|
||||
BookSourceController.saveSource(values.getAsString(postBodyKey))
|
||||
}
|
||||
@ -104,7 +104,7 @@ class ReaderProvider : ContentProvider() {
|
||||
}
|
||||
|
||||
else -> throw IllegalStateException(
|
||||
"Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name
|
||||
"Unexpected value: " + RequestCode.entries[sMatcher.match(uri)].name
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -125,7 +125,7 @@ class ReaderProvider : ContentProvider() {
|
||||
uri.getQueryParameter("path")?.let {
|
||||
map["path"] = arrayListOf(it)
|
||||
}
|
||||
return if (sMatcher.match(uri) < 0) null else when (RequestCode.values()[sMatcher.match(uri)]) {
|
||||
return if (sMatcher.match(uri) < 0) null else when (RequestCode.entries[sMatcher.match(uri)]) {
|
||||
RequestCode.GetBookSource -> SimpleCursor(BookSourceController.getSource(map))
|
||||
RequestCode.GetBookSources -> SimpleCursor(BookSourceController.sources)
|
||||
RequestCode.GetRssSource -> SimpleCursor(RssSourceController.getSource(map))
|
||||
@ -136,7 +136,7 @@ class ReaderProvider : ContentProvider() {
|
||||
RequestCode.GetChapterList -> SimpleCursor(BookController.getChapterList(map))
|
||||
RequestCode.GetBookCover -> SimpleCursor(BookController.getCover(map))
|
||||
else -> throw IllegalStateException(
|
||||
"Unexpected value: " + RequestCode.values()[sMatcher.match(uri)].name
|
||||
"Unexpected value: " + RequestCode.entries[sMatcher.match(uri)].name
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,18 @@
|
||||
package io.legado.app.data.dao
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.room.*
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Update
|
||||
import io.legado.app.constant.BookType
|
||||
import io.legado.app.data.entities.BookGroup
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
abstract interface BookGroupDao {
|
||||
interface BookGroupDao {
|
||||
|
||||
@Query("select * from book_groups where groupId = :id")
|
||||
fun getByID(id: Long): BookGroup?
|
||||
|
@ -1,6 +1,11 @@
|
||||
package io.legado.app.data.dao
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import androidx.room.Update
|
||||
import io.legado.app.constant.AppPattern
|
||||
import io.legado.app.data.entities.ReplaceRule
|
||||
import io.legado.app.utils.cnCompare
|
||||
@ -97,7 +102,7 @@ interface ReplaceRuleDao {
|
||||
}
|
||||
}
|
||||
|
||||
fun allGroups(): List<String> =dealGroups(allGroupsUnProcessed)
|
||||
fun allGroups(): List<String> = dealGroups(allGroupsUnProcessed)
|
||||
|
||||
fun flowGroups(): Flow<List<String>> {
|
||||
return flowGroupsUnProcessed().map { list ->
|
||||
|
@ -199,6 +199,7 @@ object AppWebDav {
|
||||
.toSet()
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
suspend fun exportWebDav(byteArray: ByteArray, fileName: String) {
|
||||
if (!NetworkUtils.isAvailable()) return
|
||||
try {
|
||||
|
@ -3,7 +3,6 @@ package io.legado.app.help
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import io.legado.app.R
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import splitties.init.appCtx
|
||||
|
@ -12,6 +12,7 @@ import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.Connection
|
||||
|
||||
@Suppress("ConstPropertyName")
|
||||
object CookieManager {
|
||||
/**
|
||||
* <domain>_session_cookie 会话期 cookie,应用重启后失效
|
||||
|
@ -27,11 +27,11 @@ class CronetInterceptor(private val cookieJar: CookieJar) : Interceptor {
|
||||
builder.removeHeader("Accept-Encoding")
|
||||
|
||||
val newReq = builder.build()
|
||||
proceedWithCronet(newReq, chain.call())?.let { response ->
|
||||
proceedWithCronet(newReq, chain.call())/*?.let { response ->
|
||||
//从Response 中保存Cookie到CookieJar
|
||||
//cookieJar.receiveHeaders(newReq.url, response.headers)
|
||||
response
|
||||
} ?: chain.proceed(original)
|
||||
}*/ ?: chain.proceed(original)
|
||||
} catch (e: Exception) {
|
||||
//不能抛出错误,抛出错误会导致应用崩溃
|
||||
//遇到Cronet处理有问题时的情况,如证书过期等等,回退到okhttp处理
|
||||
|
@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@file:Suppress("NOTHING_TO_INLINE", "unused")
|
||||
@file:Suppress("unused")
|
||||
|
||||
package io.legado.app.lib.dialogs
|
||||
|
||||
|
@ -16,6 +16,10 @@ import org.seimicrawler.xpath.JXNode
|
||||
@Keep
|
||||
class AnalyzeByJSoup(doc: Any) {
|
||||
|
||||
companion object {
|
||||
private val nullSet = setOf(null)
|
||||
}
|
||||
|
||||
private var element: Element = parse(doc)
|
||||
|
||||
private fun parse(doc: Any): Element {
|
||||
@ -220,6 +224,7 @@ class AnalyzeByJSoup(doc: Any) {
|
||||
textS.add(text)
|
||||
}
|
||||
}
|
||||
|
||||
"textNodes" -> for (element in elements) {
|
||||
val tn = arrayListOf<String>()
|
||||
val contentEs = element.textNodes()
|
||||
@ -233,12 +238,14 @@ class AnalyzeByJSoup(doc: Any) {
|
||||
textS.add(tn.joinToString("\n"))
|
||||
}
|
||||
}
|
||||
|
||||
"ownText" -> for (element in elements) {
|
||||
val text = element.ownText()
|
||||
if (text.isNotEmpty()) {
|
||||
textS.add(text)
|
||||
}
|
||||
}
|
||||
|
||||
"html" -> {
|
||||
elements.select("script").remove()
|
||||
elements.select("style").remove()
|
||||
@ -247,6 +254,7 @@ class AnalyzeByJSoup(doc: Any) {
|
||||
textS.add(html)
|
||||
}
|
||||
}
|
||||
|
||||
"all" -> textS.add(elements.outerHtml())
|
||||
else -> for (element in elements) {
|
||||
|
||||
@ -359,7 +367,7 @@ class AnalyzeByJSoup(doc: Any) {
|
||||
|
||||
for (pcInt in indexSet) elements[pcInt] = null
|
||||
|
||||
elements.removeAll(listOf(null)) //测试过,这样就行
|
||||
elements.removeAll(nullSet) //测试过,这样就行
|
||||
|
||||
} else if (split == '.') { //选择
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.legado.app.ui.association
|
||||
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.os.postDelayed
|
||||
|
@ -8,7 +8,6 @@ import io.legado.app.base.BaseViewModel
|
||||
import io.legado.app.constant.AppConst
|
||||
import io.legado.app.constant.AppLog
|
||||
import io.legado.app.constant.AppPattern
|
||||
import io.legado.app.constant.EventBus
|
||||
import io.legado.app.data.appDb
|
||||
import io.legado.app.data.entities.Book
|
||||
import io.legado.app.data.entities.BookChapter
|
||||
@ -22,15 +21,19 @@ import io.legado.app.help.config.SourceConfig
|
||||
import io.legado.app.help.coroutine.CompositeCoroutine
|
||||
import io.legado.app.help.coroutine.Coroutine
|
||||
import io.legado.app.model.webBook.WebBook
|
||||
import io.legado.app.utils.postEvent
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.ExecutorCoroutineDispatcher
|
||||
import kotlinx.coroutines.asCoroutineDispatcher
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.ensureActive
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.flowOn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import java.util.*
|
||||
import java.util.Collections
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.Executors
|
||||
import kotlin.math.min
|
||||
@ -319,22 +322,26 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a
|
||||
}
|
||||
|
||||
fun onLoadWordCountChecked(isChecked: Boolean) {
|
||||
postEvent(EventBus.SOURCE_CHANGED, "")
|
||||
if (isChecked) {
|
||||
startRefreshList(searchBooks.filter { it.chapterWordCountText == null })
|
||||
startRefreshList(true)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新列表
|
||||
*/
|
||||
fun startRefreshList(refreshList: List<SearchBook> = searchBooks) {
|
||||
fun startRefreshList(onlyRefreshNoWordCountBook: Boolean = false) {
|
||||
execute {
|
||||
if (refreshList.isEmpty()) return@execute
|
||||
stopSearch()
|
||||
searchBookList.clear()
|
||||
searchBookList.addAll(refreshList)
|
||||
searchBooks.removeAll(refreshList)
|
||||
if (onlyRefreshNoWordCountBook) {
|
||||
val noWordCountBook = searchBooks.filter { it.chapterWordCountText == null }
|
||||
searchBookList.addAll(noWordCountBook)
|
||||
searchBooks.removeIf { it.chapterWordCountText == null }
|
||||
} else {
|
||||
searchBookList.addAll(searchBooks)
|
||||
searchBooks.clear()
|
||||
}
|
||||
searchCallback?.upAdapter()
|
||||
searchStateData.postValue(true)
|
||||
initSearchPool()
|
||||
|
@ -251,19 +251,23 @@ class ChangeChapterSourceDialog() : BaseDialogFragment(R.layout.dialog_chapter_c
|
||||
item.isChecked = !item.isChecked
|
||||
viewModel.refresh()
|
||||
}
|
||||
|
||||
R.id.menu_load_info -> {
|
||||
AppConfig.changeSourceLoadInfo = !item.isChecked
|
||||
item.isChecked = !item.isChecked
|
||||
}
|
||||
|
||||
R.id.menu_load_toc -> {
|
||||
AppConfig.changeSourceLoadToc = !item.isChecked
|
||||
item.isChecked = !item.isChecked
|
||||
}
|
||||
|
||||
R.id.menu_load_word_count -> {
|
||||
AppConfig.changeSourceLoadWordCount = !item.isChecked
|
||||
item.isChecked = !item.isChecked
|
||||
viewModel.onLoadWordCountChecked(item.isChecked)
|
||||
}
|
||||
|
||||
R.id.menu_start_stop -> viewModel.startOrStopSearch()
|
||||
R.id.menu_source_manage -> startActivity<BookSourceActivity>()
|
||||
else -> if (item?.groupId == R.id.source_group && !item.isChecked) {
|
||||
|
@ -7,7 +7,11 @@ import android.content.Intent
|
||||
import android.content.pm.ResolveInfo
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.view.*
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupWindow
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.view.SupportMenuInflater
|
||||
@ -21,7 +25,14 @@ import io.legado.app.constant.PreferKey
|
||||
import io.legado.app.databinding.ItemTextBinding
|
||||
import io.legado.app.databinding.PopupActionMenuBinding
|
||||
import io.legado.app.help.config.AppConfig
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.getPrefBoolean
|
||||
import io.legado.app.utils.gone
|
||||
import io.legado.app.utils.isAbsUrl
|
||||
import io.legado.app.utils.printOnDebug
|
||||
import io.legado.app.utils.sendToClip
|
||||
import io.legado.app.utils.share
|
||||
import io.legado.app.utils.toastOnUi
|
||||
import io.legado.app.utils.visible
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
class TextActionMenu(private val context: Context, private val callBack: CallBack) :
|
||||
@ -108,9 +119,11 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
|
||||
windowHeight - startTopY
|
||||
)
|
||||
}
|
||||
|
||||
endBottomY - startBottomY > 500 -> {
|
||||
showAtLocation(view, Gravity.TOP or Gravity.START, startX, startBottomY)
|
||||
}
|
||||
|
||||
else -> {
|
||||
showAtLocation(view, Gravity.TOP or Gravity.START, endX, endBottomY)
|
||||
}
|
||||
@ -130,6 +143,7 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
|
||||
startTopY - popupHeight
|
||||
)
|
||||
}
|
||||
|
||||
endBottomY - startBottomY > 500 -> {
|
||||
showAtLocation(
|
||||
view,
|
||||
@ -138,6 +152,7 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
|
||||
startBottomY
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
showAtLocation(
|
||||
view,
|
||||
@ -215,6 +230,7 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
|
||||
context.toastOnUi(it.localizedMessage ?: "ERROR")
|
||||
}
|
||||
}
|
||||
|
||||
else -> item.intent?.let {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
it.putExtra(Intent.EXTRA_PROCESS_TEXT, callBack.selectedText)
|
||||
@ -233,7 +249,6 @@ class TextActionMenu(private val context: Context, private val callBack: CallBac
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
private fun getSupportedActivities(): List<ResolveInfo> {
|
||||
@Suppress("DEPRECATION")
|
||||
return context.packageManager
|
||||
.queryIntentActivities(createProcessTextIntent(), 0)
|
||||
}
|
||||
|
@ -23,7 +23,12 @@ import io.legado.app.lib.theme.getPrimaryTextColor
|
||||
import io.legado.app.model.ReadBook
|
||||
import io.legado.app.ui.book.read.ReadBookActivity
|
||||
import io.legado.app.ui.font.FontSelectDialog
|
||||
import io.legado.app.utils.*
|
||||
import io.legado.app.utils.ChineseUtils
|
||||
import io.legado.app.utils.ColorUtils
|
||||
import io.legado.app.utils.dpToPx
|
||||
import io.legado.app.utils.getIndexById
|
||||
import io.legado.app.utils.postEvent
|
||||
import io.legado.app.utils.showDialogFragment
|
||||
import io.legado.app.utils.viewbindingdelegate.viewBinding
|
||||
import splitties.views.onLongClick
|
||||
|
||||
@ -102,7 +107,7 @@ class ReadStyleDialog : BaseDialogFragment(R.layout.dialog_read_book_style),
|
||||
|
||||
private fun initViewEvent() = binding.run {
|
||||
chineseConverter.onChanged {
|
||||
ChineseUtils.unLoad(*TransType.values())
|
||||
ChineseUtils.unLoad(*TransType.entries.toTypedArray())
|
||||
postEvent(EventBus.UP_CONFIG, true)
|
||||
}
|
||||
textFontWeightConverter.onChanged {
|
||||
|
@ -11,10 +11,7 @@ class ExploreDiffItemCallBack : DiffUtil.ItemCallback<BookSource>() {
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
|
||||
if (oldItem.bookSourceName != newItem.bookSourceName) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return oldItem.bookSourceName == newItem.bookSourceName
|
||||
}
|
||||
|
||||
}
|
@ -212,13 +212,16 @@ class VerticalSeekBar @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
direction = if (mRotationAngle == ROTATION_ANGLE_CW_90) 1 else -1
|
||||
handled = true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_DPAD_UP -> {
|
||||
direction = if (mRotationAngle == ROTATION_ANGLE_CW_270) 1 else -1
|
||||
handled = true
|
||||
}
|
||||
|
||||
KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_RIGHT ->
|
||||
// move view focus to previous/next view
|
||||
return false
|
||||
|
||||
else -> handled = false
|
||||
}
|
||||
|
||||
@ -258,7 +261,7 @@ class VerticalSeekBar @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
)
|
||||
m.isAccessible = true
|
||||
mMethodSetProgressFromUser = m
|
||||
} catch (e: NoSuchMethodException) {
|
||||
} catch (_: NoSuchMethodException) {
|
||||
}
|
||||
|
||||
}
|
||||
@ -266,9 +269,9 @@ class VerticalSeekBar @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
if (mMethodSetProgressFromUser != null) {
|
||||
try {
|
||||
mMethodSetProgressFromUser!!.invoke(this, progress, fromUser)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
} catch (e: IllegalAccessException) {
|
||||
} catch (e: InvocationTargetException) {
|
||||
} catch (_: IllegalArgumentException) {
|
||||
} catch (_: IllegalAccessException) {
|
||||
} catch (_: InvocationTargetException) {
|
||||
}
|
||||
|
||||
} else {
|
||||
@ -310,6 +313,7 @@ class VerticalSeekBar @JvmOverloads constructor(context: Context, attrs: Attribu
|
||||
canvas.rotate(90f)
|
||||
canvas.translate(0f, (-super.getWidth()).toFloat())
|
||||
}
|
||||
|
||||
ROTATION_ANGLE_CW_270 -> {
|
||||
canvas.rotate(-90f)
|
||||
canvas.translate((-super.getHeight()).toFloat(), 0f)
|
||||
|
@ -5,9 +5,18 @@ package io.legado.app.utils
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.app.PendingIntent.*
|
||||
import android.app.PendingIntent.FLAG_MUTABLE
|
||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||
import android.app.PendingIntent.getActivity
|
||||
import android.app.PendingIntent.getBroadcast
|
||||
import android.app.PendingIntent.getService
|
||||
import android.app.Service
|
||||
import android.content.*
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ClipData
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.SharedPreferences
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.ColorStateList
|
||||
import android.content.res.Configuration
|
||||
@ -355,7 +364,6 @@ val Context.isPad: Boolean
|
||||
val Context.isTv: Boolean
|
||||
get() = uiModeManager.currentModeType == Configuration.UI_MODE_TYPE_TELEVISION
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
val Context.channel: String
|
||||
get() {
|
||||
try {
|
||||
|
@ -35,6 +35,7 @@ fun Menu.applyTint(context: Context, theme: Theme = Theme.Auto): Menu = this.let
|
||||
return menu
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
fun Menu.applyOpenTint(context: Context) {
|
||||
//展开菜单显示图标
|
||||
if (this.javaClass.simpleName.equals("MenuBuilder", ignoreCase = true)) {
|
||||
|
@ -9,6 +9,7 @@ import java.io.IOException
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.channels.SeekableByteChannel
|
||||
|
||||
@Suppress("unused")
|
||||
@SuppressLint("NewApi")
|
||||
class ParcelFileDescriptorChannel(private val pfd: ParcelFileDescriptor) : SeekableByteChannel {
|
||||
@Throws(IOException::class)
|
||||
|
Loading…
Reference in New Issue
Block a user