Search in sources :

Example 1 with AnswerButtons

use of com.ichi2.anki.reviewer.AnswerButtons in project AnkiChinaAndroid by ankichinateam.

the class AbstractFlashcardViewer method answerCard.

protected void answerCard(@Consts.BUTTON_TYPE int ease) {
    if (mInAnswer) {
        return;
    }
    mIsSelecting = false;
    hideLookupButton();
    int buttonNumber = getCol().getSched().answerButtons(mCurrentCard);
    // Detect invalid ease for current card (e.g. by using keyboard shortcut or gesture).
    if (buttonNumber < ease) {
        return;
    }
    // Set the dots appearing below the toolbar
    switch(ease) {
        case EASE_1:
            mChosenAnswer.setText("\u2022");
            mChosenAnswer.setTextColor(ContextCompat.getColor(this, R.color.material_red_500));
            break;
        case EASE_2:
            mChosenAnswer.setText("\u2022\u2022");
            mChosenAnswer.setTextColor(ContextCompat.getColor(this, buttonNumber == Consts.BUTTON_FOUR ? R.color.material_blue_grey_600 : R.color.material_green_500));
            break;
        case EASE_3:
            mChosenAnswer.setText("\u2022\u2022\u2022");
            mChosenAnswer.setTextColor(ContextCompat.getColor(this, buttonNumber == Consts.BUTTON_FOUR ? R.color.material_green_500 : R.color.material_light_blue_500));
            break;
        case EASE_4:
            mChosenAnswer.setText("\u2022\u2022\u2022\u2022");
            mChosenAnswer.setTextColor(ContextCompat.getColor(this, R.color.material_light_blue_500));
            break;
        default:
            Timber.w("Unknown easy type %s", ease);
            break;
    }
    // remove chosen answer hint after a while
    mTimerHandler.removeCallbacks(removeChosenAnswerText);
    mTimerHandler.postDelayed(removeChosenAnswerText, mShowChosenAnswerLength);
    mSoundPlayer.stopSounds();
    stopOnlineSpeaking();
    mCurrentEase = ease;
    CollectionTask.launchCollectionTask(ANSWER_CARD, mAnswerCardHandler(true), new TaskData(mCurrentCard, mCurrentEase));
}
Also used : SuppressLint(android.annotation.SuppressLint) TaskData(com.ichi2.async.TaskData)

Example 2 with AnswerButtons

use of com.ichi2.anki.reviewer.AnswerButtons in project AnkiChinaAndroid by ankichinateam.

the class SchedV2Test method test_preview.

@Test
public void test_preview() throws Exception {
    // add cards
    Collection col = getColV2();
    Note note = col.newNote();
    note.setItem("Front", "one");
    col.addNote(note);
    Card c = note.cards().get(0);
    Card orig = c.clone();
    Note note2 = col.newNote();
    note2.setItem("Front", "two");
    col.addNote(note2);
    // cram deck
    long did = col.getDecks().newDyn("Cram");
    Deck cram = col.getDecks().get(did);
    cram.put("resched", false);
    col.getDecks().save(cram);
    col.getSched().rebuildDyn(did);
    col.reset();
    // grab the first card
    c = col.getSched().getCard();
    assertEquals(2, col.getSched().answerButtons(c));
    assertEquals(600, col.getSched().nextIvl(c, 1));
    assertEquals(0, col.getSched().nextIvl(c, 2));
    // failing it will push its due time back
    long due = c.getDue();
    col.getSched().answerCard(c, 1);
    assertNotEquals(c.getDue(), due);
    // the other card should come next
    Card c2 = col.getSched().getCard();
    assertNotEquals(c2.getId(), c.getId());
    // passing it will remove it
    col.getSched().answerCard(c2, 2);
    assertEquals(QUEUE_TYPE_NEW, c2.getQueue());
    assertEquals(0, c2.getReps());
    assertEquals(CARD_TYPE_NEW, c2.getType());
    // the other card should appear again
    c = col.getSched().getCard();
    assertEquals(orig.getId(), c.getId());
    // emptying the filtered deck should restore card
    col.getSched().emptyDyn(did);
    c.load();
    assertEquals(QUEUE_TYPE_NEW, c.getQueue());
    assertEquals(0, c.getReps());
    assertEquals(CARD_TYPE_NEW, c.getType());
}
Also used : Note(com.ichi2.libanki.Note) Collection(com.ichi2.libanki.Collection) Deck(com.ichi2.libanki.Deck) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 3 with AnswerButtons

