Refactor alert dialogs
This commit is contained in:
@@ -9,7 +9,6 @@ import androidx.activity.viewModels
|
|||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
import org.koitharu.kotatsu.core.exceptions.resolve.SnackbarErrorObserver
|
||||||
@@ -18,8 +17,8 @@ import org.koitharu.kotatsu.core.model.parcelable.ParcelableManga
|
|||||||
import org.koitharu.kotatsu.core.parser.MangaIntent
|
import org.koitharu.kotatsu.core.parser.MangaIntent
|
||||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||||
import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED
|
|
||||||
import org.koitharu.kotatsu.core.util.ext.observe
|
import org.koitharu.kotatsu.core.util.ext.observe
|
||||||
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
import org.koitharu.kotatsu.core.util.ext.observeEvent
|
||||||
import org.koitharu.kotatsu.databinding.ActivityAlternativesBinding
|
import org.koitharu.kotatsu.databinding.ActivityAlternativesBinding
|
||||||
@@ -89,22 +88,23 @@ class AlternativesActivity : BaseActivity<ActivityAlternativesBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun confirmMigration(target: Manga) {
|
private fun confirmMigration(target: Manga) {
|
||||||
MaterialAlertDialogBuilder(this, DIALOG_THEME_CENTERED)
|
buildAlertDialog(this, isCentered = true) {
|
||||||
.setIcon(R.drawable.ic_replace)
|
setIcon(R.drawable.ic_replace)
|
||||||
.setTitle(R.string.manga_migration)
|
setTitle(R.string.manga_migration)
|
||||||
.setMessage(
|
setMessage(
|
||||||
getString(
|
getString(
|
||||||
R.string.migrate_confirmation,
|
R.string.migrate_confirmation,
|
||||||
viewModel.manga.title,
|
viewModel.manga.title,
|
||||||
viewModel.manga.source.getTitle(this),
|
viewModel.manga.source.getTitle(context),
|
||||||
target.title,
|
target.title,
|
||||||
target.source.getTitle(this),
|
target.source.getTitle(context),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.migrate) { _, _ ->
|
setPositiveButton(R.string.migrate) { _, _ ->
|
||||||
viewModel.migrate(target)
|
viewModel.migrate(target)
|
||||||
}.show()
|
}
|
||||||
|
}.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package org.koitharu.kotatsu.core.ui.dialog
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.widget.CompoundButton.OnCheckedChangeListener
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.appcompat.app.AlertDialog
|
||||||
|
import androidx.core.view.updatePadding
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.AdapterDelegate
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.AdapterDelegatesManager
|
||||||
|
import com.hannesdorfmann.adapterdelegates4.ListDelegationAdapter
|
||||||
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.databinding.DialogCheckboxBinding
|
||||||
|
import com.google.android.material.R as materialR
|
||||||
|
|
||||||
|
inline fun buildAlertDialog(
|
||||||
|
context: Context,
|
||||||
|
isCentered: Boolean = false,
|
||||||
|
block: MaterialAlertDialogBuilder.() -> Unit,
|
||||||
|
): AlertDialog = MaterialAlertDialogBuilder(
|
||||||
|
context,
|
||||||
|
if (isCentered) materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered else 0,
|
||||||
|
).apply(block).create()
|
||||||
|
|
||||||
|
fun <B : AlertDialog.Builder> B.setCheckbox(
|
||||||
|
@StringRes textResId: Int,
|
||||||
|
isChecked: Boolean,
|
||||||
|
onCheckedChangeListener: OnCheckedChangeListener
|
||||||
|
) = apply {
|
||||||
|
val binding = DialogCheckboxBinding.inflate(LayoutInflater.from(context))
|
||||||
|
binding.checkbox.setText(textResId)
|
||||||
|
binding.checkbox.isChecked = isChecked
|
||||||
|
binding.checkbox.setOnCheckedChangeListener(onCheckedChangeListener)
|
||||||
|
setView(binding.root)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <B : AlertDialog.Builder, T> B.setRecyclerViewList(
|
||||||
|
list: List<T>,
|
||||||
|
delegate: AdapterDelegate<List<T>>,
|
||||||
|
) = apply {
|
||||||
|
val delegatesManager = AdapterDelegatesManager<List<T>>()
|
||||||
|
delegatesManager.addDelegate(delegate)
|
||||||
|
setRecyclerViewList(ListDelegationAdapter(delegatesManager).also { it.items = list })
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <B : AlertDialog.Builder, T> B.setRecyclerViewList(
|
||||||
|
list: List<T>,
|
||||||
|
vararg delegates: AdapterDelegate<List<T>>,
|
||||||
|
) = apply {
|
||||||
|
val delegatesManager = AdapterDelegatesManager<List<T>>()
|
||||||
|
delegates.forEach { delegatesManager.addDelegate(it) }
|
||||||
|
setRecyclerViewList(ListDelegationAdapter(delegatesManager).also { it.items = list })
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <B : AlertDialog.Builder> B.setRecyclerViewList(adapter: RecyclerView.Adapter<*>) = apply {
|
||||||
|
val recyclerView = RecyclerView(context)
|
||||||
|
recyclerView.layoutManager = LinearLayoutManager(context)
|
||||||
|
recyclerView.updatePadding(
|
||||||
|
top = context.resources.getDimensionPixelOffset(R.dimen.list_spacing),
|
||||||
|
)
|
||||||
|
recyclerView.clipToPadding = false
|
||||||
|
recyclerView.adapter = adapter
|
||||||
|
setView(recyclerView)
|
||||||
|
}
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.core.ui.dialog
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.DialogInterface
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import org.koitharu.kotatsu.databinding.DialogCheckboxBinding
|
|
||||||
|
|
||||||
class CheckBoxAlertDialog private constructor(private val delegate: AlertDialog) :
|
|
||||||
DialogInterface by delegate {
|
|
||||||
|
|
||||||
fun show() = delegate.show()
|
|
||||||
|
|
||||||
class Builder(context: Context) {
|
|
||||||
|
|
||||||
private val binding = DialogCheckboxBinding.inflate(LayoutInflater.from(context))
|
|
||||||
|
|
||||||
private val delegate = MaterialAlertDialogBuilder(context)
|
|
||||||
.setView(binding.root)
|
|
||||||
|
|
||||||
fun setTitle(@StringRes titleResId: Int): Builder {
|
|
||||||
delegate.setTitle(titleResId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTitle(title: CharSequence): Builder {
|
|
||||||
delegate.setTitle(title)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setMessage(@StringRes messageId: Int): Builder {
|
|
||||||
delegate.setMessage(messageId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setMessage(message: CharSequence): Builder {
|
|
||||||
delegate.setMessage(message)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setCheckBoxText(@StringRes textId: Int): Builder {
|
|
||||||
binding.checkbox.setText(textId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setCheckBoxChecked(isChecked: Boolean): Builder {
|
|
||||||
binding.checkbox.isChecked = isChecked
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIcon(@DrawableRes iconId: Int): Builder {
|
|
||||||
delegate.setIcon(iconId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setPositiveButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: (DialogInterface, Boolean) -> Unit
|
|
||||||
): Builder {
|
|
||||||
delegate.setPositiveButton(textId) { dialog, _ ->
|
|
||||||
listener(dialog, binding.checkbox.isChecked)
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNegativeButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: DialogInterface.OnClickListener? = null
|
|
||||||
): Builder {
|
|
||||||
delegate.setNegativeButton(textId, listener)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun create() = CheckBoxAlertDialog(delegate.create())
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.core.ui.dialog
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.DialogInterface
|
|
||||||
import androidx.annotation.DrawableRes
|
|
||||||
import androidx.annotation.StringRes
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
|
||||||
import androidx.core.view.updatePadding
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import com.hannesdorfmann.adapterdelegates4.AdapterDelegate
|
|
||||||
import com.hannesdorfmann.adapterdelegates4.AdapterDelegatesManager
|
|
||||||
import com.hannesdorfmann.adapterdelegates4.ListDelegationAdapter
|
|
||||||
import org.koitharu.kotatsu.R
|
|
||||||
|
|
||||||
class RecyclerViewAlertDialog private constructor(
|
|
||||||
private val delegate: AlertDialog
|
|
||||||
) : DialogInterface by delegate {
|
|
||||||
|
|
||||||
fun show() = delegate.show()
|
|
||||||
|
|
||||||
class Builder<T>(context: Context) {
|
|
||||||
|
|
||||||
private val recyclerView = RecyclerView(context)
|
|
||||||
private val delegatesManager = AdapterDelegatesManager<List<T>>()
|
|
||||||
private var items: List<T>? = null
|
|
||||||
|
|
||||||
private val delegate = MaterialAlertDialogBuilder(context)
|
|
||||||
.setView(recyclerView)
|
|
||||||
|
|
||||||
init {
|
|
||||||
recyclerView.layoutManager = LinearLayoutManager(context)
|
|
||||||
recyclerView.updatePadding(
|
|
||||||
top = context.resources.getDimensionPixelOffset(R.dimen.list_spacing),
|
|
||||||
)
|
|
||||||
recyclerView.clipToPadding = false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTitle(@StringRes titleResId: Int): Builder<T> {
|
|
||||||
delegate.setTitle(titleResId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setTitle(title: CharSequence): Builder<T> {
|
|
||||||
delegate.setTitle(title)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setIcon(@DrawableRes iconId: Int): Builder<T> {
|
|
||||||
delegate.setIcon(iconId)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setPositiveButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: DialogInterface.OnClickListener,
|
|
||||||
): Builder<T> {
|
|
||||||
delegate.setPositiveButton(textId, listener)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNegativeButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: DialogInterface.OnClickListener? = null
|
|
||||||
): Builder<T> {
|
|
||||||
delegate.setNegativeButton(textId, listener)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setNeutralButton(
|
|
||||||
@StringRes textId: Int,
|
|
||||||
listener: DialogInterface.OnClickListener,
|
|
||||||
): Builder<T> {
|
|
||||||
delegate.setNeutralButton(textId, listener)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setCancelable(isCancelable: Boolean): Builder<T> {
|
|
||||||
delegate.setCancelable(isCancelable)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addAdapterDelegate(subject: AdapterDelegate<List<T>>): Builder<T> {
|
|
||||||
delegatesManager.addDelegate(subject)
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setItems(list: List<T>): Builder<T> {
|
|
||||||
items = list
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
fun create(): RecyclerViewAlertDialog {
|
|
||||||
recyclerView.adapter = ListDelegationAdapter(delegatesManager).also {
|
|
||||||
it.items = items
|
|
||||||
}
|
|
||||||
return RecyclerViewAlertDialog(delegate.create())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package org.koitharu.kotatsu.core.ui.dialog
|
||||||
|
|
||||||
|
import android.widget.CompoundButton
|
||||||
|
import android.widget.CompoundButton.OnCheckedChangeListener
|
||||||
|
|
||||||
|
class RememberCheckListener(
|
||||||
|
initialValue: Boolean,
|
||||||
|
) : OnCheckedChangeListener {
|
||||||
|
|
||||||
|
var isChecked: Boolean = initialValue
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun onCheckedChanged(buttonView: CompoundButton?, isChecked: Boolean) {
|
||||||
|
this.isChecked = isChecked
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,11 +8,9 @@ import androidx.annotation.AttrRes
|
|||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.FloatRange
|
import androidx.annotation.FloatRange
|
||||||
import androidx.annotation.Px
|
import androidx.annotation.Px
|
||||||
import androidx.annotation.StyleRes
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.res.use
|
import androidx.core.content.res.use
|
||||||
import androidx.core.graphics.ColorUtils
|
import androidx.core.graphics.ColorUtils
|
||||||
import com.google.android.material.R as materialR
|
|
||||||
|
|
||||||
fun Context.getThemeDrawable(
|
fun Context.getThemeDrawable(
|
||||||
@AttrRes resId: Int,
|
@AttrRes resId: Int,
|
||||||
@@ -77,7 +75,3 @@ fun TypedArray.getDrawableCompat(context: Context, index: Int): Drawable? {
|
|||||||
val resId = getResourceId(index, 0)
|
val resId = getResourceId(index, 0)
|
||||||
return if (resId != 0) ContextCompat.getDrawable(context, resId) else null
|
return if (resId != 0) ContextCompat.getDrawable(context, resId) else null
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:StyleRes
|
|
||||||
val DIALOG_THEME_CENTERED: Int
|
|
||||||
inline get() = materialR.style.ThemeOverlay_Material3_MaterialAlertDialog_Centered
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import android.content.DialogInterface
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.model.ids
|
import org.koitharu.kotatsu.core.model.ids
|
||||||
import org.koitharu.kotatsu.core.ui.dialog.RecyclerViewAlertDialog
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.setRecyclerViewList
|
||||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||||
import org.koitharu.kotatsu.download.ui.dialog.DownloadOption
|
import org.koitharu.kotatsu.download.ui.dialog.DownloadOption
|
||||||
import org.koitharu.kotatsu.download.ui.dialog.downloadOptionAD
|
import org.koitharu.kotatsu.download.ui.dialog.downloadOptionAD
|
||||||
@@ -53,16 +54,14 @@ class DownloadDialogHelper(
|
|||||||
callback.onItemClick(item, host)
|
callback.onItemClick(item, host)
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}
|
}
|
||||||
dialog = RecyclerViewAlertDialog.Builder<DownloadOption>(host.context)
|
dialog = buildAlertDialog(host.context) {
|
||||||
.addAdapterDelegate(downloadOptionAD(listener))
|
setCancelable(true)
|
||||||
.setCancelable(true)
|
setTitle(R.string.download)
|
||||||
.setTitle(R.string.download)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setNegativeButton(android.R.string.cancel)
|
setNeutralButton(R.string.settings) { _, _ ->
|
||||||
.setNeutralButton(R.string.settings) { _, _ ->
|
|
||||||
host.context.startActivity(SettingsActivity.newDownloadsSettingsIntent(host.context))
|
host.context.startActivity(SettingsActivity.newDownloadsSettingsIntent(host.context))
|
||||||
}
|
}
|
||||||
.setItems(options)
|
setRecyclerViewList(options, downloadOptionAD(listener))
|
||||||
.create()
|
}.also { it.show() }
|
||||||
.also { it.show() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
import org.koitharu.kotatsu.settings.SettingsActivity
|
import org.koitharu.kotatsu.settings.SettingsActivity
|
||||||
|
|
||||||
class DownloadsMenuProvider(
|
class DownloadsMenuProvider(
|
||||||
@@ -42,24 +41,22 @@ class DownloadsMenuProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun confirmCancelAll() {
|
private fun confirmCancelAll() {
|
||||||
MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED)
|
buildAlertDialog(context, isCentered = true) {
|
||||||
.setTitle(R.string.cancel_all)
|
setTitle(R.string.cancel_all)
|
||||||
.setMessage(R.string.cancel_all_downloads_confirm)
|
setMessage(R.string.cancel_all_downloads_confirm)
|
||||||
.setIcon(R.drawable.ic_cancel_multiple)
|
setIcon(R.drawable.ic_cancel_multiple)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.confirm) { _, _ ->
|
setPositiveButton(R.string.confirm) { _, _ -> viewModel.cancelAll() }
|
||||||
viewModel.cancelAll()
|
}.show()
|
||||||
}.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun confirmRemoveCompleted() {
|
private fun confirmRemoveCompleted() {
|
||||||
MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED)
|
buildAlertDialog(context, isCentered = true) {
|
||||||
.setTitle(R.string.remove_completed)
|
setTitle(R.string.remove_completed)
|
||||||
.setMessage(R.string.remove_completed_downloads_confirm)
|
setMessage(R.string.remove_completed_downloads_confirm)
|
||||||
.setIcon(R.drawable.ic_clear_all)
|
setIcon(R.drawable.ic_clear_all)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.clear) { _, _ ->
|
setPositiveButton(R.string.clear) { _, _ -> viewModel.removeCompleted() }
|
||||||
viewModel.removeCompleted()
|
}.show()
|
||||||
}.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import android.view.Menu
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
import org.koitharu.kotatsu.core.ui.list.ListSelectionController
|
||||||
import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED
|
|
||||||
|
|
||||||
class CategoriesSelectionCallback(
|
class CategoriesSelectionCallback(
|
||||||
private val recyclerView: RecyclerView,
|
private val recyclerView: RecyclerView,
|
||||||
@@ -74,15 +73,15 @@ class CategoriesSelectionCallback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun confirmDeleteCategories(ids: Set<Long>, mode: ActionMode) {
|
private fun confirmDeleteCategories(ids: Set<Long>, mode: ActionMode) {
|
||||||
val context = recyclerView.context
|
buildAlertDialog(recyclerView.context, isCentered = true) {
|
||||||
MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED)
|
setMessage(R.string.categories_delete_confirm)
|
||||||
.setMessage(R.string.categories_delete_confirm)
|
setTitle(R.string.remove_category)
|
||||||
.setTitle(R.string.remove_category)
|
setIcon(R.drawable.ic_delete)
|
||||||
.setIcon(R.drawable.ic_delete)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setPositiveButton(R.string.remove) { _, _ ->
|
||||||
.setPositiveButton(R.string.remove) { _, _ ->
|
|
||||||
viewModel.deleteCategories(ids)
|
viewModel.deleteCategories(ids)
|
||||||
mode.finish()
|
mode.finish()
|
||||||
}.show()
|
}
|
||||||
|
}.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity
|
import org.koitharu.kotatsu.favourites.ui.categories.edit.FavouritesCategoryEditActivity
|
||||||
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.NO_ID
|
import org.koitharu.kotatsu.favourites.ui.list.FavouritesListFragment.Companion.NO_ID
|
||||||
|
|
||||||
@@ -41,13 +40,12 @@ class FavouriteTabPopupMenuProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun confirmDelete() {
|
private fun confirmDelete() {
|
||||||
MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED)
|
buildAlertDialog(context, isCentered = true) {
|
||||||
.setMessage(R.string.categories_delete_confirm)
|
setMessage(R.string.categories_delete_confirm)
|
||||||
.setTitle(R.string.remove_category)
|
setTitle(R.string.remove_category)
|
||||||
.setIcon(R.drawable.ic_delete)
|
setIcon(R.drawable.ic_delete)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.remove) { _, _ ->
|
setPositiveButton(R.string.remove) { _, _ -> viewModel.deleteCategory(categoryId) }
|
||||||
viewModel.deleteCategory(categoryId)
|
}.show()
|
||||||
}.show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,14 @@ import android.view.Menu
|
|||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.ui.dialog.RememberSelectionDialogListener
|
import org.koitharu.kotatsu.core.ui.dialog.RememberSelectionDialogListener
|
||||||
import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
import org.koitharu.kotatsu.stats.ui.StatsActivity
|
import org.koitharu.kotatsu.stats.ui.StatsActivity
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
import java.time.temporal.ChronoUnit
|
import java.time.temporal.ChronoUnit
|
||||||
import com.google.android.material.R as materialR
|
|
||||||
|
|
||||||
class HistoryListMenuProvider(
|
class HistoryListMenuProvider(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
@@ -49,9 +47,9 @@ class HistoryListMenuProvider(
|
|||||||
|
|
||||||
private fun showClearHistoryDialog() {
|
private fun showClearHistoryDialog() {
|
||||||
val selectionListener = RememberSelectionDialogListener(2)
|
val selectionListener = RememberSelectionDialogListener(2)
|
||||||
MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED)
|
buildAlertDialog(context, isCentered = true) {
|
||||||
.setTitle(R.string.clear_history)
|
setTitle(R.string.clear_history)
|
||||||
.setSingleChoiceItems(
|
setSingleChoiceItems(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
context.getString(R.string.last_2_hours),
|
context.getString(R.string.last_2_hours),
|
||||||
context.getString(R.string.today),
|
context.getString(R.string.today),
|
||||||
@@ -60,9 +58,9 @@ class HistoryListMenuProvider(
|
|||||||
selectionListener.selection,
|
selectionListener.selection,
|
||||||
selectionListener,
|
selectionListener,
|
||||||
)
|
)
|
||||||
.setIcon(R.drawable.ic_delete)
|
setIcon(R.drawable.ic_delete_all)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.clear) { _, _ ->
|
setPositiveButton(R.string.clear) { _, _ ->
|
||||||
val minDate = when (selectionListener.selection) {
|
val minDate = when (selectionListener.selection) {
|
||||||
0 -> Instant.now().minus(2, ChronoUnit.HOURS)
|
0 -> Instant.now().minus(2, ChronoUnit.HOURS)
|
||||||
1 -> LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()
|
1 -> LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant()
|
||||||
@@ -70,6 +68,7 @@ class HistoryListMenuProvider(
|
|||||||
else -> return@setPositiveButton
|
else -> return@setPositiveButton
|
||||||
}
|
}
|
||||||
viewModel.clearHistory(minDate)
|
viewModel.clearHistory(minDate)
|
||||||
}.show()
|
}
|
||||||
|
}.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,10 @@ import android.view.MenuInflater
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
import org.koitharu.kotatsu.core.util.ext.resolve
|
import org.koitharu.kotatsu.core.util.ext.resolve
|
||||||
import org.koitharu.kotatsu.core.util.ext.tryLaunch
|
import org.koitharu.kotatsu.core.util.ext.tryLaunch
|
||||||
import com.google.android.material.R as materialR
|
|
||||||
|
|
||||||
class SearchSuggestionMenuProvider(
|
class SearchSuggestionMenuProvider(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
@@ -44,13 +42,13 @@ class SearchSuggestionMenuProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun clearSearchHistory() {
|
private fun clearSearchHistory() {
|
||||||
MaterialAlertDialogBuilder(context, DIALOG_THEME_CENTERED)
|
buildAlertDialog(context, isCentered = true) {
|
||||||
.setTitle(R.string.clear_search_history)
|
setTitle(R.string.clear_search_history)
|
||||||
.setIcon(R.drawable.ic_clear_all)
|
setIcon(R.drawable.ic_clear_all)
|
||||||
.setMessage(R.string.text_clear_search_history_prompt)
|
setCancelable(true)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setMessage(R.string.text_clear_search_history_prompt)
|
||||||
.setPositiveButton(R.string.clear) { _, _ ->
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
viewModel.clearSearchHistory()
|
setPositiveButton(R.string.clear) { _, _ -> viewModel.clearSearchHistory() }
|
||||||
}.show()
|
}.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import org.koitharu.kotatsu.R
|
|||||||
import org.koitharu.kotatsu.core.prefs.NavItem
|
import org.koitharu.kotatsu.core.prefs.NavItem
|
||||||
import org.koitharu.kotatsu.core.ui.BaseFragment
|
import org.koitharu.kotatsu.core.ui.BaseFragment
|
||||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||||
import org.koitharu.kotatsu.core.ui.dialog.RecyclerViewAlertDialog
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.setRecyclerViewList
|
||||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||||
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
|
import org.koitharu.kotatsu.core.ui.util.RecyclerViewOwner
|
||||||
import org.koitharu.kotatsu.core.util.ext.observe
|
import org.koitharu.kotatsu.core.util.ext.observe
|
||||||
@@ -85,14 +86,12 @@ class NavConfigFragment : BaseFragment<FragmentSettingsSourcesBinding>(), Recycl
|
|||||||
viewModel.addItem(item)
|
viewModel.addItem(item)
|
||||||
dialog?.dismiss()
|
dialog?.dismiss()
|
||||||
}
|
}
|
||||||
dialog = RecyclerViewAlertDialog.Builder<NavItem>(v.context)
|
dialog = buildAlertDialog(v.context) {
|
||||||
.setTitle(R.string.add)
|
setTitle(R.string.add)
|
||||||
.addAdapterDelegate(navAvailableAD(listener))
|
setCancelable(true)
|
||||||
.setCancelable(true)
|
setRecyclerViewList(viewModel.availableItems, navAvailableAD(listener))
|
||||||
.setItems(viewModel.availableItems)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
}.apply { show() }
|
||||||
.create()
|
|
||||||
.apply { show() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onItemClick(item: NavItem, view: View) {
|
override fun onItemClick(item: NavItem, view: View) {
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package org.koitharu.kotatsu.stats.ui
|
package org.koitharu.kotatsu.stats.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Gravity
|
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewStub
|
import android.view.ViewStub
|
||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
@@ -17,16 +15,15 @@ import androidx.recyclerview.widget.AsyncListDiffer
|
|||||||
import coil.ImageLoader
|
import coil.ImageLoader
|
||||||
import com.google.android.material.chip.Chip
|
import com.google.android.material.chip.Chip
|
||||||
import com.google.android.material.chip.ChipDrawable
|
import com.google.android.material.chip.ChipDrawable
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
import org.koitharu.kotatsu.core.model.FavouriteCategory
|
||||||
import org.koitharu.kotatsu.core.ui.BaseActivity
|
import org.koitharu.kotatsu.core.ui.BaseActivity
|
||||||
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
import org.koitharu.kotatsu.core.ui.BaseListAdapter
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
import org.koitharu.kotatsu.core.ui.list.OnListItemClickListener
|
||||||
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
|
import org.koitharu.kotatsu.core.ui.util.ReversibleActionObserver
|
||||||
import org.koitharu.kotatsu.core.util.KotatsuColors
|
import org.koitharu.kotatsu.core.util.KotatsuColors
|
||||||
import org.koitharu.kotatsu.core.util.ext.DIALOG_THEME_CENTERED
|
|
||||||
import org.koitharu.kotatsu.core.util.ext.enqueueWith
|
import org.koitharu.kotatsu.core.util.ext.enqueueWith
|
||||||
import org.koitharu.kotatsu.core.util.ext.newImageRequest
|
import org.koitharu.kotatsu.core.util.ext.newImageRequest
|
||||||
import org.koitharu.kotatsu.core.util.ext.observe
|
import org.koitharu.kotatsu.core.util.ext.observe
|
||||||
@@ -167,14 +164,13 @@ class StatsActivity : BaseActivity<ActivityStatsBinding>(),
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun showClearConfirmDialog() {
|
private fun showClearConfirmDialog() {
|
||||||
MaterialAlertDialogBuilder(this, DIALOG_THEME_CENTERED)
|
buildAlertDialog(this, isCentered = true) {
|
||||||
.setMessage(R.string.clear_stats_confirm)
|
setMessage(R.string.clear_stats_confirm)
|
||||||
.setTitle(R.string.clear_stats)
|
setTitle(R.string.clear_stats)
|
||||||
.setIcon(R.drawable.ic_delete)
|
setIcon(R.drawable.ic_delete_all)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.clear) { _, _ ->
|
setPositiveButton(R.string.clear) { _, _ -> viewModel.clearStats() }
|
||||||
viewModel.clearStats()
|
}.show()
|
||||||
}.show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPeriodSelector() {
|
private fun showPeriodSelector() {
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ import android.view.MenuItem
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.core.view.MenuProvider
|
import androidx.core.view.MenuProvider
|
||||||
import org.koitharu.kotatsu.R
|
import org.koitharu.kotatsu.R
|
||||||
import org.koitharu.kotatsu.core.ui.dialog.CheckBoxAlertDialog
|
import org.koitharu.kotatsu.core.ui.dialog.RememberCheckListener
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.buildAlertDialog
|
||||||
|
import org.koitharu.kotatsu.core.ui.dialog.setCheckbox
|
||||||
|
|
||||||
class FeedMenuProvider(
|
class FeedMenuProvider(
|
||||||
private val snackbarHost: View,
|
private val snackbarHost: View,
|
||||||
@@ -38,15 +40,17 @@ class FeedMenuProvider(
|
|||||||
}
|
}
|
||||||
|
|
||||||
R.id.action_clear_feed -> {
|
R.id.action_clear_feed -> {
|
||||||
CheckBoxAlertDialog.Builder(context)
|
val checkListener = RememberCheckListener(true)
|
||||||
.setTitle(R.string.clear_updates_feed)
|
buildAlertDialog(context, isCentered = true) {
|
||||||
.setMessage(R.string.text_clear_updates_feed_prompt)
|
setIcon(R.drawable.ic_clear_all)
|
||||||
.setNegativeButton(android.R.string.cancel, null)
|
setTitle(R.string.clear_updates_feed)
|
||||||
.setCheckBoxChecked(true)
|
setMessage(R.string.text_clear_updates_feed_prompt)
|
||||||
.setCheckBoxText(R.string.clear_new_chapters_counters)
|
setNegativeButton(android.R.string.cancel, null)
|
||||||
.setPositiveButton(R.string.clear) { _, isChecked ->
|
setCheckbox(R.string.clear_new_chapters_counters, true, checkListener)
|
||||||
viewModel.clearFeed(isChecked)
|
setPositiveButton(R.string.clear) { _, _ ->
|
||||||
}.create().show()
|
viewModel.clearFeed(checkListener.isChecked)
|
||||||
|
}
|
||||||
|
}.show()
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
app/src/main/res/drawable/ic_delete_all.xml
Normal file
11
app/src/main/res/drawable/ic_delete_all.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<vector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:tint="?colorControlNormal"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#000000"
|
||||||
|
android:pathData="M15,16H19V18H15V16M15,8H22V10H15V8M15,12H21V14H15V12M11,10V18H5V10H11M13,8H3V18A2,2 0 0,0 5,20H11A2,2 0 0,0 13,18V8M14,5H11L10,4H6L5,5H2V7H14V5Z" />
|
||||||
|
</vector>
|
||||||
Reference in New Issue
Block a user