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 dependenciespull/5554/head
parent
117fd4bd0f
commit
ae97bb0445
@ -1,87 +0,0 @@
|
||||
package eu.kanade.tachiyomi.ui.manga.track
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.core.os.bundleOf
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.datetime.datePicker
|
||||
import com.bluelinelabs.conductor.Controller
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.Calendar
|
||||
|
||||
class SetTrackReadingDatesDialog<T> : DialogController
|
||||
where T : Controller {
|
||||
|
||||
private val item: TrackItem
|
||||
|
||||
private val dateToUpdate: ReadingDate
|
||||
|
||||
private lateinit var listener: Listener
|
||||
|
||||
constructor(target: T, listener: Listener, dateToUpdate: ReadingDate, item: TrackItem) : super(
|
||||
bundleOf(KEY_ITEM_TRACK to item.track)
|
||||
) {
|
||||
targetController = target
|
||||
this.listener = listener
|
||||
this.item = item
|
||||
this.dateToUpdate = dateToUpdate
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(bundle: Bundle) : super(bundle) {
|
||||
val track = bundle.getSerializable(KEY_ITEM_TRACK) as Track
|
||||
val service = Injekt.get<TrackManager>().getService(track.sync_id)!!
|
||||
item = TrackItem(track, service)
|
||||
dateToUpdate = ReadingDate.Start
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||
return MaterialDialog(activity!!)
|
||||
.title(
|
||||
when (dateToUpdate) {
|
||||
ReadingDate.Start -> R.string.track_started_reading_date
|
||||
ReadingDate.Finish -> R.string.track_finished_reading_date
|
||||
}
|
||||
)
|
||||
.datePicker(currentDate = getCurrentDate()) { _, date ->
|
||||
listener.setReadingDate(item, dateToUpdate, date.timeInMillis)
|
||||
}
|
||||
.neutralButton(R.string.action_remove) {
|
||||
listener.setReadingDate(item, dateToUpdate, 0L)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCurrentDate(): Calendar {
|
||||
// Today if no date is set, otherwise the already set date
|
||||
return Calendar.getInstance().apply {
|
||||
item.track?.let {
|
||||
val date = when (dateToUpdate) {
|
||||
ReadingDate.Start -> it.started_reading_date
|
||||
ReadingDate.Finish -> it.finished_reading_date
|
||||
}
|
||||
if (date != 0L) {
|
||||
timeInMillis = date
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun setReadingDate(item: TrackItem, type: ReadingDate, date: Long)
|
||||
}
|
||||
|
||||
enum class ReadingDate {
|
||||
Start,
|
||||
Finish
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY_ITEM_TRACK = "SetTrackReadingDatesDialog.item.track"
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package eu.kanade.tachiyomi.widget.materialdialogs
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import eu.kanade.tachiyomi.databinding.DialogStubQuadstatemultichoiceBinding
|
||||
import eu.kanade.tachiyomi.databinding.DialogStubTextinputBinding
|
||||
|
||||
fun MaterialAlertDialogBuilder.setTextInput(
|
||||
hint: String? = null,
|
||||
prefill: String? = null,
|
||||
onTextChanged: (String) -> Unit
|
||||
): MaterialAlertDialogBuilder {
|
||||
val binding = DialogStubTextinputBinding.inflate(LayoutInflater.from(context))
|
||||
binding.textField.hint = hint
|
||||
binding.textField.editText?.apply {
|
||||
setText(prefill, TextView.BufferType.EDITABLE)
|
||||
doAfterTextChanged {
|
||||
onTextChanged(it?.toString() ?: "")
|
||||
}
|
||||
post {
|
||||
requestFocusFromTouch()
|
||||
context.getSystemService<InputMethodManager>()?.showSoftInput(this, 0)
|
||||
}
|
||||
}
|
||||
return setView(binding.root)
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a list of items with checkboxes that supports 4 states.
|
||||
*
|
||||
* @see eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView
|
||||
*/
|
||||
fun MaterialAlertDialogBuilder.setQuadStateMultiChoiceItems(
|
||||
items: List<CharSequence>,
|
||||
initialSelected: IntArray,
|
||||
disabledIndices: IntArray? = null,
|
||||
selection: QuadStateMultiChoiceListener
|
||||
): MaterialAlertDialogBuilder {
|
||||
val binding = DialogStubQuadstatemultichoiceBinding.inflate(LayoutInflater.from(context))
|
||||
binding.list.layoutManager = LinearLayoutManager(context)
|
||||
binding.list.adapter = QuadStateMultiChoiceDialogAdapter(
|
||||
items = items,
|
||||
disabledItems = disabledIndices,
|
||||
initialSelected = initialSelected,
|
||||
listener = selection
|
||||
)
|
||||
setView(binding.root)
|
||||
return this
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package eu.kanade.tachiyomi.widget.materialdialogs
|
||||
|
||||
import androidx.annotation.CheckResult
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.list.customListAdapter
|
||||
|
||||
/**
|
||||
* A variant of listItemsMultiChoice that allows for checkboxes that supports 4 states instead.
|
||||
*/
|
||||
@CheckResult
|
||||
fun MaterialDialog.listItemsQuadStateMultiChoice(
|
||||
items: List<CharSequence>,
|
||||
disabledIndices: IntArray? = null,
|
||||
initialSelected: IntArray = IntArray(items.size),
|
||||
selection: QuadStateMultiChoiceListener
|
||||
): MaterialDialog {
|
||||
return customListAdapter(
|
||||
QuadStateMultiChoiceDialogAdapter(
|
||||
dialog = this,
|
||||
items = items,
|
||||
disabledItems = disabledIndices,
|
||||
initialSelected = initialSelected,
|
||||
selection = selection
|
||||
)
|
||||
)
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package eu.kanade.tachiyomi.widget.materialdialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.util.view.setVectorCompat
|
||||
|
||||
class QuadStateCheckBox @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
AppCompatImageView(context, attrs) {
|
||||
|
||||
var state: State = State.UNCHECKED
|
||||
set(value) {
|
||||
field = value
|
||||
updateDrawable()
|
||||
}
|
||||
|
||||
private fun updateDrawable() {
|
||||
when (state) {
|
||||
State.UNCHECKED -> setVectorCompat(R.drawable.ic_check_box_outline_blank_24dp, R.attr.colorControlNormal)
|
||||
State.INDETERMINATE -> setVectorCompat(R.drawable.ic_indeterminate_check_box_24dp, R.attr.colorAccent)
|
||||
State.CHECKED -> setVectorCompat(R.drawable.ic_check_box_24dp, R.attr.colorAccent)
|
||||
State.INVERSED -> setVectorCompat(R.drawable.ic_check_box_x_24dp, R.attr.colorAccent)
|
||||
}
|
||||
}
|
||||
|
||||
enum class State {
|
||||
UNCHECKED,
|
||||
INDETERMINATE,
|
||||
CHECKED,
|
||||
INVERSED,
|
||||
;
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package eu.kanade.tachiyomi.widget.materialdialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import com.mikepenz.aboutlibraries.util.getThemeColor
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
class QuadStateTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
AppCompatTextView(context, attrs) {
|
||||
|
||||
var state: State = State.UNCHECKED
|
||||
set(value) {
|
||||
field = value
|
||||
updateDrawable()
|
||||
}
|
||||
|
||||
private fun updateDrawable() {
|
||||
val drawableStartId = when (state) {
|
||||
State.UNCHECKED -> R.drawable.ic_check_box_outline_blank_24dp
|
||||
State.INDETERMINATE -> R.drawable.ic_indeterminate_check_box_24dp
|
||||
State.CHECKED -> R.drawable.ic_check_box_24dp
|
||||
State.INVERSED -> R.drawable.ic_check_box_x_24dp
|
||||
}
|
||||
setCompoundDrawablesRelativeWithIntrinsicBounds(drawableStartId, 0, 0, 0)
|
||||
|
||||
val tint = if (state == State.UNCHECKED) {
|
||||
context.getThemeColor(R.attr.colorControlNormal)
|
||||
} else {
|
||||
context.getThemeColor(R.attr.colorAccent)
|
||||
}
|
||||
if (tint != 0) {
|
||||
compoundDrawableTintList = ColorStateList.valueOf(tint)
|
||||
}
|
||||
}
|
||||
|
||||
enum class State {
|
||||
UNCHECKED,
|
||||
INDETERMINATE,
|
||||
CHECKED,
|
||||
INVERSED,
|
||||
;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
|
||||
</vector>
|
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<eu.kanade.tachiyomi.widget.materialdialogs.QuadStateTextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="?attr/materialAlertDialogBodyTextStyle"
|
||||
android:id="@+id/quad_state_control"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:minHeight="?attr/listPreferredItemHeightSmall"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textAlignment="viewStart"
|
||||
android:paddingStart="@dimen/abc_select_dialog_padding_start_material"
|
||||
android:paddingEnd="?attr/dialogPreferredPadding"
|
||||
android:drawablePadding="20dp"
|
||||
android:ellipsize="marquee"
|
||||
app:drawableStartCompat="@drawable/ic_check_box_outline_blank_24dp"
|
||||
tools:text="Quad-state item" />
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp"
|
||||
android:scrollIndicators="none"
|
||||
tools:listitem="@layout/dialog_quadstatemultichoice_item" />
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:paddingVertical="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:id="@+id/text_field"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</FrameLayout>
|
@ -1,15 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
style="@style/MD_ListItem.Choice">
|
||||
|
||||
<eu.kanade.tachiyomi.widget.materialdialogs.QuadStateCheckBox
|
||||
android:id="@+id/md_quad_state_control"
|
||||
style="@style/MD_ListItem_Control" />
|
||||
|
||||
<com.afollestad.materialdialogs.internal.rtl.RtlTextView
|
||||
android:id="@+id/md_quad_state_title"
|
||||
style="@style/MD_ListItemText.Choice"
|
||||
tools:text="Item" />
|
||||
|
||||
</LinearLayout>
|
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_open_in_browser"
|
||||
android:title="@string/action_open_in_browser"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_remove"
|
||||
android:title="@string/action_remove"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_edit"
|
||||
android:title="@string/action_edit"
|
||||
app:showAsAction="never" />
|
||||
|
||||
<item
|
||||
android:id="@+id/action_remove"
|
||||
android:title="@string/action_remove"
|
||||
app:showAsAction="never" />
|
||||
|
||||
</menu>
|
Loading…
Reference in new issue