Add basic backend for showing words
This commit is contained in:
		| @@ -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)) | ||||
|     } | ||||
|      | ||||
| } | ||||
|   | ||||
| @@ -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()) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user