Skip to content

Commit

Permalink
Merge pull request #81 from kean/metadata-view
Browse files Browse the repository at this point in the history
Metadata View
  • Loading branch information
kean committed May 14, 2022
2 parents 38df231 + 741892c commit 403699c
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 64 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Pulse 1.x

## Pulse 1.1.0

*May 14, 2022*

- [iOS, watchOS] Update message details design, display custom metadata – [#81](https://github.com/kean/Pulse/pull/81)
- [iOS] Fix an issue with search toolbar not showing up during searching

## Pulse 1.0.3

*May 3, 2022*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,16 @@
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
launchAutomaticallySubstyle = "32">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Pulse">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEAB3D925FE862D00F09B0F"
BuildableName = "Pulse Demo watchOS.app"
BlueprintName = "Pulse Demo watchOS"
ReferencedContainer = "container:Pulse.xcodeproj">
</BuildableReference>
</RemoteRunnable>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
Expand All @@ -75,27 +73,16 @@
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES"
launchAutomaticallySubstyle = "32">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Pulse">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEAB3D925FE862D00F09B0F"
BuildableName = "Pulse Demo watchOS.app"
BlueprintName = "Pulse Demo watchOS"
ReferencedContainer = "container:Pulse.xcodeproj">
</BuildableReference>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEAB3D925FE862D00F09B0F"
BuildableName = "Pulse Demo watchOS.app"
BlueprintName = "Pulse Demo watchOS"
ReferencedContainer = "container:Pulse.xcodeproj">
</BuildableReference>
</MacroExpansion>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down
25 changes: 6 additions & 19 deletions Pulse.xcodeproj/xcshareddata/xcschemes/Pulse Demo watchOS.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -54,46 +54,33 @@
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Pulse">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEAB3D925FE862D00F09B0F"
BuildableName = "Pulse Demo watchOS.app"
BlueprintName = "Pulse Demo watchOS"
ReferencedContainer = "container:Pulse.xcodeproj">
</BuildableReference>
</RemoteRunnable>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<RemoteRunnable
runnableDebuggingMode = "2"
BundleIdentifier = "com.apple.Carousel"
RemotePath = "/Pulse">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEAB3D925FE862D00F09B0F"
BuildableName = "Pulse Demo watchOS.app"
BlueprintName = "Pulse Demo watchOS"
ReferencedContainer = "container:Pulse.xcodeproj">
</BuildableReference>
</RemoteRunnable>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "0CEAB3D925FE862D00F09B0F"
BuildableName = "Pulse Demo watchOS.app"
BlueprintName = "Pulse Demo watchOS"
ReferencedContainer = "container:Pulse.xcodeproj">
</BuildableReference>
</MacroExpansion>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ struct ConsoleMessageDetailsView: View {
var body: some View {
contents
.navigationBarTitle("", displayMode: .inline)
.navigationBarItems(trailing: HStack(spacing: 18) {
.navigationBarItems(trailing: HStack(spacing: 14) {
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
Expand All @@ -32,10 +35,21 @@ struct ConsoleMessageDetailsView: View {
#elseif os(watchOS)
var body: some View {
ScrollView {
contents
}.toolbar(content: {
PinButton(viewModel: viewModel.pin, isTextNeeded: false)
})
VStack {
HStack {
PinButton3(viewModel: viewModel.pin)
NavigationLink(destination: ConsoleMessageMetadataView(message: viewModel.message)) {
VStack(spacing: 4) {
Image(systemName: "info.circle")
.foregroundColor(.blue)
Text("Details")
.font(.caption2)
}.frame(height: 42)
}
}
contents
}
}
}
#elseif os(tvOS)
var body: some View {
Expand All @@ -45,7 +59,6 @@ struct ConsoleMessageDetailsView: View {

private var contents: some View {
VStack {
tags
textView
}.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
Expand Down Expand Up @@ -76,25 +89,40 @@ struct ConsoleMessageDetailsView: View {
.background(Color.gray.opacity(0.15))
.cornerRadius(8)
}
#else
private var tags: some View {
VStack(alignment: .leading) {
ForEach(viewModel.tags, id: \.title) { tag in
HStack {
Text(tag.title)
.font(.caption)
.foregroundColor(.secondary)
Text(tag.value)
.font(.caption)
.bold()
.foregroundColor(.secondary)
}
#endif
}

#if DEBUG
@available(iOS 13.0, tvOS 14.0, watchOS 7.0, *)
struct ConsoleMessageDetailsView_Previews: PreviewProvider {
static var previews: some View {
Group {
NavigationView {
ConsoleMessageDetailsView(viewModel: .init(store: LoggerStore.mock, message: makeMockMessage()))
}
}
.padding(16)
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.gray.opacity(0.15))
}
#endif
}

func makeMockMessage() -> LoggerMessageEntity {
let entity = LoggerMessageEntity(context: LoggerStore.mock.container.viewContext)
entity.text = "test"
entity.createdAt = Date()
entity.label = "auth"
entity.level = "critical"
entity.session = UUID().uuidString
entity.file = "~/Develop/Pulse/LoggerStore.swift"
entity.filename = "LoggerStore.swift"
entity.function = "createMockMessage()"
entity.line = 12

let meta = LoggerMetadataEntity(context: LoggerStore.mock.container.viewContext)
meta.key = "customKey"
meta.value = "customValue"

entity.metadata = Set([meta])
return entity
}
#endif

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class ConsoleMessageDetailsViewModel {
let text: String
let badge: BadgeViewModel?

private let message: LoggerMessageEntity
let message: LoggerMessageEntity
private let store: LoggerStore

static let dateFormatter: DateFormatter = {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// The MIT License (MIT)
//
// Copyright (c) 2020–2022 Alexander Grebenyuk (github.com/kean).

import SwiftUI
import PulseCore

#if os(iOS) || os(tvOS) || os(watchOS)
@available(iOS 13.0, tvOS 14.0, watchOS 7.0, *)
struct ConsoleMessageMetadataView: View {
let message: LoggerMessageEntity

@State private var isMetadataRawLinkActive = false

var body: some View {
contents
.background(linksView)
#if os(iOS)
.navigationBarTitle("Details", displayMode: .inline)
#endif
}

@ViewBuilder
private var contents: some View {
ScrollView {
#if os(iOS) || os(tvOS)
VStack {
stackContents
}.padding()
#elseif os(watchOS)
VStack(spacing: 16) {
stackContents
}
#endif
}
}

@ViewBuilder
private var stackContents: some View {
KeyValueSectionView(viewModel: .init(title: "Summary", color: message.tintColor, items: [
("Date", dateFormatter.string(from: message.createdAt)),
("Level", message.level),
("Label", message.label.nonEmpty)
]))
KeyValueSectionView(viewModel: .init(title: "Details", color: .secondary, items: [
("Session", message.session.nonEmpty),
("File", message.file.nonEmpty),
("Filename", message.filename.nonEmpty),
("Function", message.function.nonEmpty),
("Line", message.line == 0 ? nil : "\(message.line)"),
]))
KeyValueSectionView(viewModel: metadataViewModel)
}

private var metadataViewModel: KeyValueSectionViewModel {
KeyValueSectionViewModel(title: "Metadata", color: .indigo, action: .init(action: {
isMetadataRawLinkActive = true
}, title: "View"), items: metadataItems)
}

private var metadataItems: [(String, String?)] {
message.metadata.sorted(by: { $0.key < $1.key }).map { ($0.key, $0.value )}
}

private var linksView: some View {
NavigationLink(destination: NetworkHeadersDetailsView(viewModel: metadataViewModel), isActive: $isMetadataRawLinkActive) {
EmptyView()
}.opacity(0)
}
}

@available(iOS 13.0, tvOS 14.0, watchOS 7.0, *)
private extension LoggerMessageEntity {
var tintColor: Color {
Color.badgeColor(for: .init(rawValue: level) ?? .debug)
}
}

private extension String {
var nonEmpty: String? {
isEmpty ? nil : self
}
}

private let dateFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss.SSS, yyyy-MM-dd"
return formatter
}()

#if DEBUG
@available(iOS 13.0, tvOS 14.0, watchOS 7.0, *)
struct ConsoleMessageMetadataView_Previews: PreviewProvider {
static var previews: some View {
Group {
NavigationView {
ConsoleMessageMetadataView(message: makeMockMessage())
}
}
}
}
#endif

#endif
18 changes: 18 additions & 0 deletions Sources/PulseUI/Views/PinButton.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,24 @@ struct PinButton2: View {
}
}

#if os(watchOS)
@available(iOS 14.0, tvOS 14.0, watchOS 7.0, *)
struct PinButton3: View {
@ObservedObject var viewModel: PinButtonViewModel

var body: some View {
Button(action: viewModel.togglePin) {
VStack(spacing: 4) {
Image(systemName: viewModel.isPinned ? "pin.slash" : "pin")
.foregroundColor(.blue)
Text(viewModel.isPinned ? "Remove Pin" : "Pin")
.font(.caption2)
}.frame(height: 42)
}
}
}
#endif

#if os(iOS)
@available(iOS 13.0, *)
extension UIAction {
Expand Down
4 changes: 2 additions & 2 deletions Sources/PulseUI/Views/SearchBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ struct SearchBar: UIViewRepresentable {
}

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {

self.onEditingChanged?(true)
}

func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {

self.onEditingChanged?(false)
}
}

Expand Down

0 comments on commit 403699c

Please sign in to comment.