krz/hutch
an ios client for sourcehut
clone: git clone https://gitbay.org/krz/hutch.git
v3.10.0: Hutch/Views/Lookup/LookupHistoryStore.swift · raw
1import Foundation
2
3struct LookupHistoryEntry: Codable, Hashable, Identifiable, Sendable {
4 let type: LookupType
5 let query: String
6 let createdAt: Date
7
8 var id: String {
9 "\(type.rawValue):\(query)"
10 }
11}
12
13enum LookupHistoryStore {
14 private static let maximumEntries = 20
15
16 static func load(defaults: UserDefaults = .standard) -> [LookupHistoryEntry] {
17 guard let data = defaults.data(forKey: AppStorageKeys.lookupHistory) else {
18 return []
19 }
20
21 do {
22 return try JSONDecoder().decode([LookupHistoryEntry].self, from: data)
23 } catch {
24 defaults.removeObject(forKey: AppStorageKeys.lookupHistory)
25 return []
26 }
27 }
28
29 static func record(
30 type: LookupType,
31 query: String,
32 defaults: UserDefaults = .standard,
33 now: Date = .now
34 ) {
35 let normalizedQuery = query.trimmingCharacters(in: .whitespacesAndNewlines)
36 guard !normalizedQuery.isEmpty else { return }
37
38 var entries = load(defaults: defaults)
39 entries.removeAll { $0.type == type && $0.query == normalizedQuery }
40 entries.insert(
41 LookupHistoryEntry(type: type, query: normalizedQuery, createdAt: now),
42 at: 0
43 )
44
45 if entries.count > maximumEntries {
46 entries = Array(entries.prefix(maximumEntries))
47 }
48
49 save(entries, defaults: defaults)
50 }
51
52 static func clear(defaults: UserDefaults = .standard) {
53 defaults.removeObject(forKey: AppStorageKeys.lookupHistory)
54 }
55
56 private static func save(_ entries: [LookupHistoryEntry], defaults: UserDefaults) {
57 guard let data = try? JSONEncoder().encode(entries) else { return }
58 defaults.set(data, forKey: AppStorageKeys.lookupHistory)
59 }
60}