Add a SwiftUI iOS app that plays the same maturita content.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
pepaskopec-blip 2026-09-18 14:01:01 +02:00
commit 6c7336c7bb
33 changed files with 4498 additions and 10 deletions

View file

@ -0,0 +1,81 @@
import Foundation
final class ProgressStore {
private let defaults = UserDefaults.standard
var themeId: ThemeId {
get { ThemeId(rawValue: defaults.integer(forKey: "theme")) ?? .catppuccin }
set { defaults.set(newValue.rawValue, forKey: "theme") }
}
var mode: ColorMode {
get { defaults.string(forKey: "mode") == "dark" ? .dark : .light }
set { defaults.set(newValue == .light ? "light" : "dark", forKey: "mode") }
}
var lang: UiLang {
get { defaults.string(forKey: "lang") == "en" ? .en : .cs }
set { defaults.set(newValue == .en ? "en" : "cs", forKey: "lang") }
}
func germanDone(_ unit: Int, _ ex: Int) -> Bool { defaults.bool(forKey: "g.\(unit).\(ex)") }
func markGerman(_ unit: Int, _ ex: Int) { defaults.set(true, forKey: "g.\(unit).\(ex)") }
func vocabDone(_ unit: Int) -> Bool { defaults.bool(forKey: "g.\(unit).vocab") }
func markVocab(_ unit: Int) { defaults.set(true, forKey: "g.\(unit).vocab") }
func netDone(_ id: Int) -> Bool { defaults.bool(forKey: "net.\(id)") }
func markNet(_ id: Int) { defaults.set(true, forKey: "net.\(id)") }
func hwDone(_ id: Int) -> Bool { defaults.bool(forKey: "hw.\(id)") }
func markHw(_ id: Int) { defaults.set(true, forKey: "hw.\(id)") }
func mluvDone(_ n: Int) -> Bool { defaults.bool(forKey: "mluv.\(n)") }
func markMluv(_ n: Int) { defaults.set(true, forKey: "mluv.\(n)") }
func bookQuiz(_ id: String) -> Bool { defaults.bool(forKey: "book.\(id).quiz") }
func markBookQuiz(_ id: String) { defaults.set(true, forKey: "book.\(id).quiz") }
func bookPlot(_ id: String) -> Bool { defaults.bool(forKey: "book.\(id).plot") }
func markBookPlot(_ id: String) { defaults.set(true, forKey: "book.\(id).plot") }
}
struct ProgressSum {
var doneEx = 0
var totalEx = 0
var doneUnits = 0
var openUnits = 0
}
func summarize(_ content: Content, _ p: ProgressStore) -> ProgressSum {
var sum = ProgressSum()
for u in content.german where u.bool("unlocked") {
let id = u.int("id")
let names = u.strs("names")
sum.totalEx += names.count
sum.openUnits += 1
let done = names.indices.filter { p.germanDone(id, $0 + 1) }.count
sum.doneEx += done
if !names.isEmpty && done == names.count { sum.doneUnits += 1 }
}
for l in content.netLessons {
sum.totalEx += 1
sum.openUnits += 1
if p.netDone(l.int("id")) {
sum.doneEx += 1
sum.doneUnits += 1
}
}
for l in content.hw {
sum.totalEx += 1
sum.openUnits += 1
if p.hwDone(l.int("id")) {
sum.doneEx += 1
sum.doneUnits += 1
}
}
sum.totalEx += content.mluvnice.count
sum.openUnits += 1
let md = content.mluvnice.filter { p.mluvDone($0.int("id")) }.count
sum.doneEx += md
if md == content.mluvnice.count && !content.mluvnice.isEmpty { sum.doneUnits += 1 }
return sum
}