Merge branch 'gedoor:master' into master

pull/1222/head
HalfLife 3 years ago committed by GitHub
commit 814112060a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      app/src/main/assets/updateLog.md
  2. 10
      app/src/main/java/io/legado/app/data/AppDatabase.kt
  3. 2
      app/src/main/java/io/legado/app/data/entities/BookGroup.kt
  4. 55
      app/src/main/java/io/legado/app/ui/book/group/GroupEdit.kt
  5. 110
      app/src/main/java/io/legado/app/ui/book/group/GroupEditDialog.kt
  6. 26
      app/src/main/java/io/legado/app/ui/book/group/GroupManageDialog.kt
  7. 45
      app/src/main/java/io/legado/app/ui/book/group/GroupSelectDialog.kt
  8. 23
      app/src/main/java/io/legado/app/ui/book/group/GroupViewModel.kt
  9. 4
      app/src/main/java/io/legado/app/ui/main/bookshelf/style2/BookshelfFragment2.kt
  10. 5
      app/src/main/java/io/legado/app/ui/widget/image/CoverImageView.kt
  11. 89
      app/src/main/res/layout/dialog_book_group_edit.xml

@ -12,6 +12,10 @@
* 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源! * 漫画源看书显示乱码,**阅读与其他软件的源并不通用**,请导入阅读的支持的漫画源!
* 关于最近版本有时候界面没有数据的问题是因为把LiveData组件换成了谷歌推荐的Flow组件导致的问题,正在查找解决办法 * 关于最近版本有时候界面没有数据的问题是因为把LiveData组件换成了谷歌推荐的Flow组件导致的问题,正在查找解决办法
**2021/08/09**
1. 修复选择文字不能选择单个文字的bug
**2021/08/08** **2021/08/08**
1. 背景图片添加模糊设置 1. 背景图片添加模糊设置

@ -24,7 +24,7 @@ val appDb by lazy {
RssSource::class, Bookmark::class, RssArticle::class, RssReadRecord::class, RssSource::class, Bookmark::class, RssArticle::class, RssReadRecord::class,
RssStar::class, TxtTocRule::class, ReadRecord::class, HttpTTS::class, Cache::class, RssStar::class, TxtTocRule::class, ReadRecord::class, HttpTTS::class, Cache::class,
RuleSub::class], RuleSub::class],
version = 33, version = 34,
exportSchema = true exportSchema = true
) )
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
@ -60,7 +60,7 @@ abstract class AppDatabase : RoomDatabase() {
migration_19_20, migration_20_21, migration_21_22, migration_22_23, migration_19_20, migration_20_21, migration_21_22, migration_22_23,
migration_23_24, migration_24_25, migration_25_26, migration_26_27, migration_23_24, migration_24_25, migration_25_26, migration_26_27,
migration_27_28, migration_28_29, migration_29_30, migration_30_31, migration_27_28, migration_28_29, migration_29_30, migration_30_31,
migration_31_32, migration_32_33 migration_31_32, migration_32_33, migration_33_34
) )
.allowMainThreadQueries() .allowMainThreadQueries()
.addCallback(dbCallback) .addCallback(dbCallback)
@ -331,6 +331,12 @@ abstract class AppDatabase : RoomDatabase() {
) )
} }
} }
private val migration_33_34 = object : Migration(33, 34) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `book_groups` ADD `cover` TEXT")
}
}
} }
} }

@ -14,6 +14,7 @@ data class BookGroup(
@PrimaryKey @PrimaryKey
val groupId: Long = 0b1, val groupId: Long = 0b1,
var groupName: String, var groupName: String,
var cover: String? = null,
var order: Int = 0, var order: Int = 0,
var show: Boolean = true var show: Boolean = true
) : Parcelable { ) : Parcelable {
@ -36,6 +37,7 @@ data class BookGroup(
if (other is BookGroup) { if (other is BookGroup) {
return other.groupId == groupId return other.groupId == groupId
&& other.groupName == groupName && other.groupName == groupName
&& other.cover == cover
&& other.order == order && other.order == order
&& other.show == show && other.show == show
} }

@ -1,55 +0,0 @@
package io.legado.app.ui.book.group
import android.content.Context
import android.view.LayoutInflater
import io.legado.app.R
import io.legado.app.data.appDb
import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.lib.dialogs.alert
import io.legado.app.utils.requestInputMethod
object GroupEdit {
fun show(context: Context, layoutInflater: LayoutInflater, bookGroup: BookGroup) = context.run {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
editView.setText(bookGroup.groupName)
}
if (bookGroup.groupId >= 0) {
neutralButton(R.string.delete) {
deleteGroup(context, bookGroup)
}
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
bookGroup.groupName = it
Coroutine.async {
appDb.bookGroupDao.update(bookGroup)
}
}
}
noButton()
}.show().requestInputMethod()
}
private fun deleteGroup(context: Context, bookGroup: BookGroup) = context.run {
alert(R.string.delete, R.string.sure_del) {
okButton {
Coroutine.async {
appDb.bookGroupDao.delete(bookGroup)
val books = appDb.bookDao.getBooksByGroup(bookGroup.groupId)
books.forEach {
it.group = it.group - bookGroup.groupId
}
appDb.bookDao.update(*books.toTypedArray())
}
}
noButton()
}.show()
}
}

