This commit is contained in:
Horis 2024-01-23 14:48:38 +08:00
parent aa0cc6ec91
commit 7d552cc3eb
10 changed files with 135 additions and 87 deletions

View File

@ -1,6 +1,12 @@
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.Transaction
import androidx.room.Update
import io.legado.app.constant.AppPattern
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart
@ -92,8 +98,12 @@ interface BookSourceDao {
)
fun flowDisabled(): Flow<List<BookSourcePart>>
@Query("select * from book_sources where enabledExplore = 1 and trim(exploreUrl) <> '' order by customOrder asc")
fun flowExplore(): Flow<List<BookSource>>
@Query(
"""select bookSourceUrl, bookSourceName, bookSourceGroup, customOrder, enabled, enabledExplore,
trim(loginUrl) <> '' hasLoginUrl, lastUpdateTime, respondTime, weight, trim(exploreUrl) <> '' hasExploreUrl
from book_sources where enabledExplore = 1 and trim(exploreUrl) <> '' order by customOrder asc"""
)
fun flowExplore(): Flow<List<BookSourcePart>>
@Query(
"""select bookSourceUrl, bookSourceName, bookSourceGroup, customOrder, enabled, enabledExplore,
@ -126,17 +136,21 @@ interface BookSourceDao {
fun flowDisabledExplore(): Flow<List<BookSourcePart>>
@Query(
"""select * from book_sources
"""select bookSourceUrl, bookSourceName, bookSourceGroup, customOrder, enabled, enabledExplore,
trim(loginUrl) <> '' hasLoginUrl, lastUpdateTime, respondTime, weight, trim(exploreUrl) <> '' hasExploreUrl
from book_sources
where enabledExplore = 1
and trim(exploreUrl) <> ''
and (bookSourceGroup like '%' || :key || '%'
or bookSourceName like '%' || :key || '%')
order by customOrder asc"""
)
fun flowExplore(key: String): Flow<List<BookSource>>
fun flowExplore(key: String): Flow<List<BookSourcePart>>
@Query(
"""select * from book_sources
"""select bookSourceUrl, bookSourceName, bookSourceGroup, customOrder, enabled, enabledExplore,
trim(loginUrl) <> '' hasLoginUrl, lastUpdateTime, respondTime, weight, trim(exploreUrl) <> '' hasExploreUrl
from book_sources
where enabledExplore = 1
and trim(exploreUrl) <> ''
and (bookSourceGroup = :key
@ -145,7 +159,7 @@ interface BookSourceDao {
or bookSourceGroup like '%,' || :key || ',%')
order by customOrder asc"""
)
fun flowGroupExplore(key: String): Flow<List<BookSource>>
fun flowGroupExplore(key: String): Flow<List<BookSourcePart>>
@Query("select distinct bookSourceGroup from book_sources where trim(bookSourceGroup) <> ''")
fun flowGroupsUnProcessed(): Flow<List<String>>
@ -286,6 +300,10 @@ interface BookSourceDao {
}
}
fun upOrder(bookSource: BookSourcePart) {
upOrder(bookSource.bookSourceUrl, bookSource.customOrder)
}
@Query("update book_sources set bookSourceGroup = :bookSourceGroup where bookSourceUrl = :bookSourceUrl")
fun upGroup(bookSourceUrl: String, bookSourceGroup: String)

View File

@ -2,10 +2,20 @@ package io.legado.app.data.entities
import android.os.Parcelable
import android.text.TextUtils
import androidx.room.*
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Index
import androidx.room.PrimaryKey
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import io.legado.app.constant.AppPattern
import io.legado.app.constant.BookSourceType
import io.legado.app.data.entities.rule.*
import io.legado.app.data.entities.rule.BookInfoRule
import io.legado.app.data.entities.rule.ContentRule
import io.legado.app.data.entities.rule.ExploreRule
import io.legado.app.data.entities.rule.ReviewRule
import io.legado.app.data.entities.rule.SearchRule
import io.legado.app.data.entities.rule.TocRule
import io.legado.app.utils.GSON
import io.legado.app.utils.fromJsonObject
import io.legado.app.utils.splitNotBlank
@ -268,12 +278,10 @@ data class BookSource(
GSON.fromJsonObject<ContentRule>(json).getOrNull()
@TypeConverter
fun stringToReviewRule(json: String?) =
GSON.fromJsonObject<ReviewRule>(json).getOrNull()
fun stringToReviewRule(json: String?): ReviewRule? = null
@TypeConverter
fun reviewRuleToString(reviewRule: ReviewRule?): String =
GSON.toJson(reviewRule)
fun reviewRuleToString(reviewRule: ReviewRule?): String = "null"
}
}

View File

@ -1,6 +1,7 @@
package io.legado.app.help.source
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart
import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.utils.ACache
import io.legado.app.utils.GSON
@ -27,6 +28,14 @@ private fun BookSource.getExploreKindsKey(): String {
return MD5Utils.md5Encode(bookSourceUrl + exploreUrl)
}
private fun BookSourcePart.getExploreKindsKey(): String {
return getBookSource()!!.getExploreKindsKey()
}
suspend fun BookSourcePart.exploreKinds(): List<ExploreKind> {
return getBookSource()!!.exploreKinds()
}
suspend fun BookSource.exploreKinds(): List<ExploreKind> {
val exploreKindsKey = getExploreKindsKey()
exploreKindsMap[exploreKindsKey]?.let { return it }
@ -75,11 +84,11 @@ suspend fun BookSource.exploreKinds(): List<ExploreKind> {
}
}
suspend fun BookSource.clearExploreKindsCache() {
suspend fun BookSourcePart.clearExploreKindsCache() {
withContext(Dispatchers.IO) {
val exploreKindsKey = getExploreKindsKey()
aCache.remove(exploreKindsKey)
exploreKindsMap.remove(getExploreKindsKey())
exploreKindsMap.remove(exploreKindsKey)
}
}

View File

@ -49,6 +49,7 @@ class CronetInterceptor(private val cookieJar: CookieJar) : Interceptor {
}
@SuppressLint("ObsoleteSdkInt")
@Throws(IOException::class)
private fun proceedWithCronet(request: Request, call: Call, readTimeoutMillis: Int): Response? {
val callBack = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
NewCallBack(request, call, readTimeoutMillis)

View File

@ -14,13 +14,21 @@ import io.legado.app.utils.printOnDebug
import org.chromium.net.CronetEngine
import org.json.JSONObject
import splitties.init.appCtx
import java.io.*
import java.io.BufferedReader
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.InputStream
import java.io.InputStreamReader
import java.io.OutputStream
import java.math.BigInteger
import java.net.HttpURLConnection
import java.net.URL
import java.security.MessageDigest
import java.util.*
import java.util.Objects
@Suppress("ConstPropertyName")
@Keep
object CronetLoader : CronetEngine.Builder.LibraryLoader(), Cronet.LoaderInterface {
//https://storage.googleapis.com/chromium-cronet/android/92.0.4515.159/Release/cronet/libs/arm64-v8a/libcronet.92.0.4515.159.so

View File

@ -19,7 +19,6 @@ import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.rule.BookInfoRule
import io.legado.app.data.entities.rule.ContentRule
import io.legado.app.data.entities.rule.ExploreRule
import io.legado.app.data.entities.rule.ReviewRule
import io.legado.app.data.entities.rule.SearchRule
import io.legado.app.data.entities.rule.TocRule
import io.legado.app.databinding.ActivityBookSourceEditBinding
@ -70,7 +69,7 @@ class BookSourceEditActivity :
private val infoEntities: ArrayList<EditEntity> = ArrayList()
private val tocEntities: ArrayList<EditEntity> = ArrayList()
private val contentEntities: ArrayList<EditEntity> = ArrayList()
private val reviewEntities: ArrayList<EditEntity> = ArrayList()
// private val reviewEntities: ArrayList<EditEntity> = ArrayList()
private val qrCodeResult = registerForActivityResult(QrCodeResult()) {
it ?: return@registerForActivityResult
viewModel.importSource(it) { source ->
@ -221,14 +220,14 @@ class BookSourceEditActivity :
}
private fun setEditEntities(tabPosition: Int?) {
when (tabPosition) {
1 -> adapter.editEntities = searchEntities
2 -> adapter.editEntities = exploreEntities
3 -> adapter.editEntities = infoEntities
4 -> adapter.editEntities = tocEntities
5 -> adapter.editEntities = contentEntities
6 -> adapter.editEntities = reviewEntities
else -> adapter.editEntities = sourceEntities
adapter.editEntities = when (tabPosition) {
1 -> searchEntities
2 -> exploreEntities
3 -> infoEntities
4 -> tocEntities
5 -> contentEntities
// 6 -> reviewEntities
else -> sourceEntities
}
binding.recyclerView.scrollToPosition(0)
}
@ -342,20 +341,20 @@ class BookSourceEditActivity :
add(EditEntity("payAction", cr.payAction, R.string.rule_pay_action))
}
// 段评
val rr = bs.getReviewRule()
reviewEntities.clear()
reviewEntities.apply {
add(EditEntity("reviewUrl", rr.reviewUrl, R.string.rule_review_url))
add(EditEntity("avatarRule", rr.avatarRule, R.string.rule_avatar))
add(EditEntity("contentRule", rr.contentRule, R.string.rule_review_content))
add(EditEntity("postTimeRule", rr.postTimeRule, R.string.rule_post_time))
add(EditEntity("reviewQuoteUrl", rr.reviewQuoteUrl, R.string.rule_review_quote))
add(EditEntity("voteUpUrl", rr.voteUpUrl, R.string.review_vote_up))
add(EditEntity("voteDownUrl", rr.voteDownUrl, R.string.review_vote_down))
add(EditEntity("postReviewUrl", rr.postReviewUrl, R.string.post_review_url))
add(EditEntity("postQuoteUrl", rr.postQuoteUrl, R.string.post_quote_url))
add(EditEntity("deleteUrl", rr.deleteUrl, R.string.delete_review_url))
}
// val rr = bs.getReviewRule()
// reviewEntities.clear()
// reviewEntities.apply {
// add(EditEntity("reviewUrl", rr.reviewUrl, R.string.rule_review_url))
// add(EditEntity("avatarRule", rr.avatarRule, R.string.rule_avatar))
// add(EditEntity("contentRule", rr.contentRule, R.string.rule_review_content))
// add(EditEntity("postTimeRule", rr.postTimeRule, R.string.rule_post_time))
// add(EditEntity("reviewQuoteUrl", rr.reviewQuoteUrl, R.string.rule_review_quote))
// add(EditEntity("voteUpUrl", rr.voteUpUrl, R.string.review_vote_up))
// add(EditEntity("voteDownUrl", rr.voteDownUrl, R.string.review_vote_down))
// add(EditEntity("postReviewUrl", rr.postReviewUrl, R.string.post_review_url))
// add(EditEntity("postQuoteUrl", rr.postQuoteUrl, R.string.post_quote_url))
// add(EditEntity("deleteUrl", rr.deleteUrl, R.string.delete_review_url))
// }
binding.tabLayout.selectTab(binding.tabLayout.getTabAt(0))
setEditEntities(0)
}
@ -376,7 +375,7 @@ class BookSourceEditActivity :
val bookInfoRule = BookInfoRule()
val tocRule = TocRule()
val contentRule = ContentRule()
val reviewRule = ReviewRule()
// val reviewRule = ReviewRule()
sourceEntities.forEach {
when (it.key) {
"bookSourceUrl" -> source.bookSourceUrl = it.value ?: ""
@ -526,34 +525,34 @@ class BookSourceEditActivity :
"payAction" -> contentRule.payAction = it.value
}
}
reviewEntities.forEach {
when (it.key) {
"reviewUrl" -> reviewRule.reviewUrl = it.value
"avatarRule" -> reviewRule.avatarRule =
viewModel.ruleComplete(it.value, reviewRule.reviewUrl, 3)
"contentRule" -> reviewRule.contentRule =
viewModel.ruleComplete(it.value, reviewRule.reviewUrl)
"postTimeRule" -> reviewRule.postTimeRule =
viewModel.ruleComplete(it.value, reviewRule.reviewUrl)
"reviewQuoteUrl" -> reviewRule.reviewQuoteUrl =
viewModel.ruleComplete(it.value, reviewRule.reviewUrl, 2)
"voteUpUrl" -> reviewRule.voteUpUrl = it.value
"voteDownUrl" -> reviewRule.voteDownUrl = it.value
"postReviewUrl" -> reviewRule.postReviewUrl = it.value
"postQuoteUrl" -> reviewRule.postQuoteUrl = it.value
"deleteUrl" -> reviewRule.deleteUrl = it.value
}
}
// reviewEntities.forEach {
// when (it.key) {
// "reviewUrl" -> reviewRule.reviewUrl = it.value
// "avatarRule" -> reviewRule.avatarRule =
// viewModel.ruleComplete(it.value, reviewRule.reviewUrl, 3)
//
// "contentRule" -> reviewRule.contentRule =
// viewModel.ruleComplete(it.value, reviewRule.reviewUrl)
//
// "postTimeRule" -> reviewRule.postTimeRule =
// viewModel.ruleComplete(it.value, reviewRule.reviewUrl)
//
// "reviewQuoteUrl" -> reviewRule.reviewQuoteUrl =
// viewModel.ruleComplete(it.value, reviewRule.reviewUrl, 2)
//
// "voteUpUrl" -> reviewRule.voteUpUrl = it.value
// "voteDownUrl" -> reviewRule.voteDownUrl = it.value
// "postReviewUrl" -> reviewRule.postReviewUrl = it.value
// "postQuoteUrl" -> reviewRule.postQuoteUrl = it.value
// "deleteUrl" -> reviewRule.deleteUrl = it.value
// }
// }
source.ruleSearch = searchRule
source.ruleExplore = exploreRule
source.ruleBookInfo = bookInfoRule
source.ruleToc = tocRule
source.ruleContent = contentRule
source.ruleReview = reviewRule
// source.ruleReview = reviewRule
return source
}

View File

@ -10,7 +10,7 @@ import com.google.android.flexbox.FlexboxLayout
import io.legado.app.R
import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart
import io.legado.app.data.entities.rule.ExploreKind
import io.legado.app.databinding.ItemFilletTextBinding
import io.legado.app.databinding.ItemFindBookBinding
@ -20,12 +20,17 @@ import io.legado.app.help.source.exploreKinds
import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.login.SourceLoginActivity
import io.legado.app.ui.widget.dialog.TextDialog
import io.legado.app.utils.*
import io.legado.app.utils.activity
import io.legado.app.utils.dpToPx
import io.legado.app.utils.gone
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.startActivity
import io.legado.app.utils.visible
import kotlinx.coroutines.CoroutineScope
import splitties.views.onLongClick
class ExploreAdapter(context: Context, val callBack: CallBack) :
RecyclerAdapter<BookSource, ItemFindBookBinding>(context) {
RecyclerAdapter<BookSourcePart, ItemFindBookBinding>(context) {
private val recycler = arrayListOf<View>()
private var exIndex = -1
@ -38,7 +43,7 @@ class ExploreAdapter(context: Context, val callBack: CallBack) :
override fun convert(
holder: ItemViewHolder,
binding: ItemFindBookBinding,
item: BookSource,
item: BookSourcePart,
payloads: MutableList<Any>
) {
binding.run {
@ -159,7 +164,7 @@ class ExploreAdapter(context: Context, val callBack: CallBack) :
val source = getItem(position) ?: return true
val popupMenu = PopupMenu(context, view)
popupMenu.inflate(R.menu.explore_item)
popupMenu.menu.findItem(R.id.menu_login).isVisible = !source.loginUrl.isNullOrBlank()
popupMenu.menu.findItem(R.id.menu_login).isVisible = source.hasLoginUrl
popupMenu.setOnMenuItemClickListener {
when (it.itemId) {
R.id.menu_edit -> callBack.editSource(source.bookSourceUrl)
@ -187,8 +192,8 @@ class ExploreAdapter(context: Context, val callBack: CallBack) :
fun scrollTo(pos: Int)
fun openExplore(sourceUrl: String, title: String, exploreUrl: String?)
fun editSource(sourceUrl: String)
fun toTop(source: BookSource)
fun deleteSource(source: BookSource)
fun searchBook(bookSource: BookSource)
fun toTop(source: BookSourcePart)
fun deleteSource(source: BookSourcePart)
fun searchBook(bookSource: BookSourcePart)
}
}

View File

@ -1,16 +1,16 @@
package io.legado.app.ui.main.explore
import androidx.recyclerview.widget.DiffUtil
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart
class ExploreDiffItemCallBack : DiffUtil.ItemCallback<BookSource>() {
class ExploreDiffItemCallBack : DiffUtil.ItemCallback<BookSourcePart>() {
override fun areItemsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
return true
override fun areItemsTheSame(oldItem: BookSourcePart, newItem: BookSourcePart): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: BookSource, newItem: BookSource): Boolean {
override fun areContentsTheSame(oldItem: BookSourcePart, newItem: BookSourcePart): Boolean {
return oldItem.bookSourceName == newItem.bookSourceName
}

View File

@ -15,7 +15,7 @@ import io.legado.app.R
import io.legado.app.base.VMBaseFragment
import io.legado.app.constant.AppLog
import io.legado.app.data.appDb
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart
import io.legado.app.databinding.FragmentExploreBinding
import io.legado.app.help.config.AppConfig
import io.legado.app.lib.dialogs.alert
@ -201,11 +201,11 @@ class ExploreFragment() : VMBaseFragment<ExploreViewModel>(R.layout.fragment_exp
}
}
override fun toTop(source: BookSource) {
override fun toTop(source: BookSourcePart) {
viewModel.topSource(source)
}
override fun deleteSource(source: BookSource) {
override fun deleteSource(source: BookSourcePart) {
alert(R.string.draw) {
setMessage(getString(R.string.sure_del) + "\n" + source.bookSourceName)
noButton()
@ -215,7 +215,7 @@ class ExploreFragment() : VMBaseFragment<ExploreViewModel>(R.layout.fragment_exp
}
}
override fun searchBook(bookSource: BookSource) {
override fun searchBook(bookSource: BookSourcePart) {
startActivity<SearchActivity> {
putExtra("searchScope", SearchScope(bookSource).toString())
}

View File

@ -3,22 +3,22 @@ package io.legado.app.ui.main.explore
import android.app.Application
import io.legado.app.base.BaseViewModel
import io.legado.app.data.appDb
import io.legado.app.data.entities.BookSource
import io.legado.app.data.entities.BookSourcePart
import io.legado.app.help.config.SourceConfig
class ExploreViewModel(application: Application) : BaseViewModel(application) {
fun topSource(bookSource: BookSource) {
fun topSource(bookSource: BookSourcePart) {
execute {
val minXh = appDb.bookSourceDao.minOrder
bookSource.customOrder = minXh - 1
appDb.bookSourceDao.insert(bookSource)
appDb.bookSourceDao.upOrder(bookSource)
}
}
fun deleteSource(source: BookSource) {
fun deleteSource(source: BookSourcePart) {
execute {
appDb.bookSourceDao.delete(source)
appDb.bookSourceDao.delete(source.bookSourceUrl)
SourceConfig.removeSource(source.bookSourceUrl)
}
}