Vocab Flashcards — make session size configurable in Settings

VocabVerbPool.sessionCardLimit was hardcoded at 20. Settings now has a
"Vocab Flashcards → Cards per session" picker (10 / 15 / 20 / 25 / 30 /
50 / All) backed by the vocabSessionCardLimit @AppStorage key.

VocabVerbPool.sessionCardLimit became a computed property reading that
key (0/unset → default 20; 999 → "All"). Applies to both Quiz and Learn
modes since they share the same session pool.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Trey T
2026-05-17 13:06:07 -05:00
parent f14008f96f
commit cee962c0e0
2 changed files with 23 additions and 3 deletions
@@ -116,9 +116,13 @@ struct VocabSessionQueue {
/// sitting is bounded proper SRS behaviour rather than a 100+ card slog. /// sitting is bounded proper SRS behaviour rather than a 100+ card slog.
enum VocabVerbPool { enum VocabVerbPool {
/// Maximum verbs in one session. Overdue cards are pulled first, then new /// Maximum verbs in one session, from the "Cards per session" setting
/// (never-reviewed) verbs fill the rest. /// (`vocabSessionCardLimit`). Defaults to 20 when unset; 999 means "All".
static let sessionCardLimit = 20 /// Overdue cards are pulled first, then new (never-reviewed) verbs.
static var sessionCardLimit: Int {
let stored = UserDefaults.standard.integer(forKey: "vocabSessionCardLimit")
return stored == 0 ? 20 : stored
}
static func sessionVerbs( static func sessionVerbs(
localContext: ModelContext, localContext: ModelContext,
@@ -10,6 +10,10 @@ struct SettingsView: View {
@State private var showVosotros: Bool = true @State private var showVosotros: Bool = true
@State private var autoFillStem: Bool = false @State private var autoFillStem: Bool = false
/// Cards per vocab-practice session. 999 = "All" (no cap).
@AppStorage("vocabSessionCardLimit") private var vocabSessionCardLimit: Int = 20
private let vocabSessionSizes: [Int] = [10, 15, 20, 25, 30, 50, 999]
private let levels = VerbLevel.allCases private let levels = VerbLevel.allCases
private let irregularCategories: [IrregularSpan.SpanCategory] = [ private let irregularCategories: [IrregularSpan.SpanCategory] = [
.spelling, .stemChange, .uniqueIrregular .spelling, .stemChange, .uniqueIrregular
@@ -42,6 +46,18 @@ struct SettingsView: View {
} }
} }
Section {
Picker("Cards per session", selection: $vocabSessionCardLimit) {
ForEach(vocabSessionSizes, id: \.self) { size in
Text(size == 999 ? "All" : "\(size)").tag(size)
}
}
} header: {
Text("Vocab Flashcards")
} footer: {
Text("How many verbs a Vocab Flashcards session draws. Overdue verbs are pulled first, then new ones.")
}
Section { Section {
ForEach(levels, id: \.self) { level in ForEach(levels, id: \.self) { level in
Toggle(level.displayName, isOn: Binding( Toggle(level.displayName, isOn: Binding(