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