@@ -22,21 +22,35 @@ struct AlarmListView: View {
2222 @State private var sheetInfo : SheetInfo ?
2323 @State private var deleteAfterDismiss : UUID ?
2424 @State private var selectedAlarm : Alarm ?
25+ @State private var searchText = " "
26+
27+ // MARK: - Search
28+
29+ private func matches( _ alarm: Alarm ) -> Bool {
30+ let query = searchText. trimmingCharacters ( in: . whitespacesAndNewlines)
31+ guard !query. isEmpty else { return true }
32+ return alarm. name. localizedCaseInsensitiveContains ( query)
33+ || alarm. type. rawValue. localizedCaseInsensitiveContains ( query)
34+ }
35+
36+ private var hasResults : Bool {
37+ !snoozedAlarms. isEmpty || !activeAlarms. isEmpty || !inactiveAlarms. isEmpty
38+ }
2539
2640 // MARK: - Categorized Alarms
2741
2842 private var snoozedAlarms : [ Alarm ] {
29- store. value. filter { $0. snoozedUntil ?? . distantPast > Date ( ) && $0. isEnabled }
43+ store. value. filter { $0. snoozedUntil ?? . distantPast > Date ( ) && $0. isEnabled && matches ( $0 ) }
3044 . sorted ( by: Alarm . byPriorityThenSpec)
3145 }
3246
3347 private var activeAlarms : [ Alarm ] {
34- store. value. filter { $0. isEnabled && ( $0. snoozedUntil ?? . distantPast <= Date ( ) ) }
48+ store. value. filter { $0. isEnabled && ( $0. snoozedUntil ?? . distantPast <= Date ( ) ) && matches ( $0 ) }
3549 . sorted ( by: Alarm . byPriorityThenSpec)
3650 }
3751
3852 private var inactiveAlarms : [ Alarm ] {
39- store. value. filter { !$0. isEnabled }
53+ store. value. filter { !$0. isEnabled && matches ( $0 ) }
4054 . sorted ( by: Alarm . byPriorityThenSpec)
4155 }
4256
@@ -81,6 +95,23 @@ struct AlarmListView: View {
8195 }
8296 }
8397 }
98+ . overlay {
99+ if !hasResults, !searchText. trimmingCharacters ( in: . whitespacesAndNewlines) . isEmpty {
100+ VStack ( spacing: 8 ) {
101+ Image ( systemName: " magnifyingglass " )
102+ . font ( . largeTitle)
103+ . foregroundColor ( . secondary)
104+ Text ( " No Results " )
105+ . font ( . headline)
106+ Text ( " No alarms match “ \( searchText) ”. " )
107+ . font ( . subheadline)
108+ . foregroundColor ( . secondary)
109+ . multilineTextAlignment ( . center)
110+ }
111+ . padding ( . horizontal)
112+ }
113+ }
114+ . searchable ( text: $searchText, prompt: " Search alarms " )
84115 . sheet ( item: $sheetInfo, onDismiss: handleSheetDismiss) { info in
85116 sheetContent ( for: info)
86117 }
0 commit comments