Search in sources :

Example 26 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project AnkiChinaAndroid by ankichinateam.

the class SchedV2 method undoReview.

@Override
public void undoReview(@NonNull Card oldCardData, boolean wasLeech) {
    // remove leech tag if it didn't have it before
    if (!wasLeech && oldCardData.note().hasTag("leech")) {
        oldCardData.note().delTag("leech");
        oldCardData.note().flush();
    }
    Timber.i("Undo Review of card %d, leech: %b", oldCardData.getId(), wasLeech);
    // write old data
    oldCardData.flush(false);
    DeckConfig conf = _cardConf(oldCardData);
    boolean previewing = conf.getInt("dyn") != 0 && !conf.getBoolean("resched");
    if (!previewing) {
        // and delete revlog entry
        long last = mCol.getDb().queryLongScalar("SELECT id FROM revlog WHERE cid = ? ORDER BY id DESC LIMIT 1", oldCardData.getId());
        mCol.getDb().execute("DELETE FROM revlog WHERE id = " + last);
    }
    // restore any siblings
    mCol.getDb().execute("update cards set queue=type,mod=?,usn=? where queue=" + Consts.QUEUE_TYPE_SIBLING_BURIED + " and nid=?", getTime().intTime(), mCol.usn(), oldCardData.getNid());
    // and finally, update daily count
    @Consts.CARD_QUEUE int n = oldCardData.getQueue() == Consts.QUEUE_TYPE_DAY_LEARN_RELEARN ? Consts.QUEUE_TYPE_LRN : oldCardData.getQueue();
    String type = (new String[] { "new", "lrn", "rev" })[n];
    _updateStats(oldCardData, type, -1);
    decrReps();
}
Also used : DeckConfig(com.ichi2.libanki.DeckConfig)

Example 27 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project AnkiChinaAndroid by ankichinateam.

the class AbstractSchedTest method testUndoResetsCardCountsToCorrectValue.

@Test
public void testUndoResetsCardCountsToCorrectValue() throws InterruptedException {
    // #6587
    addNoteUsingBasicModel("Hello", "World");
    Collection col = getCol();
    AbstractSched sched = col.getSched();
    col.reset();
    Card cardBeforeUndo = sched.getCard();
    int[] countsBeforeUndo = sched.counts();
    // Not shown in the UI, but there is a state where the card has been removed from the queue, but not answered
    // where the counts are decremented.
    assertThat(countsBeforeUndo, is(new int[] { 0, 0, 0 }));
    sched.answerCard(cardBeforeUndo, EASE_3);
    waitForTask(UNDO, 5000);
    int[] countsAfterUndo = sched.counts();
    assertThat("Counts after an undo should be the same as before an undo", countsAfterUndo, is(countsBeforeUndo));
}
Also used : Collection(com.ichi2.libanki.Collection) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 28 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project Anki-Android by ankidroid.

the class UndoTest method test_review.

@Test
public void test_review() throws Exception {
    Collection col = getColV2();
    col.set_config("counts", COUNT_REMAINING);
    Note note = col.newNote();
    note.setItem("Front", "one");
    col.addNote(note);
    col.reset();
    /* TODO:  undo after reset ?
        assertNotNull(col.undoType());

         */
    // answer
    assertEquals(new Counts(1, 0, 0), col.getSched().counts());
    Card c = col.getSched().getCard();
    assertEquals(QUEUE_TYPE_NEW, c.getQueue());
    col.getSched().answerCard(c, Consts.BUTTON_THREE);
    assertEquals(1001, c.getLeft());
    assertEquals(new Counts(0, 1, 0), col.getSched().counts());
    assertEquals(QUEUE_TYPE_LRN, c.getQueue());
    // undo
    assertNotNull(col.undoType());
    col.undo();
    col.reset();
    assertEquals(new Counts(1, 0, 0), col.getSched().counts());
    c.load();
    assertEquals(QUEUE_TYPE_NEW, c.getQueue());
    assertNotEquals(1001, c.getLeft());
    assertNull(col.undoType());
    // we should be able to undo multiple answers too
    note = col.newNote();
    note.setItem("Front", "two");
    col.addNote(note);
    col.reset();
    assertEquals(new Counts(2, 0, 0), col.getSched().counts());
    c = col.getSched().getCard();
    col.getSched().answerCard(c, Consts.BUTTON_THREE);
    c = col.getSched().getCard();
    col.getSched().answerCard(c, Consts.BUTTON_THREE);
    assertEquals(new Counts(0, 2, 0), col.getSched().counts());
    col.undo();
    col.reset();
    assertEquals(new Counts(1, 1, 0), col.getSched().counts());
    col.undo();
    col.reset();
    assertEquals(new Counts(2, 0, 0), col.getSched().counts());
    // performing a normal op will clear the review queue
    c = col.getSched().getCard();
    col.getSched().answerCard(c, Consts.BUTTON_THREE);
    assertThat(col.undoType(), is(instanceOf(Collection.UndoReview.class)));
    col.save("foo");
    // Upstream, "save" can be undone. This test fails here because it's not the case in AnkiDroid
    assumeThat(col.undoName(getTargetContext().getResources()), is("foo"));
    col.undo();
}
Also used : Counts(com.ichi2.libanki.sched.Counts) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 29 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project Anki-Android by ankidroid.

