Use Chipgroup for edit manga dialog

Prepping to remove old tag group library

Adding new string: Add tag
Editing strings: Clear Tags and Reset Tags to Clear tags and Reset tags respectively
This commit is contained in:
Jays2Kings 2021-07-17 20:18:43 -04:00
parent 1762859977
commit 71da2ae4b8
4 changed files with 157 additions and 38 deletions

View File

@ -1,14 +1,25 @@
package eu.kanade.tachiyomi.ui.manga package eu.kanade.tachiyomi.ui.manga
import android.app.Dialog import android.app.Dialog
import android.content.Context
import android.content.res.ColorStateList
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.view.inputmethod.EditorInfo
import android.view.inputmethod.InputMethodManager
import androidx.core.graphics.ColorUtils
import androidx.core.view.children
import androidx.core.view.isVisible import androidx.core.view.isVisible
import coil.loadAny import coil.loadAny
import coil.request.Parameters import coil.request.Parameters
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView import com.afollestad.materialdialogs.customview.getCustomView
import com.google.android.material.chip.Chip
import com.google.android.material.chip.ChipGroup
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
@ -20,9 +31,11 @@ import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.util.isLocal import eu.kanade.tachiyomi.util.isLocal
import eu.kanade.tachiyomi.util.lang.chop import eu.kanade.tachiyomi.util.lang.chop
import me.gujun.android.taggroup.TagGroup import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.isInNightMode
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import kotlin.math.abs
class EditMangaDialog : DialogController { class EditMangaDialog : DialogController {
@ -80,7 +93,6 @@ class EditMangaDialog : DialogController {
binding.mangaAuthor.append(manga.author ?: "") binding.mangaAuthor.append(manga.author ?: "")
binding.mangaArtist.append(manga.artist ?: "") binding.mangaArtist.append(manga.artist ?: "")
binding.mangaDescription.append(manga.description ?: "") binding.mangaDescription.append(manga.description ?: "")
binding.mangaGenresTags.setTags(manga.genre?.split(", ") ?: emptyList())
} else { } else {
if (manga.title != manga.originalTitle) { if (manga.title != manga.originalTitle) {
binding.title.append(manga.title) binding.title.append(manga.title)
@ -94,12 +106,6 @@ class EditMangaDialog : DialogController {
if (manga.description != manga.originalDescription) { if (manga.description != manga.originalDescription) {
binding.mangaDescription.append(manga.description ?: "") binding.mangaDescription.append(manga.description ?: "")
} }
binding.mangaGenresTags.setTags(
manga.genre?.split(",")
?.map { it.trim() }
?.filter { it.isNotBlank() } ?: emptyList()
)
binding.title.hint = "${resources?.getString(R.string.title)}: ${manga.originalTitle}" binding.title.hint = "${resources?.getString(R.string.title)}: ${manga.originalTitle}"
if (manga.originalAuthor != null) { if (manga.originalAuthor != null) {
binding.mangaAuthor.hint = "${resources?.getString(R.string.author)}: ${manga.originalAuthor}" binding.mangaAuthor.hint = "${resources?.getString(R.string.author)}: ${manga.originalAuthor}"
@ -115,18 +121,7 @@ class EditMangaDialog : DialogController {
)?.chop(20)}" )?.chop(20)}"
} }
} }
binding.mangaGenresTags.setOnTagChangeListener(object : TagGroup.OnTagChangeListener { setGenreTags(manga.getGenres().orEmpty())
override fun onAppend(tagGroup: TagGroup?, tag: String?): Boolean {
val tags: List<String> = tagGroup?.tags.orEmpty().toList() + (tag ?: "")
binding.seriesType.setSelection(manga.seriesType(customTags = tags.joinToString(", ")) - 1)
return true
}
override fun onDelete(tagGroup: TagGroup?, tag: String?) {
val tags: List<String> = tagGroup?.tags.orEmpty().toList() - (tag ?: "")
binding.seriesType.setSelection(manga.seriesType(customTags = tags.joinToString(", ")) - 1)
}
})
binding.mangaStatus.setSelection(manga.status.coerceIn(SManga.UNKNOWN, SManga.LICENSED)) binding.mangaStatus.setSelection(manga.status.coerceIn(SManga.UNKNOWN, SManga.LICENSED))
val oldType = manga.seriesType() val oldType = manga.seriesType()
binding.seriesType.setSelection(oldType - 1) binding.seriesType.setSelection(oldType - 1)
@ -145,6 +140,26 @@ class EditMangaDialog : DialogController {
R.string.reset_tags R.string.reset_tags
} }
) )
binding.addTagChip.setOnClickListener {
binding.addTagChip.isVisible = false
binding.addTagEditText.isVisible = true
binding.addTagEditText.requestFocus()
showKeyboard()
}
binding.addTagEditText.setOnEditorActionListener { _, actionId, _ ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
val tags: List<String> = binding.mangaGenresTags.tags.toList() + binding.addTagEditText.text.toString()
setGenreTags(tags)
binding.seriesType.setSelection(manga.seriesType(customTags = tags.joinToString(", ")) - 1)
binding.addTagEditText.clearFocus()
binding.addTagEditText.setText("")
hideKeyboard()
}
binding.addTagChip.isVisible = true
binding.addTagEditText.isVisible = false
true
}
binding.resetCover.isVisible = !isLocal binding.resetCover.isVisible = !isLocal
binding.resetCover.setOnClickListener { binding.resetCover.setOnClickListener {
binding.mangaCover.loadAny( binding.mangaCover.loadAny(
@ -158,12 +173,92 @@ class EditMangaDialog : DialogController {
} }
} }
private fun resetTags() { private fun showKeyboard() {
if (manga.genre.isNullOrBlank() || manga.source == LocalSource.ID) binding.mangaGenresTags.setTags( val inputMethodManager: InputMethodManager =
emptyList() binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(
binding.addTagEditText,
WindowManager.LayoutParams
.SOFT_INPUT_ADJUST_PAN
) )
}
private fun hideKeyboard() {
val inputMethodManager: InputMethodManager =
binding.root.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(binding.addTagEditText.windowToken, 0)
}
private fun setGenreTags(genres: List<String>) {
with(binding.mangaGenresTags) {
val addTagChip = binding.addTagChip
val addTagEditText = binding.addTagEditText
removeAllViews()
val dark = context.isInNightMode()
val accentArray = FloatArray(3)
val onAccentArray = FloatArray(3)
ColorUtils.colorToHSL(context.getResourceColor(R.attr.colorAccent), accentArray)
ColorUtils.colorToHSL(context.getResourceColor(R.attr.colorOnAccent), onAccentArray)
val downloadedColor = ColorUtils.setAlphaComponent(
ColorUtils.HSLToColor(
floatArrayOf(
accentArray[0],
accentArray[1],
// fun math just for good contrast
((if (dark) 0.35f else 0.87f) + (abs(onAccentArray[2] - 0.5f) * .7f)) / 2f
)
),
165
)
val textColor = ColorUtils.HSLToColor(
floatArrayOf(
accentArray[0],
0.8f,
if (dark) 0.925f else 0.15f
)
)
genres.map { genreText ->
val chip = LayoutInflater.from(binding.root.context).inflate(
R.layout.genre_chip,
this,
false
) as Chip
val id = View.generateViewId()
chip.id = id
chip.chipBackgroundColor = ColorStateList.valueOf(downloadedColor)
chip.setTextColor(textColor)
chip.text = genreText
chip.isCloseIconVisible = true
chip.setOnCloseIconClickListener { view ->
this.removeView(view)
val tags: List<String> = tags.toList() - (view as Chip).text.toString()
binding.seriesType.setSelection(
manga.seriesType(
customTags = tags.joinToString(
", "
)
) - 1
)
}
this.addView(chip)
}
addView(addTagChip)
addView(addTagEditText)
}
}
private val ChipGroup.tags: Array<String>
get() = children
.toList()
.filterIsInstance<Chip>()
.filter { it.isCloseIconVisible }
.map { it.text.toString() }
.toTypedArray()
private fun resetTags() {
if (manga.genre.isNullOrBlank() || manga.source == LocalSource.ID) setGenreTags(emptyList())
else { else {
binding.mangaGenresTags.setTags(manga.originalGenre?.split(", ")) setGenreTags(manga.getOriginalGenres().orEmpty())
binding.seriesType.setSelection(manga.seriesType(true) - 1) binding.seriesType.setSelection(manga.seriesType(true) - 1)
binding.resetsReadingMode.isVisible = false binding.resetsReadingMode.isVisible = false
} }

View File

@ -42,6 +42,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/title" android:hint="@string/title"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:importantForAutofill="no"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:inputType="text" android:inputType="text"
android:maxLines="1"/> android:maxLines="1"/>
@ -52,6 +53,7 @@
android:hint="@string/author" android:hint="@string/author"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:importantForAutofill="no"
android:inputType="text" android:inputType="text"
android:maxLines="1"/> android:maxLines="1"/>
@ -61,6 +63,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/artist" android:hint="@string/artist"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:importantForAutofill="no"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:inputType="text" android:inputType="text"
android:maxLines="1"/> android:maxLines="1"/>
@ -71,6 +74,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:importantForAutofill="no"
android:hint="@string/description" android:hint="@string/description"
android:inputType="text|textMultiLine" android:inputType="text|textMultiLine"
android:scrollHorizontally="false" /> android:scrollHorizontally="false" />
@ -107,24 +111,33 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>
<me.gujun.android.taggroup.TagGroup <com.google.android.material.chip.ChipGroup
android:id="@+id/manga_genres_tags" android:id="@+id/manga_genres_tags"
style="@style/TagGroup"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginBottom="8dp" app:chipSpacing="-12dp"
app:atg_borderStrokeWidth="1dp" android:layout_marginBottom="8dp" >
app:atg_backgroundColor="@android:color/transparent"
app:atg_isAppendMode="true" <com.google.android.material.chip.Chip
app:atg_inputHintColor="?android:attr/textColorSecondary" android:id="@+id/add_tag_chip"
app:atg_inputTextColor="?android:attr/textColorPrimary" android:layout_width="wrap_content"
app:atg_checkedBackgroundColor="@color/material_red_500" style="@style/Theme.Widget.Chip.AddTag"
app:atg_checkedBorderColor="@color/material_red_500" android:layout_height="wrap_content"
app:atg_borderColor="?attr/colorAccent" android:text="@string/add_tag"/>
app:atg_textColor="?attr/colorAccent" />
<EditText
android:id="@+id/add_tag_edit_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
android:importantForAutofill="no"
android:hint="@string/add_tag"
android:inputType="text"
android:maxLines="1"/>
</com.google.android.material.chip.ChipGroup>
<Button <Button
android:id="@+id/reset_tags" android:id="@+id/reset_tags"

View File

@ -500,8 +500,9 @@
<string name="sort_by_chapter_number">Sort by chapter number</string> <string name="sort_by_chapter_number">Sort by chapter number</string>
<string name="newest_first">Newest to oldest</string> <string name="newest_first">Newest to oldest</string>
<string name="oldest_first">Oldest to newest</string> <string name="oldest_first">Oldest to newest</string>
<string name="clear_tags">Clear Tags</string> <string name="add_tag">Add tag</string>
<string name="reset_tags">Reset Tags</string> <string name="clear_tags">Clear tags</string>
<string name="reset_tags">Reset tags</string>
<string name="reset_cover">Reset cover</string> <string name="reset_cover">Reset cover</string>
<string name="failed_to_update_cover">Failed to update cover</string> <string name="failed_to_update_cover">Failed to update cover</string>
<string name="must_be_in_library_to_edit">Manga must be in your library to edit</string> <string name="must_be_in_library_to_edit">Manga must be in your library to edit</string>

View File

@ -306,6 +306,16 @@
<item name="android:checkable">false</item> <item name="android:checkable">false</item>
</style> </style>
<style name="Theme.Widget.Chip.AddTag" parent="Widget.MaterialComponents.Chip.Action">
<item name="chipBackgroundColor">@android:color/transparent</item>
<item name="chipMinHeight">28dp</item>
<item name="android:textColor">?colorOnSurface</item>
<item name="android:textAppearance">@style/Theme.TextAppearance.Chip</item>
<item name="chipStrokeColor">?colorOnSurface</item>
<item name="chipStrokeWidth">1dp</item>
<item name="android:checkable">false</item>
</style>
<style name="Theme.TextAppearance.Chip" parent="TextAppearance.MaterialComponents.Chip"> <style name="Theme.TextAppearance.Chip" parent="TextAppearance.MaterialComponents.Chip">
<item name="android:textSize">13sp</item> <item name="android:textSize">13sp</item>