// The MIT License (MIT) // // Copyright (c) 2020–2022 Alexander Grebenyuk (github.com/kean). import SwiftUI import CoreData import Pulse import Combine #if os(iOS) public struct ConsoleView: View { @ObservedObject var viewModel: ConsoleViewModel @State private var isSharing = false public init(store: LoggerStore = .shared) { self.viewModel = ConsoleViewModel(store: store) } init(viewModel: ConsoleViewModel) { self.viewModel = viewModel } public var body: some View { contentView .onAppear(perform: viewModel.onAppear) .onDisappear(perform: viewModel.onDisappear) .edgesIgnoringSafeArea(.bottom) .navigationBarTitle(Text("Console")) .navigationBarItems( leading: viewModel.onDismiss.map { Button(action: $0) { Image(systemName: "xmark") } }, trailing: ShareButton { isSharing = true } ) .sheet(isPresented: $isSharing) { if #available(iOS 14.0, *) { NavigationView { ShareStoreView(store: viewModel.store, isPresented: $isSharing) } } else { ShareView(ShareItems(messages: viewModel.store)) } } } private var contentView: some View { ConsoleTableView( header: { ConsoleToolbarView(viewModel: viewModel) }, viewModel: viewModel.table, detailsViewModel: viewModel.details ) .overlay(tableOverlay) } @ViewBuilder private var tableOverlay: some View { if viewModel.entities.isEmpty { PlaceholderView.make(viewModel: viewModel) } } } private struct ConsoleToolbarView: View { @ObservedObject var viewModel: ConsoleViewModel @State private var isShowingFilters = false @State private var messageCount = 0 var body: some View { VStack(spacing: 8) { HStack(spacing: 0) { SearchBar(title: "Search \(viewModel.entities.count) messages", text: $viewModel.filterTerm) Button(action: { viewModel.isOnlyErrors.toggle() }) { Image(systemName: viewModel.isOnlyErrors ? "exclamationmark.octagon.fill" : "exclamationmark.octagon") .font(.system(size: 20)) .foregroundColor(.accentColor) }.frame(width: 40, height: 44) Button(action: { isShowingFilters = true }) { Image(systemName: viewModel.searchCriteria.isDefaultSearchCriteria ? "line.horizontal.3.decrease.circle" : "line.3.horizontal.decrease.circle.fill") .font(.system(size: 20)) .foregroundColor(.accentColor) }.frame(width: 40, height: 44) }.buttonStyle(.plain) } .padding(EdgeInsets(top: 2, leading: 8, bottom: 2, trailing: 8)) .sheet(isPresented: $isShowingFilters) { NavigationView { ConsoleFiltersView(viewModel: viewModel.searchCriteria, isPresented: $isShowingFilters) } } } } #if DEBUG struct ConsoleView_Previews: PreviewProvider { static var previews: some View { NavigationView { ConsoleView(viewModel: .init(store: .mock)) } } } #endif #endif