Add buttons for light and dark mode, fix functions for setting/getting milestone
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
6C8185022B88C9FB0033CF46 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185012B88C9FB0033CF46 /* SettingsView.swift */; };
|
6C8185022B88C9FB0033CF46 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185012B88C9FB0033CF46 /* SettingsView.swift */; };
|
||||||
6C8185042B88CA210033CF46 /* AnkiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185032B88CA210033CF46 /* AnkiView.swift */; };
|
6C8185042B88CA210033CF46 /* AnkiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185032B88CA210033CF46 /* AnkiView.swift */; };
|
||||||
6C8185062B8A537F0033CF46 /* WordView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C8185052B8A537F0033CF46 /* WordView.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 */; };
|
6CF439522B83541D004C3543 /* WordAXApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439512B83541D004C3543 /* WordAXApp.swift */; };
|
||||||
6CF439542B83541D004C3543 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439532B83541D004C3543 /* MainView.swift */; };
|
6CF439542B83541D004C3543 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CF439532B83541D004C3543 /* MainView.swift */; };
|
||||||
6CF439562B83541E004C3543 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CF439552B83541E004C3543 /* Assets.xcassets */; };
|
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 = "<group>"; };
|
6C8185012B88C9FB0033CF46 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||||
6C8185032B88CA210033CF46 /* AnkiView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnkiView.swift; sourceTree = "<group>"; };
|
6C8185032B88CA210033CF46 /* AnkiView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnkiView.swift; sourceTree = "<group>"; };
|
||||||
6C8185052B8A537F0033CF46 /* WordView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordView.swift; sourceTree = "<group>"; };
|
6C8185052B8A537F0033CF46 /* WordView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordView.swift; sourceTree = "<group>"; };
|
||||||
|
6C8185072B8B523D0033CF46 /* NextRepetitionButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NextRepetitionButtonView.swift; sourceTree = "<group>"; };
|
||||||
6CF4394E2B83541D004C3543 /* WordAX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WordAX.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
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 = "<group>"; };
|
6CF439512B83541D004C3543 /* WordAXApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordAXApp.swift; sourceTree = "<group>"; };
|
||||||
6CF439532B83541D004C3543 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
|
6CF439532B83541D004C3543 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
|
||||||
@@ -66,6 +68,7 @@
|
|||||||
6C8185012B88C9FB0033CF46 /* SettingsView.swift */,
|
6C8185012B88C9FB0033CF46 /* SettingsView.swift */,
|
||||||
6C8185032B88CA210033CF46 /* AnkiView.swift */,
|
6C8185032B88CA210033CF46 /* AnkiView.swift */,
|
||||||
6C8185052B8A537F0033CF46 /* WordView.swift */,
|
6C8185052B8A537F0033CF46 /* WordView.swift */,
|
||||||
|
6C8185072B8B523D0033CF46 /* NextRepetitionButtonView.swift */,
|
||||||
6C8184FD2B88C9580033CF46 /* WordAX.swift */,
|
6C8184FD2B88C9580033CF46 /* WordAX.swift */,
|
||||||
6C8184FF2B88C9660033CF46 /* WordAXModelView.swift */,
|
6C8184FF2B88C9660033CF46 /* WordAXModelView.swift */,
|
||||||
6CF439552B83541E004C3543 /* Assets.xcassets */,
|
6CF439552B83541E004C3543 /* Assets.xcassets */,
|
||||||
@@ -154,6 +157,7 @@
|
|||||||
files = (
|
files = (
|
||||||
6C8185022B88C9FB0033CF46 /* SettingsView.swift in Sources */,
|
6C8185022B88C9FB0033CF46 /* SettingsView.swift in Sources */,
|
||||||
6CF439542B83541D004C3543 /* MainView.swift in Sources */,
|
6CF439542B83541D004C3543 /* MainView.swift in Sources */,
|
||||||
|
6C8185082B8B523E0033CF46 /* NextRepetitionButtonView.swift in Sources */,
|
||||||
6C8185062B8A537F0033CF46 /* WordView.swift in Sources */,
|
6C8185062B8A537F0033CF46 /* WordView.swift in Sources */,
|
||||||
6C8185002B88C9660033CF46 /* WordAXModelView.swift in Sources */,
|
6C8185002B88C9660033CF46 /* WordAXModelView.swift in Sources */,
|
||||||
6C8185042B88CA210033CF46 /* AnkiView.swift in Sources */,
|
6C8185042B88CA210033CF46 /* AnkiView.swift in Sources */,
|
||||||
|
|||||||
@@ -9,12 +9,26 @@ import SwiftUI
|
|||||||
|
|
||||||
struct AnkiView: View {
|
struct AnkiView: View {
|
||||||
@EnvironmentObject var model: WordAXModelView
|
@EnvironmentObject var model: WordAXModelView
|
||||||
|
@State var showDescription = true
|
||||||
var word: WordAX.Word? {
|
var word: WordAX.Word? {
|
||||||
model.getWordToDisplay()
|
model.getWordToDisplay()
|
||||||
}
|
}
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if word != nil {
|
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 {
|
} else {
|
||||||
Text("There is no word to display, come back later")
|
Text("There is no word to display, come back later")
|
||||||
}
|
}
|
||||||
|
|||||||
39
WordAX/NextRepetitionButtonView.swift
Normal file
39
WordAX/NextRepetitionButtonView.swift
Normal file
@@ -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())
|
||||||
|
}
|
||||||
@@ -36,9 +36,12 @@ struct WordAX {
|
|||||||
allCases.sorted {$0.rawValue < $1.rawValue }
|
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 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 {
|
if milestoneIndex < WordAX.SpacedRepetitionMilestoneEnum.allCasesSorted.count {
|
||||||
return sorted[milestoneIndex + 1]
|
return sorted[milestoneIndex + 1]
|
||||||
}
|
}
|
||||||
@@ -52,7 +55,7 @@ struct WordAX {
|
|||||||
var dateFormatter: DateFormatter
|
var dateFormatter: DateFormatter
|
||||||
}
|
}
|
||||||
|
|
||||||
private mutating func setNextSpacedRepetitionMilestone(word: Word) {
|
public mutating func setNextSpacedRepetitionMilestone(word: Word) {
|
||||||
if word.nextSpacedRepetitionMilestone != nil {
|
if word.nextSpacedRepetitionMilestone != nil {
|
||||||
let current = SpacedRepetitionMilestoneEnum.allCasesSorted.firstIndex(of: word.nextSpacedRepetitionMilestone!) ?? SpacedRepetitionMilestoneEnum.allCases.count
|
let current = SpacedRepetitionMilestoneEnum.allCasesSorted.firstIndex(of: word.nextSpacedRepetitionMilestone!) ?? SpacedRepetitionMilestoneEnum.allCases.count
|
||||||
let index = words.firstIndex(where:{$0.id == word.id}) ?? nil
|
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 words: [Word] = []
|
||||||
var settings: Settings
|
var settings: Settings
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,10 @@ class WordAXModelView: ObservableObject {
|
|||||||
// otherwise show nothing
|
// otherwise show nothing
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func setSpacedRepetitionMilestone(wordId: Int, milestone: WordAX.SpacedRepetitionMilestoneEnum?) {
|
||||||
|
model.setSpacedRepetitionMilestone(wordId: wordId, milestone: milestone)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import UIKit
|
|||||||
|
|
||||||
struct WordView: View {
|
struct WordView: View {
|
||||||
var word: WordAX.Word
|
var word: WordAX.Word
|
||||||
@State var showDescription: Bool = false
|
@Binding var showDescription: Bool
|
||||||
@EnvironmentObject var model: WordAXModelView
|
@EnvironmentObject var model: WordAXModelView
|
||||||
@Environment(\.colorScheme) var colorScheme
|
@Environment(\.colorScheme) var colorScheme
|
||||||
|
|
||||||
@@ -19,7 +19,6 @@ struct WordView: View {
|
|||||||
let wordText = Text(word.name)
|
let wordText = Text(word.name)
|
||||||
.font(.title)
|
.font(.title)
|
||||||
.bold()
|
.bold()
|
||||||
|
|
||||||
VStack {
|
VStack {
|
||||||
if word.shown && word.lastSeenOn != nil {
|
if word.shown && word.lastSeenOn != nil {
|
||||||
Text(model.getDateFormatter().string(from: word.lastSeenOn!))
|
Text(model.getDateFormatter().string(from: word.lastSeenOn!))
|
||||||
@@ -46,6 +45,7 @@ struct WordView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
WordView(word: WordAXModelView().getWordToDisplay()!)
|
@State var showDescription = false
|
||||||
|
return WordView(word: WordAXModelView().getWordToDisplay()!, showDescription: $showDescription)
|
||||||
.environmentObject(WordAXModelView())
|
.environmentObject(WordAXModelView())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user