use of com.ichi2.anki.reviewer.AnswerButtons in project AnkiChinaAndroid by ankichinateam.

the class SchedV2Test method filteredDeckSchedulingOptionsRegressionTest.

/**
 * Reported by /u/CarelessSecretary9 on reddit:
 */
@Test
public void filteredDeckSchedulingOptionsRegressionTest() {
    Collection col = getCol();
    col.setCrt(1587852900L);
    // 30 minutes learn ahead. required as we have 20m delay
    col.getConf().put("collapseTime", 1800);
    long homeDeckId = addDeck("Poorretention");
    DeckConfig homeDeckConf = col.getDecks().confForDid(homeDeckId);
    JSONObject lapse = homeDeckConf.getJSONObject("lapse");
    lapse.put("minInt", 2);
    lapse.put("mult", 0.7d);
    lapse.put("delays", new JSONArray("[20]"));
    ensureLapseMatchesSppliedAnkiDesktopConfig(lapse);
    col.flush();
    long dynId = addDynamicDeck("Dyn");
    /*
        >>> pp(self.reviewer.card)
        {'data': '', 'did': 1587939535230, 'due': 0, 'factor': 1300, 'flags': 0, 'id': 1510928829863, 'ivl': 25,
        'lapses': 5, 'left': 1004, 'mod': 1587921512, 'nid': 1510928805161, 'odid': 1587920944107,
        'odue': 0, 'ord': 0, 'queue': 2, 'reps': 22, 'type': 2, 'usn': -1}

         */
    Note n = addNoteUsingBasicModel("Hello", "World");
    Card c = getOnlyElement(n.cards());
    c.setType(Consts.CARD_TYPE_REV);
    c.setQueue(Consts.QUEUE_TYPE_REV);
    c.setIvl(25);
    c.setDue(0);
    c.setLapses(5);
    c.setFactor(1300);
    c.setLeft(1004);
    c.setODid(homeDeckId);
    c.setDid(dynId);
    c.flush();
    SchedV2 v2 = new SchedV2(col);
    Card schedCard = v2.getCard();
    assertThat(schedCard, Matchers.notNullValue());
    v2.answerCard(schedCard, Consts.BUTTON_ONE);
    assertThat("The lapsed card should now be counted as lrn", v2.mLrnCount, is(1));
    Card after = v2.getCard();
    assertThat("A card should be returned ", after, Matchers.notNullValue());
    /* Data from Anki - pp(self.reviewer.card)
        {'data': '', 'did': 1587939535230, 'due': 1587941137, 'factor': 1300,
        'flags': 0, 'id': 1510928829863, 'ivl': 17, 'lapses': 6, 'left': 1001,
        'mod': 1587939720, 'nid': 1510928805161, 'odid': 1587920944107, 'odue': 0,
        'ord': 0, 'queue': 1, 'reps': 23, 'type': 3, 'usn': -1}
         */
    assertThat(after.getType(), is(Consts.CARD_TYPE_RELEARNING));
    assertThat(after.getQueue(), is(Consts.QUEUE_TYPE_LRN));
    assertThat(after.getLeft(), is(1001));
    assertThat("ivl is reduced by 70%", after.getIvl(), is(17));
    assertThat("One lapse is added", after.getLapses(), is(6));
    assertThat(v2.answerButtons(after), is(4));
    long one = v2.nextIvl(after, Consts.BUTTON_ONE);
    long two = v2.nextIvl(after, Consts.BUTTON_TWO);
    long three = v2.nextIvl(after, Consts.BUTTON_THREE);
    long four = v2.nextIvl(after, Consts.BUTTON_FOUR);
    // 20 mins
    assertThat("Again should pick the current step", one, is(1200L));
    // 30 mins
    assertThat("Repeating single step - 20 minutes * 1.5", two, is(1800L));
    // 17 days
    assertThat("Good should take the reduced interval (25 * 0.7)", three, is(1468800L));
    // 18 days
    assertThat("Easy should have a bonus day over good", four, is(1555200L));
}
Also used : JSONObject(com.ichi2.utils.JSONObject) Note(com.ichi2.libanki.Note) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 4 with AnswerButtons

