diff --git a/Meshtastic/Views/Settings/AppLog.swift b/Meshtastic/Views/Settings/AppLog.swift index c1872802..d9bc4ccb 100644 --- a/Meshtastic/Views/Settings/AppLog.swift +++ b/Meshtastic/Views/Settings/AppLog.swift @@ -15,11 +15,12 @@ struct AppLog: View { @State private var logs: [OSLogEntryLog] = [] @State private var sortOrder = [KeyPathComparator(\OSLogEntryLog.date, order: .reverse)] @State private var selection: OSLogEntry.ID? + @State private var selectedLog: OSLogEntryLog? @State private var presentingErrorDetails: Bool = false @State private var searchText = "" - @State private var category: Int = -1 - @State private var level: Int = -1 + @State private var categories: Set = [0, 1, 2, 3, 4, 5, 6] + @State private var levels: Set = [0, 1, 2, 3, 4] @State var isExporting = false @State var exportString = "" @State var isEditingFilters = false @@ -54,7 +55,7 @@ struct AppLog: View { } .monospaced() .sheet(isPresented: $isEditingFilters) { - AppLogFilter(category: $category, level: $level) + AppLogFilter(categories: $categories, levels: $levels) } .safeAreaInset(edge: .bottom, alignment: .trailing) { HStack { @@ -98,13 +99,13 @@ struct AppLog: View { logs.sort(using: sortOrder) } } - .onChange(of: category) { _ in + .onChange(of: [categories]) { _ in Task { await logs = searchAppLogs() logs.sort(using: sortOrder) } } - .onChange(of: level) { _ in + .onChange(of: [levels]) { _ in Task { await logs = searchAppLogs() logs.sort(using: sortOrder) @@ -188,15 +189,25 @@ extension AppLog { /// Subsystem Predicate let subsystemPredicate = NSPredicate(format: "subsystem IN %@", ["com.apple.SwiftUI", "com.apple.coredata", "gvh.MeshtasticClient"]) predicates.append(subsystemPredicate) - /// Category - if category > -1 { - let categoryPredicate = NSPredicate(format: "category == %@", LogCategories(rawValue: category)!.description) - predicates.append(categoryPredicate) + /// Categories + if categories.count > 0 { + var categoriesArray: [NSPredicate] = [] + for c in categories { + let categoriesPredicate = NSPredicate(format: "category == %@", LogCategories(rawValue: c)?.description ?? "services") + categoriesArray.append(categoriesPredicate) + } + let compoundPredicate = NSCompoundPredicate(type: .or, subpredicates: categoriesArray) + predicates.append(compoundPredicate) } - /// Log Level - if level > -1 { - let levelPredicate = NSPredicate(format: "messageType == %@", LogLevels(rawValue: level)?.level ?? "info") - predicates.append(levelPredicate) + /// Log Levels + if levels.count > 0 { + var levelsArray: [NSPredicate] = [] + for l in levels { + let levelsPredicate = NSPredicate(format: "messageType == %@", LogLevels(rawValue: l)?.level ?? "info") + levelsArray.append(levelsPredicate) + } + let compoundPredicate = NSCompoundPredicate(type: .or, subpredicates: levelsArray) + predicates.append(compoundPredicate) } if predicates.count > 0 || !searchText.isEmpty { if !searchText.isEmpty { diff --git a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift index b3dbcdad..fa3a41e6 100644 --- a/Meshtastic/Views/Settings/Logs/AppLogFilter.swift +++ b/Meshtastic/Views/Settings/Logs/AppLogFilter.swift @@ -85,39 +85,36 @@ struct AppLogFilter: View { @Environment(\.dismiss) private var dismiss /// Filters var filterTitle = "App Log Filters" - @Binding var category: Int - @Binding var level: Int + @Binding var categories: Set + @Binding var levels: Set + @State var editMode = EditMode.active /// the edit mode var body: some View { NavigationStack { Form { - Section(header: Text(filterTitle)) { - HStack { - Label("Category", systemImage: "square.grid.2x2") - Picker("", selection: $category) { - Text("All Categories") - .tag(-1) - ForEach(LogCategories.allCases) { lc in - Text("\(lc.description)") - } + Section(header: Text("Categories")) { + VStack { + List(LogCategories.allCases, selection: $categories) { cat in + Text(cat.description) } - .pickerStyle(DefaultPickerStyle()) + .listStyle(.plain) + .environment(\.editMode, $editMode) /// bind it here! + .frame(minHeight: 300, maxHeight: .infinity) } - - HStack { - Label("Level", systemImage: "stairs") - Picker("", selection: $level) { - Text("All Levels") - .tag(-1) - ForEach(LogLevels.allCases) { ll in - Text("\(ll.description)") - } + } + Section(header: Text("Log Levels")) { + VStack { + List(LogLevels.allCases, selection: $levels) { level in + Text(level.description) } - .pickerStyle(DefaultPickerStyle()) + .listStyle(.plain) + .environment(\.editMode, $editMode) /// bind it here! + .frame(minHeight: 210, maxHeight: .infinity) } } } + #if targetEnvironment(macCatalyst) Spacer() Button { @@ -131,7 +128,7 @@ struct AppLogFilter: View { .padding(.bottom) #endif } - .presentationDetents([.fraction(0.6), .fraction(0.75)]) + .presentationDetents([.fraction(1.0)]) .presentationDragIndicator(.visible) } }