mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2025-01-11 13:29:08 +01:00
Binding Category stuff
This commit is contained in:
parent
fe7c235110
commit
3c2bd8c661
@ -17,7 +17,6 @@ import eu.kanade.tachiyomi.ui.main.MainActivity
|
|||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import eu.kanade.tachiyomi.util.view.liftAppbarWith
|
import eu.kanade.tachiyomi.util.view.liftAppbarWith
|
||||||
import eu.kanade.tachiyomi.util.view.snack
|
import eu.kanade.tachiyomi.util.view.snack
|
||||||
import kotlinx.android.synthetic.main.categories_controller.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Controller to manage the categories for the users' library.
|
* Controller to manage the categories for the users' library.
|
||||||
@ -59,12 +58,12 @@ class CategoryController(bundle: Bundle? = null) :
|
|||||||
*/
|
*/
|
||||||
override fun onViewCreated(view: View) {
|
override fun onViewCreated(view: View) {
|
||||||
super.onViewCreated(view)
|
super.onViewCreated(view)
|
||||||
liftAppbarWith(recycler)
|
liftAppbarWith(binding.recycler)
|
||||||
|
|
||||||
adapter = CategoryAdapter(this@CategoryController)
|
adapter = CategoryAdapter(this@CategoryController)
|
||||||
recycler.layoutManager = LinearLayoutManager(view.context)
|
binding.recycler.layoutManager = LinearLayoutManager(view.context)
|
||||||
recycler.setHasFixedSize(true)
|
binding.recycler.setHasFixedSize(true)
|
||||||
recycler.adapter = adapter
|
binding.recycler.adapter = adapter
|
||||||
adapter?.isHandleDragEnabled = true
|
adapter?.isHandleDragEnabled = true
|
||||||
adapter?.isPermanentDelete = false
|
adapter?.isPermanentDelete = false
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.ui.category
|
package eu.kanade.tachiyomi.ui.category
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.text.InputType
|
import android.text.InputType
|
||||||
@ -10,12 +11,12 @@ import android.view.inputmethod.InputMethodManager
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.database.models.Category
|
import eu.kanade.tachiyomi.data.database.models.Category
|
||||||
|
import eu.kanade.tachiyomi.databinding.CategoriesItemBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
import eu.kanade.tachiyomi.ui.base.holder.BaseFlexibleViewHolder
|
||||||
import eu.kanade.tachiyomi.ui.category.CategoryPresenter.Companion.CREATE_CATEGORY_ORDER
|
import eu.kanade.tachiyomi.ui.category.CategoryPresenter.Companion.CREATE_CATEGORY_ORDER
|
||||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||||
import eu.kanade.tachiyomi.util.view.gone
|
import eu.kanade.tachiyomi.util.view.gone
|
||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
import kotlinx.android.synthetic.main.categories_item.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holder used to display category items.
|
* Holder used to display category items.
|
||||||
@ -25,8 +26,9 @@ import kotlinx.android.synthetic.main.categories_item.*
|
|||||||
*/
|
*/
|
||||||
class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleViewHolder(view, adapter) {
|
class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleViewHolder(view, adapter) {
|
||||||
|
|
||||||
|
private val binding = CategoriesItemBinding.bind(view)
|
||||||
init {
|
init {
|
||||||
edit_button.setOnClickListener {
|
binding.editButton.setOnClickListener {
|
||||||
submitChanges()
|
submitChanges()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,8 +43,8 @@ class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleVie
|
|||||||
*/
|
*/
|
||||||
fun bind(category: Category) {
|
fun bind(category: Category) {
|
||||||
// Set capitalized title.
|
// Set capitalized title.
|
||||||
title.text = category.name.capitalize()
|
binding.title.text = category.name.capitalize()
|
||||||
edit_text.setOnEditorActionListener { _, actionId, _ ->
|
binding.editText.setOnEditorActionListener { _, actionId, _ ->
|
||||||
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
if (actionId == EditorInfo.IME_ACTION_DONE) {
|
||||||
submitChanges()
|
submitChanges()
|
||||||
}
|
}
|
||||||
@ -50,79 +52,80 @@ class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleVie
|
|||||||
}
|
}
|
||||||
createCategory = category.order == CREATE_CATEGORY_ORDER
|
createCategory = category.order == CREATE_CATEGORY_ORDER
|
||||||
if (createCategory) {
|
if (createCategory) {
|
||||||
title.setTextColor(ContextCompat.getColor(itemView.context, R.color.text_color_hint))
|
binding.title.setTextColor(ContextCompat.getColor(itemView.context, R.color.text_color_hint))
|
||||||
regularDrawable = ContextCompat.getDrawable(
|
regularDrawable = ContextCompat.getDrawable(
|
||||||
itemView.context,
|
itemView.context,
|
||||||
R.drawable
|
R.drawable
|
||||||
.ic_add_24dp
|
.ic_add_24dp
|
||||||
)
|
)
|
||||||
image.gone()
|
binding.image.gone()
|
||||||
edit_button.setImageDrawable(null)
|
binding.editButton.setImageDrawable(null)
|
||||||
edit_text.setText("")
|
binding.editText.setText("")
|
||||||
edit_text.hint = title.text
|
binding.editText.hint = binding.title.text
|
||||||
} else {
|
} else {
|
||||||
title.setTextColor(ContextCompat.getColor(itemView.context, R.color.textColorPrimary))
|
binding.title.setTextColor(ContextCompat.getColor(itemView.context, R.color.textColorPrimary))
|
||||||
regularDrawable = ContextCompat.getDrawable(
|
regularDrawable = ContextCompat.getDrawable(
|
||||||
itemView.context,
|
itemView.context,
|
||||||
R.drawable
|
R.drawable
|
||||||
.ic_drag_handle_24dp
|
.ic_drag_handle_24dp
|
||||||
)
|
)
|
||||||
image.visible()
|
binding.image.visible()
|
||||||
edit_text.setText(title.text)
|
binding.editText.setText(binding.title.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
fun isEditing(editing: Boolean) {
|
fun isEditing(editing: Boolean) {
|
||||||
itemView.isActivated = editing
|
itemView.isActivated = editing
|
||||||
title.visibility = if (editing) View.INVISIBLE else View.VISIBLE
|
binding.title.visibility = if (editing) View.INVISIBLE else View.VISIBLE
|
||||||
edit_text.visibility = if (!editing) View.INVISIBLE else View.VISIBLE
|
binding.editText.visibility = if (!editing) View.INVISIBLE else View.VISIBLE
|
||||||
if (editing) {
|
if (editing) {
|
||||||
edit_text.inputType = InputType.TYPE_TEXT_FLAG_AUTO_CORRECT
|
binding.editText.inputType = InputType.TYPE_TEXT_FLAG_AUTO_CORRECT
|
||||||
edit_text.requestFocus()
|
binding.editText.requestFocus()
|
||||||
edit_text.selectAll()
|
binding.editText.selectAll()
|
||||||
edit_button.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.ic_check_24dp))
|
binding.editButton.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.ic_check_24dp))
|
||||||
edit_button.drawable.mutate().setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
binding.editButton.drawable.mutate().setTint(itemView.context.getResourceColor(R.attr.colorAccent))
|
||||||
showKeyboard()
|
showKeyboard()
|
||||||
if (!createCategory) {
|
if (!createCategory) {
|
||||||
reorder.setImageDrawable(
|
binding.reorder.setImageDrawable(
|
||||||
ContextCompat.getDrawable(
|
ContextCompat.getDrawable(
|
||||||
itemView.context,
|
itemView.context,
|
||||||
R.drawable.ic_delete_24dp
|
R.drawable.ic_delete_24dp
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
reorder.setOnClickListener {
|
binding.reorder.setOnClickListener {
|
||||||
adapter.categoryItemListener.onItemDelete(flexibleAdapterPosition)
|
adapter.categoryItemListener.onItemDelete(flexibleAdapterPosition)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!createCategory) {
|
if (!createCategory) {
|
||||||
setDragHandleView(reorder)
|
setDragHandleView(binding.reorder)
|
||||||
edit_button.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.ic_edit_24dp))
|
binding.editButton.setImageDrawable(ContextCompat.getDrawable(itemView.context, R.drawable.ic_edit_24dp))
|
||||||
} else {
|
} else {
|
||||||
edit_button.setImageDrawable(null)
|
binding.editButton.setImageDrawable(null)
|
||||||
reorder.setOnTouchListener { _, _ -> true }
|
binding.reorder.setOnTouchListener { _, _ -> true }
|
||||||
}
|
}
|
||||||
edit_text.clearFocus()
|
binding.editText.clearFocus()
|
||||||
edit_button.drawable?.mutate()?.setTint(
|
binding.editButton.drawable?.mutate()?.setTint(
|
||||||
ContextCompat.getColor(
|
ContextCompat.getColor(
|
||||||
itemView.context,
|
itemView.context,
|
||||||
R
|
R
|
||||||
.color.gray_button
|
.color.gray_button
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
reorder.setImageDrawable(regularDrawable)
|
binding.reorder.setImageDrawable(regularDrawable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun submitChanges() {
|
private fun submitChanges() {
|
||||||
if (edit_text.visibility == View.VISIBLE) {
|
if (binding.editText.visibility == View.VISIBLE) {
|
||||||
if (adapter.categoryItemListener
|
if (adapter.categoryItemListener
|
||||||
.onCategoryRename(flexibleAdapterPosition, edit_text.text.toString())
|
.onCategoryRename(flexibleAdapterPosition, binding.editText.text.toString())
|
||||||
) {
|
) {
|
||||||
isEditing(false)
|
isEditing(false)
|
||||||
edit_text.inputType = InputType.TYPE_NULL
|
binding.editText.inputType = InputType.TYPE_NULL
|
||||||
if (!createCategory) {
|
if (!createCategory) {
|
||||||
title.text = edit_text.text.toString()
|
binding.title.text = binding.editText.text.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -134,7 +137,7 @@ class CategoryHolder(view: View, val adapter: CategoryAdapter) : BaseFlexibleVie
|
|||||||
val inputMethodManager: InputMethodManager =
|
val inputMethodManager: InputMethodManager =
|
||||||
itemView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
itemView.context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
inputMethodManager.showSoftInput(
|
inputMethodManager.showSoftInput(
|
||||||
edit_text,
|
binding.editText,
|
||||||
WindowManager.LayoutParams
|
WindowManager.LayoutParams
|
||||||
.SOFT_INPUT_ADJUST_PAN
|
.SOFT_INPUT_ADJUST_PAN
|
||||||
)
|
)
|
||||||
|
@ -13,6 +13,7 @@ import eu.kanade.tachiyomi.data.database.models.Category
|
|||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
|
import eu.kanade.tachiyomi.databinding.MangaCategoryDialogBinding
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
@ -20,8 +21,6 @@ import eu.kanade.tachiyomi.util.view.gone
|
|||||||
import eu.kanade.tachiyomi.util.view.visible
|
import eu.kanade.tachiyomi.util.view.visible
|
||||||
import eu.kanade.tachiyomi.util.view.visibleIf
|
import eu.kanade.tachiyomi.util.view.visibleIf
|
||||||
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
import eu.kanade.tachiyomi.util.view.withFadeTransaction
|
||||||
import kotlinx.android.synthetic.main.edit_manga_dialog.view.title
|
|
||||||
import kotlinx.android.synthetic.main.manga_category_dialog.view.*
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
class ManageCategoryDialog(bundle: Bundle? = null) :
|
class ManageCategoryDialog(bundle: Bundle? = null) :
|
||||||
@ -32,45 +31,45 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
this.category = category
|
this.category = category
|
||||||
}
|
}
|
||||||
|
|
||||||
private lateinit var libraryController: LibraryController
|
private var libraryController: LibraryController? = null
|
||||||
private lateinit var category: Category
|
private var category: Category? = null
|
||||||
|
|
||||||
private var dialogView: View? = null
|
|
||||||
|
|
||||||
private val preferences by injectLazy<PreferencesHelper>()
|
private val preferences by injectLazy<PreferencesHelper>()
|
||||||
private val db by injectLazy<DatabaseHelper>()
|
private val db by injectLazy<DatabaseHelper>()
|
||||||
|
var binding: MangaCategoryDialogBinding? = null
|
||||||
|
|
||||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||||
|
binding = MangaCategoryDialogBinding.inflate(activity!!.layoutInflater)
|
||||||
val dialog = MaterialDialog(activity!!).apply {
|
val dialog = MaterialDialog(activity!!).apply {
|
||||||
title(R.string.manage_category)
|
title(R.string.manage_category)
|
||||||
customView(viewRes = R.layout.manga_category_dialog)
|
customView(view = binding!!.root)
|
||||||
negativeButton(android.R.string.cancel)
|
negativeButton(android.R.string.cancel)
|
||||||
positiveButton(R.string.save) { onPositiveButtonClick() }
|
positiveButton(R.string.save) { onPositiveButtonClick() }
|
||||||
}
|
}
|
||||||
dialogView = dialog.view
|
|
||||||
onViewCreated(dialog.view)
|
onViewCreated(dialog.view)
|
||||||
return dialog
|
return dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onPositiveButtonClick() {
|
private fun onPositiveButtonClick() {
|
||||||
val view = dialogView ?: return
|
val binding = binding ?: return
|
||||||
|
val category = category ?: return
|
||||||
if (category.id ?: 0 <= 0) return
|
if (category.id ?: 0 <= 0) return
|
||||||
val text = view.title.text.toString()
|
val text = binding.title.text.toString()
|
||||||
val categoryExists = categoryExists(text)
|
val categoryExists = categoryExists(text)
|
||||||
if (text.isNotBlank() && !categoryExists && !text.equals(category.name, true)) {
|
if (text.isNotBlank() && !categoryExists && !text.equals(category.name, true)) {
|
||||||
category.name = text
|
category.name = text
|
||||||
db.insertCategory(category).executeAsBlocking()
|
db.insertCategory(category).executeAsBlocking()
|
||||||
libraryController.presenter.getLibrary()
|
libraryController?.presenter?.getLibrary()
|
||||||
} else if (categoryExists) {
|
} else if (categoryExists) {
|
||||||
activity?.toast(R.string.category_with_name_exists)
|
activity?.toast(R.string.category_with_name_exists)
|
||||||
}
|
}
|
||||||
if (!updatePref(preferences.downloadNewCategories(), view.download_new)) {
|
if (!updatePref(preferences.downloadNewCategories(), binding.downloadNew)) {
|
||||||
preferences.downloadNew().set(false)
|
preferences.downloadNew().set(false)
|
||||||
} else {
|
} else {
|
||||||
preferences.downloadNew().set(true)
|
preferences.downloadNew().set(true)
|
||||||
}
|
}
|
||||||
if (preferences.libraryUpdateInterval().getOrDefault() > 0 &&
|
if (preferences.libraryUpdateInterval().getOrDefault() > 0 &&
|
||||||
!updatePref(preferences.libraryUpdateCategories(), view.include_global)
|
!updatePref(preferences.libraryUpdateCategories(), binding.downloadNew)
|
||||||
) {
|
) {
|
||||||
preferences.libraryUpdateInterval().set(0)
|
preferences.libraryUpdateInterval().set(0)
|
||||||
LibraryUpdateJob.setupTask(0)
|
LibraryUpdateJob.setupTask(0)
|
||||||
@ -82,38 +81,40 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
*/
|
*/
|
||||||
private fun categoryExists(name: String): Boolean {
|
private fun categoryExists(name: String): Boolean {
|
||||||
return db.getCategories().executeAsBlocking().any {
|
return db.getCategories().executeAsBlocking().any {
|
||||||
it.name.equals(name, true) && category.id != it.id
|
it.name.equals(name, true) && category?.id != it.id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onViewCreated(view: View) {
|
fun onViewCreated(view: View) {
|
||||||
|
val binding = binding ?: return
|
||||||
|
val category = category ?: return
|
||||||
if (category.id ?: 0 <= 0) {
|
if (category.id ?: 0 <= 0) {
|
||||||
view.title.gone()
|
binding.title.gone()
|
||||||
view.download_new.gone()
|
binding.downloadNew.gone()
|
||||||
view.include_global.gone()
|
binding.includeGlobal.gone()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
view.edit_categories.setOnClickListener {
|
binding.editCategories.setOnClickListener {
|
||||||
router.popCurrentController()
|
router.popCurrentController()
|
||||||
router.pushController(CategoryController().withFadeTransaction())
|
router.pushController(CategoryController().withFadeTransaction())
|
||||||
}
|
}
|
||||||
view.title.hint = category.name
|
binding.title.hint = category.name
|
||||||
view.title.append(category.name)
|
binding.title.append(category.name)
|
||||||
val downloadNew = preferences.downloadNew().get()
|
val downloadNew = preferences.downloadNew().get()
|
||||||
setCheckbox(
|
setCheckbox(
|
||||||
view.download_new,
|
binding.downloadNew,
|
||||||
preferences.downloadNewCategories(),
|
preferences.downloadNewCategories(),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
if (downloadNew && preferences.downloadNewCategories().get().isEmpty()) {
|
if (downloadNew && preferences.downloadNewCategories().get().isEmpty()) {
|
||||||
view.download_new.gone()
|
binding.downloadNew.gone()
|
||||||
} else if (!downloadNew) {
|
} else if (!downloadNew) {
|
||||||
view.download_new.visible()
|
binding.downloadNew.visible()
|
||||||
}
|
}
|
||||||
view.download_new.isChecked =
|
binding.downloadNew.isChecked =
|
||||||
preferences.downloadNew().get() && view.download_new.isChecked
|
preferences.downloadNew().get() && binding.downloadNew.isChecked
|
||||||
setCheckbox(
|
setCheckbox(
|
||||||
view.include_global,
|
binding.includeGlobal,
|
||||||
preferences.libraryUpdateCategories(),
|
preferences.libraryUpdateCategories(),
|
||||||
preferences.libraryUpdateInterval().getOrDefault() > 0
|
preferences.libraryUpdateInterval().getOrDefault() > 0
|
||||||
)
|
)
|
||||||
@ -121,7 +122,7 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
|
|
||||||
/** Update a pref based on checkbox, and return if the pref is not empty */
|
/** Update a pref based on checkbox, and return if the pref is not empty */
|
||||||
private fun updatePref(categories: Preference<Set<String>>, box: CompoundButton): Boolean {
|
private fun updatePref(categories: Preference<Set<String>>, box: CompoundButton): Boolean {
|
||||||
val categoryId = category.id ?: return true
|
val categoryId = category?.id ?: return true
|
||||||
val updateCategories = categories.get().toMutableSet()
|
val updateCategories = categories.get().toMutableSet()
|
||||||
if (box.isChecked) {
|
if (box.isChecked) {
|
||||||
updateCategories.add(categoryId.toString())
|
updateCategories.add(categoryId.toString())
|
||||||
@ -132,6 +133,11 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
return updateCategories.isNotEmpty()
|
return updateCategories.isNotEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroyView(view: View) {
|
||||||
|
super.onDestroyView(view)
|
||||||
|
binding = null
|
||||||
|
}
|
||||||
|
|
||||||
private fun setCheckbox(
|
private fun setCheckbox(
|
||||||
box: CompoundButton,
|
box: CompoundButton,
|
||||||
categories: Preference<Set<String>>,
|
categories: Preference<Set<String>>,
|
||||||
@ -140,6 +146,6 @@ class ManageCategoryDialog(bundle: Bundle? = null) :
|
|||||||
val updateCategories = categories.get()
|
val updateCategories = categories.get()
|
||||||
box.visibleIf(updateCategories.isNotEmpty() && shouldShow)
|
box.visibleIf(updateCategories.isNotEmpty() && shouldShow)
|
||||||
if (updateCategories.isNotEmpty() && shouldShow) box.isChecked =
|
if (updateCategories.isNotEmpty() && shouldShow) box.isChecked =
|
||||||
updateCategories.any { category.id == it.toIntOrNull() }
|
updateCategories.any { category?.id == it.toIntOrNull() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user