ソースを参照

Add search filter to the Add Alarm sheet (#681)

Jonas Björkert 3 週間 前
コミット
094c9ddad2
1 ファイル変更30 行追加2 行削除
  1. 30 2
      LoopFollow/Alarm/AddAlarm/AddAlarmSheet.swift

+ 30 - 2
LoopFollow/Alarm/AddAlarm/AddAlarmSheet.swift

@@ -7,22 +7,33 @@ struct AddAlarmSheet: View {
     let onSelect: (AlarmType) -> Void
     @Environment(\.dismiss) private var dismiss
 
+    @State private var searchText = ""
+
     private let columns = [
         GridItem(.adaptive(minimum: 110), spacing: 16),
     ]
 
+    private func matches(_ type: AlarmType) -> Bool {
+        let query = searchText.trimmingCharacters(in: .whitespacesAndNewlines)
+        guard !query.isEmpty else { return true }
+        return type.rawValue.localizedCaseInsensitiveContains(query)
+            || type.blurb.localizedCaseInsensitiveContains(query)
+            || type.group.rawValue.localizedCaseInsensitiveContains(query)
+    }
+
     var body: some View {
         NavigationStack {
             ScrollView {
                 LazyVGrid(columns: columns, spacing: 16) {
                     ForEach(AlarmType.Group.allCases, id: \.self) { group in
-                        if AlarmType.allCases.contains(where: { $0.group == group }) {
+                        let types = AlarmType.allCases.filter { $0.group == group && matches($0) }
+                        if !types.isEmpty {
                             Section(header: Text(group.rawValue)
                                 .font(.headline)
                                 .frame(maxWidth: .infinity, alignment: .leading)
                                 .padding(.horizontal, 4)
                             ) {
-                                ForEach(AlarmType.allCases.filter { $0.group == group }, id: \.self) { type in
+                                ForEach(types, id: \.self) { type in
                                     AlarmTile(type: type) {
                                         onSelect(type)
                                     }
@@ -32,8 +43,25 @@ struct AddAlarmSheet: View {
                     }
                 }
                 .padding()
+
+                if !AlarmType.allCases.contains(where: matches) {
+                    VStack(spacing: 8) {
+                        Image(systemName: "magnifyingglass")
+                            .font(.largeTitle)
+                            .foregroundColor(.secondary)
+                        Text("No Results")
+                            .font(.headline)
+                        Text("No alarms match “\(searchText)”.")
+                            .font(.subheadline)
+                            .foregroundColor(.secondary)
+                            .multilineTextAlignment(.center)
+                    }
+                    .padding(.top, 40)
+                    .padding(.horizontal)
+                }
             }
             .navigationTitle("Add Alarm")
+            .searchable(text: $searchText, prompt: "Search alarms")
             .toolbar {
                 ToolbarItem(placement: .cancellationAction) {
                     Button("Cancel") { dismiss() }