Skip to content

Commit

Permalink
Support deleting/undoing deck from deck picker
Browse files Browse the repository at this point in the history
+ Delete the cards inside the default deck if user tries to delete it

Closes ankidroid#11703
  • Loading branch information
dae committed Jul 4, 2022
1 parent e4eb805 commit c5d0f1b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 12 deletions.
32 changes: 24 additions & 8 deletions AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,8 @@ import com.ichi2.async.CollectionTask.*
import com.ichi2.async.Connection.CancellableTaskListener
import com.ichi2.async.Connection.ConflictResolution
import com.ichi2.compat.CompatHelper.Companion.sdkVersion
import com.ichi2.libanki.ChangeManager
import com.ichi2.libanki.*
import com.ichi2.libanki.Collection.CheckDatabaseResult
import com.ichi2.libanki.Consts
import com.ichi2.libanki.Decks
import com.ichi2.libanki.Utils
import com.ichi2.libanki.importer.AnkiPackageImporter
import com.ichi2.libanki.sched.AbstractDeckTreeNode
import com.ichi2.libanki.sched.TreeNode
Expand All @@ -108,6 +105,7 @@ import com.ichi2.ui.BadgeDrawableBuilder
import com.ichi2.utils.*
import com.ichi2.utils.Permissions.hasStorageAccessPermission
import com.ichi2.widget.WidgetStatus
import kotlinx.coroutines.Job
import net.ankiweb.rsdroid.BackendFactory
import net.ankiweb.rsdroid.RustCleanup
import timber.log.Timber
Expand Down Expand Up @@ -2224,15 +2222,32 @@ open class DeckPicker :
createDeckDialog.showDialog()
}

fun confirmDeckDeletion(did: Long) {
fun confirmDeckDeletion(did: Long): Job? {
if (!BackendFactory.defaultLegacySchema) {
dismissAllDialogFragments()
// No confirmation required, as undoable
return launchCatchingCollectionTask { col ->
val changes = runInBackgroundWithProgress {
undoableOp {
col.newDecks.removeDecks(listOf(did))
}
}
showSimpleSnackbar(
this@DeckPicker,
col.tr.browsingCardsDeleted(changes.count),
false
)
}
}

val res = resources
if (!colIsOpen()) {
return
return null
}
if (did == 1L) {
showSimpleSnackbar(this, R.string.delete_deck_default_deck, true)
dismissAllDialogFragments()
return
return null
}
// Get the number of cards contained in this deck and its subdecks
val cnt = DeckService.countCardsInDeckTree(col, did)
Expand All @@ -2241,7 +2256,7 @@ open class DeckPicker :
if (cnt == 0 && !isDyn) {
deleteDeck(did)
dismissAllDialogFragments()
return
return null
}
// Otherwise we show a warning and require confirmation
val msg: String
Expand All @@ -2252,6 +2267,7 @@ open class DeckPicker :
res.getQuantityString(R.plurals.delete_deck_message, cnt, deckName, cnt)
}
showDialogFragment(DeckPickerConfirmDeleteDeckDialog.newInstance(msg, did))
return null
}

/**
Expand Down
8 changes: 7 additions & 1 deletion AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import com.ichi2.testutils.DbUtils;
import com.ichi2.utils.ResourceLoader;

import net.ankiweb.rsdroid.BackendFactory;

import org.apache.commons.exec.OS;
import org.junit.Before;
import org.junit.Test;
Expand Down Expand Up @@ -237,7 +239,7 @@ public void confirmDeckDeletionDeletesEmptyDeck() {

DeckPicker deckPicker = startActivityNormallyOpenCollectionWithIntent(DeckPicker.class, new Intent());

deckPicker.confirmDeckDeletion(did);
awaitJob(deckPicker.confirmDeckDeletion(did));

advanceRobolectricLooperWithSleep();

Expand All @@ -246,6 +248,10 @@ public void confirmDeckDeletionDeletesEmptyDeck() {

@Test
public void deletion_of_filtered_deck_shows_warning_issue_10238() {
if (!BackendFactory.getDefaultLegacySchema()) {
// undoable
return;
}
// Filtered decks contain their own options, deleting one can cause a significant loss of work.
// And they are more likely to be empty temporarily
long did = addDynamicDeck("filtered");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class CreateDeckDialogTest : RobolectricTest() {

// After the last deck was created, delete a deck
if (decks.count() >= 10) {
deckPicker.confirmDeckDeletion(did)
awaitJob(deckPicker.confirmDeckDeletion(did))
assertEquals(deckCounter.decrementAndGet(), decks.count())

assertEquals(deckCounter.get(), decks.count())
Expand All @@ -186,7 +186,8 @@ class CreateDeckDialogTest : RobolectricTest() {
deckPicker.updateDeckList()
assertTrue(deckPicker.searchDecksIcon!!.isVisible)

deckPicker.confirmDeckDeletion(decks.id("Deck0::Deck1"))
awaitJob(deckPicker.confirmDeckDeletion(decks.id("Deck0::Deck1")))

assertEquals(2, decks.count())
deckPicker.updateDeckList()
assertFalse(deckPicker.searchDecksIcon!!.isVisible)
Expand All @@ -199,7 +200,8 @@ class CreateDeckDialogTest : RobolectricTest() {
deckPicker.updateDeckList()
assertTrue(deckPicker.searchDecksIcon!!.isVisible)

deckPicker.confirmDeckDeletion(decks.id("Deck0::Deck1"))
awaitJob(deckPicker.confirmDeckDeletion(decks.id("Deck0::Deck1")))

assertEquals(2, decks.count())
deckPicker.updateDeckList()
assertFalse(deckPicker.searchDecksIcon!!.isVisible)
Expand Down

0 comments on commit c5d0f1b

Please sign in to comment.