@ -0,0 +1,110 @@
package io.legado.app.ui.book.group
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import io.legado.app.R
import io.legado.app.base.BaseDialogFragment
import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogBookGroupEditBinding
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.primaryColor
import io.legado.app.utils.gone
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize
import splitties.views.onClick
class GroupEditDialog : BaseDialogFragment() {
companion object {
fun start(fragmentManager: FragmentManager, bookGroup: BookGroup? = null) {
GroupEditDialog().apply {
arguments = Bundle().apply {
putParcelable("group", bookGroup)
}
}.show(fragmentManager, "bookGroupEdit")
}
}
private val binding by viewBinding(DialogBookGroupEditBinding::bind)
private val viewModel by viewModels<GroupViewModel>()
private var bookGroup: BookGroup? = null
override fun onStart() {
super.onStart()
val dm = requireActivity().windowSize
dialog?.window?.setLayout(
(dm.widthPixels * 0.9).toInt(),
ViewGroup.LayoutParams.WRAP_CONTENT
)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.dialog_book_group_edit, container)
}
override fun onFragmentCreated(view: View, savedInstanceState: Bundle?) {
binding.toolBar.setBackgroundColor(primaryColor)
bookGroup = arguments?.getParcelable("group")
bookGroup?.let {
binding.tieGroupName.setText(it.groupName)
binding.ivCover.load(it.cover)
} ?: let {
binding.toolBar.title = getString(R.string.add_group)
binding.btnDelete.gone()
}
binding.run {
btnCancel.onClick {
dismiss()
}
btnOk.onClick {
val groupName = tieGroupName.text?.toString()
if (groupName.isNullOrEmpty()) {
toastOnUi("分组名称不能为空")
} else {
bookGroup?.let {
it.groupName = groupName
it.cover = binding.ivCover.path
viewModel.upGroup(it) {
dismiss()
}
} ?: let {
viewModel.addGroup(groupName, binding.ivCover.path) {
dismiss()
}
}
}
}
btnDelete.onClick {
deleteGroup {
bookGroup?.let {
viewModel.delGroup(it) {
dismiss()
}
}
}
}
}
}
private fun deleteGroup(ok: () -> Unit) {
alert(R.string.delete, R.string.sure_del) {
okButton {
ok.invoke()
}
noButton()
}.show()
}
}

