diff --git a/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt b/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt index d4c1eb14f..468e3bdf2 100644 --- a/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt +++ b/app/src/main/java/io/legado/app/api/controller/BookSourceController.kt @@ -5,6 +5,7 @@ import android.text.TextUtils import io.legado.app.api.ReturnData import io.legado.app.data.appDb import io.legado.app.data.entities.BookSource +import io.legado.app.help.config.SourceConfig import io.legado.app.utils.GSON import io.legado.app.utils.fromJsonArray @@ -70,6 +71,7 @@ object BookSourceController { GSON.fromJsonArray(postData).getOrThrow()?.let { it.forEach { source -> appDb.bookSourceDao.delete(source) + SourceConfig.removeSource(source.bookSourceUrl) } } }.onFailure { diff --git a/app/src/main/java/io/legado/app/help/config/SourceConfig.kt b/app/src/main/java/io/legado/app/help/config/SourceConfig.kt new file mode 100644 index 000000000..67368309c --- /dev/null +++ b/app/src/main/java/io/legado/app/help/config/SourceConfig.kt @@ -0,0 +1,45 @@ +package io.legado.app.help.config + +import android.content.Context.MODE_PRIVATE +import androidx.core.content.edit +import splitties.init.appCtx + +object SourceConfig { + private val sp = appCtx.getSharedPreferences("SourceConfig", MODE_PRIVATE) + fun setBookScore(origin: String, name: String, author: String, score: Int) { + sp.edit { + val preScore = getBookScore(origin, name, author) + var newScore = score + if (preScore != 0) { + newScore = score - preScore + } + + putInt(origin, getSourceScore(origin) + newScore) + + putInt("${origin}_${name}_${author}", score) + } + } + + fun getBookScore(origin: String, name: String, author: String): Int { + return sp.getInt("${origin}_${name}_${author}", 0) + } + + fun getSourceScore(origin: String): Int { + return sp.getInt(origin, 0) + } + + + fun removeSource(origin: String) { + sp.all.keys.filter { + it.startsWith(origin) + }.let { + sp.edit { + it.forEach { + remove(it) + } + } + } + } + + +} \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceAdapter.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceAdapter.kt index 00a3b9f30..0ccfe3e41 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceAdapter.kt @@ -1,16 +1,19 @@ package io.legado.app.ui.book.changesource import android.content.Context +import android.graphics.Color import android.os.Bundle import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.PopupMenu +import androidx.core.view.isVisible import androidx.recyclerview.widget.DiffUtil import io.legado.app.R import io.legado.app.base.adapter.DiffRecyclerAdapter import io.legado.app.base.adapter.ItemViewHolder import io.legado.app.data.entities.SearchBook import io.legado.app.databinding.ItemChangeSourceBinding +import io.legado.app.utils.gone import io.legado.app.utils.invisible import io.legado.app.utils.visible import splitties.views.onLongClick @@ -68,10 +71,55 @@ class ChangeBookSourceAdapter( } } } + val score = callBack.getBookScore(item) + if (score > 0) { + binding.ivBad.gone() + binding.ivGood.visible() + binding.ivGood.drawable.setTint(Color.parseColor("#D50000")) + } else if (score < 0) { + binding.ivGood.gone() + binding.ivBad.visible() + binding.ivBad.drawable.setTint(Color.parseColor("#2962FF")) + } else { + binding.ivGood.visible() + binding.ivBad.visible() + binding.ivGood.drawable.setTint(Color.parseColor("#FF8A80")) + binding.ivBad.drawable.setTint(Color.parseColor("#82B1FF")) + } } } override fun registerListener(holder: ItemViewHolder, binding: ItemChangeSourceBinding) { + binding.ivGood.setOnClickListener { + if (binding.ivBad.isVisible) { + binding.ivGood.drawable.setTint(Color.parseColor("#D50000")) + binding.ivBad.gone() + getItem(holder.layoutPosition)?.let { + callBack.setBookScore(it, 1) + } + } else { + binding.ivGood.drawable.setTint(Color.parseColor("#FF8A80")) + binding.ivBad.visible() + getItem(holder.layoutPosition)?.let { + callBack.setBookScore(it, 0) + } + } + } + binding.ivBad.setOnClickListener { + if (binding.ivGood.isVisible) { + binding.ivBad.drawable.setTint(Color.parseColor("#2962FF")) + binding.ivGood.gone() + getItem(holder.layoutPosition)?.let { + callBack.setBookScore(it, -1) + } + } else { + binding.ivBad.drawable.setTint(Color.parseColor("#82B1FF")) + binding.ivGood.visible() + getItem(holder.layoutPosition)?.let { + callBack.setBookScore(it, 0) + } + } + } holder.itemView.setOnClickListener { getItem(holder.layoutPosition)?.let { if (it.bookUrl != callBack.bookUrl) { @@ -120,5 +168,7 @@ class ChangeBookSourceAdapter( fun editSource(searchBook: SearchBook) fun disableSource(searchBook: SearchBook) fun deleteSource(searchBook: SearchBook) + fun setBookScore(searchBook: SearchBook, score: Int) + fun getBookScore(searchBook: SearchBook): Int } } \ No newline at end of file diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt index ee7410764..5602a9007 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceDialog.kt @@ -294,6 +294,14 @@ class ChangeBookSourceDialog() : BaseDialogFragment(R.layout.dialog_book_change_ } } + override fun setBookScore(searchBook: SearchBook, score: Int) { + viewModel.setBookScore(searchBook,score) + } + + override fun getBookScore(searchBook: SearchBook): Int { + return viewModel.getBookScore(searchBook) + } + private fun changeSource(searchBook: SearchBook, onSuccess: (() -> Unit)? = null) { waitDialog.setText(R.string.load_toc) waitDialog.show() diff --git a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt index bdd4c6922..a886df99e 100644 --- a/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/changesource/ChangeBookSourceViewModel.kt @@ -16,6 +16,7 @@ import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.SearchBook import io.legado.app.exception.NoStackTraceException import io.legado.app.help.config.AppConfig +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 @@ -82,7 +83,27 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a searchCallback = null } }.map { - searchBooks.sortedBy { it.originOrder } + searchBooks.sortedWith(object : Comparator { + override fun compare(o1: SearchBook, o2: SearchBook): Int { + val o1bs = SourceConfig.getBookScore(o1.origin, o1.name, o1.author) + val o2bs = SourceConfig.getBookScore(o2.origin, o2.name, o2.author) + if (o1bs - o2bs > 0) { + return -1 + } else if (o1bs - o2bs < 0) { + return 1 + } else { + val o1ss = SourceConfig.getSourceScore(o1.origin) + val o2ss = SourceConfig.getSourceScore(o2.origin) + if (o1ss - o2ss > 0) { + return -1 + } else if (o1ss - o2ss < 0) { + return 1 + } else { + return o1.originOrder - o2.originOrder + } + } + } + }) }.flowOn(IO) @Volatile @@ -351,6 +372,7 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a appDb.bookSourceDao.getBookSource(searchBook.origin)?.let { source -> appDb.bookSourceDao.delete(source) appDb.searchBookDao.delete(searchBook) + SourceConfig.removeSource(source.bookSourceUrl) } } searchBooks.remove(searchBook) @@ -379,6 +401,17 @@ open class ChangeBookSourceViewModel(application: Application) : BaseViewModel(a } } + fun setBookScore(searchBook: SearchBook, score: Int) { + execute { + SourceConfig.setBookScore(searchBook.origin, searchBook.name, searchBook.author, score) + searchCallback?.upAdapter() + } + } + + fun getBookScore(searchBook: SearchBook): Int { + return SourceConfig.getBookScore(searchBook.origin, searchBook.name, searchBook.author) + } + interface SourceCallback { fun searchSuccess(searchBook: SearchBook) diff --git a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt index d9fe5ca83..09ca680f4 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/edit/BookSourceEditViewModel.kt @@ -7,6 +7,7 @@ import io.legado.app.data.appDb import io.legado.app.data.entities.BookSource import io.legado.app.exception.NoStackTraceException import io.legado.app.help.RuleComplete +import io.legado.app.help.config.SourceConfig import io.legado.app.help.http.CookieStore import io.legado.app.help.http.newCallStrResponse import io.legado.app.help.http.okHttpClient @@ -40,6 +41,7 @@ class BookSourceEditViewModel(application: Application) : BaseViewModel(applicat oldSourceUrl?.let { if (oldSourceUrl != source.bookSourceUrl) { appDb.bookSourceDao.delete(it) + SourceConfig.removeSource(it) } } oldSourceUrl = source.bookSourceUrl diff --git a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt index 390dd5ec2..f90633923 100644 --- a/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/source/manage/BookSourceViewModel.kt @@ -5,6 +5,7 @@ import android.text.TextUtils import io.legado.app.base.BaseViewModel import io.legado.app.data.appDb import io.legado.app.data.entities.BookSource +import io.legado.app.help.config.SourceConfig import io.legado.app.utils.* import java.io.File import java.io.FileOutputStream @@ -38,7 +39,12 @@ class BookSourceViewModel(application: Application) : BaseViewModel(application) } fun del(vararg sources: BookSource) { - execute { appDb.bookSourceDao.delete(*sources) } + execute { + appDb.bookSourceDao.delete(*sources) + sources.forEach { + SourceConfig.removeSource(it.bookSourceUrl) + } + } } fun update(vararg bookSource: BookSource) { diff --git a/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt b/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt index 71a61d82c..41890da49 100644 --- a/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/main/explore/ExploreAdapter.kt @@ -15,6 +15,7 @@ import io.legado.app.data.entities.BookSource import io.legado.app.data.entities.rule.ExploreKind import io.legado.app.databinding.ItemFilletTextBinding import io.legado.app.databinding.ItemFindBookBinding +import io.legado.app.help.config.SourceConfig import io.legado.app.help.coroutine.Coroutine import io.legado.app.lib.theme.accentColor import io.legado.app.ui.login.SourceLoginActivity @@ -174,6 +175,7 @@ class ExploreAdapter(context: Context, val callBack: CallBack) : } R.id.menu_del -> Coroutine.async(callBack.scope) { appDb.bookSourceDao.delete(source) + SourceConfig.removeSource(source.bookSourceUrl) } } true diff --git a/app/src/main/res/drawable/ic_praise.xml b/app/src/main/res/drawable/ic_praise.xml new file mode 100644 index 000000000..a1ccb8566 --- /dev/null +++ b/app/src/main/res/drawable/ic_praise.xml @@ -0,0 +1,7 @@ + + + + + + diff --git a/app/src/main/res/layout/item_change_source.xml b/app/src/main/res/layout/item_change_source.xml index fa04abeda..1338fbae8 100644 --- a/app/src/main/res/layout/item_change_source.xml +++ b/app/src/main/res/layout/item_change_source.xml @@ -1,56 +1,87 @@ + + + + + app:layout_constraintRight_toLeftOf="@+id/tv_author" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintRight_toLeftOf="@+id/iv_checked" + app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintRight_toLeftOf="@+id/iv_checked" + app:layout_constraintTop_toBottomOf="@+id/tv_origin" /> + app:tint="@color/primaryText" + tools:visibility="visible" /> + \ No newline at end of file