Replace material-dialogs usage with Material Components' (#5423)

* Use Material Components' dialogs

For all dialogs that has direct replacement.

* Convert text input dialogs

* Convert quad-state multi choices dialogs

* Convert date picker dialogs

This also changes the flow to remove selected start/finish tracking date and
the track item itself

* Remove material-dialogs dependencies
This commit is contained in:
Ivan Iskandar
2021-07-15 05:04:03 +07:00
committed by GitHub
parent 117fd4bd0f
commit ae97bb0445
56 changed files with 701 additions and 696 deletions
@@ -8,7 +8,7 @@ import android.os.Bundle
import android.provider.Settings
import androidx.core.net.toUri
import androidx.preference.PreferenceScreen
import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.cache.ChapterCache
@@ -184,12 +184,13 @@ class SettingsAdvancedController : SettingsController() {
class ClearDatabaseDialogController : DialogController() {
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
return MaterialDialog(activity!!)
.message(R.string.clear_database_confirmation)
.positiveButton(android.R.string.ok) {
return MaterialAlertDialogBuilder(activity!!)
.setMessage(R.string.clear_database_confirmation)
.setPositiveButton(android.R.string.ok) { _, _ ->
(targetController as? SettingsAdvancedController)?.clearDatabase()
}
.negativeButton(android.R.string.cancel)
.setNegativeButton(android.R.string.cancel, null)
.create()
}
}
@@ -9,12 +9,12 @@ import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.core.net.toUri
import androidx.core.os.bundleOf
import androidx.documentfile.provider.DocumentFile
import androidx.preference.PreferenceScreen
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsMultiChoice
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.backup.BackupConst
@@ -246,29 +246,34 @@ class SettingsBackupController : SettingsController() {
R.string.history
)
.map { activity.getString(it) }
val selected = options.map { true }.toBooleanArray()
return MaterialDialog(activity)
.title(R.string.pref_create_backup)
.message(R.string.backup_choice)
.listItemsMultiChoice(
items = options,
disabledIndices = intArrayOf(0),
initialSelection = intArrayOf(0, 1, 2, 3, 4)
) { _, positions, _ ->
return MaterialAlertDialogBuilder(activity)
.setTitle(R.string.backup_choice)
.setMultiChoiceItems(options.toTypedArray(), selected) { dialog, which, checked ->
if (which == 0) {
(dialog as AlertDialog).listView.setItemChecked(which, true)
} else {
selected[which] = checked
}
}
.setPositiveButton(R.string.action_create) { _, _ ->
var flags = 0
for (i in 1 until positions.size) {
when (positions[i]) {
1 -> flags = flags or BackupCreateService.BACKUP_CATEGORY
2 -> flags = flags or BackupCreateService.BACKUP_CHAPTER
3 -> flags = flags or BackupCreateService.BACKUP_TRACK
4 -> flags = flags or BackupCreateService.BACKUP_HISTORY
selected.forEachIndexed { i, checked ->
if (checked) {
when (i) {
1 -> flags = flags or BackupCreateService.BACKUP_CATEGORY
2 -> flags = flags or BackupCreateService.BACKUP_CHAPTER
3 -> flags = flags or BackupCreateService.BACKUP_TRACK
4 -> flags = flags or BackupCreateService.BACKUP_HISTORY
}
}
}
(targetController as? SettingsBackupController)?.createBackup(flags)
}
.positiveButton(R.string.action_create)
.negativeButton(android.R.string.cancel)
.setNegativeButton(android.R.string.cancel, null)
.create()
}
}
@@ -306,17 +311,19 @@ class SettingsBackupController : SettingsController() {
message += "\n\n${activity.getString(R.string.backup_restore_missing_trackers)}\n${results.missingTrackers.joinToString("\n") { "- $it" }}"
}
MaterialDialog(activity)
.title(R.string.pref_restore_backup)
.message(text = message)
.positiveButton(R.string.action_restore) {
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.pref_restore_backup)
.setMessage(message)
.setPositiveButton(R.string.action_restore) { _, _ ->
BackupRestoreService.start(activity, uri, type)
}
.create()
} catch (e: Exception) {
MaterialDialog(activity)
.title(R.string.invalid_backup_file)
.message(text = e.message)
.positiveButton(android.R.string.cancel)
MaterialAlertDialogBuilder(activity)
.setTitle(R.string.invalid_backup_file)
.setMessage(e.message)
.setPositiveButton(android.R.string.cancel, null)
.create()
}
}
@@ -10,8 +10,7 @@ import androidx.core.content.ContextCompat
import androidx.core.net.toUri
import androidx.core.text.buildSpannedString
import androidx.preference.PreferenceScreen
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsSingleChoice
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
@@ -28,8 +27,8 @@ import eu.kanade.tachiyomi.util.preference.preferenceCategory
import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.toast
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateCheckBox
import eu.kanade.tachiyomi.widget.materialdialogs.listItemsQuadStateMultiChoice
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
import eu.kanade.tachiyomi.widget.materialdialogs.setQuadStateMultiChoiceItems
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import uy.kohesive.injekt.Injekt
@@ -194,20 +193,22 @@ class SettingsDownloadController : SettingsController() {
val activity = activity!!
val currentDir = preferences.downloadsDirectory().get()
val externalDirs = (getExternalDirs() + File(activity.getString(R.string.custom_dir))).map(File::toString)
val selectedIndex = externalDirs.indexOfFirst { it in currentDir }
var selectedIndex = externalDirs.indexOfFirst { it in currentDir }
return MaterialDialog(activity)
.listItemsSingleChoice(
items = externalDirs,
initialSelection = selectedIndex
) { _, position, text ->
return MaterialAlertDialogBuilder(activity)
.setTitle(R.string.pref_download_directory)
.setSingleChoiceItems(externalDirs.toTypedArray(), selectedIndex) { _, which ->
selectedIndex = which
}
.setPositiveButton(android.R.string.ok) { _, _ ->
val target = targetController as? SettingsDownloadController
if (position == externalDirs.lastIndex) {
if (selectedIndex == externalDirs.lastIndex) {
target?.customDirectorySelected()
} else {
target?.predefinedDirectorySelected(text.toString())
target?.predefinedDirectorySelected(externalDirs[selectedIndex])
}
}
.create()
}
private fun getExternalDirs(): List<File> {
@@ -230,30 +231,33 @@ class SettingsDownloadController : SettingsController() {
val categories = listOf(Category.createDefault()) + dbCategories
val items = categories.map { it.name }
val preselected = categories
var selected = categories
.map {
when (it.id.toString()) {
in preferences.downloadNewCategories().get() -> QuadStateCheckBox.State.CHECKED.ordinal
in preferences.downloadNewCategoriesExclude().get() -> QuadStateCheckBox.State.INVERSED.ordinal
else -> QuadStateCheckBox.State.UNCHECKED.ordinal
in preferences.downloadNewCategories().get() -> QuadStateTextView.State.CHECKED.ordinal
in preferences.downloadNewCategoriesExclude().get() -> QuadStateTextView.State.INVERSED.ordinal
else -> QuadStateTextView.State.UNCHECKED.ordinal
}
}
.toIntArray()
return MaterialDialog(activity!!)
.title(R.string.categories)
.message(R.string.pref_download_new_categories_details)
.listItemsQuadStateMultiChoice(
return MaterialAlertDialogBuilder(activity!!)
.setTitle(R.string.categories)
.setMessage(R.string.pref_download_new_categories_details)
.setQuadStateMultiChoiceItems(
items = items,
initialSelected = preselected
initialSelected = selected
) { selections ->
val included = selections
.mapIndexed { index, value -> if (value == QuadStateCheckBox.State.CHECKED.ordinal) index else null }
selected = selections
}
.setPositiveButton(android.R.string.ok) { _, _ ->
val included = selected
.mapIndexed { index, value -> if (value == QuadStateTextView.State.CHECKED.ordinal) index else null }
.filterNotNull()
.map { categories[it].id.toString() }
.toSet()
val excluded = selections
.mapIndexed { index, value -> if (value == QuadStateCheckBox.State.INVERSED.ordinal) index else null }
val excluded = selected
.mapIndexed { index, value -> if (value == QuadStateTextView.State.INVERSED.ordinal) index else null }
.filterNotNull()
.map { categories[it].id.toString() }
.toSet()
@@ -261,8 +265,8 @@ class SettingsDownloadController : SettingsController() {
preferences.downloadNewCategories().set(included)
preferences.downloadNewCategoriesExclude().set(excluded)
}
.positiveButton(android.R.string.ok)
.negativeButton(android.R.string.cancel)
.setNegativeButton(android.R.string.cancel, null)
.create()
}
}
@@ -2,12 +2,11 @@ package eu.kanade.tachiyomi.ui.setting
import android.app.Dialog
import android.os.Bundle
import android.view.View
import android.view.LayoutInflater
import androidx.core.content.ContextCompat
import androidx.core.text.buildSpannedString
import androidx.preference.PreferenceScreen
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category
@@ -17,6 +16,7 @@ import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.UNMETERED_NETWORK
import eu.kanade.tachiyomi.data.preference.asImmediateFlow
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.databinding.PrefLibraryColumnsBinding
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.category.CategoryController
@@ -32,9 +32,8 @@ import eu.kanade.tachiyomi.util.preference.summaryRes
import eu.kanade.tachiyomi.util.preference.switchPreference
import eu.kanade.tachiyomi.util.preference.titleRes
import eu.kanade.tachiyomi.util.system.isTablet
import eu.kanade.tachiyomi.widget.MinMaxNumberPicker
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateCheckBox
import eu.kanade.tachiyomi.widget.materialdialogs.listItemsQuadStateMultiChoice
import eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
import eu.kanade.tachiyomi.widget.materialdialogs.setQuadStateMultiChoiceItems
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -299,21 +298,21 @@ class SettingsLibraryController : SettingsController() {
private var landscape = preferences.landscapeColumns().get()
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val dialog = MaterialDialog(activity!!)
.title(R.string.pref_library_columns)
.customView(R.layout.pref_library_columns, horizontalPadding = true)
.positiveButton(android.R.string.ok) {
val binding = PrefLibraryColumnsBinding.inflate(LayoutInflater.from(activity!!))
onViewCreated(binding)
return MaterialAlertDialogBuilder(activity!!)
.setTitle(R.string.pref_library_columns)
.setView(binding.root)
.setPositiveButton(android.R.string.ok) { _, _ ->
preferences.portraitColumns().set(portrait)
preferences.landscapeColumns().set(landscape)
}
.negativeButton(android.R.string.cancel)
onViewCreated(dialog.view)
return dialog
.setNegativeButton(android.R.string.cancel, null)
.create()
}
fun onViewCreated(view: View) {
with(view.findViewById(R.id.portrait_columns) as MinMaxNumberPicker) {
fun onViewCreated(binding: PrefLibraryColumnsBinding) {
with(binding.portraitColumns) {
displayedValues = arrayOf(context.getString(R.string.default_columns)) +
IntRange(1, 10).map(Int::toString)
value = portrait
@@ -322,7 +321,7 @@ class SettingsLibraryController : SettingsController() {
portrait = newValue
}
}
with(view.findViewById(R.id.landscape_columns) as MinMaxNumberPicker) {
with(binding.landscapeColumns) {
displayedValues = arrayOf(context.getString(R.string.default_columns)) +
IntRange(1, 10).map(Int::toString)
value = landscape
@@ -344,30 +343,30 @@ class SettingsLibraryController : SettingsController() {
val categories = listOf(Category.createDefault()) + dbCategories
val items = categories.map { it.name }
val preselected = categories
var selected = categories
.map {
when (it.id.toString()) {
in preferences.libraryUpdateCategories().get() -> QuadStateCheckBox.State.CHECKED.ordinal
in preferences.libraryUpdateCategoriesExclude().get() -> QuadStateCheckBox.State.INVERSED.ordinal
else -> QuadStateCheckBox.State.UNCHECKED.ordinal
in preferences.libraryUpdateCategories().get() -> QuadStateTextView.State.CHECKED.ordinal
in preferences.libraryUpdateCategoriesExclude().get() -> QuadStateTextView.State.INVERSED.ordinal
else -> QuadStateTextView.State.UNCHECKED.ordinal
}
}
.toIntArray()
return MaterialDialog(activity!!)
.title(R.string.categories)
.message(R.string.pref_library_update_categories_details)
.listItemsQuadStateMultiChoice(
items = items,
initialSelected = preselected
) { selections ->
val included = selections
.mapIndexed { index, value -> if (value == QuadStateCheckBox.State.CHECKED.ordinal) index else null }
return MaterialAlertDialogBuilder(activity!!)
.setTitle(R.string.categories)
.setMessage(R.string.pref_library_update_categories_details)
.setQuadStateMultiChoiceItems(items = items, initialSelected = selected) { selections ->
selected = selections
}
.setPositiveButton(android.R.string.ok) { _, _ ->
val included = selected
.mapIndexed { index, value -> if (value == QuadStateTextView.State.CHECKED.ordinal) index else null }
.filterNotNull()
.map { categories[it].id.toString() }
.toSet()
val excluded = selections
.mapIndexed { index, value -> if (value == QuadStateCheckBox.State.INVERSED.ordinal) index else null }
val excluded = selected
.mapIndexed { index, value -> if (value == QuadStateTextView.State.INVERSED.ordinal) index else null }
.filterNotNull()
.map { categories[it].id.toString() }
.toSet()
@@ -375,8 +374,8 @@ class SettingsLibraryController : SettingsController() {
preferences.libraryUpdateCategories().set(included)
preferences.libraryUpdateCategoriesExclude().set(excluded)
}
.positiveButton(android.R.string.ok)
.negativeButton(android.R.string.cancel)
.setNegativeButton(android.R.string.cancel, null)
.create()
}
}
}
@@ -3,7 +3,7 @@ package eu.kanade.tachiyomi.ui.setting.track
import android.app.Dialog
import android.os.Bundle
import androidx.core.os.bundleOf
import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService
@@ -20,14 +20,15 @@ class TrackLogoutDialog(bundle: Bundle? = null) : DialogController(bundle) {
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
val serviceName = activity!!.getString(service.nameRes())
return MaterialDialog(activity!!)
.title(text = activity!!.getString(R.string.logout_title, serviceName))
.positiveButton(R.string.logout) {
return MaterialAlertDialogBuilder(activity!!)
.setTitle(activity!!.getString(R.string.logout_title, serviceName))
.setPositiveButton(R.string.logout) { _, _ ->
service.logout()
(targetController as? Listener)?.trackLogoutDialogClosed(service)
activity?.toast(R.string.logout_success)
}
.negativeButton(android.R.string.cancel)
.setNegativeButton(android.R.string.cancel, null)
.create()
}
interface Listener {