the class AbstractSchedTest method testUndoResetsCardCountsToCorrectValue.

@Test
public void testUndoResetsCardCountsToCorrectValue() throws InterruptedException {
    // #6587
    addNoteUsingBasicModel("Hello", "World");
    Collection col = getCol();
    AbstractSched sched = col.getSched();
    col.reset();
    Card cardBeforeUndo = sched.getCard();
    Counts countsBeforeUndo = sched.counts();
    // Not shown in the UI, but there is a state where the card has been removed from the queue, but not answered
    // where the counts are decremented.
    assertThat(countsBeforeUndo, is(new Counts(0, 0, 0)));
    sched.answerCard(cardBeforeUndo, Consts.BUTTON_THREE);
    waitFortask(new UndoService.Undo().toDelegate(), 5000);
    Counts countsAfterUndo = sched.counts();
    assertThat("Counts after an undo should be the same as before an undo", countsAfterUndo, is(countsBeforeUndo));
}
Also used : Collection(com.ichi2.libanki.Collection) CollectionTask.nonTaskUndo(com.ichi2.async.CollectionTask.nonTaskUndo) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 30 with UNDO

use of com.ichi2.async.CollectionTask.TASK_TYPE.UNDO in project Anki-Android by ankidroid.

the class SchedV2 method undoReview.

@Override
public void undoReview(@NonNull Card oldCardData, boolean wasLeech) {
    // remove leech tag if it didn't have it before
    if (!wasLeech && oldCardData.note().hasTag("leech")) {
        oldCardData.note().delTag("leech");
        oldCardData.note().flush();
    }
    Timber.i("Undo Review of card %d, leech: %b", oldCardData.getId(), wasLeech);
    // write old data
    oldCardData.flush(false);
    DeckConfig conf = _cardConf(oldCardData);
    boolean previewing = conf.isDyn() && !conf.getBoolean("resched");
    if (!previewing) {
        // and delete revlog entry
        long last = mCol.getDb().queryLongScalar("SELECT id FROM revlog WHERE cid = ? ORDER BY id DESC LIMIT 1", oldCardData.getId());
        mCol.getDb().execute("DELETE FROM revlog WHERE id = " + last);
    }
    // restore any siblings
    mCol.getDb().execute("update cards set queue=type,mod=?,usn=? where queue=" + Consts.QUEUE_TYPE_SIBLING_BURIED + " and nid=?", getTime().intTime(), mCol.usn(), oldCardData.getNid());
    // and finally, update daily count
    @Consts.CARD_QUEUE int n = (oldCardData.getQueue() == Consts.QUEUE_TYPE_DAY_LEARN_RELEARN || oldCardData.getQueue() == Consts.QUEUE_TYPE_PREVIEW) ? Consts.QUEUE_TYPE_LRN : oldCardData.getQueue();
    String type = (new String[] { "new", "lrn", "rev" })[n];
    _updateStats(oldCardData, type, -1);
    decrReps();
}
Also used : DeckConfig(com.ichi2.libanki.DeckConfig)

Aggregations

Collection (com.ichi2.libanki.Collection)22 Card (com.ichi2.libanki.Card)15 JSONObject (com.ichi2.utils.JSONObject)13 Intent (android.content.Intent)8 JSONException (com.ichi2.utils.JSONException)7 ArrayList (java.util.ArrayList)7 MenuItem (android.view.MenuItem)6 View (android.view.View)6 VisibleForTesting (androidx.annotation.VisibleForTesting)6 Context (android.content.Context)5 SharedPreferences (android.content.SharedPreferences)5 Bundle (android.os.Bundle)5 Menu (android.view.Menu)5 WindowManager (android.view.WindowManager)5 TextView (android.widget.TextView)5 NonNull (androidx.annotation.NonNull)5 Nullable (androidx.annotation.Nullable)5 SearchView (androidx.appcompat.widget.SearchView)5 MaterialDialog (com.afollestad.materialdialogs.MaterialDialog)5 Snackbar (com.google.android.material.snackbar.Snackbar)5