Skip to content

Commit d553b09

Browse files
committed
Added SaveSearch query
1 parent 654f3a5 commit d553b09

File tree

1 file changed

+67
-82
lines changed

1 file changed

+67
-82
lines changed

PG5602_H24-4/Views/SearchView.swift

+67-82
Original file line numberDiff line numberDiff line change
@@ -13,74 +13,6 @@ enum SortOption: String, CaseIterable {
1313
case publishedAt = "Newest"
1414
}
1515

16-
//struct SearchView: View {
17-
// @Environment(\.modelContext) var modelContext
18-
// @Query(sort: \Search.timestamp, order: .reverse) var searchHistory: [Search]
19-
// @State var query: String = ""
20-
// @State var articles: [NewsArticle] = []
21-
// @State var isLoading = false
22-
// @State var errorMessage: String?
23-
// @State var selectedSortOption: SortOption = .relevance
24-
//
25-
// var body: some View {
26-
// NavigationStack {
27-
// VStack {
28-
// HStack {
29-
// ForEach(SortOption.allCases, id: \.self) { option in
30-
// Button(action: {
31-
// selectedSortOption = option
32-
// sortArticles()
33-
// }) {
34-
// Text(option.rawValue)
35-
// .padding()
36-
// .background(selectedSortOption == option ? Color.blue : Color.gray.opacity(0.3))
37-
// .foregroundStyle(.white)
38-
// .clipShape(RoundedRectangle(cornerRadius: 8))
39-
// }
40-
// }
41-
// }
42-
// .padding()
43-
//
44-
// if isLoading || errorMessage != nil {
45-
// ZStack {
46-
// if isLoading {
47-
// ProgressView("Loading articles")
48-
// .controlSize(.large)
49-
// .tint(.blue)
50-
// } else if let errorMessage = errorMessage {
51-
// Text(errorMessage)
52-
// .foregroundStyle(.red)
53-
// }
54-
// }
55-
// .frame(maxWidth: .infinity)
56-
// .padding()
57-
//
58-
// } else {
59-
// List(articles, id: \.url) { article in
60-
// NavigationLink(destination: ArticleDetailView(article: article)) {
61-
// VStack(alignment: .leading) {
62-
// Text(article.title)
63-
// .font(.headline)
64-
// Text(article.description ?? "No description available")
65-
// .font(.subheadline)
66-
// .foregroundStyle(.secondary)
67-
// }
68-
// }
69-
// }
70-
// }
71-
// }
72-
// .navigationTitle("Search for anything...")
73-
// .searchable(text: $query, placement: .toolbar, prompt: "Search for articles")
74-
// .onChange(of: query) { oldValue, newValue in
75-
// if newValue.isEmpty {
76-
// articles = []
77-
// } else {
78-
// performSearch()
79-
// }
80-
// }
81-
// }
82-
// }
83-
8416
struct SearchView: View {
8517
@Environment(\.modelContext) var modelContext
8618
@Query(sort: \Search.timestamp, order: .reverse) var searchHistory: [Search]
@@ -93,8 +25,42 @@ struct SearchView: View {
9325
var body: some View {
9426
NavigationStack {
9527
ZStack {
96-
// Hovedinnholdet i grensesnittet
9728
VStack {
29+
HStack {
30+
TextField("Search for articles", text: $query, onCommit: {
31+
performSearch()
32+
})
33+
.textFieldStyle(RoundedBorderTextFieldStyle())
34+
35+
if !searchHistory.isEmpty {
36+
Menu {
37+
ForEach(searchHistory) { search in
38+
Button(action: {
39+
query = search.query
40+
performSearch()
41+
}) {
42+
Text(search.query)
43+
}
44+
}
45+
Button(action: clearSearchHistory) {
46+
HStack {
47+
Text("Clear History")
48+
.font(.headline)
49+
Spacer()
50+
Image(systemName: "trash")
51+
.foregroundStyle(.red)
52+
}
53+
.padding(8)
54+
}
55+
} label: {
56+
Image(systemName: "arrowtriangle.down.circle")
57+
.foregroundColor(.blue)
58+
.imageScale(.large)
59+
}
60+
}
61+
}
62+
.padding()
63+
9864
HStack {
9965
ForEach(SortOption.allCases, id: \.self) { option in
10066
Button(action: {
@@ -123,8 +89,6 @@ struct SearchView: View {
12389
}
12490
}
12591
}
126-
127-
// Overlay for ProgressView og feilmelding
12892
if isLoading || errorMessage != nil {
12993
VStack {
13094
if isLoading {
@@ -139,22 +103,16 @@ struct SearchView: View {
139103
}
140104
}
141105
.frame(maxWidth: .infinity, maxHeight: .infinity)
142-
.background(Color.black.opacity(0.4)) // Gjør bakgrunnen semi-transparent
106+
.background(Color.black.opacity(0.4))
143107
.edgesIgnoringSafeArea(.all)
144108
}
145109
}
146-
.navigationTitle("Search for anything...")
147-
.searchable(text: $query, placement: .toolbar, prompt: "Search for articles")
148-
.onChange(of: query) { oldValue, newValue in
149-
if newValue.isEmpty {
150-
articles = []
151-
} else {
152-
performSearch()
153-
}
154-
}
110+
.navigationTitle("Search")
155111
}
156112
}
157113

114+
115+
158116
func search() {
159117
guard !query.isEmpty else { return }
160118

@@ -189,6 +147,9 @@ struct SearchView: View {
189147

190148
func performSearch() {
191149
guard !query.isEmpty else { return }
150+
151+
saveSearch(query)
152+
192153
isLoading = true
193154
errorMessage = nil
194155

@@ -205,9 +166,33 @@ struct SearchView: View {
205166
}
206167
}
207168
}
169+
170+
func saveSearch(_ query: String) {
171+
if searchHistory.contains(where: { $0.query == query }) {
172+
return
173+
}
174+
let newSearch = Search(query: query)
175+
modelContext.insert(newSearch)
176+
do {
177+
try modelContext.save()
178+
print("Search saved: '\(query)'.")
179+
} catch {
180+
print("Error saving search: \(error)")
181+
}
182+
}
183+
func clearSearchHistory() {
184+
for search in searchHistory {
185+
modelContext.delete(search)
186+
}
187+
do {
188+
try modelContext.save()
189+
print("Search history cleared.")
190+
} catch {
191+
print("Error clearing search history: \(error)")
192+
}
193+
}
208194
}
209195

210196
#Preview {
211197
SearchView()
212198
}
213-

0 commit comments

Comments
 (0)