mirror of
https://github.com/kean/Pulse.git
synced 2026-05-30 21:07:33 +00:00
104 lines
3.4 KiB
Swift
104 lines
3.4 KiB
Swift
// 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
|