From 69ffe49e8a52b79c611740159a8e2d92b90a5464 Mon Sep 17 00:00:00 2001 From: oliverhnat Date: Sun, 25 Feb 2024 14:47:52 +0100 Subject: [PATCH] Add buttons for light and dark mode, fix functions for setting/getting milestone --- WordAX.xcodeproj/project.pbxproj | 4 +++ WordAX/AnkiView.swift | 16 ++++++++++- WordAX/NextRepetitionButtonView.swift | 39 +++++++++++++++++++++++++++ WordAX/WordAX.swift | 16 ++++++++--- WordAX/WordAXModelView.swift | 4 +++ WordAX/WordView.swift | 6 ++--- 6 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 WordAX/NextRepetitionButtonView.swift diff --git a/WordAX.xcodeproj/project.pbxproj b/WordAX.xcodeproj/project.pbxproj index 76767c3..75a78d0 100644 --- a/WordAX.xcodeproj/project.pbxproj +++ b/WordAX.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 6C8185022B88C9FB0033CF46 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185012B88C9FB0033CF46 /* SettingsView.swift */; }; 6C8185042B88CA210033CF46 /* AnkiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185032B88CA210033CF46 /* AnkiView.swift */; }; 6C8185062B8A537F0033CF46 /* WordView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185052B8A537F0033CF46 /* WordView.swift */; }; + 6C8185082B8B523E0033CF46 /* NextRepetitionButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185072B8B523D0033CF46 /* NextRepetitionButtonView.swift */; }; 6CF439522B83541D004C3543 /* WordAXApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439512B83541D004C3543 /* WordAXApp.swift */; }; 6CF439542B83541D004C3543 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439532B83541D004C3543 /* MainView.swift */; }; 6CF439562B83541E004C3543 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF439552B83541E004C3543 /* Assets.xcassets */; }; @@ -24,6 +25,7 @@ 6C8185012B88C9FB0033CF46 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; 6C8185032B88CA210033CF46 /* AnkiView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnkiView.swift; sourceTree = ""; }; 6C8185052B8A537F0033CF46 /* WordView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordView.swift; sourceTree = ""; }; + 6C8185072B8B523D0033CF46 /* NextRepetitionButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextRepetitionButtonView.swift; sourceTree = ""; }; 6CF4394E2B83541D004C3543 /* WordAX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WordAX.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6CF439512B83541D004C3543 /* WordAXApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordAXApp.swift; sourceTree = ""; }; 6CF439532B83541D004C3543 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; @@ -66,6 +68,7 @@ 6C8185012B88C9FB0033CF46 /* SettingsView.swift */, 6C8185032B88CA210033CF46 /* AnkiView.swift */, 6C8185052B8A537F0033CF46 /* WordView.swift */, + 6C8185072B8B523D0033CF46 /* NextRepetitionButtonView.swift */, 6C8184FD2B88C9580033CF46 /* WordAX.swift */, 6C8184FF2B88C9660033CF46 /* WordAXModelView.swift */, 6CF439552B83541E004C3543 /* Assets.xcassets */, @@ -154,6 +157,7 @@ files = ( 6C8185022B88C9FB0033CF46 /* SettingsView.swift in Sources */, 6CF439542B83541D004C3543 /* MainView.swift in Sources */, + 6C8185082B8B523E0033CF46 /* NextRepetitionButtonView.swift in Sources */, 6C8185062B8A537F0033CF46 /* WordView.swift in Sources */, 6C8185002B88C9660033CF46 /* WordAXModelView.swift in Sources */, 6C8185042B88CA210033CF46 /* AnkiView.swift in Sources */, diff --git a/WordAX/AnkiView.swift b/WordAX/AnkiView.swift index cfd594e..88041ce 100644 --- a/WordAX/AnkiView.swift +++ b/WordAX/AnkiView.swift @@ -9,12 +9,26 @@ import SwiftUI struct AnkiView: View { @EnvironmentObject var model: WordAXModelView + @State var showDescription = true var word: WordAX.Word? { model.getWordToDisplay() } var body: some View { if word != nil { - WordView(word: word!) + VStack { + WordView(word: word!, showDescription: $showDescription) + if showDescription { + Text("How did you do?") + .font(.subheadline) + .foregroundStyle(.gray) + HStack { + NextRepetitionButtonView(buttonText: "Poor", nextMilestone: word!.nextSpacedRepetitionMilestone, wordId: word!.id) + NextRepetitionButtonView(buttonText: "Good", nextMilestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: word!.nextSpacedRepetitionMilestone), wordId: word!.id) + NextRepetitionButtonView(buttonText: "Excellent", nextMilestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: WordAX.SpacedRepetitionMilestoneEnum.getNext(milestone: word!.nextSpacedRepetitionMilestone)), wordId: word!.id) + } + .padding(.bottom) + } + } } else { Text("There is no word to display, come back later") } diff --git a/WordAX/NextRepetitionButtonView.swift b/WordAX/NextRepetitionButtonView.swift new file mode 100644 index 0000000..a86f307 --- /dev/null +++ b/WordAX/NextRepetitionButtonView.swift @@ -0,0 +1,39 @@ +// +// NextRepetitionButtonView.swift +// WordAX +// +// Created by Oliver Hnát on 25.02.2024. +// + +import SwiftUI + +struct NextRepetitionButtonView: View { + let buttonText: String + let nextMilestone: WordAX.SpacedRepetitionMilestoneEnum? + let wordId: Int + @EnvironmentObject var model: WordAXModelView + @Environment(\.colorScheme) var colorScheme + var body: some View { + Button(action: { + model.setSpacedRepetitionMilestone(wordId: wordId, milestone: nextMilestone) + }) { + Text(buttonText) + .padding() + .foregroundColor(colorScheme == .light ? .black : .white) + .background(colorScheme == .light ? .cyan : .darkCyan) + .clipShape(RoundedRectangle(cornerRadius: 50)) + } + } +} + +extension ShapeStyle where Self == Color { + // color darker version of cyan from hex palette + public static var darkCyan: Color { + Color(red: 34/255, green: 121/255, blue: 161/255) + } +} + +#Preview { + NextRepetitionButtonView(buttonText: "Excellent", nextMilestone: WordAX.SpacedRepetitionMilestoneEnum.OneDay, wordId: 0) + .environmentObject(WordAXModelView()) +} diff --git a/WordAX/WordAX.swift b/WordAX/WordAX.swift index 3342746..2d3506d 100644 --- a/WordAX/WordAX.swift +++ b/WordAX/WordAX.swift @@ -36,9 +36,12 @@ struct WordAX { allCases.sorted {$0.rawValue < $1.rawValue } } - func getNext() -> SpacedRepetitionMilestoneEnum? { + static func getNext(milestone: SpacedRepetitionMilestoneEnum?) -> SpacedRepetitionMilestoneEnum? { + if milestone == nil { + return SpacedRepetitionMilestoneEnum.OneDay + } let sorted = WordAX.SpacedRepetitionMilestoneEnum.allCasesSorted - let milestoneIndex = sorted.firstIndex(where: {$0.rawValue == self.rawValue})! + let milestoneIndex = sorted.firstIndex(where: {$0.rawValue == milestone!.rawValue})! if milestoneIndex < WordAX.SpacedRepetitionMilestoneEnum.allCasesSorted.count { return sorted[milestoneIndex + 1] } @@ -52,7 +55,7 @@ struct WordAX { var dateFormatter: DateFormatter } - private mutating func setNextSpacedRepetitionMilestone(word: Word) { + public 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 @@ -64,6 +67,13 @@ struct WordAX { } } + public mutating func setSpacedRepetitionMilestone(wordId: Int, milestone: SpacedRepetitionMilestoneEnum?) { + let index = words.firstIndex(where:{$0.id == wordId}) ?? nil + if index != nil { + words[index!].nextSpacedRepetitionMilestone = milestone + } + } + var words: [Word] = [] var settings: Settings diff --git a/WordAX/WordAXModelView.swift b/WordAX/WordAXModelView.swift index c2ac620..68ab606 100644 --- a/WordAX/WordAXModelView.swift +++ b/WordAX/WordAXModelView.swift @@ -45,6 +45,10 @@ class WordAXModelView: ObservableObject { // otherwise show nothing return nil } + + public func setSpacedRepetitionMilestone(wordId: Int, milestone: WordAX.SpacedRepetitionMilestoneEnum?) { + model.setSpacedRepetitionMilestone(wordId: wordId, milestone: milestone) + } } diff --git a/WordAX/WordView.swift b/WordAX/WordView.swift index de7dbf4..6b91ce7 100644 --- a/WordAX/WordView.swift +++ b/WordAX/WordView.swift @@ -10,7 +10,7 @@ import UIKit struct WordView: View { var word: WordAX.Word - @State var showDescription: Bool = false + @Binding var showDescription: Bool @EnvironmentObject var model: WordAXModelView @Environment(\.colorScheme) var colorScheme @@ -19,7 +19,6 @@ struct WordView: View { let wordText = Text(word.name) .font(.title) .bold() - VStack { if word.shown && word.lastSeenOn != nil { Text(model.getDateFormatter().string(from: word.lastSeenOn!)) @@ -46,6 +45,7 @@ struct WordView: View { } #Preview { - WordView(word: WordAXModelView().getWordToDisplay()!) + @State var showDescription = false + return WordView(word: WordAXModelView().getWordToDisplay()!, showDescription: $showDescription) .environmentObject(WordAXModelView()) }