Add basic backend for showing words
This commit is contained in:
77
WordAX.xcodeproj/xcshareddata/xcschemes/WordAX.xcscheme
Normal file
77
WordAX.xcodeproj/xcshareddata/xcschemes/WordAX.xcscheme
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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