Add basic backend for showing words

This commit is contained in:
2024-02-24 17:40:16 +01:00
parent 5f474ca9cd
commit 5b383f6258
4 changed files with 199 additions and 0 deletions

View File

@@ -6,3 +6,62 @@
//
import Foundation
struct WordAX {
struct Word: Identifiable {
var id: Int
var name: String
var description: String
var shown: Bool
var nextSpacedRepetitionMilestone: SpacedRepetitionMilestoneEnum?
var displayOn: Date?
}
enum FrequencyEnum: Int {
case Daily = 1
case Weekly = 7
case BiWeekly = 14
case Monthly = 30
}
enum SpacedRepetitionMilestoneEnum: Int, CaseIterable {
case OneDay = 1
case OneWeek = 7
case TwoWeeks = 14
case OneMonth = 30
case TwoMonths = 60
case FiveMonths = 150
case OneYear = 365
static var allCasesSorted: [SpacedRepetitionMilestoneEnum] {
allCases.sorted {$0.rawValue < $1.rawValue }
}
}
struct Settings {
var frequency: FrequencyEnum = .Daily
var lastShownNew: Date?
}
private mutating func setNextSpacedRepetitionMilestone(word: Word) {
if word.nextSpacedRepetitionMilestone != nil {
let current = SpacedRepetitionMilestoneEnum.allCasesSorted.firstIndex(of: word.nextSpacedRepetitionMilestone!) ?? SpacedRepetitionMilestoneEnum.allCases.count
let index = words.firstIndex(where:{$0.id == word.id}) ?? nil
if current + 1 < SpacedRepetitionMilestoneEnum.allCases.count && index != nil {
words[index!].nextSpacedRepetitionMilestone = SpacedRepetitionMilestoneEnum.allCasesSorted[current + 1]
} else if index != nil {
words[index!].nextSpacedRepetitionMilestone = nil
}
}
}
var words: [Word] = []
var settings: Settings
init() {
self.words = []
self.settings = Settings()
self.words.append(Word(id: 0, name: "Magnificent", description: "When something is awesome", shown: false))
self.words.append(Word(id: 1, name: "Mesmerising", description: "When something is beautiful", shown: false))
}
}

View File

@@ -8,7 +8,62 @@
import Foundation
class WordAXModelView: ObservableObject {
@Published private var model: WordAX
typealias Word = WordAX.Word
init() {
model = WordAX()
}
public func getWordToDisplay() -> Word? {
let words = model.words
if words.count > 0 {
// if today is the date they're supposed to be shown
let displayToday = words.filter({ $0.displayOn != nil && $0.displayOn!.isToday()})
if displayToday.count > 0 {
return displayToday.first!
}
// first word ever shown
let shownWords = words.filter({ $0.shown })
if shownWords.count == 0 {
return words.first!
}
// if today is the day to show a new word
let settings = model.settings
if shownWords.count == 0 ||
settings.lastShownNew == nil ||
settings.lastShownNew!.addingTimeInterval(TimeInterval(settings.frequency.rawValue * 24 * 60 * 60)).isAfterToday() {
return words.first!
}
}
// otherwise show nothing
return nil
}
}
extension Date {
private func getOnlyDate(date: Date) -> DateComponents {
Calendar.current.dateComponents([.day, .month, .year], from: date)
}
func isSameAs(_ date: Date) -> Bool {
let selfDate = getOnlyDate(date: self)
let paramDate = getOnlyDate(date: date)
return selfDate.day == paramDate.day && selfDate.month == paramDate.month && selfDate.year == paramDate.year
}
func isToday() -> Bool {
self.isSameAs(Date())
}
func isAfter(_ date: Date) -> Bool {
let selfDate = getOnlyDate(date: self)
let paramDate = getOnlyDate(date: date)
return selfDate.year! > paramDate.year! || selfDate.month! > paramDate.month! || selfDate.day! > paramDate.day!
}
func isAfterToday() -> Bool {
self.isAfter(Date())
}
}