use of com.ichi2.anki.reviewer.AnswerButtons in project AnkiChinaAndroid by ankichinateam.

the class SchedV2Test method test_filt_reviewing_early_normal.

@Test
public void test_filt_reviewing_early_normal() throws Exception {
    Collection col = getColV2();
    Note note = col.newNote();
    note.setItem("Front", "one");
    col.addNote(note);
    Card c = note.cards().get(0);
    c.setIvl(100);
    c.setQueue(CARD_TYPE_REV);
    c.setType(QUEUE_TYPE_REV);
    // due in 25 days, so it's been waiting 75 days
    c.setDue(col.getSched().getToday() + 25);
    c.setMod(1);
    c.setFactor(STARTING_FACTOR);
    c.startTimer();
    c.flush();
    col.reset();
    assertArrayEquals(new int[] { 0, 0, 0 }, col.getSched().counts());
    // create a dynamic deck and refresh it
    long did = col.getDecks().newDyn("Cram");
    col.getSched().rebuildDyn(did);
    col.reset();
    // should appear as normal in the deck list
    /* todo sort
           assertEquals(1, sorted(col.getSched().deckDueTree().getChildren())[0].review_count);
        */
    // and should appear in the counts
    assertArrayEquals(new int[] { 0, 0, 1 }, col.getSched().counts());
    // grab it and check estimates
    c = col.getSched().getCard();
    assertEquals(4, col.getSched().answerButtons(c));
    assertEquals(600, col.getSched().nextIvl(c, 1));
    assertEquals(Math.round(75 * 1.2) * SECONDS_PER_DAY, col.getSched().nextIvl(c, 2));
    assertThat(col.getSched().nextIvl(c, 3), is((long) (75 * 2.5) * SECONDS_PER_DAY));
    assertThat(col.getSched().nextIvl(c, 4), is((long) (75 * 2.5 * 1.15) * SECONDS_PER_DAY));
    // answer 'good'
    col.getSched().answerCard(c, 3);
    checkRevIvl(col, c, 90);
    assertEquals(col.getSched().getToday() + c.getIvl(), c.getDue());
    assertEquals(0L, c.getODue());
    // should not be in learning
    assertEquals(QUEUE_TYPE_REV, c.getQueue());
    // should be logged as a cram rep
    assertEquals(3, col.getDb().queryLongScalar("select type from revlog order by id desc limit 1"));
    // due in 75 days, so it's been waiting 25 days
    c.setIvl(100);
    c.setDue(col.getSched().getToday() + 75);
    c.flush();
    col.getSched().rebuildDyn(did);
    col.reset();
    c = col.getSched().getCard();
    assertEquals(60 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 2));
    assertEquals(100 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 3));
    assertEquals(114 * SECONDS_PER_DAY, col.getSched().nextIvl(c, 4));
}
Also used : Note(com.ichi2.libanki.Note) Collection(com.ichi2.libanki.Collection) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Example 5 with AnswerButtons

use of com.ichi2.anki.reviewer.AnswerButtons in project Anki-Android by ankidroid.

the class SchedV2Test method filteredDeckSchedulingOptionsRegressionTest.

/**
 * Reported by /u/CarelessSecretary9 on reddit:
 */
