Skip to content

Commit

Permalink
Added multiselect delete in manageNotesType
Browse files Browse the repository at this point in the history
Added Multiselect delete in manageNoteType

djsakj

adding payload to reduce ui rendering

Debuging

debugging
  • Loading branch information
jainv4156 committed Sep 18, 2024
1 parent fab5a8c commit 02b52e3
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/****************************************************************************************
* Copyright (c) 2022 lukstbit <[email protected]> *
* *
* This program is free software; you can redistribute it and/or modify it under *
* the terms of the GNU General Public License as published by the Free Software *
* Foundation; either version 3 of the License, or (at your option) any later *
* version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT ANY *
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A *
* PARTICULAR PURPOSE. See the GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along with *
* this program. If not, see <http://www.gnu.org/licenses/>. *
****************************************************************************************/
package com.ichi2.anki.notetype

interface ManageNoteTypeCallbacks {
fun enableMultiSelectMode()
fun addInToDeleteList(id: Long, position: Int)
fun isToDeleteListContains(id: Long): Boolean
fun removeIdFromToDeleteList(id: Long, position: Int)
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.activity.result.ActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.ActionBar
Expand Down Expand Up @@ -51,12 +52,19 @@ import com.ichi2.utils.positiveButton
import com.ichi2.utils.show
import com.ichi2.utils.title

class ManageNotetypes : AnkiActivity() {
class ManageNotetypes : AnkiActivity(), ManageNoteTypeCallbacks {
private lateinit var actionBar: ActionBar
private lateinit var noteTypesList: RecyclerView

private var currentNotetypes: List<ManageNoteTypeUiModel> = emptyList()

private var toDeleteList: List<Long> = emptyList()

private var isInMultiSelectMode = false
private fun getIsInMultiSelectMode(): Boolean {
return isInMultiSelectMode
}

private val notetypesAdapter: NotetypesAdapter by lazy {
NotetypesAdapter(
this@ManageNotetypes,
Expand All @@ -70,6 +78,8 @@ class ManageNotetypes : AnkiActivity() {
},
onEditCards = { launchForChanges<CardTemplateEditor>(mapOf("modelId" to it.id)) },
onRename = ::renameNotetype,
callback = this,
getIsInMultiSelectMode = ::getIsInMultiSelectMode,
onDelete = ::deleteNotetype
)
}
Expand Down Expand Up @@ -101,6 +111,7 @@ class ManageNotetypes : AnkiActivity() {

override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.search, menu)
menuInflater.inflate(R.menu.menu_manage_notes, menu)

val searchItem = menu.findItem(R.id.search_item)
val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
Expand All @@ -125,8 +136,21 @@ class ManageNotetypes : AnkiActivity() {
return true
}
})

launchCatchingTask {
menu.findItem(R.id.action_delete_notes).isVisible = toDeleteList.isNotEmpty() && isInMultiSelectMode
}
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.action_delete_notes -> {
deleteSelectedNotetype()
true
}
else -> super.onOptionsItemSelected(item)
}
}

@SuppressLint("CheckResult")
private fun renameNotetype(manageNoteTypeUiModel: ManageNoteTypeUiModel) {
Expand Down Expand Up @@ -167,6 +191,28 @@ class ManageNotetypes : AnkiActivity() {
}
}

private fun deleteSelectedNotetype() {
val selectedItems = toDeleteList
AlertDialog.Builder(this@ManageNotetypes).show {
title(R.string.model_browser_delete)
message(R.string.model_delete_warning)
positiveButton(R.string.dialog_positive_delete) {
launchCatchingTask {
withProgress {
withCol {
selectedItems.forEach { item ->
removeNotetype(item)
}
}
}
runAndRefreshAfter()
}
disableMultiSelectMode()
}
negativeButton(R.string.dialog_cancel)
}
}

