Skip to content

Enable deck option target selection in study screen#19963

Open
lukstbit wants to merge 1 commit intoankidroid:mainfrom
lukstbit:feat_pickDeckOptionsTarget
Open

Enable deck option target selection in study screen#19963
lukstbit wants to merge 1 commit intoankidroid:mainfrom
lukstbit:feat_pickDeckOptionsTarget

Conversation

@lukstbit
Copy link
Member

@lukstbit lukstbit commented Dec 29, 2025

Purpose / Description

Added an implementation for this feature around the current code of DeckOptionsDestination. I'm open for suggestions on UI, I just added a simple dialog:

Normal decks(and with long names) + filtered decks Screenshot_20251230_093803Screenshot_20251230_093839

Screenshot_20251230_093858Screenshot_20251230_093915

Notice: the contrast isn't great for filtered deck color and black background.

Screenshot_20251230_093932Screenshot_20251230_094001

Screenshot_20251230_094023Screenshot_20251230_094049

Fixes

How Has This Been Tested?

Opened a lot of decks options screens, verified other usages of DeckOptionsDestination, ran tests.

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 (in particular showing any new or changed strings)
  • UI Changes: You have tested your change using the Google Accessibility Scanner

@david-allison
Copy link
Member

david-allison commented Dec 29, 2025

Awesome!


Something feels like it's missing visually, but I don't know what

What happens when a deck in the list is long and truncation occurs? Does :: cause problems here

What if there's a lot of entries in the list?

I'd be tempted to add the card count as a subtitle and see how this looks

Can you colour the filtered deck options the same colour as in the deck picker?

Does cancel need to be there? Back or tapping outside should be sufficient

@ZornHadNoChoice
Copy link

I might not be seeing clearly, but the dialog title doesn't feel prominent enough. Also, the Material 2 guidelines agree with david-allison.

@lukstbit lukstbit force-pushed the feat_pickDeckOptionsTarget branch from 354ef23 to 87279d8 Compare December 30, 2025 07:37
@lukstbit
Copy link
Member Author

I updated the images.

What happens when a deck in the list is long and truncation occurs? Does :: cause problems here

Just wraps around and makes the row bigger. I think this is better than truncating.

What if there's a lot of entries in the list?

At most there could be 3 entries based on the implementation.

I'd be tempted to add the card count as a subtitle and see how this looks

I don't think this is a good idea: it would complicate the implementation and I'm not sure what value offers to the user(besides desktop doesn't show this).

Can you colour the filtered deck options the same colour as in the deck picker?

Should've done this from the start.

Does cancel need to be there? Back or tapping outside should be sufficient

No and I removed it. I added it initially to follow the desktop ui.

I updated the dialog appearance by using MaterialAlertDialogBuilder. It has the same surface/container colors issue but this will be fixed later. The contrast for dynamic color on black theme is not great but I'm tempted to leave it for now and wait for the surface colors to be addressed.

Note on the previous design: I just used the normal dialog. Having the title so long probably feels like a message text and not a title.

Copy link
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.

Looks good! A couple questions

Also could do with @NeedsTest


viewModel.destinationFlow.collectIn(lifecycleScope) { destination ->
if (destination is DeckOptionsDestination && destination.haMultipleOptions) {
if (destination.options.any { it.name == null }) {
Copy link
Member

Choose a reason for hiding this comment

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

Is there any other way to handle a 'bad' deck as a non-representable state

for example: making the option itself null, rather than relying on the implicit assumption of name == null => invalid'.

Copy link
Member Author

Choose a reason for hiding this comment

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

making the option itself null, rather than relying on the implicit assumption of name == null => invalid'.

I modified the code to filter out the options that have a null deck name.

@david-allison david-allison added the Needs Author Reply Waiting for a reply from the original author label Jan 4, 2026
@lukstbit lukstbit force-pushed the feat_pickDeckOptionsTarget branch from 87279d8 to 3f64421 Compare January 21, 2026 08:57
@lukstbit lukstbit removed Needs Author Reply Waiting for a reply from the original author Has Conflicts labels Jan 21, 2026
The implementation is inserted around the current code so other usages
outside of the new study screen work as before.

See https://github.com/lukstbit/anki/blob/d24d2e33943af2361b5a9880572b30887efcf3ee/qt/aqt/deckoptions.py#L83-L100
@lukstbit lukstbit force-pushed the feat_pickDeckOptionsTarget branch from 3f64421 to df78cbb Compare January 21, 2026 11:26
@lukstbit
Copy link
Member Author

I think I fixed all raised issues.

@david-allison david-allison self-requested a review January 21, 2026 14:42
Copy link
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.

Image

Not sure if the start margin is correct.

I feel the text could do with more weight/size


Does this meet the contrast accessibility check?

Screenshot 2026-01-29 at 13 19 23

I'm an approve, trusting implementer on this

)
startActivity(updatedDestination.toIntent(requireContext()))
}
return@collectIn
Copy link
Member

Choose a reason for hiding this comment

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

Is there a need for this return?

val card = currentCard.await()
val options = getDeckOptionsTargets(deckId, card)
val isFiltered = options.first { it.deckId == deckId }.isFiltered
val destination = DeckOptionsDestination(deckId, isFiltered, options)
Copy link
Member

Choose a reason for hiding this comment

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

nit: this logic could be inside either: DeckOptionsDestination.create(deckId) or DeckOptionsDestination.from(deckId, options), one doing the isFiltered check, one extracting the logic

This feels like a general utility, rather than a responsibility of the study screen

@david-allison david-allison added Needs Author Reply Waiting for a reply from the original author Needs Second Approval Has one approval, one more approval to merge and removed Needs Review labels Jan 29, 2026
@david-allison david-allison added this to the 2.24 release milestone Jan 29, 2026
@github-actions
Copy link
Contributor

Hello 👋, this PR has had no activity for more than 2 weeks and needs a reply from the author. If you think this is a mistake please comment and ping a maintainer to get this merged ASAP! Thanks for contributing! You have 7 days until this gets closed automatically

@github-actions github-actions bot added the Stale label Feb 12, 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 Second Approval Has one approval, one more approval to merge Stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Let the user choose which deck's options to open in the reviewer

4 participants