@ -1,6 +1,5 @@
package io.legado.app.ui.book.group package io.legado.app.ui.book.group
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@ -18,17 +17,14 @@ import io.legado.app.base.adapter.ItemViewHolder
import io.legado.app.base.adapter.RecyclerAdapter import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.DialogRecyclerViewBinding import io.legado.app.databinding.DialogRecyclerViewBinding
import io.legado.app.databinding.ItemBookGroupManageBinding import io.legado.app.databinding.ItemBookGroupManageBinding
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.visible import io.legado.app.utils.visible
import io.legado.app.utils.windowSize import io.legado.app.utils.windowSize
@ -94,29 +90,11 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onMenuItemClick(item: MenuItem?): Boolean { override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) { when (item?.itemId) {
R.id.menu_add -> addGroup() R.id.menu_add -> GroupEditDialog.start(childFragmentManager)
} }
return true return true
} }
@SuppressLint("InflateParams")
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) {
viewModel.addGroup(it)
}
}
}
noButton()
}.show().requestInputMethod()
}
private inner class GroupAdapter(context: Context) : private inner class GroupAdapter(context: Context) :
RecyclerAdapter<BookGroup, ItemBookGroupManageBinding>(context), RecyclerAdapter<BookGroup, ItemBookGroupManageBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
@ -144,7 +122,7 @@ class GroupManageDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
binding.run { binding.run {
tvEdit.setOnClickListener { tvEdit.setOnClickListener {
getItem(holder.layoutPosition)?.let { bookGroup -> getItem(holder.layoutPosition)?.let { bookGroup ->
GroupEdit.show(context, layoutInflater, bookGroup) GroupEditDialog.start(childFragmentManager, bookGroup)
} }
} }
swShow.setOnCheckedChangeListener { buttonView, isChecked -> swShow.setOnCheckedChangeListener { buttonView, isChecked ->

@ -1,6 +1,5 @@
package io.legado.app.ui.book.group package io.legado.app.ui.book.group
import android.annotation.SuppressLint
import android.content.Context import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
@ -20,16 +19,13 @@ import io.legado.app.base.adapter.RecyclerAdapter
import io.legado.app.data.appDb import io.legado.app.data.appDb
import io.legado.app.data.entities.BookGroup import io.legado.app.data.entities.BookGroup
import io.legado.app.databinding.DialogBookGroupPickerBinding import io.legado.app.databinding.DialogBookGroupPickerBinding
import io.legado.app.databinding.DialogEditTextBinding
import io.legado.app.databinding.ItemGroupSelectBinding import io.legado.app.databinding.ItemGroupSelectBinding
import io.legado.app.lib.dialogs.alert
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.lib.theme.backgroundColor import io.legado.app.lib.theme.backgroundColor
import io.legado.app.lib.theme.primaryColor import io.legado.app.lib.theme.primaryColor
import io.legado.app.ui.widget.recycler.ItemTouchCallback import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.applyTint import io.legado.app.utils.applyTint
import io.legado.app.utils.requestInputMethod
import io.legado.app.utils.viewbindingdelegate.viewBinding import io.legado.app.utils.viewbindingdelegate.viewBinding
import io.legado.app.utils.windowSize import io.legado.app.utils.windowSize
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
@ -116,46 +112,11 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
override fun onMenuItemClick(item: MenuItem?): Boolean { override fun onMenuItemClick(item: MenuItem?): Boolean {
when (item?.itemId) { when (item?.itemId) {
R.id.menu_add -> addGroup() R.id.menu_add -> GroupEditDialog.start(childFragmentManager)
} }
return true return true
} }
@SuppressLint("InflateParams")
private fun addGroup() {
alert(title = getString(R.string.add_group)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
if (it.isNotBlank()) {
viewModel.addGroup(it)
}
}
}
noButton()
}.show().requestInputMethod()
}
@SuppressLint("InflateParams")
private fun editGroup(bookGroup: BookGroup) {
alert(title = getString(R.string.group_edit)) {
val alertBinding = DialogEditTextBinding.inflate(layoutInflater).apply {
textInputLayout.setHint(R.string.group_name)
editView.setText(bookGroup.groupName)
}
customView { alertBinding.root }
yesButton {
alertBinding.editView.text?.toString()?.let {
viewModel.upGroup(bookGroup.copy(groupName = it))
}
}
noButton()
}.show().requestInputMethod()
}
private inner class GroupAdapter(context: Context) : private inner class GroupAdapter(context: Context) :
RecyclerAdapter<BookGroup, ItemGroupSelectBinding>(context), RecyclerAdapter<BookGroup, ItemGroupSelectBinding>(context),
ItemTouchCallback.Callback { ItemTouchCallback.Callback {
@ -192,7 +153,9 @@ class GroupSelectDialog : BaseDialogFragment(), Toolbar.OnMenuItemClickListener
} }
} }
} }
tvEdit.setOnClickListener { getItem(holder.layoutPosition)?.let { editGroup(it) } } tvEdit.setOnClickListener {
GroupEditDialog.start(childFragmentManager, getItem(holder.layoutPosition))
}
} }
} }

