Search in sources :

Example 1 with Computation

use of com.ichi2.utils.Computation in project AnkiChinaAndroid by ankichinateam.

the class AdvancedStatistics method calculateDueAsMetaInfo.

/**
 * Determine forecast statistics based on a computation or simulation of future reviews.
 * Returns all information required by stats.java to plot the 'forecast' chart based on these statistics.
 * The chart will display:
 * - The forecasted number of reviews per review type (relearn, mature, young, learn) as bars
 * - The forecasted number of cards in each state (new, young, mature) as lines
 * @param metaInfo Object which will be filled with all information required by stats.java to plot the 'forecast' chart and returned by this method.
 * @param type Type of 'forecast' chart for which to determine forecast statistics. Accepted values:
 *             Stats.TYPE_MONTH: Determine forecast statistics for next 30 days with 1-day chunks
 *             Stats.TYPE_YEAR:  Determine forecast statistics for next year with 7-day chunks
 *             Stats.TYPE_LIFE:  Determine forecast statistics for next 2 years with 30-day chunks
 * @param context Contains The collection which contains the decks to be simulated.
 *             Also used for access to the database and access to the creation time of the collection.
 *             The creation time of the collection is needed since due times of cards are relative to the creation time of the collection.
 *             So we could pass mCol here.
 * @param dids Deck id's
 * @return @see #metaInfo
 */
