Files
Pulse/Sources/PulseUI/Features/MessageDetails/ConsoleMessageDetailsView.swift
2022-08-14 17:25:28 -04:00

157 lines
5.2 KiB
Swift
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// The MIT License (MIT)
//
// Copyright (c) 2020–2022 Alexander Grebenyuk (github.com/kean).
import SwiftUI
import Pulse
struct ConsoleMessageDetailsView: View {
let viewModel: ConsoleMessageDetailsViewModel
@Environment(\.colorScheme) var colorScheme: ColorScheme
@State private var isShowingShareSheet = false
var onClose: (() -> Void)?
#if os(iOS)
var body: some View {
contents
.navigationBarTitle("", displayMode: .inline)
.navigationBarItems(trailing: trailingNavigationBarItems)
.sheet(isPresented: $isShowingShareSheet) {
ShareView(activityItems: [self.viewModel.prepareForSharing()])
}
}
@ViewBuilder
private var trailingNavigationBarItems: some View {
HStack(spacing: 10) {
if let badge = viewModel.badge {
BadgeView(viewModel: BadgeViewModel(title: badge.title, color: badge.color.opacity(colorScheme == .light ? 0.25 : 0.5)))
}
NavigationLink(destination: ConsoleMessageMetadataView(message: viewModel.message)) {
Image(systemName: "info.circle")
}
PinButton(viewModel: viewModel.pin, isTextNeeded: false)
ShareButton {
self.isShowingShareSheet = true
}
}
}
#elseif os(watchOS)
var body: some View {
ScrollView {
VStack(spacing: 8) {
NavigationLink(destination: ConsoleMessageMetadataView(message: viewModel.message)) {
Label("Details", systemImage: "info.circle")
}
contents
}
}
}
#elseif os(tvOS)
var body: some View {
contents
}
#elseif os(macOS)
@State var isMetaVisible = false
var body: some View {
VStack(spacing: 0) {
HStack(spacing: 12) {
Button(action: { isMetaVisible = true }) {
Image(systemName: "info.circle")
}.padding(.leading, 4)
if let badge = viewModel.badge {
BadgeView(viewModel: BadgeViewModel(title: badge.title, color: badge.color.opacity(colorScheme == .light ? 0.25 : 0.5)))
}
Spacer()
if let onClose = onClose {
Button(action: onClose) {
Image(systemName: "xmark").foregroundColor(.secondary)
}.buttonStyle(.plain)
}
}
.padding([.leading, .trailing], 6)
.frame(height: 27, alignment: .center)
Divider()
textView
.background(colorScheme == .dark ? Color(NSColor(red: 30/255.0, green: 30/255.0, blue: 30/255.0, alpha: 1)) : .clear)
}
.sheet(isPresented: $isMetaVisible, content: {
VStack(spacing: 0) {
HStack {
Text("Message Details")
.font(.headline)
.foregroundColor(.secondary)
Spacer()
Button("Close") { isMetaVisible = false }
.keyboardShortcut(.cancelAction)
}.padding()
ConsoleMessageMetadataView(message: viewModel.message)
}.frame(width: 440, height: 600)
})
}
#endif
private var contents: some View {
VStack {
textView
}.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
private var textView: some View {
RichTextView(viewModel: viewModel.textViewModel)
}
#if os(watchOS) || os(tvOS)
private var tags: some View {
VStack(alignment: .leading) {
if let badge = viewModel.badge {
BadgeView(viewModel: BadgeViewModel(title: badge.title, color: badge.color.opacity(colorScheme == .light ? 0.25 : 0.5)))
}
ForEach(viewModel.tags, id: \.title) { tag in
HStack {
Text(tag.title)
.font(.caption)
.foregroundColor(.secondary)
Text(tag.value)
.font(.caption)
.foregroundColor(.primary)
}
}
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.gray.opacity(0.15))
.cornerRadius(8)
}
#endif
}
#if DEBUG
struct ConsoleMessageDetailsView_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
ConsoleMessageDetailsView(viewModel: .init(message: makeMockMessage()), onClose: {})
}
}
}
func makeMockMessage() -> LoggerMessageEntity {
let entity = LoggerMessageEntity(context: LoggerStore.mock.viewContext)
entity.text = "test"
entity.createdAt = Date()
let label = LoggerLabelEntity(context: LoggerStore.mock.viewContext)
label.name = "auth"
entity.label = label
entity.level = LoggerStore.Level.critical.rawValue
entity.session = UUID()
entity.file = "LoggerStore.swift"
entity.function = "createMockMessage()"
entity.line = 12
entity.rawMetadata = "customKey: customValue"
return entity
}
#endif