private fun deleteNotetype(manageNoteTypeUiModel: ManageNoteTypeUiModel) {
launchCatchingTask {
val messageResourceId: Int? = if (userAcceptsSchemaChange()) {
Expand Down Expand Up @@ -236,4 +282,36 @@ class ManageNotetypes : AnkiActivity() {
else -> throw IllegalArgumentException("Unexpected value type: ${newExtra.value}")
}
}

override fun enableMultiSelectMode() {
isInMultiSelectMode = false
notetypesAdapter.notifyItemRangeChanged(0, notetypesAdapter.itemCount, "payload_checkbox_visibility")
invalidateMenu()
}

override fun isToDeleteListContains(id: Long): Boolean {
return toDeleteList.contains(id)
}

override fun addInToDeleteList(id: Long, position: Int) {
if (!toDeleteList.contains(id)) {
toDeleteList = toDeleteList.plus(id)
}
notetypesAdapter.notifyItemChanged(position, "payload_checkbox_selection")
invalidateMenu()
}
override fun removeIdFromToDeleteList(id: Long, position: Int) {
if (toDeleteList.contains(id)) {
toDeleteList = toDeleteList.minus(id)
if (toDeleteList.isEmpty()) disableMultiSelectMode()
notetypesAdapter.notifyItemChanged(position, "payload_checkbox_selection")
}
invalidateMenu()
}
private fun disableMultiSelectMode() {
toDeleteList = emptyList()
isInMultiSelectMode = false
notetypesAdapter.notifyItemRangeChanged(0, notetypesAdapter.itemCount, "payload_checkbox_visibility")
invalidateMenu()
}
}
86 changes: 83 additions & 3 deletions AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.CheckBox
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
Expand All @@ -46,6 +47,8 @@ internal class NotetypesAdapter(
private val onShowFields: (ManageNoteTypeUiModel) -> Unit,
private val onEditCards: (ManageNoteTypeUiModel) -> Unit,
private val onRename: (ManageNoteTypeUiModel) -> Unit,
private val callback: ManageNoteTypeCallbacks,
private val getIsInMultiSelectMode: () -> Boolean,
private val onDelete: (ManageNoteTypeUiModel) -> Unit
) : ListAdapter<ManageNoteTypeUiModel, NotetypeViewHolder>(notetypeNamesAndCountDiff) {
private val layoutInflater = LayoutInflater.from(context)
Expand All @@ -56,44 +59,121 @@ internal class NotetypesAdapter(
onDelete = onDelete,
onRename = onRename,
onEditCards = onEditCards,
callback = callback,
getIsInMultiSelectMode = getIsInMultiSelectMode,
onShowFields = onShowFields
)
}

override fun onBindViewHolder(holder: NotetypeViewHolder, position: Int) {
holder.bind(getItem(position))
}

override fun onBindViewHolder(holder: NotetypeViewHolder, position: Int, payloads: List<Any>) {
if (payloads.isEmpty()) {
onBindViewHolder(holder, position)
} else {
for (payload in payloads) {
when (payload) {
"payload_checkbox_selection" -> {
// holder.setCheckBoxSelection(getItem(position))
}
"payload_checkbox_visibility" -> {
// holder.handleMultiselectMode(getItem(position))
}
}
}
}
}
}

