Avoid showing the same verb back-to-back in practice

fetchDueCard now accepts the last-shown verb ID and prefers a
different verb from the due queue. Falls back to the same verb
only when it's the sole due card.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-04-11 23:27:29 -05:00
parent 636193fae1
commit c58313496e
2 changed files with 14 additions and 5 deletions

View File

@@ -48,7 +48,7 @@ struct PracticeSessionService {
PracticeSettings(progress: ReviewStore.fetchOrCreateUserProgress(context: cloudContext))
}
func nextCard(for focusMode: FocusMode) -> PracticeCardLoad? {
func nextCard(for focusMode: FocusMode, excludingVerbId lastVerbId: Int? = nil) -> PracticeCardLoad? {
switch focusMode {
case .weakVerbs:
if let form = pickWeakForm() {
@@ -62,7 +62,7 @@ struct PracticeSessionService {
break
}
if let dueCard = fetchDueCard() {
if let dueCard = fetchDueCard(excluding: lastVerbId) {
return loadCard(from: dueCard)
}
@@ -146,7 +146,7 @@ struct PracticeSessionService {
)
}
private func fetchDueCard() -> ReviewCard? {
private func fetchDueCard(excluding lastVerbId: Int?) -> ReviewCard? {
let settings = settings()
let allowedVerbIds = referenceStore.allowedVerbIDs(selectedLevel: settings.selectedLevel)
let now = Date()
@@ -157,11 +157,20 @@ struct PracticeSessionService {
descriptor.fetchLimit = settings.enabledTenses.isEmpty ? 10 : 50
let cards = (try? cloudContext.fetch(descriptor)) ?? []
return cards.first { card in
let eligible = cards.filter { card in
allowedVerbIds.contains(card.verbId) &&
(settings.enabledTenses.isEmpty || settings.enabledTenses.contains(card.tenseId)) &&
(settings.showVosotros || card.personIndex != 4)
}
// Prefer a card from a different verb than the last one shown.
// Fall back to the same verb only if it's the sole due card.
if let lastVerbId {
if let different = eligible.first(where: { $0.verbId != lastVerbId }) {
return different
}
}
return eligible.first
}
private func pickWeakForm() -> VerbForm? {

View File

@@ -96,7 +96,7 @@ final class PracticeViewModel {
hasCards = true
isLoading = true
let service = PracticeSessionService(localContext: localContext, cloudContext: cloudContext)
guard let cardLoad = service.nextCard(for: focusMode) else {
guard let cardLoad = service.nextCard(for: focusMode, excludingVerbId: currentVerb?.id) else {
clearCurrentCard()
hasCards = false
isLoading = false