public StatsMetaInfo calculateDueAsMetaInfo(StatsMetaInfo metaInfo, Stats.AxisType type, Context context, String dids) {
    if (!AnkiDroidApp.getSharedPrefs(context).getBoolean("advanced_statistics_enabled", false)) {
        return metaInfo;
    }
    // To indicate that we calculated the statistics so that Stats.java knows that it shouldn't display the standard Forecast chart.
    Settings = new Settings(context);
    metaInfo.setStatsCalculated(true);
    Collection mCol = CollectionHelper.getInstance().getCol(context);
    double[][] mSeriesList;
    int[] mValueLabels;
    int[] mColors;
    int[] mAxisTitles;
    int mMaxCards = 0;
    int mMaxElements;
    double mFirstElement;
    double mLastElement = 0;
    int mZeroIndex = 0;
    double[][] mCumulative;
    double mMcount;
    mValueLabels = new int[] { R.string.statistics_relearn, R.string.statistics_mature, R.string.statistics_young, R.string.statistics_learn };
    mColors = new int[] { R.attr.stats_relearn, R.attr.stats_mature, R.attr.stats_young, R.attr.stats_learn };
    mAxisTitles = new int[] { type.ordinal(), R.string.stats_cards, R.string.stats_cumulative_cards };
    PlottableSimulationResult simuationResult = calculateDueAsPlottableSimulationResult(type, mCol, dids);
    ArrayList<int[]> dues = simuationResult.getNReviews();
    mSeriesList = new double[REVIEW_TYPE_COUNT_PLUS_1][dues.size()];
    for (int t = 0; t < dues.size(); t++) {
        int[] data = dues.get(t);
        int nReviews = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + data[REVIEW_TYPE_MATURE_PLUS_1] + data[REVIEW_TYPE_RELEARN_PLUS_1];
        if (nReviews > mMaxCards)
            // Y-Axis: Max. value
            mMaxCards = nReviews;
        // In the bar-chart, the bars will be stacked on top of each other.
        // For the i^{th} bar counting from the bottom we therefore have to
        // provide the sum of the heights of the i^{th} bar and all bars below it.
        // X-Axis: Day / Week / Month
        mSeriesList[TIME][t] = data[TIME];
        mSeriesList[REVIEW_TYPE_LEARN_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + data[REVIEW_TYPE_MATURE_PLUS_1] + // Y-Axis: # Cards
        data[REVIEW_TYPE_RELEARN_PLUS_1];
        mSeriesList[REVIEW_TYPE_YOUNG_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + // Y-Axis: # Mature cards
        data[REVIEW_TYPE_MATURE_PLUS_1];
        mSeriesList[REVIEW_TYPE_MATURE_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + // Y-Axis: # Young
        data[REVIEW_TYPE_YOUNG_PLUS_1];
        // Y-Axis: # Learn
        mSeriesList[REVIEW_TYPE_RELEARN_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1];
        if (data[TIME] > mLastElement)
            // X-Axis: Max. value (only for TYPE_LIFE)
            mLastElement = data[TIME];
        if (data[TIME] == 0) {
            // Because we retrieve dues in the past and we should not cumulate them
            mZeroIndex = t;
        }
    }
    // # X values
    mMaxElements = dues.size() - 1;
    switch(type) {
        case TYPE_MONTH:
            // X-Axis: Max. value
            mLastElement = 31;
            break;
        case TYPE_YEAR:
            // X-Axis: Max. value
            mLastElement = 52;
            break;
        default:
    }
    // X-Axis: Min. value
    mFirstElement = 0;
    // Day starting at mZeroIndex, Cumulative # cards
    mCumulative = simuationResult.getNInState();
    mMcount = // Y-Axis: Max. cumulative value
    mCumulative[CARD_TYPE_NEW_PLUS_1][mCumulative[CARD_TYPE_NEW_PLUS_1].length - 1] + mCumulative[CARD_TYPE_YOUNG_PLUS_1][mCumulative[CARD_TYPE_YOUNG_PLUS_1].length - 1] + mCumulative[CARD_TYPE_MATURE_PLUS_1][mCumulative[CARD_TYPE_MATURE_PLUS_1].length - 1];
    // some adjustments to not crash the chartbuilding with empty data
    if (mMaxElements == 0) {
        mMaxElements = 10;
    }
    if (mMcount == 0) {
        mMcount = 10;
    }
    if (mFirstElement == mLastElement) {
        mFirstElement = 0;
        mLastElement = 6;
    }
    if (mMaxCards == 0)
        mMaxCards = 10;
    metaInfo.setmDynamicAxis(true);
    metaInfo.setmHasColoredCumulative(true);
    metaInfo.setmType(type);
    metaInfo.setmTitle(R.string.stats_forecast);
    metaInfo.setmBackwards(true);
    metaInfo.setmValueLabels(mValueLabels);
    metaInfo.setmColors(mColors);
    metaInfo.setmAxisTitles(mAxisTitles);
    metaInfo.setmMaxCards(mMaxCards);
    metaInfo.setmMaxElements(mMaxElements);
    metaInfo.setmFirstElement(mFirstElement);
    metaInfo.setmLastElement(mLastElement);
    metaInfo.setmZeroIndex(mZeroIndex);
    metaInfo.setmCumulative(mCumulative);
    metaInfo.setmMcount(mMcount);
    metaInfo.setmSeriesList(mSeriesList);
    metaInfo.setDataAvailable(dues.size() > 0);
    return metaInfo;
}
Also used : Collection(com.ichi2.libanki.Collection)

Example 2 with Computation

use of com.ichi2.utils.Computation in project Anki-Android by ankidroid.

the class AbstractFlashcardViewer method undo.

protected void undo() {
    if (isUndoAvailable()) {
        Resources res = getResources();
        String undoName = getCol().undoName(res);
        new UndoService.Undo().runWithHandler(answerCardHandler(false).alsoExecuteAfter(computation -> UIUtils.showThemedToast(AbstractFlashcardViewer.this, res.getString(R.string.undo_succeeded, undoName), false)));
    }
}
Also used : Bundle(android.os.Bundle) MaxExecFunction(com.ichi2.utils.MaxExecFunction) JsResult(android.webkit.JsResult) NonNull(androidx.annotation.NonNull) Uri(android.net.Uri) FrameLayout(android.widget.FrameLayout) ClipboardUtil(com.ichi2.utils.ClipboardUtil) AbstractSched(com.ichi2.libanki.sched.AbstractSched) RenderProcessGoneDetail(android.webkit.RenderProcessGoneDetail) HitTestResult(android.webkit.WebView.HitTestResult) ActionBar(androidx.appcompat.app.ActionBar) Decks(com.ichi2.libanki.Decks) AndroidUiUtils(com.ichi2.utils.AndroidUiUtils) CookieManager(android.webkit.CookieManager) Handler(android.os.Handler) GestureProcessor(com.ichi2.anki.cardviewer.GestureProcessor) AutomaticAnswer(com.ichi2.anki.reviewer.AutomaticAnswer) AssetHelper(com.ichi2.utils.AssetHelper) PreviousAnswerIndicator(com.ichi2.anki.reviewer.PreviousAnswerIndicator) TargetApi(android.annotation.TargetApi) ReadWriteLock(java.util.concurrent.locks.ReadWriteLock) FullDraggableContainer(com.drakeet.drawer.FullDraggableContainer) CoordinatorLayout(androidx.coordinatorlayout.widget.CoordinatorLayout) IntentFilter(android.content.IntentFilter) TTS(com.ichi2.anki.cardviewer.TTS) TypeAnswer(com.ichi2.anki.cardviewer.TypeAnswer) IdRes(androidx.annotation.IdRes) StringRes(androidx.annotation.StringRes) Unit(kotlin.Unit) Nullable(androidx.annotation.Nullable) TagsDialogListener(com.ichi2.anki.dialogs.tags.TagsDialogListener) Consts(com.ichi2.libanki.Consts) CompatHelper(com.ichi2.compat.CompatHelper) WebViewDebugging(com.ichi2.utils.WebViewDebugging) TagsDialogFactory(com.ichi2.anki.dialogs.tags.TagsDialogFactory) SoundOrVideoTag(com.ichi2.libanki.SoundOrVideoTag) WebResourceResponse(android.webkit.WebResourceResponse) RustCleanup(net.ankiweb.rsdroid.RustCleanup) GestureDetector(android.view.GestureDetector) ViewParent(android.view.ViewParent) HandlerUtils(com.ichi2.utils.HandlerUtils) TagsDialog(com.ichi2.anki.dialogs.tags.TagsDialog) Direction(com.ichi2.anim.ActivityTransitionAnimation.Direction) SystemClock(android.os.SystemClock) SdCardReceiver(com.ichi2.anki.receiver.SdCardReceiver) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) Supplier(java.util.function.Supplier) ViewAnimation(com.ichi2.anim.ViewAnimation) ArrayList(java.util.ArrayList) WebResourceRequest(android.webkit.WebResourceRequest) CardAppearance(com.ichi2.anki.cardviewer.CardAppearance) WebChromeClient(android.webkit.WebChromeClient) CheckResult(androidx.annotation.CheckResult) MissingImageHandler(com.ichi2.anki.cardviewer.MissingImageHandler) FileOutputStream(java.io.FileOutputStream) TextUtils(android.text.TextUtils) IOException(java.io.IOException) SoundSide(com.ichi2.libanki.Sound.SoundSide) File(java.io.File) Gravity(android.view.Gravity) Lock(java.util.concurrent.locks.Lock) SharedPreferences(android.content.SharedPreferences) Configuration(android.content.res.Configuration) AnkiMethod(com.ichi2.anki.servicelayer.AnkiMethod) SchedulerService(com.ichi2.anki.servicelayer.SchedulerService) LinearLayout(android.widget.LinearLayout) URLDecoder(java.net.URLDecoder) TaskManager(com.ichi2.async.TaskManager) EaseButton(com.ichi2.anki.reviewer.EaseButton) AutomaticAnswerAction(com.ichi2.anki.reviewer.AutomaticAnswerAction) WindowManager(android.view.WindowManager) ByteArrayInputStream(java.io.ByteArrayInputStream) ViewerCommand(com.ichi2.anki.cardviewer.ViewerCommand) WebViewClient(android.webkit.WebViewClient) View(android.view.View) Button(android.widget.Button) WebViewAssetLoader(androidx.webkit.WebViewAssetLoader) WebView(android.webkit.WebView) HashUtil(com.ichi2.utils.HashUtil) SimpleOnGestureListener(android.view.GestureDetector.SimpleOnGestureListener) TaskListenerBuilder(com.ichi2.anki.servicelayer.TaskListenerBuilder) BroadcastReceiver(android.content.BroadcastReceiver) ViewGroup(android.view.ViewGroup) Timber(timber.log.Timber) Objects(java.util.Objects) UndoService(com.ichi2.anki.servicelayer.UndoService) List(java.util.List) SoundPlayer(com.ichi2.anki.cardviewer.SoundPlayer) ActivityNotFoundException(android.content.ActivityNotFoundException) RelativeLayout(android.widget.RelativeLayout) MaterialDialog(com.afollestad.materialdialogs.MaterialDialog) FixedEditText(com.ichi2.ui.FixedEditText) EditorInfo(android.view.inputmethod.EditorInfo) Snackbar(com.google.android.material.snackbar.Snackbar) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Note(com.ichi2.libanki.Note) Context(android.content.Context) NextCard(com.ichi2.anki.servicelayer.SchedulerService.NextCard) TaskListener(com.ichi2.async.TaskListener) KeyEvent(android.view.KeyEvent) CardHtml(com.ichi2.anki.cardviewer.CardHtml) Pair(android.util.Pair) Intent(android.content.Intent) HashMap(java.util.HashMap) Collection(com.ichi2.libanki.Collection) Function(java.util.function.Function) InputMethodManager(android.view.inputmethod.InputMethodManager) ClipData(android.content.ClipData) HashSet(java.util.HashSet) SuppressLint(android.annotation.SuppressLint) MotionEvent(android.view.MotionEvent) TTSTag(com.ichi2.libanki.TTSTag) Build(android.os.Build) WeakReference(java.lang.ref.WeakReference) Sound(com.ichi2.libanki.Sound) Utils(com.ichi2.libanki.Utils) NoteService(com.ichi2.anki.servicelayer.NoteService) Computation(com.ichi2.utils.Computation) LayoutInflater(android.view.LayoutInflater) ReviewerUi(com.ichi2.anki.reviewer.ReviewerUi) CollectionTask(com.ichi2.async.CollectionTask) FileInputStream(java.io.FileInputStream) HtmlGenerator(com.ichi2.anki.cardviewer.HtmlGenerator) Side(com.ichi2.anki.cardviewer.Side) Themes(com.ichi2.themes.Themes) Color(android.graphics.Color) WebResourceError(android.webkit.WebResourceError) LanguageHintService(com.ichi2.anki.servicelayer.LanguageHintService) Consumer(java.util.function.Consumer) AdaptionUtil(com.ichi2.utils.AdaptionUtil) OnRenderProcessGoneDelegate(com.ichi2.anki.cardviewer.OnRenderProcessGoneDelegate) Card(com.ichi2.libanki.Card) VisibleForTesting(androidx.annotation.VisibleForTesting) FullScreenMode(com.ichi2.anki.reviewer.FullScreenMode) Resources(android.content.res.Resources) OnClickListener(android.view.View.OnClickListener) UndoService(com.ichi2.anki.servicelayer.UndoService) Resources(android.content.res.Resources)

Example 3 with Computation

use of com.ichi2.utils.Computation in project Anki-Android by ankidroid.

the class AdvancedStatistics method calculateDueAsMetaInfo.

/**
 * Determine forecast statistics based on a computation or simulation of future reviews.
 * Returns all information required by stats.java to plot the 'forecast' chart based on these statistics.
 * The chart will display:
 * - The forecasted number of reviews per review type (relearn, mature, young, learn) as bars
 * - The forecasted number of cards in each state (new, young, mature) as lines
 * @param metaInfo Object which will be filled with all information required by stats.java to plot the 'forecast' chart and returned by this method.
 * @param type Type of 'forecast' chart for which to determine forecast statistics. Accepted values:
 *             Stats.TYPE_MONTH: Determine forecast statistics for next 30 days with 1-day chunks
 *             Stats.TYPE_YEAR:  Determine forecast statistics for next year with 7-day chunks
 *             Stats.TYPE_LIFE:  Determine forecast statistics for next 2 years with 30-day chunks
 * @param context Contains The collection which contains the decks to be simulated.
 *             Also used for access to the database and access to the creation time of the collection.
 *             The creation time of the collection is needed since due times of cards are relative to the creation time of the collection.
 *             So we could pass mCol here.
 * @param dids Deck id's
 * @return @see #metaInfo
 */
public StatsMetaInfo calculateDueAsMetaInfo(StatsMetaInfo metaInfo, Stats.AxisType type, Context context, String dids) {
    if (!AnkiDroidApp.getSharedPrefs(context).getBoolean("advanced_statistics_enabled", false)) {
        return metaInfo;
    }
    // To indicate that we calculated the statistics so that Stats.java knows that it shouldn't display the standard Forecast chart.
    mSettings = new Settings(context);
    metaInfo.setStatsCalculated(true);
    Collection col = CollectionHelper.getInstance().getCol(context);
    int maxCards = 0;
    double lastElement = 0;
    int zeroIndex = 0;
    int[] valueLabels = { R.string.statistics_relearn, R.string.statistics_mature, R.string.statistics_young, R.string.statistics_learn };
    int[] colors = { R.attr.stats_relearn, R.attr.stats_mature, R.attr.stats_young, R.attr.stats_learn };
    int[] axisTitles = { type.ordinal(), R.string.stats_cards, R.string.stats_cumulative_cards };
    PlottableSimulationResult simuationResult = calculateDueAsPlottableSimulationResult(type, col, dids);
    ArrayList<int[]> dues = simuationResult.getNReviews();
    double[][] seriesList = new double[REVIEW_TYPE_COUNT_PLUS_1][dues.size()];
    for (int t = 0; t < dues.size(); t++) {
        int[] data = dues.get(t);
        int nReviews = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + data[REVIEW_TYPE_MATURE_PLUS_1] + data[REVIEW_TYPE_RELEARN_PLUS_1];
        if (nReviews > maxCards)
            // Y-Axis: Max. value
            maxCards = nReviews;
        // In the bar-chart, the bars will be stacked on top of each other.
        // For the i^{th} bar counting from the bottom we therefore have to
        // provide the sum of the heights of the i^{th} bar and all bars below it.
        // X-Axis: Day / Week / Month
        seriesList[TIME][t] = data[TIME];
        seriesList[REVIEW_TYPE_LEARN_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + data[REVIEW_TYPE_MATURE_PLUS_1] + // Y-Axis: # Cards
        data[REVIEW_TYPE_RELEARN_PLUS_1];
        seriesList[REVIEW_TYPE_YOUNG_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + data[REVIEW_TYPE_YOUNG_PLUS_1] + // Y-Axis: # Mature cards
        data[REVIEW_TYPE_MATURE_PLUS_1];
        seriesList[REVIEW_TYPE_MATURE_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] + // Y-Axis: # Young
        data[REVIEW_TYPE_YOUNG_PLUS_1];
        // Y-Axis: # Learn
        seriesList[REVIEW_TYPE_RELEARN_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1];
        if (data[TIME] > lastElement)
            // X-Axis: Max. value (only for TYPE_LIFE)
            lastElement = data[TIME];
        if (data[TIME] == 0) {
            // Because we retrieve dues in the past and we should not cumulate them
            zeroIndex = t;
        }
    }
    // # X values
    int maxElements = dues.size() - 1;
    switch(type) {
        case TYPE_MONTH:
            // X-Axis: Max. value
            lastElement = 31;
            break;
        case TYPE_YEAR:
            // X-Axis: Max. value
            lastElement = 52;
            break;
        default:
    }
    // X-Axis: Min. value
    double firstElement = 0;
    // Day starting at zeroIndex, Cumulative # cards
    double[][] cumulative = simuationResult.getNInState();
    double count = // Y-Axis: Max. cumulative value
    cumulative[CARD_TYPE_NEW_PLUS_1][cumulative[CARD_TYPE_NEW_PLUS_1].length - 1] + cumulative[CARD_TYPE_YOUNG_PLUS_1][cumulative[CARD_TYPE_YOUNG_PLUS_1].length - 1] + cumulative[CARD_TYPE_MATURE_PLUS_1][cumulative[CARD_TYPE_MATURE_PLUS_1].length - 1];
    // some adjustments to not crash the chartbuilding with empty data
    if (maxElements == 0) {
        maxElements = 10;
    }
    if (count == 0) {
        count = 10;
    }
    if (firstElement == lastElement) {
        firstElement = 0;
        lastElement = 6;
    }
    if (maxCards == 0)
        maxCards = 10;
    metaInfo.setmDynamicAxis(true);
    metaInfo.setmHasColoredCumulative(true);
    metaInfo.setmType(type);
    metaInfo.setmTitle(R.string.stats_forecast);
    metaInfo.setmBackwards(true);
    metaInfo.setmValueLabels(valueLabels);
    metaInfo.setmColors(colors);
    metaInfo.setmAxisTitles(axisTitles);
    metaInfo.setmMaxCards(maxCards);
    metaInfo.setmMaxElements(maxElements);
    metaInfo.setmFirstElement(firstElement);
    metaInfo.setmLastElement(lastElement);
    metaInfo.setmZeroIndex(zeroIndex);
    metaInfo.setmCumulative(cumulative);
    metaInfo.setmMcount(count);
    metaInfo.setmSeriesList(seriesList);
    metaInfo.setDataAvailable(!dues.isEmpty());
    return metaInfo;
}
Also used : Collection(com.ichi2.libanki.Collection)

Example 4 with Computation

use of com.ichi2.utils.Computation in project AnkiChinaAndroid by ankichinateam.

the class SchedV2 method _deckRevLimitSingle.

/**
 * Maximal number of rev card still to see today in deck d. It's computed as:
 * the number of rev card to see by day according to the deck optinos
 * minus the number of rev cards seen today in deck d or a descendant
 * plus the number of extra cards to see today in deck d, a parent or a descendant.
 *
 * Respects the limits of its ancestor, either given as parentLimit, or through direct computation.
 */
private int _deckRevLimitSingle(@Nullable Deck d, Integer parentLimit) {
    // invalid deck selected?
    if (d == null) {
        return 0;
    }
    if (d.getInt("dyn") != 0) {
        return mDynReportLimit;
    }
    long did = d.getLong("id");
    @NonNull DeckConfig c = mCol.getDecks().confForDid(did);
    int lim = Math.max(0, c.getJSONObject("rev").getInt("perDay") - d.getJSONArray("revToday").getInt(1));
    // So currentCard does not have to be taken into consideration in this method
    if (currentCardIsInQueueWithDeck(Consts.QUEUE_TYPE_REV, did)) {
        lim--;
    }
    if (parentLimit != null) {
        return Math.min(parentLimit, lim);
    } else if (!d.getString("name").contains("::")) {
        return lim;
    } else {
        for (@NonNull Deck parent : mCol.getDecks().parents(did)) {
            // pass in dummy parentLimit so we don't do parent lookup again
            lim = Math.min(lim, _deckRevLimitSingle(parent, lim));
        }
        return lim;
    }
}
Also used : NonNull(androidx.annotation.NonNull) Deck(com.ichi2.libanki.Deck) DeckConfig(com.ichi2.libanki.DeckConfig)

Example 5 with Computation

use of com.ichi2.utils.Computation in project Anki-Android by ankidroid.

the class SchedV2 method _deckRevLimitSingle.

/**
 * Maximal number of rev card still to see today in deck d. It's computed as:
 * the number of rev card to see by day according to the deck optinos
 * minus the number of rev cards seen today in deck d or a descendant
 * plus the number of extra cards to see today in deck d, a parent or a descendant.
 *
 * Respects the limits of its ancestor, either given as parentLimit, or through direct computation.
 * @param parentLimit Limit of the parent, this is an upper bound on the limit of this deck
 * @param considerCurrentCard whether the current card should be taken from the limit (if it belongs to this deck)
 */
private int _deckRevLimitSingle(@Nullable Deck d, Integer parentLimit, boolean considerCurrentCard) {
    // invalid deck selected?
    if (d == null) {
        return 0;
    }
    if (d.isDyn()) {
        return mDynReportLimit;
    }
    long did = d.getLong("id");
    @NonNull DeckConfig c = mCol.getDecks().confForDid(did);
    int lim = Math.max(0, c.getJSONObject("rev").getInt("perDay") - d.getJSONArray("revToday").getInt(1));
    // So currentCard does not have to be taken into consideration in this method
    if (considerCurrentCard && currentCardIsInQueueWithDeck(Consts.QUEUE_TYPE_REV, did)) {
        lim--;
    }
    return lim;
}
Also used : NonNull(androidx.annotation.NonNull) DeckConfig(com.ichi2.libanki.DeckConfig)

Aggregations

Collection (com.ichi2.libanki.Collection)3 NonNull (androidx.annotation.NonNull)2 DeckConfig (com.ichi2.libanki.DeckConfig)2 SuppressLint (android.annotation.SuppressLint)1 TargetApi (android.annotation.TargetApi)1 ActivityNotFoundException (android.content.ActivityNotFoundException)1 BroadcastReceiver (android.content.BroadcastReceiver)1 ClipData (android.content.ClipData)1 Context (android.content.Context)1 Intent (android.content.Intent)1 IntentFilter (android.content.IntentFilter)1 SharedPreferences (android.content.SharedPreferences)1 Configuration (android.content.res.Configuration)1 Resources (android.content.res.Resources)1 Color (android.graphics.Color)1 Uri (android.net.Uri)1 Build (android.os.Build)1 Bundle (android.os.Bundle)1 Handler (android.os.Handler)1 SystemClock (android.os.SystemClock)1