Files
Spanish/Conjuga/Conjuga/Models/TenseInfo.swift
Trey t 40d436ad9c Highlight main tenses with Essential badges and focus mode
Mark 6 core tenses (presente, pretérito, imperfecto, futuro,
subjuntivo presente, imperativo) as essential. Add "Common Tenses"
quick action in Practice to drill only these. Show "Essential"
badge on core tenses in Guide > Tenses list.

Closes #3

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 10:07:46 -05:00

95 lines
4.9 KiB
Swift

import Foundation
enum TenseID: String, CaseIterable, Codable, Sendable, Hashable {
case ind_presente
case ind_preterito
case ind_imperfecto
case ind_futuro
case ind_perfecto
case ind_pluscuamperfecto
case ind_futuro_perfecto
case ind_preterito_anterior
case cond_presente
case cond_perfecto
case subj_presente
case subj_imperfecto_1
case subj_imperfecto_2
case subj_perfecto
case subj_pluscuamperfecto_1
case subj_pluscuamperfecto_2
case subj_futuro
case subj_futuro_perfecto
case imp_afirmativo
case imp_negativo
static let defaultPractice: [TenseID] = [
.ind_presente,
.ind_preterito,
.ind_imperfecto,
.ind_futuro,
]
/// The 6 most essential tenses every learner should master.
static let coreTenses: Set<TenseID> = [
.ind_presente,
.ind_preterito,
.ind_imperfecto,
.ind_futuro,
.subj_presente,
.imp_afirmativo,
]
static let coreTenseIDs = coreTenses.map(\.rawValue)
static let defaultPracticeIDs = defaultPractice.map(\.rawValue)
}
struct TenseInfo: Identifiable, Hashable, Sendable {
let id: String
let spanish: String
let english: String
let mood: String
let order: Int
var isCore: Bool {
TenseID(rawValue: id).map { TenseID.coreTenses.contains($0) } ?? false
}
static let all: [TenseInfo] = [
TenseInfo(id: TenseID.ind_presente.rawValue, spanish: "Indicativo Presente", english: "Present", mood: "Indicative", order: 0),
TenseInfo(id: TenseID.ind_preterito.rawValue, spanish: "Indicativo Pretérito", english: "Preterite", mood: "Indicative", order: 1),
TenseInfo(id: TenseID.ind_imperfecto.rawValue, spanish: "Indicativo Imperfecto", english: "Imperfect", mood: "Indicative", order: 2),
TenseInfo(id: TenseID.ind_futuro.rawValue, spanish: "Indicativo Futuro", english: "Future", mood: "Indicative", order: 3),
TenseInfo(id: TenseID.ind_perfecto.rawValue, spanish: "Indicativo Perfecto", english: "Present Perfect", mood: "Indicative", order: 4),
TenseInfo(id: TenseID.ind_pluscuamperfecto.rawValue, spanish: "Indicativo Pluscuamperfecto", english: "Pluperfect", mood: "Indicative", order: 5),
TenseInfo(id: TenseID.ind_futuro_perfecto.rawValue, spanish: "Indicativo Futuro Perfecto", english: "Future Perfect", mood: "Indicative", order: 6),
TenseInfo(id: TenseID.ind_preterito_anterior.rawValue, spanish: "Indicativo Pretérito Anterior", english: "Preterite Perfect", mood: "Indicative", order: 7),
TenseInfo(id: TenseID.cond_presente.rawValue, spanish: "Condicional Presente", english: "Conditional", mood: "Conditional", order: 8),
TenseInfo(id: TenseID.cond_perfecto.rawValue, spanish: "Condicional Perfecto", english: "Conditional Perfect", mood: "Conditional", order: 9),
TenseInfo(id: TenseID.subj_presente.rawValue, spanish: "Subjuntivo Presente", english: "Present Subjunctive", mood: "Subjunctive", order: 10),
TenseInfo(id: TenseID.subj_imperfecto_1.rawValue, spanish: "Subjuntivo Imperfecto I", english: "Past Subjunctive (ra)", mood: "Subjunctive", order: 11),
TenseInfo(id: TenseID.subj_imperfecto_2.rawValue, spanish: "Subjuntivo Imperfecto II", english: "Past Subjunctive (se)", mood: "Subjunctive", order: 12),
TenseInfo(id: TenseID.subj_perfecto.rawValue, spanish: "Subjuntivo Perfecto", english: "Subjunctive Perfect", mood: "Subjunctive", order: 13),
TenseInfo(id: TenseID.subj_pluscuamperfecto_1.rawValue, spanish: "Subjuntivo Pluscuamperfecto I", english: "Subjunctive Pluperfect (ra)", mood: "Subjunctive", order: 14),
TenseInfo(id: TenseID.subj_pluscuamperfecto_2.rawValue, spanish: "Subjuntivo Pluscuamperfecto II", english: "Subjunctive Pluperfect (se)", mood: "Subjunctive", order: 15),
TenseInfo(id: TenseID.subj_futuro.rawValue, spanish: "Subjuntivo Futuro", english: "Subjunctive Future", mood: "Subjunctive", order: 16),
TenseInfo(id: TenseID.subj_futuro_perfecto.rawValue, spanish: "Subjuntivo Futuro Perfecto", english: "Subjunctive Future Perfect", mood: "Subjunctive", order: 17),
TenseInfo(id: TenseID.imp_afirmativo.rawValue, spanish: "Imperativo Afirmativo", english: "Imperative", mood: "Imperative", order: 18),
TenseInfo(id: TenseID.imp_negativo.rawValue, spanish: "Imperativo Negativo", english: "Negative Imperative", mood: "Imperative", order: 19),
]
static let persons = ["yo", "", "él/ella/Ud.", "nosotros", "vosotros", "ellos/ellas/Uds."]
static func byMood() -> [(String, [TenseInfo])] {
let grouped = Dictionary(grouping: all, by: \.mood)
return ["Indicative", "Conditional", "Subjunctive", "Imperative"].compactMap { mood in
guard let tenses = grouped[mood] else { return nil }
return (mood, tenses.sorted { $0.order < $1.order })
}
}
static func find(_ id: String) -> TenseInfo? {
all.first { $0.id == id }
}
}