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:
@@ -48,7 +48,7 @@ struct PracticeSessionService {
|
|||||||
PracticeSettings(progress: ReviewStore.fetchOrCreateUserProgress(context: cloudContext))
|
PracticeSettings(progress: ReviewStore.fetchOrCreateUserProgress(context: cloudContext))
|
||||||
}
|
}
|
||||||
|
|
||||||
func nextCard(for focusMode: FocusMode) -> PracticeCardLoad? {
|
func nextCard(for focusMode: FocusMode, excludingVerbId lastVerbId: Int? = nil) -> PracticeCardLoad? {
|
||||||
switch focusMode {
|
switch focusMode {
|
||||||
case .weakVerbs:
|
case .weakVerbs:
|
||||||
if let form = pickWeakForm() {
|
if let form = pickWeakForm() {
|
||||||
@@ -62,7 +62,7 @@ struct PracticeSessionService {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if let dueCard = fetchDueCard() {
|
if let dueCard = fetchDueCard(excluding: lastVerbId) {
|
||||||
return loadCard(from: dueCard)
|
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 settings = settings()
|
||||||
let allowedVerbIds = referenceStore.allowedVerbIDs(selectedLevel: settings.selectedLevel)
|
let allowedVerbIds = referenceStore.allowedVerbIDs(selectedLevel: settings.selectedLevel)
|
||||||
let now = Date()
|
let now = Date()
|
||||||
@@ -157,11 +157,20 @@ struct PracticeSessionService {
|
|||||||
descriptor.fetchLimit = settings.enabledTenses.isEmpty ? 10 : 50
|
descriptor.fetchLimit = settings.enabledTenses.isEmpty ? 10 : 50
|
||||||
let cards = (try? cloudContext.fetch(descriptor)) ?? []
|
let cards = (try? cloudContext.fetch(descriptor)) ?? []
|
||||||
|
|
||||||
return cards.first { card in
|
let eligible = cards.filter { card in
|
||||||
allowedVerbIds.contains(card.verbId) &&
|
allowedVerbIds.contains(card.verbId) &&
|
||||||
(settings.enabledTenses.isEmpty || settings.enabledTenses.contains(card.tenseId)) &&
|
(settings.enabledTenses.isEmpty || settings.enabledTenses.contains(card.tenseId)) &&
|
||||||
(settings.showVosotros || card.personIndex != 4)
|
(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? {
|
private func pickWeakForm() -> VerbForm? {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ final class PracticeViewModel {
|
|||||||
hasCards = true
|
hasCards = true
|
||||||
isLoading = true
|
isLoading = true
|
||||||
let service = PracticeSessionService(localContext: localContext, cloudContext: cloudContext)
|
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()
|
clearCurrentCard()
|
||||||
hasCards = false
|
hasCards = false
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
|||||||
Reference in New Issue
Block a user