@ -7,7 +7,15 @@ import io.legado.app.data.entities.BookGroup
class GroupViewModel(application: Application) : BaseViewModel(application) { class GroupViewModel(application: Application) : BaseViewModel(application) {
fun addGroup(groupName: String) { fun upGroup(vararg bookGroup: BookGroup, finally: (() -> Unit)? = null) {
execute {
appDb.bookGroupDao.update(*bookGroup)
}.onFinally {
finally?.invoke()
}
}
fun addGroup(groupName: String, cover: String?, finally: () -> Unit) {
execute { execute {
var id = 1L var id = 1L
val idsSum = appDb.bookGroupDao.idsSum val idsSum = appDb.bookGroupDao.idsSum
@ -17,19 +25,16 @@ class GroupViewModel(application: Application) : BaseViewModel(application) {
val bookGroup = BookGroup( val bookGroup = BookGroup(
groupId = id, groupId = id,
groupName = groupName, groupName = groupName,
cover = cover,
order = appDb.bookGroupDao.maxOrder.plus(1) order = appDb.bookGroupDao.maxOrder.plus(1)
) )
appDb.bookGroupDao.insert(bookGroup) appDb.bookGroupDao.insert(bookGroup)
}.onFinally {
finally()
} }
} }
fun upGroup(vararg bookGroup: BookGroup) { fun delGroup(vararg bookGroup: BookGroup, finally: () -> Unit) {
execute {
appDb.bookGroupDao.update(*bookGroup)
}
}
fun delGroup(vararg bookGroup: BookGroup) {
execute { execute {
appDb.bookGroupDao.delete(*bookGroup) appDb.bookGroupDao.delete(*bookGroup)
bookGroup.forEach { group -> bookGroup.forEach { group ->
@ -39,6 +44,8 @@ class GroupViewModel(application: Application) : BaseViewModel(application) {
} }
appDb.bookDao.update(*books.toTypedArray()) appDb.bookDao.update(*books.toTypedArray())
} }
}.onFinally {
finally()
} }
} }

@ -22,7 +22,7 @@ import io.legado.app.help.AppConfig
import io.legado.app.lib.theme.ATH import io.legado.app.lib.theme.ATH
import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.accentColor
import io.legado.app.ui.book.audio.AudioPlayActivity import io.legado.app.ui.book.audio.AudioPlayActivity
import io.legado.app.ui.book.group.GroupEdit import io.legado.app.ui.book.group.GroupEditDialog
import io.legado.app.ui.book.info.BookInfoActivity import io.legado.app.ui.book.info.BookInfoActivity
import io.legado.app.ui.book.read.ReadBookActivity import io.legado.app.ui.book.read.ReadBookActivity
import io.legado.app.ui.book.search.SearchActivity import io.legado.app.ui.book.search.SearchActivity
@ -190,7 +190,7 @@ class BookshelfFragment2 : BaseBookshelfFragment(R.layout.fragment_bookshelf1),
putExtra("name", item.name) putExtra("name", item.name)
putExtra("author", item.author) putExtra("author", item.author)
} }
is BookGroup -> GroupEdit.show(requireContext(), layoutInflater, item) is BookGroup -> GroupEditDialog.start(childFragmentManager, item)
} }
} }

@ -30,6 +30,8 @@ class CoverImageView @JvmOverloads constructor(
) { ) {
internal var width: Float = 0.toFloat() internal var width: Float = 0.toFloat()
internal var height: Float = 0.toFloat() internal var height: Float = 0.toFloat()
var path: String? = null
private set
private var nameHeight = 0f private var nameHeight = 0f
private var authorHeight = 0f private var authorHeight = 0f
private val namePaint by lazy { private val namePaint by lazy {
@ -131,7 +133,8 @@ class CoverImageView @JvmOverloads constructor(
} }
} }
fun load(path: String?, name: String?, author: String?) { fun load(path: String?, name: String? = null, author: String? = null) {
this.path = path
setText(name, author) setText(name, author)
if (AppConfig.useDefaultCover) { if (AppConfig.useDefaultCover) {
ImageLoader.load(context, defaultDrawable) ImageLoader.load(context, defaultDrawable)

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_menu">
<androidx.appcompat.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/background_menu"
android:elevation="5dp"
android:theme="?attr/actionBarStyle"
app:displayHomeAsUp="false"
app:fitStatusBar="false"
app:layout_constraintTop_toTopOf="parent"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/group_edit"
app:titleTextAppearance="@style/ToolbarTitle" />
<io.legado.app.ui.widget.image.CoverImageView
android:id="@+id/iv_cover"
android:layout_width="90dp"
android:layout_height="126dp"
android:layout_margin="6dp"
android:contentDescription="@string/img_cover"
android:scaleType="centerCrop"
android:src="@drawable/image_cover_default"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tool_bar" />
<io.legado.app.ui.widget.text.TextInputLayout
android:id="@+id/til_group_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:hint="@string/group_name"
app:layout_constraintLeft_toRightOf="@+id/iv_cover"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tool_bar"
app:layout_constraintBottom_toTopOf="@+id/btn_ok">
<io.legado.app.ui.widget.text.EditText
android:id="@+id/tie_group_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleLine="true"
tools:ignore="TouchTargetSizeCheck,SpeakableTextPresentCheck" />
</io.legado.app.ui.widget.text.TextInputLayout>
<io.legado.app.ui.widget.text.AccentTextView
android:id="@+id/btn_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:layout_marginLeft="12dp"
android:text="@string/delete"
app:layout_constraintBottom_toBottomOf="@id/btn_ok"
app:layout_constraintLeft_toRightOf="@+id/iv_cover"
app:layout_constraintTop_toTopOf="@+id/btn_ok"
tools:ignore="RtlHardcoded" />
<io.legado.app.ui.widget.text.AccentTextView
android:id="@+id/btn_ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:layout_marginRight="12dp"
android:text="@string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/til_group_name"
tools:ignore="RtlHardcoded" />
<io.legado.app.ui.widget.text.AccentTextView
android:id="@+id/btn_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:text="@string/cancel"
app:layout_constraintBottom_toBottomOf="@id/btn_ok"
app:layout_constraintRight_toLeftOf="@+id/btn_ok"
app:layout_constraintTop_toTopOf="@+id/btn_ok" />
</androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save