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

@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1520"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6CF4394D2B83541D004C3543"
BuildableName = "WordAX.app"
BlueprintName = "WordAX"
ReferencedContainer = "container:WordAX.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6CF4394D2B83541D004C3543"
BuildableName = "WordAX.app"
BlueprintName = "WordAX"
ReferencedContainer = "container:WordAX.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "6CF4394D2B83541D004C3543"
BuildableName = "WordAX.app"
BlueprintName = "WordAX"
ReferencedContainer = "container:WordAX.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -10,5 +10,13 @@
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>6CF4394D2B83541D004C3543</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

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())
}
}