internal class NotetypeViewHolder(
rowView: View,
onShowFields: (ManageNoteTypeUiModel) -> Unit,
private val onShowFields: (ManageNoteTypeUiModel) -> Unit,
private val callback: ManageNoteTypeCallbacks,
onEditCards: (ManageNoteTypeUiModel) -> Unit,
onRename: (ManageNoteTypeUiModel) -> Unit,
getIsInMultiSelectMode: () -> Boolean,
onDelete: (ManageNoteTypeUiModel) -> Unit
) : RecyclerView.ViewHolder(rowView) {
val name: TextView = rowView.findViewById(R.id.note_name)
val useCount: TextView = rowView.findViewById(R.id.note_use_count)
private val useCount: TextView = rowView.findViewById(R.id.note_use_count)
private val btnDelete: Button = rowView.findViewById(R.id.note_delete)
private val btnRename: Button = rowView.findViewById(R.id.note_rename)
private val btnEditCards: Button = rowView.findViewById(R.id.note_edit_cards)
private var mManageNoteTypeUiModel: ManageNoteTypeUiModel? = null
private val resources = rowView.context.resources
private val isInMultiSelectMode = getIsInMultiSelectMode
private val selectedItemCheckbox: CheckBox = rowView.findViewById(R.id.selected_item_checkbox)

init {
rowView.setOnClickListener { mManageNoteTypeUiModel?.let(onShowFields) }
btnEditCards.setOnClickListener { mManageNoteTypeUiModel?.let(onEditCards) }
btnDelete.setOnClickListener { mManageNoteTypeUiModel?.let(onDelete) }
btnRename.setOnClickListener { mManageNoteTypeUiModel?.let(onRename) }
}

fun bind(manageNoteTypeUiModel: ManageNoteTypeUiModel) {
if (isInMultiSelectMode()) {
showCheckBox(selectedItemCheckbox)
itemView.setOnClickListener {
toggleCheckBoxSelection(manageNoteTypeUiModel.id, bindingAdapterPosition)
}
} else {
hideCheckBox(selectedItemCheckbox)
itemView.setOnClickListener { mManageNoteTypeUiModel?.let(onShowFields) }
}

this.mManageNoteTypeUiModel = manageNoteTypeUiModel
name.text = manageNoteTypeUiModel.name
useCount.text = resources.getQuantityString(
R.plurals.model_browser_of_type,
manageNoteTypeUiModel.useCount,
manageNoteTypeUiModel.useCount
)
itemView.setOnLongClickListener {
if (!isInMultiSelectMode()) {
callback.enableMultiSelectMode()
}
callback.addInToDeleteList(manageNoteTypeUiModel.id, bindingAdapterPosition)
true
}
}

// fun handleMultiselectMode(manageNoteTypeUiModel: ManageNoteTypeUiModel) {
// if (isInMultiSelectMode()) {
// applyMultiSelectMode(manageNoteTypeUiModel)
// } else {
// removeMultiSelectMode(manageNoteTypeUiModel)
// }
// }
// fun setCheckBoxSelection(manageNoteTypeUiModel: ManageNoteTypeUiModel) {
// val isSelectedToDelete = callback.isToDeleteListContains(manageNoteTypeUiModel.id)
// selectedItemCheckbox.isChecked = isSelectedToDelete
// }
//
private fun toggleCheckBoxSelection(id: Long, bindingAdapterPosition: Int) {
if (callback.isToDeleteListContains(id)) {
callback.removeIdFromToDeleteList(id, bindingAdapterPosition)
} else {
callback.addInToDeleteList(id, bindingAdapterPosition)
}
}

// private fun removeMultiSelectMode(manageNoteTypeUiModel: ManageNoteTypeUiModel) {
// hideCheckBox(selectedItemCheckbox)
// callback.removeIdFromToDeleteList(manageNoteTypeUiModel.id, bindingAdapterPosition)
// itemView.setOnClickListener { mManageNoteTypeUiModel?.let(onShowFields) }
// }
// private fun applyMultiSelectMode(manageNoteTypeUiModel: ManageNoteTypeUiModel) {
// showCheckBox(selectedItemCheckbox)
// itemView.setOnClickListener {
// toggleCheckBoxSelection(manageNoteTypeUiModel.id, bindingAdapterPosition)
// }
// }
private fun hideCheckBox(checkBox: CheckBox) {
checkBox.visibility = View.GONE
}
private fun showCheckBox(checkBox: CheckBox) {
checkBox.visibility = View.VISIBLE
}
}
42 changes: 30 additions & 12 deletions AnkiDroid/src/main/res/layout/item_manage_note_type.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,41 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:orientation="horizontal"
android:padding="16dp">

<TextView
android:id="@+id/note_name"
tools:text="Basic (and reversed card)"
android:layout_width="wrap_content"
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="?attr/textAppearanceHeadline6" />
<TextView
android:id="@+id/note_use_count"
android:layout_weight="1"
android:orientation="vertical">

<TextView
android:id="@+id/note_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?attr/textAppearanceHeadline6"
tools:text="Basic (and reversed card)" />

<TextView
android:id="@+id/note_use_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textAppearance="?attr/textAppearanceBody2"
android:textColor="?android:attr/textColorSecondary"
tools:text="912 notes"/>
</LinearLayout>
<CheckBox
android:id="@+id/selected_item_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textAppearance="?attr/textAppearanceBody2"
android:textColor="?android:attr/textColorSecondary"
tools:text="912 notes"/>
android:checked="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:visibility="gone"
tools:visibility="visible" />

</LinearLayout>

<androidx.constraintlayout.widget.ConstraintLayout
Expand Down
12 changes: 12 additions & 0 deletions AnkiDroid/src/main/res/menu/menu_manage_notes.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ankidroid="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".DeckPicker">
<item
android:id="@+id/action_delete_notes"
android:icon="@drawable/ic_delete_white"
android:title="@string/dialog_positive_delete"
android:visible="false"
ankidroid:showAsAction="always"/>
</menu>

0 comments on commit 02b52e3

Please sign in to comment.