Skip to content

Commit

Permalink
🔧 fix(.gitignore): add Products/ directory to .gitignore
Browse files Browse the repository at this point in the history
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add Products/ directory to .gitignore
🔧 fix(.gitignore): add

🔧 chore(WordService.swift): add WordService class to handle loading and searching words
🔧 chore(WordSearchView.swift): remove onAppear method to load words data from ContentView
🔧 chore(WordListView.swift): remove onAppear method to load words data from WordListView
  • Loading branch information
andskur committed Jul 30, 2023
1 parent e9e7423 commit de2b2f0
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 96 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ DerivedData/
# Other
/.env
/.vscode

/Products/
24 changes: 19 additions & 5 deletions OldNorseDictionary.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
A1F2B8532A76696F003EBF17 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = A1F2B8502A76696F003EBF17 /* README.md */; };
A1F2B8542A76696F003EBF17 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = A1F2B8512A76696F003EBF17 /* LICENSE */; };
A1F2B8552A76696F003EBF17 /* PrivacyPolicy.md in Resources */ = {isa = PBXBuildFile; fileRef = A1F2B8522A76696F003EBF17 /* PrivacyPolicy.md */; };
A1F2B8582A767231003EBF17 /* WordService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F2B8572A767231003EBF17 /* WordService.swift */; };
A1F2B8592A7672B4003EBF17 /* WordService.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F2B8572A767231003EBF17 /* WordService.swift */; };
A1F6CDAE2A75A743006F020E /* OldNorseDictionaryWatchOsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F6CDAD2A75A743006F020E /* OldNorseDictionaryWatchOsApp.swift */; };
A1F6CDB02A75A743006F020E /* WordListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1F6CDAF2A75A743006F020E /* WordListView.swift */; };
A1F6CDB22A75A744006F020E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A1F6CDB12A75A744006F020E /* Assets.xcassets */; };
Expand Down Expand Up @@ -116,6 +118,7 @@
A1F2B8502A76696F003EBF17 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
A1F2B8512A76696F003EBF17 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
A1F2B8522A76696F003EBF17 /* PrivacyPolicy.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = PrivacyPolicy.md; sourceTree = "<group>"; };
A1F2B8572A767231003EBF17 /* WordService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordService.swift; sourceTree = "<group>"; };
A1F6CDAB2A75A743006F020E /* OldNorseDictionaryWatchOs Watch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "OldNorseDictionaryWatchOs Watch App.app"; sourceTree = BUILT_PRODUCTS_DIR; };
A1F6CDAD2A75A743006F020E /* OldNorseDictionaryWatchOsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OldNorseDictionaryWatchOsApp.swift; sourceTree = "<group>"; };
A1F6CDAF2A75A743006F020E /* WordListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordListView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -178,11 +181,11 @@
A1F2B8512A76696F003EBF17 /* LICENSE */,
A1F2B8522A76696F003EBF17 /* PrivacyPolicy.md */,
A1F2B8502A76696F003EBF17 /* README.md */,
A1F2B84F2A76693B003EBF17 /* WatchOSApp */,
A1F2B84A2A7667ED003EBF17 /* Tests */,
A1F2B8462A7667C8003EBF17 /* Source */,
A1F6CDE02A75AC1A006F020E /* Assets */,
A14FC42A2A6185A7009D91EC /* Products */,
A1F2B8462A7667C8003EBF17 /* Source */,
A1F2B84A2A7667ED003EBF17 /* Tests */,
A1F2B84F2A76693B003EBF17 /* WatchOSApp */,
);
sourceTree = "<group>";
};
Expand All @@ -203,11 +206,12 @@
isa = PBXGroup;
children = (
A14FC4322A6185A7009D91EC /* OldNorseDictionary.entitlements */,
A14FC4302A6185A7009D91EC /* Assets.xcassets */,
A14FC42C2A6185A7009D91EC /* OldNorseDictionaryApp.swift */,
A14FC4302A6185A7009D91EC /* Assets.xcassets */,
A1F2B8492A7667DF003EBF17 /* Controllers */,
A1F2B8482A7667D9003EBF17 /* Views */,
A1F2B8472A7667D2003EBF17 /* Models */,
A1F2B8562A767225003EBF17 /* Services */,
A1F2B8482A7667D9003EBF17 /* Views */,
);
path = Source;
sourceTree = "<group>";
Expand Down Expand Up @@ -289,6 +293,14 @@
path = WatchOSApp;
sourceTree = "<group>";
};
A1F2B8562A767225003EBF17 /* Services */ = {
isa = PBXGroup;
children = (
A1F2B8572A767231003EBF17 /* WordService.swift */,
);
path = Services;
sourceTree = "<group>";
};
A1F6CDE02A75AC1A006F020E /* Assets */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -525,6 +537,7 @@
A15829452A66BF9D00BD97D4 /* Conjugation.swift in Sources */,
A14FC42D2A6185A7009D91EC /* OldNorseDictionaryApp.swift in Sources */,
A15829592A68249100BD97D4 /* Number.swift in Sources */,
A1F2B8582A767231003EBF17 /* WordService.swift in Sources */,
A158294F2A66DE0500BD97D4 /* WordSearchView.swift in Sources */,
A158294D2A66DDCB00BD97D4 /* WordDetailView.swift in Sources */,
A15829512A66DE4600BD97D4 /* WordSearchController.swift in Sources */,
Expand Down Expand Up @@ -561,6 +574,7 @@
A1F6CDDD2A75AB1A006F020E /* Case.swift in Sources */,
A1F6CDDC2A75AB18006F020E /* Conjugation.swift in Sources */,
A1F6CDDB2A75AB16006F020E /* Word.swift in Sources */,
A1F2B8592A7672B4003EBF17 /* WordService.swift in Sources */,
A1F6CDDE2A75AB1C006F020E /* Person.swift in Sources */,
A1F6CDB02A75A743006F020E /* WordListView.swift in Sources */,
A1F6CDAE2A75A743006F020E /* OldNorseDictionaryWatchOsApp.swift in Sources */,
Expand Down
89 changes: 5 additions & 84 deletions Source/Controllers/WordSearchController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,102 +31,23 @@ class WordSearchController: ObservableObject {
@Published var searchQuery: String = ""
@Published var searchDirection: SearchDirection = .oldNorseToRussian
@Published var selectedWordType: WordType?
@Published var loadedWords: [Word] = []
private var wordService: WordService

var filteredWords: [Word] {
if !searchQuery.isEmpty || selectedWordType != nil {
return fetchWordDetails(for: searchQuery, searchDirection: searchDirection, wordType: selectedWordType)
return wordService.searchWords(query: searchQuery, direction: searchDirection, wordType: selectedWordType)
} else {
// Show all loaded words when the search query is empty
return loadedWords.sorted(by: {
return wordService.words.sorted(by: {
if $1.oldNorseWord > $0.oldNorseWord {
return true
}

return false
})
}
}

init() {
loadWordsData()
}

func loadWordsData() {
guard let fileURL = Bundle.main.url(forResource: "WordsData", withExtension: "json") else {
fatalError("Failed to locate WordsData.json file.")
}

do {
let data = try Data(contentsOf: fileURL)
let decoder = JSONDecoder()
let words = try decoder.decode([Word].self, from: data)
loadedWords = words // Update the loadedWords property
} catch {
fatalError("Failed to load WordsData.json: \(error)")
}
}

func fetchWordDetails(for searchQuery: String, searchDirection: SearchDirection, wordType: WordType?) -> [Word] {
let lowercaseQuery = searchQuery.lowercased()
var filteredWords: [Word] = loadedWords

if wordType != nil {
filteredWords = filteredWords
.filter { $0.type == wordType }
.sorted(by: {
if $1.oldNorseWord > $0.oldNorseWord {
return true
}

return false
})
}


if !searchQuery.isEmpty {
switch searchDirection {
case .englishToOldNorse:
filteredWords = filteredWords.filter { $0.englishTranslation.lowercased().contains(lowercaseQuery) }
case .oldNorseToEnglish:
filteredWords = filterWords(filteredWords, with: lowercaseQuery)
case .russianToOldNorse:
filteredWords = filteredWords.filter { $0.russianTranslation.lowercased().contains(lowercaseQuery) }
case .oldNorseToRussian:
filteredWords = filterWords(filteredWords, with: lowercaseQuery)
}
}

return filteredWords
}

func filterWords(_ words: [Word], with query: String) -> [Word] {
let lowercaseQuery = query.lowercased()
return words.filter { word in
let wordMatchesQuery = word.oldNorseWord.lowercased().contains(lowercaseQuery)
let nominativeSingularMatchesQuery = word.generateNominative(number: Number.singular, article: false)?.lowercased().contains(lowercaseQuery) == true
let nominativeDualMatchesQuery = word.generateNominative(number: Number.dual, article: false)?.lowercased().contains(lowercaseQuery) == true
let nominativePluralMatchesQuery = word.generateNominative(number: Number.plural, article: false)?.lowercased().contains(lowercaseQuery) == true
let accusativeSingularMatchesQuery = word.generateAccusative(number: Number.singular, article: false)?.lowercased().contains(lowercaseQuery) == true
let accusativeDualMatchesQuery = word.generateAccusative(number: Number.dual, article: false)?.lowercased().contains(lowercaseQuery) == true
let accusativePluralMatchesQuery = word.generateAccusative(number: Number.plural, article: false)?.lowercased().contains(lowercaseQuery) == true
let dativeSingularMatchesQuery = word.generateDative(number: Number.singular, article: false)?.lowercased().contains(lowercaseQuery) == true
let dativeDualMatchesQuery = word.generateDative(number: Number.dual, article: false)?.lowercased().contains(lowercaseQuery) == true
let dativePluralMatchesQuery = word.generateDative(number: Number.plural, article: false)?.lowercased().contains(lowercaseQuery) == true
let firstSingularMatchesQuery = word.generateConjugation(person: .first, number: .singular)?.lowercased().contains(lowercaseQuery) == true
let secondSingularMatchesQuery = word.generateConjugation(person: .second, number: .singular)?.lowercased().contains(lowercaseQuery) == true
let thirdSingularMatchesQuery = word.generateConjugation(person: .third, number: .singular)?.lowercased().contains(lowercaseQuery) == true
let firstPluralMatchesQuery = word.generateConjugation(person: .first, number: .plural)?.lowercased().contains(lowercaseQuery) == true
let secondPluralMatchesQuery = word.generateConjugation(person: .second, number: .plural)?.lowercased().contains(lowercaseQuery) == true
let thirdPluralMatchesQuery = word.generateConjugation(person: .third, number: .plural)?.lowercased().contains(lowercaseQuery) == true

return wordMatchesQuery || nominativeSingularMatchesQuery || nominativeDualMatchesQuery || nominativePluralMatchesQuery || accusativeSingularMatchesQuery || accusativeDualMatchesQuery || accusativePluralMatchesQuery || dativeSingularMatchesQuery || dativeDualMatchesQuery || dativePluralMatchesQuery || firstSingularMatchesQuery || secondSingularMatchesQuery || thirdSingularMatchesQuery || firstPluralMatchesQuery || secondPluralMatchesQuery || thirdPluralMatchesQuery
}.sorted(by: {
if $1.oldNorseWord.count > $0.oldNorseWord.count {
return true
}

return false
})
init() {
wordService = WordService()
}
}
92 changes: 92 additions & 0 deletions Source/Services/WordService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//
// WordService.swift
// OldNorseDictionary
//
// Created by Andrey Skurlatov on 30.7.23..
//

import Foundation

class WordService {
var words: [Word] = []

init() {
loadWords()
}

func loadWords() {
guard let fileURL = Bundle.main.url(forResource: "WordsData", withExtension: "json") else {
fatalError("Failed to locate WordsData.json file.")
}

do {
let data = try Data(contentsOf: fileURL)
let decoder = JSONDecoder()
let words = try decoder.decode([Word].self, from: data)
self.words = words // Update the words property
} catch {
fatalError("Failed to load WordsData.json: \(error)")
}
}

func searchWords(query: String, direction: SearchDirection, wordType: WordType?) -> [Word] {
let lowercaseQuery = query.lowercased()
var filteredWords: [Word] = words

if wordType != nil {
filteredWords = filteredWords
.filter { $0.type == wordType }
.sorted(by: {
if $1.oldNorseWord > $0.oldNorseWord {
return true
}
return false
})
}

if !query.isEmpty {
switch direction {
case .englishToOldNorse:
filteredWords = filteredWords.filter { $0.englishTranslation.lowercased().contains(lowercaseQuery) }
case .oldNorseToEnglish:
filteredWords = filterWords(filteredWords, with: lowercaseQuery)
case .russianToOldNorse:
filteredWords = filteredWords.filter { $0.russianTranslation.lowercased().contains(lowercaseQuery) }
case .oldNorseToRussian:
filteredWords = filterWords(filteredWords, with: lowercaseQuery)
}
}

return filteredWords
}

func filterWords(_ words: [Word], with query: String) -> [Word] {
let lowercaseQuery = query.lowercased()
return words.filter { word in
let wordMatchesQuery = word.oldNorseWord.lowercased().contains(lowercaseQuery)
let nominativeSingularMatchesQuery = word.generateNominative(number: Number.singular, article: false)?.lowercased().contains(lowercaseQuery) == true
let nominativeDualMatchesQuery = word.generateNominative(number: Number.dual, article: false)?.lowercased().contains(lowercaseQuery) == true
let nominativePluralMatchesQuery = word.generateNominative(number: Number.plural, article: false)?.lowercased().contains(lowercaseQuery) == true
let accusativeSingularMatchesQuery = word.generateAccusative(number: Number.singular, article: false)?.lowercased().contains(lowercaseQuery) == true
let accusativeDualMatchesQuery = word.generateAccusative(number: Number.dual, article: false)?.lowercased().contains(lowercaseQuery) == true
let accusativePluralMatchesQuery = word.generateAccusative(number: Number.plural, article: false)?.lowercased().contains(lowercaseQuery) == true
let dativeSingularMatchesQuery = word.generateDative(number: Number.singular, article: false)?.lowercased().contains(lowercaseQuery) == true
let dativeDualMatchesQuery = word.generateDative(number: Number.dual, article: false)?.lowercased().contains(lowercaseQuery) == true
let dativePluralMatchesQuery = word.generateDative(number: Number.plural, article: false)?.lowercased().contains(lowercaseQuery) == true
let firstSingularMatchesQuery = word.generateConjugation(person: .first, number: .singular)?.lowercased().contains(lowercaseQuery) == true
let secondSingularMatchesQuery = word.generateConjugation(person: .second, number: .singular)?.lowercased().contains(lowercaseQuery) == true
let thirdSingularMatchesQuery = word.generateConjugation(person: .third, number: .singular)?.lowercased().contains(lowercaseQuery) == true
let firstPluralMatchesQuery = word.generateConjugation(person: .first, number: .plural)?.lowercased().contains(lowercaseQuery) == true
let secondPluralMatchesQuery = word.generateConjugation(person: .second, number: .plural)?.lowercased().contains(lowercaseQuery) == true
let thirdPluralMatchesQuery = word.generateConjugation(person: .third, number: .plural)?.lowercased().contains(lowercaseQuery) == true

return wordMatchesQuery || nominativeSingularMatchesQuery || nominativeDualMatchesQuery || nominativePluralMatchesQuery || accusativeSingularMatchesQuery || accusativeDualMatchesQuery || accusativePluralMatchesQuery || dativeSingularMatchesQuery || dativeDualMatchesQuery || dativePluralMatchesQuery || firstSingularMatchesQuery || secondSingularMatchesQuery || thirdSingularMatchesQuery || firstPluralMatchesQuery || secondPluralMatchesQuery || thirdPluralMatchesQuery
}.sorted(by: {
if $1.oldNorseWord.count > $0.oldNorseWord.count {
return true
}

return false
})
}
}
4 changes: 0 additions & 4 deletions Source/Views/WordSearchView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ struct ContentView: View {
@StateObject private var controller = WordSearchController()
@State private var isSidebarActive = false


var settings: some View {
Group {
#if os(iOS)
Expand Down Expand Up @@ -73,9 +72,6 @@ struct ContentView: View {
}
}
.padding()
.onAppear {
controller.loadWordsData()
}
#if os(iOS)
.onTapGesture {
self.endTextEditing()
Expand Down
3 changes: 0 additions & 3 deletions WatchOSApp/WordListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ struct WordListView: View {
.font(.system(size: 60))
}
.navigationTitle("Words")
.onAppear {
controller.loadWordsData()
}
}
}
.onAppear {
Expand Down

0 comments on commit de2b2f0

Please sign in to comment.