diff --git a/Toki Trainer Widgets/Toki_Trainer_Widgets.swift b/Toki Trainer Widgets/Toki_Trainer_Widgets.swift index 8a1ada0..133ed2f 100644 --- a/Toki Trainer Widgets/Toki_Trainer_Widgets.swift +++ b/Toki Trainer Widgets/Toki_Trainer_Widgets.swift @@ -35,7 +35,7 @@ struct Provider: IntentTimelineProvider { func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline) -> ()) { var entries: [DefinitionEntry] = [] - for i in 0...5 { + for _ in 0...5 { entries.append(getRandomEntry(configuration: configuration)) } diff --git a/Toki Trainer.xcodeproj/project.pbxproj b/Toki Trainer.xcodeproj/project.pbxproj index 3abb989..583dc52 100644 --- a/Toki Trainer.xcodeproj/project.pbxproj +++ b/Toki Trainer.xcodeproj/project.pbxproj @@ -43,6 +43,9 @@ 7EBAE6AA273D65FD00BCFA09 /* toki-lessons.json in Resources */ = {isa = PBXBuildFile; fileRef = 7EBAE6A9273D65FD00BCFA09 /* toki-lessons.json */; }; 7EF546162737B8FB00537AE6 /* FlashCardResultsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EF546152737B8FA00537AE6 /* FlashCardResultsView.swift */; }; E1D79AE328EC396200A104BF /* DictionaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D79AE228EC396200A104BF /* DictionaryView.swift */; }; + E1D79AE528F1914600A104BF /* TranslatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D79AE428F1914600A104BF /* TranslatorView.swift */; }; + E1D79AE728F1925400A104BF /* TokiWordsListEntryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D79AE628F1925400A104BF /* TokiWordsListEntryView.swift */; }; + E1D79AEB28F194EF00A104BF /* LanguageDirectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1D79AEA28F194EF00A104BF /* LanguageDirectionView.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -102,6 +105,9 @@ 7EBAE6A9273D65FD00BCFA09 /* toki-lessons.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "toki-lessons.json"; sourceTree = ""; }; 7EF546152737B8FA00537AE6 /* FlashCardResultsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlashCardResultsView.swift; sourceTree = ""; }; E1D79AE228EC396200A104BF /* DictionaryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DictionaryView.swift; sourceTree = ""; }; + E1D79AE428F1914600A104BF /* TranslatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslatorView.swift; sourceTree = ""; }; + E1D79AE628F1925400A104BF /* TokiWordsListEntryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokiWordsListEntryView.swift; sourceTree = ""; }; + E1D79AEA28F194EF00A104BF /* LanguageDirectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageDirectionView.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -138,14 +144,13 @@ 7E2811122733024F0063DC78 /* Views */ = { isa = PBXGroup; children = ( + E1D79AE828F1947F00A104BF /* WordListViews */, 7E943A20273211C200E7DDF4 /* Toki_TrainerApp.swift */, 7E943A22273211C200E7DDF4 /* ContentView.swift */, - 7E20D5FE2733AFE700D75B9A /* PartsOfSpeechView.swift */, 7E71E6EC2735D70C007CFF72 /* FlashCardView.swift */, 7EF546152737B8FA00537AE6 /* FlashCardResultsView.swift */, 7E716B4127398CDF009E2CF6 /* FlashCardLessonsView.swift */, 7E716B452739B968009E2CF6 /* FlashCardLessonResultsView.swift */, - E1D79AE228EC396200A104BF /* DictionaryView.swift */, ); path = Views; sourceTree = ""; @@ -234,6 +239,26 @@ path = "Preview Content"; sourceTree = ""; }; + E1D79AE828F1947F00A104BF /* WordListViews */ = { + isa = PBXGroup; + children = ( + E1D79AE928F1949900A104BF /* SharedViews */, + E1D79AE228EC396200A104BF /* DictionaryView.swift */, + E1D79AE428F1914600A104BF /* TranslatorView.swift */, + ); + path = WordListViews; + sourceTree = ""; + }; + E1D79AE928F1949900A104BF /* SharedViews */ = { + isa = PBXGroup; + children = ( + E1D79AE628F1925400A104BF /* TokiWordsListEntryView.swift */, + 7E20D5FE2733AFE700D75B9A /* PartsOfSpeechView.swift */, + E1D79AEA28F194EF00A104BF /* LanguageDirectionView.swift */, + ); + path = SharedViews; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -357,6 +382,8 @@ 7E943A2A273211C300E7DDF4 /* Persistence.swift in Sources */, 7E20D5FF2733AFE700D75B9A /* PartsOfSpeechView.swift in Sources */, 7E71E6F12736DAE4007CFF72 /* FlashCardsViewModel.swift in Sources */, + E1D79AEB28F194EF00A104BF /* LanguageDirectionView.swift in Sources */, + E1D79AE528F1914600A104BF /* TranslatorView.swift in Sources */, 7E20D6012734466800D75B9A /* TokiDictionaryViewModel.swift in Sources */, 7E716B4427398D3D009E2CF6 /* FlashCardLessonsViewModel.swift in Sources */, 7E2811192733027F0063DC78 /* TokiPartOfSpeech.swift in Sources */, @@ -366,6 +393,7 @@ 7EF546162737B8FB00537AE6 /* FlashCardResultsView.swift in Sources */, 7E716B4227398CDF009E2CF6 /* FlashCardLessonsView.swift in Sources */, 7E2811172733027F0063DC78 /* TokiDictionary.swift in Sources */, + E1D79AE728F1925400A104BF /* TokiWordsListEntryView.swift in Sources */, 7E71E6ED2735D70C007CFF72 /* FlashCardView.swift in Sources */, 7E943A21273211C200E7DDF4 /* Toki_TrainerApp.swift in Sources */, 7E716B462739B968009E2CF6 /* FlashCardLessonResultsView.swift in Sources */, diff --git a/Toki Trainer.xcodeproj/xcuserdata/madelinecr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Toki Trainer.xcodeproj/xcuserdata/madelinecr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..45035ff --- /dev/null +++ b/Toki Trainer.xcodeproj/xcuserdata/madelinecr.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/Toki Trainer.xcodeproj/xcuserdata/madelinecr.xcuserdatad/xcschemes/xcschememanagement.plist b/Toki Trainer.xcodeproj/xcuserdata/madelinecr.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..4153716 --- /dev/null +++ b/Toki Trainer.xcodeproj/xcuserdata/madelinecr.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,19 @@ + + + + + SchemeUserState + + Toki Trainer WidgetsExtension.xcscheme_^#shared#^_ + + orderHint + 0 + + Toki Trainer.xcscheme_^#shared#^_ + + orderHint + 1 + + + + diff --git a/Toki Trainer/ViewModels/TokiDictionaryViewModel.swift b/Toki Trainer/ViewModels/TokiDictionaryViewModel.swift index f26d088..b610041 100644 --- a/Toki Trainer/ViewModels/TokiDictionaryViewModel.swift +++ b/Toki Trainer/ViewModels/TokiDictionaryViewModel.swift @@ -44,6 +44,11 @@ class TokiDictionaryViewModel: ObservableObject { dictionary = [] translatedDictionary = [] + if input.isEmpty { + dictionary = fullDictionary + translatedDictionary.append(TokiSubWordListEntry("Dictionary")) + } + let capturePattern = #"(\w+)"# let captures = self.searchStringForRegex(string: input, regex: capturePattern) for capture in captures { diff --git a/Toki Trainer/Views/ContentView.swift b/Toki Trainer/Views/ContentView.swift index d64a930..ff40d11 100644 --- a/Toki Trainer/Views/ContentView.swift +++ b/Toki Trainer/Views/ContentView.swift @@ -15,8 +15,6 @@ extension String: Identifiable { struct ContentView: View { @Environment(\.managedObjectContext) private var viewContext - @State private var tokiInput: String = "" - var body: some View { TabView { DictionaryView() @@ -34,11 +32,6 @@ struct ContentView: View { Image(systemName: "character.textbox") Text("Flash Cards") } - // FlashCardResultsView() - // .tabItem { - // Image(systemName: "number.circle") - // Text("Flash Card Results") - // } } } @@ -47,177 +40,6 @@ struct ContentView: View { } } -struct TranslatorView: View { - @ObservedObject var tokiDictViewModel = TokiDictionaryViewModel() - @State private var selectedPartOfSpeech: String? - @State private var tokiInput: String = "" - @State private var translateToTokiPona: Bool = false - - var body: some View { - VStack { - Button(action: changeTranslationDirection) { - if translateToTokiPona == true { - LanguageDirectionView(from: "English", to: "Toki Pona", fromColor: .blue, toColor: .cyan) - } else { - LanguageDirectionView(from: "Toki Pona", to: "English", fromColor: .cyan, toColor: .blue) - } - } - TextField("Enter Toki Pona Word or Phrase", text: $tokiInput) - .multilineTextAlignment(.center) - .textInputAutocapitalization(.never) - .disableAutocorrection(true) - .padding(8) - .onSubmit { - tokiDictViewModel.translatePhrase(tokiInput) - } - if tokiInput.count == 0 { - List(tokiDictViewModel.dictionary, id: \.word) { entry in - TokiWordsListEntryView(entry: entry, selectedPartOfSpeech: $selectedPartOfSpeech) - } - //TokiWordsView(tokiDictViewModel: tokiDictViewModel, selectedPartOfSpeech: selectedPartOfSpeech, tokiInput: $tokiInput) - } else { - List(tokiDictViewModel.translatedDictionary, id: \.header) { section in - Section { - ForEach(section.subDictionary, id: \.word) { entry in - TokiWordsListEntryView(entry: entry, selectedPartOfSpeech: $selectedPartOfSpeech) - } - } header: { - Text(section.header) - } - } -// ForEach(tokiDictViewModel.translatedDictionary) { entry in -// TokiSectionedWordsView(tokiDictViewModel: tokiDictViewModel, tokiInput: $tokiInput) -// } - } - } - .onChange(of: tokiInput) { newValue in - tokiDictViewModel.translatePhrase(newValue) - } - } - - func changeTranslationDirection() { - translateToTokiPona.toggle() - } -} - -struct TokiSectionedWordsView: View { - @ObservedObject var tokiDictViewModel: TokiDictionaryViewModel - @Binding var tokiInput: String - - var body: some View { - Section(header: Text(tokiInput)) { - TokiWordsView(tokiDictViewModel: tokiDictViewModel, tokiInput: $tokiInput) - } - } -} - -struct TokiWordsListEntryView: View { - @State var entry: TokiDictEntry - @Binding var selectedPartOfSpeech: String? - - var body: some View { - VStack(alignment: .leading) { - Text(entry.word) - .font(.title) - ForEach(entry.definitions, id: \.pos) { definition in - HStack(alignment: .top) { - Button(action: { - self.selectedPartOfSpeech = String(definition.pos) - }) { - Text(definition.pos) - .frame(width: 45, height: 22, alignment: .center) - .foregroundColor(.black) - .background(Color(K.posColors[definition.pos]!)) - .cornerRadius(5.0) - .padding(4) - } - .buttonStyle(BorderlessButtonStyle()) - Text(definition.definition) - .fixedSize(horizontal: false, vertical: true) - .padding(4) - } - } - } - } -} - -struct TokiWordsView: View { - @ObservedObject var tokiDictViewModel: TokiDictionaryViewModel - @State var selectedPartOfSpeech: String? - - @Binding var tokiInput: String - - var body: some View { - List(tokiDictViewModel.dictionary, id: \.word) { entry in - VStack(alignment: .leading) { - Text(entry.word) - .font(.title) - ForEach(entry.definitions, id: \.pos) { definition in - HStack(alignment: .top) { - Button(action: { - self.selectedPartOfSpeech = String(definition.pos) - }) { - Text(definition.pos) - .frame(width: 45, height: 22, alignment: .center) - .foregroundColor(.black) - .background(Color(K.posColors[definition.pos]!)) - .cornerRadius(5.0) - .padding(4) - } - .buttonStyle(BorderlessButtonStyle()) - Text(definition.definition) - .fixedSize(horizontal: false, vertical: true) - .padding(4) - } - } - } - } - .sheet(item: $selectedPartOfSpeech) { selectedPOS in - PartsOfSpeechView(selectedPartOfSpeech: selectedPOS, partsOfSpeech: tokiDictViewModel.partsOfSpeech) - } - .onChange(of: tokiInput) { newValue in - tokiDictViewModel.translatePhrase(newValue) - } - } -} - -struct LanguageDirectionView: View { - private var fromText: String = "" - private var toText: String = "" - private var fromColor: Color = .black - private var toColor: Color = .black - - init(from: String, to: String, fromColor: Color, toColor: Color) { - self.fromText = from - self.toText = to - self.fromColor = fromColor - self.toColor = toColor - } - - var body: some View { - HStack { - Text(fromText) - .bold() - .multilineTextAlignment(.center) - .foregroundColor(.white) - .frame(width: 100) - .background(fromColor) - .border(fromColor) - .cornerRadius(5) - Image(systemName: "chevron.right") - //rforegroundColor(.black) - Text(toText) - .bold() - .multilineTextAlignment(.center) - .foregroundColor(.white) - .frame(width: 100) - .background(toColor) - .border(toColor) - .cornerRadius(5) - } - .padding(.top, 4) - } -} struct ContentView_Previews: PreviewProvider { diff --git a/Toki Trainer/Views/FlashCardView.swift b/Toki Trainer/Views/FlashCardView.swift index 355f69e..9e3856e 100644 --- a/Toki Trainer/Views/FlashCardView.swift +++ b/Toki Trainer/Views/FlashCardView.swift @@ -157,7 +157,7 @@ struct FlashCardStack: View { var cardInDatabase = false for answer in flashCardAnswers { if answer.word == shuffledDictionary[currentFlashCard].word { - print("word in database: \(answer.word)") + print("word in database: \(answer.word ?? "nil")") print("tries: \(answer.triesCount)") print("correct`: \(answer.correctCount)") cardInDatabase = true diff --git a/Toki Trainer/Views/DictionaryView.swift b/Toki Trainer/Views/WordListViews/DictionaryView.swift similarity index 70% rename from Toki Trainer/Views/DictionaryView.swift rename to Toki Trainer/Views/WordListViews/DictionaryView.swift index dc791d7..6067791 100644 --- a/Toki Trainer/Views/DictionaryView.swift +++ b/Toki Trainer/Views/WordListViews/DictionaryView.swift @@ -26,9 +26,19 @@ struct DictionaryView: View { List(tokiDictViewModel.dictionary, id: \.word) { entry in TokiWordsListEntryView(entry: entry, selectedPartOfSpeech: $selectedPartOfSpeech) } + .sheet(item: $selectedPartOfSpeech) { selectedPOS in + PartsOfSpeechView(selectedPartOfSpeech: selectedPOS) + } .onChange(of: tokiInput) { newValue in tokiDictViewModel.filterDictionary(newValue) } } } } + +struct DictionaryView_Previews: PreviewProvider { + + static var previews: some View { + DictionaryView(selectedPartOfSpeech: "n").previewLayout(.sizeThatFits).environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) + } +} diff --git a/Toki Trainer/Views/WordListViews/SharedViews/LanguageDirectionView.swift b/Toki Trainer/Views/WordListViews/SharedViews/LanguageDirectionView.swift new file mode 100644 index 0000000..8f4d5a8 --- /dev/null +++ b/Toki Trainer/Views/WordListViews/SharedViews/LanguageDirectionView.swift @@ -0,0 +1,53 @@ +// +// LanguageDirectionView.swift +// Toki Trainer +// +// Created by maddiefuzz on 10/8/22. +// + +import SwiftUI + +struct LanguageDirectionView: View { + private var fromText: String = "" + private var toText: String = "" + private var fromColor: Color = .black + private var toColor: Color = .black + + init(from: String, to: String, fromColor: Color, toColor: Color) { + self.fromText = from + self.toText = to + self.fromColor = fromColor + self.toColor = toColor + } + + var body: some View { + HStack { + Text(fromText) + .bold() + .multilineTextAlignment(.center) + .foregroundColor(.white) + .frame(width: 100) + .background(fromColor) + .border(fromColor) + .cornerRadius(5) + Image(systemName: "chevron.right") + Text(toText) + .bold() + .multilineTextAlignment(.center) + .foregroundColor(.white) + .frame(width: 100) + .background(toColor) + .border(toColor) + .cornerRadius(5) + } + .padding(.top, 4) + } +} + +struct LanguageDirectionView_Previews: PreviewProvider { + + static var previews: some View { + LanguageDirectionView(from: "English", to: "Toki Pona", fromColor: .blue, toColor: .cyan) + .previewLayout(.fixed(width: 260, height: 40)) + } +} diff --git a/Toki Trainer/Views/PartsOfSpeechView.swift b/Toki Trainer/Views/WordListViews/SharedViews/PartsOfSpeechView.swift similarity index 82% rename from Toki Trainer/Views/PartsOfSpeechView.swift rename to Toki Trainer/Views/WordListViews/SharedViews/PartsOfSpeechView.swift index d07cc89..ad6a044 100644 --- a/Toki Trainer/Views/PartsOfSpeechView.swift +++ b/Toki Trainer/Views/WordListViews/SharedViews/PartsOfSpeechView.swift @@ -12,8 +12,6 @@ struct PartsOfSpeechView: View { @ObservedObject var tokiDictViewModel = TokiDictionaryViewModel() - var partsOfSpeech: [TokiPartOfSpeech] - var body: some View { VStack { Text("Parts of Speech") @@ -42,8 +40,8 @@ struct PartsOfSpeechView: View { struct PartsOfSpeechView_Previews: PreviewProvider { static var previews: some View { - PartsOfSpeechView(selectedPartOfSpeech: "sep", partsOfSpeech: [TokiPartOfSpeech(pos: "sep", definition: "test")]) + PartsOfSpeechView(selectedPartOfSpeech: "sep") .preferredColorScheme(.dark) - PartsOfSpeechView(selectedPartOfSpeech: "sep", partsOfSpeech: [TokiPartOfSpeech(pos: "sep", definition: "test")]) + PartsOfSpeechView(selectedPartOfSpeech: "sep") } } diff --git a/Toki Trainer/Views/WordListViews/SharedViews/TokiWordsListEntryView.swift b/Toki Trainer/Views/WordListViews/SharedViews/TokiWordsListEntryView.swift new file mode 100644 index 0000000..ca442e9 --- /dev/null +++ b/Toki Trainer/Views/WordListViews/SharedViews/TokiWordsListEntryView.swift @@ -0,0 +1,47 @@ +// +// TokiWordsListEntryView.swift +// Toki Trainer +// +// Created by maddiefuzz on 10/8/22. +// + +import SwiftUI + +struct TokiWordsListEntryView: View { + @State var entry: TokiDictEntry + @Binding var selectedPartOfSpeech: String? + + var body: some View { + VStack(alignment: .leading) { + Text(entry.word) + .font(.title) + ForEach(entry.definitions, id: \.pos) { definition in + HStack(alignment: .top) { + Button(action: { + self.selectedPartOfSpeech = String(definition.pos) + }) { + Text(definition.pos) + .frame(width: 45, height: 22, alignment: .center) + .foregroundColor(.black) + .background(Color(K.posColors[definition.pos]!)) + .cornerRadius(5.0) + .padding(4) + } + .buttonStyle(BorderlessButtonStyle()) + Text(definition.definition) + .fixedSize(horizontal: false, vertical: true) + .padding(4) + } + } + } + } +} + +struct TokiWordsListEntryView_Previews: PreviewProvider { + static var entry = TokiDictionaryViewModel().dictionary[5] + + static var previews: some View { + TokiWordsListEntryView(entry: entry, selectedPartOfSpeech: .constant("n")) + .previewLayout(.sizeThatFits) + } +} diff --git a/Toki Trainer/Views/WordListViews/TranslatorView.swift b/Toki Trainer/Views/WordListViews/TranslatorView.swift new file mode 100644 index 0000000..11de7eb --- /dev/null +++ b/Toki Trainer/Views/WordListViews/TranslatorView.swift @@ -0,0 +1,68 @@ +// +// TranslatorView.swift +// Toki Trainer +// +// Created by maddiefuzz on 10/8/22. +// + +import SwiftUI + +struct TranslatorView: View { + @ObservedObject var tokiDictViewModel = TokiDictionaryViewModel() + @State private var selectedPartOfSpeech: String? + @State private var tokiInput: String = "" + @State private var translateToTokiPona: Bool = false + + var body: some View { + VStack { + Button(action: changeTranslationDirection) { + // TODO: This needs to actually switch how the lookup happens + if translateToTokiPona == true { + LanguageDirectionView(from: "English", to: "Toki Pona", fromColor: .blue, toColor: .cyan) + } else { + LanguageDirectionView(from: "Toki Pona", to: "English", fromColor: .cyan, toColor: .blue) + } + } + TextField("Enter Toki Pona Word or Phrase", text: $tokiInput) + .multilineTextAlignment(.center) + .textInputAutocapitalization(.never) + .disableAutocorrection(true) + .padding(8) + .onSubmit { + tokiDictViewModel.translatePhrase(tokiInput) + } + if tokiInput.count == 0 { + List(tokiDictViewModel.dictionary, id: \.word) { entry in + TokiWordsListEntryView(entry: entry, selectedPartOfSpeech: $selectedPartOfSpeech) + } + } else { + List(tokiDictViewModel.translatedDictionary, id: \.header) { section in + Section { + ForEach(section.subDictionary, id: \.word) { entry in + TokiWordsListEntryView(entry: entry, selectedPartOfSpeech: $selectedPartOfSpeech) + } + } header: { + Text(section.header) + } + } + } + } + .sheet(item: $selectedPartOfSpeech) { selectedPOS in + PartsOfSpeechView(selectedPartOfSpeech: selectedPOS) + } + .onChange(of: tokiInput) { newValue in + tokiDictViewModel.translatePhrase(newValue) + } + } + + func changeTranslationDirection() { + translateToTokiPona.toggle() + } +} + +struct TranslatorView_Previews: PreviewProvider { + + static var previews: some View { + TranslatorView().previewLayout(.sizeThatFits).environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) + } +}