Skip to content

fix: deck picker subtitle ignores 9999 cap#21035

Open
onurds wants to merge 1 commit into
ankidroid:mainfrom
onurds:fix-17605-uncap-deck-picker-subtitle
Open

fix: deck picker subtitle ignores 9999 cap#21035
onurds wants to merge 1 commit into
ankidroid:mainfrom
onurds:fix-17605-uncap-deck-picker-subtitle

Conversation

@onurds
Copy link
Copy Markdown

@onurds onurds commented May 13, 2026

Purpose / Description

The "X cards due" subtitle on the deck picker home screen is capped at 9999
even when the user has many more cards due. Per discussion on r/Anki,
the 9999 cap on individual decks seems to be an intentional architectural decision in
the backend (rslib). Large numbers are not useful for individual
decks, and the clamp simplifies storage and display. That part is fine.

However, the overall total at the top of the screen also gets clamped,
because it is computed by reading the same count fields off the root of the
deck tree protobuf. That looks accidental to me, i think it would be a better idea to show the total amount of due cards for better understanding. But I would understand if it is also an architectural decision.

Fixes

Approach

Scheduler.counts() reads from getQueuedCards, which returns limit aware
and unclamped counts. This is the same source StudyOptionsFragment uses to
show the correct count for individual decks after Custom Study. Added a small
Scheduler.allDecksCountsUncapped() extension that iterates top level decks
and sums counts(), and switched DeckPickerViewModel.flowOfCardsDue to use
it instead of the clamped protobuf root. The 9999 cap on individual decks is preserved.

Side benefit: Custom Study limit extensions are now reflected in the subtitle.

How Has This Been Tested?

  • Tested on Android 16 physical device and emulator.
  • Before: subtitle reads "9999 cards due" on a large collection.
  • After: subtitle reads the true total (about 40k in my test collection).
  • Small collections (under 100 due) has no change.
  • Debug and lint tests.

Screenshots

6048706909906341658 6048706909906341670

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard to understand areas
  • You have performed a self review of your own code
  • UI changes: include screenshots of all affected screens
  • UI Changes: You have tested your change using the Google Accessibility Scanner

The subtitle reads the deck tree protobuf root's new, review and learn
count fields, each independently clamped at 9999 by the backend. As a
result the collection wide total stops at 9999 (or 3 × 9999 in mixed
queue collections) even when the user has many more cards due.

The per deck 9999 clamp is intentional in the upstream backend, but the
overall total at the top of the deck picker is not. Route that total
through Scheduler.counts (which sources from getQueuedCards and is both
limit aware and unclamped, same as StudyOptionsFragment) summed across
top level decks.

Side benefit: Custom Study limit extensions are now reflected in the
subtitle.

Fixes ankidroid#17605
Copy link
Copy Markdown
Member

@david-allison david-allison left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thanks for the PR!! This seems good quality, but it breaches our AI policy for new contributors:

https://github.com/ankidroid/Anki-Android/blob/main/AI_POLICY.md

emdash:

> * `getQueuedCards` and is both limit-aware and unclamped — the same source

It needs a test, and then a rewrite [assuming my comments are accurate and the uncapped values are correct], I'd happily merge after this is performed, great work!

// (backend behavior, shared with Anki Desktop), so summing the root's three
// fields underreports for large collections — see issue #17605. Route through
// `allDecksCountsUncapped` (uncapped, limit-aware via getQueuedCards) instead.
val flowOfCardsDue =
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a unit test

combine(flowOfDeckDueTree, flowOfDeckListInInitialState) { tree, inInitialState ->
if (tree == null || inInitialState != false) return@combine null
tree.newCount + tree.revCount + tree.lrnCount
withCol { sched.allDecksCountsUncapped().count() }
Copy link
Copy Markdown
Member

@david-allison david-allison May 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

com.ichi2.anki.libanki.sched.DeckNode's node property is a anki.decks.DeckTreeNode with uncapped values:

https://github.com/ankitects/anki/blob/1f0fc05f931fd5ac546d5e50bdf00508210912c6/proto/anki/decks.proto#L168-L172

I would define accessor properties in com.ichi2.anki.libanki.sched.DeckNode to expose the uncapped counts, and use them to build the total count.

Most of the work here will be defining an intuitive naming pattern to distinguish uncapped counts from regular counts, as the uncapped counts do not include children, whereas the capped counts do

@david-allison david-allison added the Needs Author Reply Waiting for a reply from the original author label May 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs Author Reply Waiting for a reply from the original author Needs Review New contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Total cards due at the top of the screen is incorrect if > 9999 cards in a queue

2 participants