@Test
public void filteredDeckSchedulingOptionsRegressionTest() {
    Collection col = getCol();
    col.setCrt(1587852900L);
    // 30 minutes learn ahead. required as we have 20m delay
    col.set_config("collapseTime", 1800);
    long homeDeckId = addDeck("Poorretention");
    DeckConfig homeDeckConf = col.getDecks().confForDid(homeDeckId);
    JSONObject lapse = homeDeckConf.getJSONObject("lapse");
    lapse.put("minInt", 2);
    lapse.put("mult", 0.7d);
    lapse.put("delays", new JSONArray("[20]"));
    col.getDecks().save(homeDeckConf);
    ensureLapseMatchesSppliedAnkiDesktopConfig(lapse);
    col.flush();
    long dynId = addDynamicDeck("Dyn");
    /*
        >>> pp(self.reviewer.card)
        {'data': '', 'did': 1587939535230, 'due': 0, 'factor': 1300, 'flags': 0, 'id': 1510928829863, 'ivl': 25,
        'lapses': 5, 'left': 1004, 'mod': 1587921512, 'nid': 1510928805161, 'odid': 1587920944107,
        'odue': 0, 'ord': 0, 'queue': 2, 'reps': 22, 'type': 2, 'usn': -1}

         */
    Note n = addNoteUsingBasicModel("Hello", "World");
    Card c = getOnlyElement(n.cards());
    c.setType(CARD_TYPE_REV);
    c.setQueue(QUEUE_TYPE_REV);
    c.setIvl(25);
    c.setDue(0);
    c.setLapses(5);
    c.setFactor(1300);
    c.setLeft(1004);
    c.setODid(homeDeckId);
    c.setDid(dynId);
    c.flush();
    SchedV2 v2 = new SchedV2(col);
    Card schedCard = v2.getCard();
    assertThat(schedCard, Matchers.notNullValue());
    v2.answerCard(schedCard, BUTTON_ONE);
    assertThat("The lapsed card should now be counted as lrn", v2.mLrnCount, is(1));
    Card after = v2.getCard();
    assertThat("A card should be returned ", after, Matchers.notNullValue());
    /* Data from Anki - pp(self.reviewer.card)
        {'data': '', 'did': 1587939535230, 'due': 1587941137, 'factor': 1300,
        'flags': 0, 'id': 1510928829863, 'ivl': 17, 'lapses': 6, 'left': 1001,
        'mod': 1587939720, 'nid': 1510928805161, 'odid': 1587920944107, 'odue': 0,
        'ord': 0, 'queue': 1, 'reps': 23, 'type': 3, 'usn': -1}
         */
    assertThat(after.getType(), is(Consts.CARD_TYPE_RELEARNING));
    assertThat(after.getQueue(), is(Consts.QUEUE_TYPE_LRN));
    assertThat(after.getLeft(), is(1001));
    assertThat("ivl is reduced by 70%", after.getIvl(), is(17));
    assertThat("One lapse is added", after.getLapses(), is(6));
    assertThat(v2.answerButtons(after), is(4));
    long one = v2.nextIvl(after, BUTTON_ONE);
    long two = v2.nextIvl(after, BUTTON_TWO);
    long three = v2.nextIvl(after, BUTTON_THREE);
    long four = v2.nextIvl(after, BUTTON_FOUR);
    // 20 mins
    assertThat("Again should pick the current step", one, is(1200L));
    // 30 mins
    assertThat("Repeating single step - 20 minutes * 1.5", two, is(1800L));
    // 17 days
    assertThat("Good should take the reduced interval (25 * 0.7)", three, is(1468800L));
    // 18 days
    assertThat("Easy should have a bonus day over good", four, is(1555200L));
}
Also used : JSONObject(com.ichi2.utils.JSONObject) Note(com.ichi2.libanki.Note) JSONArray(com.ichi2.utils.JSONArray) Collection(com.ichi2.libanki.Collection) DeckConfig(com.ichi2.libanki.DeckConfig) Card(com.ichi2.libanki.Card) RobolectricTest(com.ichi2.anki.RobolectricTest) Test(org.junit.Test)

Aggregations

Card (com.ichi2.libanki.Card)10 Collection (com.ichi2.libanki.Collection)10 Note (com.ichi2.libanki.Note)10 RobolectricTest (com.ichi2.anki.RobolectricTest)8 Test (org.junit.Test)8 JSONArray (com.ichi2.utils.JSONArray)6 Deck (com.ichi2.libanki.Deck)4 JSONObject (com.ichi2.utils.JSONObject)4 SuppressLint (android.annotation.SuppressLint)2 MatrixCursor (android.database.MatrixCursor)2 DeckConfig (com.ichi2.libanki.DeckConfig)2 Model (com.ichi2.libanki.Model)2 DeckDueTreeNode (com.ichi2.libanki.sched.DeckDueTreeNode)2 JSONException (com.ichi2.utils.JSONException)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 SharedPreferences (android.content.SharedPreferences)1 View (android.view.View)1 WebView (android.webkit.WebView)1 ImageView (android.widget.ImageView)1