Skip to content

Commit ba74c54

Browse files
committed
Update
1 parent d679320 commit ba74c54

21 files changed

+120
-267
lines changed

Sources/Pulse/LoggerStore/LoggerStore+Entities.swift

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public final class LoggerMessageEntity: NSManagedObject {
3030
public final class NetworkTaskEntity: NSManagedObject {
3131
// Primary
3232
@NSManaged public var createdAt: Date
33+
@NSManaged public var isPinned: Bool
3334
@NSManaged public var session: UUID
3435
@NSManaged public var taskId: UUID
3536

Sources/Pulse/LoggerStore/LoggerStore+Model.swift

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ extension LoggerStore {
4545

4646
task.properties = [
4747
Attribute("createdAt", .dateAttributeType),
48+
Attribute("isPinned", .booleanAttributeType),
4849
Attribute("session", .UUIDAttributeType),
4950
Attribute("taskId", .UUIDAttributeType),
5051
Attribute("taskType", .integer16AttributeType),

Sources/Pulse/LoggerStore/LoggerStore.swift

+13-1
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,12 @@ extension LoggerStore {
808808
}
809809
}
810810

811+
package func clearSessions(withIDs sessionIDs: Set<UUID>) {
812+
perform { _ in
813+
try? self._removeMessagesForSessions(withIDs: sessionIDs, isInverted: false)
814+
}
815+
}
816+
811817
private func _removeSessions(withIDs sessionIDs: Set<UUID>, isInverted: Bool = false) throws {
812818
try deleteEntities(for: {
813819
let request = LoggerSessionEntity.fetchRequest()
@@ -816,6 +822,10 @@ extension LoggerStore {
816822
return request
817823
}())
818824

825+
try _removeMessagesForSessions(withIDs: sessionIDs, isInverted: isInverted)
826+
}
827+
828+
private func _removeMessagesForSessions(withIDs sessionIDs: Set<UUID>, isInverted: Bool) throws {
819829
var predicate = NSPredicate(format: "session IN %@", sessionIDs)
820830
predicate = isInverted ? NSCompoundPredicate(notPredicateWithSubpredicate: predicate) : predicate
821831
try removeMessages(with: predicate)
@@ -825,7 +835,9 @@ extension LoggerStore {
825835

826836
/// Removes all of the previously recorded messages.
827837
public func removeAll() {
828-
perform { _ in self._removeAll() }
838+
perform { _ in
839+
self._removeAll()
840+
}
829841
}
830842

831843
private func _removeAll() {

Sources/PulseUI/Features/Console/Views/ConsoleHelperViews.swift

+9
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,12 @@ struct StatusIndicatorView: View {
5858
}
5959
}
6060
}
61+
62+
struct BookmarkIconView: View {
63+
var body: some View {
64+
Image(systemName: "bookmark.fill")
65+
.font(.footnote)
66+
.foregroundColor(.pink)
67+
.frame(width: 8, height: 8)
68+
}
69+
}

Sources/PulseUI/Features/Console/Views/ConsoleMessageCell.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ package struct ConsoleMessageCell: View {
4343
.foregroundColor(titleColor)
4444
Spacer()
4545
#if !os(watchOS)
46-
#if canImport(RiftSupport)
47-
PinView(message: message)
48-
#endif
46+
if message.isPinned {
47+
BookmarkIconView()
48+
}
4949
ConsoleTimestampView(date: message.createdAt)
5050
.padding(.trailing, 3)
5151
#endif

Sources/PulseUI/Features/Console/Views/ConsoleTaskCell.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ package struct ConsoleTaskCell: View {
5757
info.higlighted(highlightedArea == .header)
5858

5959
Spacer()
60-
#if canImport(RiftSupport)
61-
PinView(task: task)
62-
#endif
60+
if task.isPinned {
61+
BookmarkIconView()
62+
}
6363
ConsoleTimestampView(date: task.createdAt)
6464
.padding(.trailing, 3)
6565
}

Sources/PulseUI/Features/Filters/Views/ConsoleDomainsSelectionView.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import SwiftUI
66
import Pulse
77
import Combine
88

9+
#if !os(macOS)
10+
911
@available(iOS 16, visionOS 1, *)
1012
struct ConsoleDomainsSelectionView: View {
1113
@ObservedObject var viewModel: ConsoleFiltersViewModel
@@ -23,8 +25,8 @@ struct ConsoleDomainsSelectionView: View {
2325
}
2426
}
2527

26-
private extension ConsoleFiltersViewModel {
27-
func bindingForHosts(index: LoggerStoreIndex) -> Binding<Set<String>> {
28+
extension ConsoleFiltersViewModel {
29+
package func bindingForHosts(index: LoggerStoreIndex) -> Binding<Set<String>> {
2830
Binding(get: {
2931
if let focused = self.criteria.network.host.focused {
3032
return [focused]
@@ -43,3 +45,5 @@ private extension ConsoleFiltersViewModel {
4345
})
4446
}
4547
}
48+
49+
#endif

Sources/PulseUI/Features/Filters/Views/ConsoleLabelsSelectionView.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import SwiftUI
66
import Pulse
77
import Combine
88

9+
#if !os(macOS)
10+
911
@available(iOS 16, visionOS 1, *)
1012
struct ConsoleLabelsSelectionView: View {
1113
@ObservedObject var viewModel: ConsoleFiltersViewModel
@@ -23,8 +25,10 @@ struct ConsoleLabelsSelectionView: View {
2325
}
2426
}
2527

26-
private extension ConsoleFiltersViewModel {
27-
func bindingForSelectedLabels(index: LoggerStoreIndex) -> Binding<Set<String>> {
28+
#endif
29+
30+
extension ConsoleFiltersViewModel {
31+
package func bindingForSelectedLabels(index: LoggerStoreIndex) -> Binding<Set<String>> {
2832
Binding(get: {
2933
if let focused = self.criteria.messages.labels.focused {
3034
return [focused]

Sources/PulseUI/Features/Filters/Views/ConsoleSearchListSelectionView.swift

+5-34
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
//
33
// Copyright (c) 2020-2024 Alexander Grebenyuk (github.com/kean).
44

5+
#if !os(macOS)
6+
57
import SwiftUI
68
import Pulse
79

@@ -14,7 +16,7 @@ package struct ConsoleSearchListSelectionView<Data: RandomAccessCollection, ID:
1416
package let description: (Data.Element) -> String
1517
@ViewBuilder package let label: (Data.Element) -> Label
1618

17-
#if os(iOS) || os(macOS) || os(visionOS)
19+
#if os(iOS) || os(visionOS)
1820
package var limit = 6
1921
#else
2022
package var limit = 3
@@ -42,34 +44,6 @@ package struct ConsoleSearchListSelectionView<Data: RandomAccessCollection, ID:
4244

4345
@State private var searchText = ""
4446

45-
#if os(macOS)
46-
@State private var isExpanded = false
47-
48-
package var body: some View {
49-
if items.isEmpty {
50-
emptyView
51-
} else {
52-
let filtered = self.filteredItems
53-
HStack {
54-
SearchBar(title: "Search", text: $searchText)
55-
Spacer()
56-
buttonToggleAll
57-
}
58-
ForEach(isExpanded ? filtered : Array(filtered.prefix(limit)), id: id, content: makeRow)
59-
if filtered.count > limit {
60-
HStack {
61-
if !isExpanded {
62-
Button(action: { isExpanded = true }) {
63-
Text("Show All ") + Text("(\(items.count))").foregroundColor(.secondary)
64-
}
65-
} else {
66-
Button("Show Less") { isExpanded = false }
67-
}
68-
}
69-
}
70-
}
71-
}
72-
#else
7347
@State private var isExpandedListPresented = false
7448
@State private var isSearching = false
7549

@@ -116,7 +90,6 @@ package struct ConsoleSearchListSelectionView<Data: RandomAccessCollection, ID:
11690
.disableAutocorrection(true)
11791
#endif
11892
}
119-
#endif
12093

12194
// MARK: - Shared
12295

@@ -136,10 +109,6 @@ package struct ConsoleSearchListSelectionView<Data: RandomAccessCollection, ID:
136109
selection.remove(item[keyPath: id])
137110
}
138111
}), label: { label(item).lineLimit(1) })
139-
#if os(macOS)
140-
.help(description(item))
141-
.frame(maxWidth: .infinity, alignment: .leading)
142-
#endif
143112
}
144113

145114
private var filteredItems: [Data.Element] {
@@ -182,3 +151,5 @@ private struct ConsoleSearchListSelectionViewDemo: View {
182151
}
183152
}
184153
#endif
154+
155+
#endif

Sources/PulseUI/Features/Filters/Views/ConsoleSessionsPickerView.swift

+4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ package struct ConsoleSessionsPickerView: View {
1515

1616
#if os(iOS) || os(visionOS) || os(macOS)
1717
package static var makeSessionPicker: (_ selection: Binding<Set<UUID>>) -> AnyView = {
18+
#if os(macOS)
19+
AnyView(EmptyView()) // Has to be injected
20+
#else
1821
AnyView(SessionPickerView(selection: $0))
22+
#endif
1923
}
2024
#endif
2125

Sources/PulseUI/Features/Search/Services/ConsoleSearchOccurrence.swift

+31-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import Pulse
99
import CoreData
1010
import Combine
1111

12+
#if os(macOS)
13+
import AppKit
14+
#endif
15+
1216
@available(iOS 16, visionOS 1, *)
1317
package final class ConsoleSearchOccurrence: Identifiable, Equatable, Hashable {
1418
package let id = ConsoleSearchOccurrenceId()
@@ -40,9 +44,33 @@ private let previewAttibutes = TextHelper().attributes(role: .body2, style: .mon
4044

4145
@available(iOS 16, visionOS 1, *)
4246
extension ConsoleSearchOccurrence {
43-
static func makePreview(for match: ConsoleSearchMatch, attributes customAttributes: [NSAttributedString.Key: Any] = [:]) -> AttributedString {
47+
package static func makePreview(for match: ConsoleSearchMatch, attributes customAttributes: [NSAttributedString.Key: Any] = [:]) -> AttributedString {
48+
let segments = makePreviewSegments(for: match)
49+
50+
var attributes = AttributeContainer(customAttributes)
51+
#if os(macOS)
52+
attributes.foregroundColor = .secondary
53+
attributes.font = .callout
54+
#endif
4455

45-
let prefixStartIndex = match.line.index(match.range.lowerBound, offsetBy: -50, limitedBy: match.line.startIndex) ?? match.line.startIndex
56+
var middle = AttributedString(segments[1], attributes: attributes)
57+
#if os(macOS)
58+
middle.foregroundColor = .primary
59+
middle.font = Font.callout.weight(.semibold)
60+
#else
61+
middle.foregroundColor = .orange
62+
#endif
63+
return AttributedString(segments[0], attributes: attributes) + middle + AttributedString(segments[2], attributes: attributes)
64+
}
65+
66+
package static func makePreviewSegments(for match: ConsoleSearchMatch) -> [Substring] {
67+
let prefixOffset: Int
68+
#if os(macOS)
69+
prefixOffset = -20
70+
#else
71+
prefixOffset = -50
72+
#endif
73+
let prefixStartIndex = match.line.index(match.range.lowerBound, offsetBy: prefixOffset, limitedBy: match.line.startIndex) ?? match.line.startIndex
4674
let prefixRange = prefixStartIndex..<match.range.lowerBound
4775

4876
let suffixUpperBound = match.line.index(match.range.upperBound, offsetBy: 200, limitedBy: match.line.endIndex) ?? match.line.endIndex
@@ -62,11 +90,7 @@ extension ConsoleSearchOccurrence {
6290
if isEllipsisNeeded {
6391
prefix.insert("", at: prefix.startIndex)
6492
}
65-
66-
let attributes = AttributeContainer(customAttributes)
67-
var middle = AttributedString(match.line[match.range], attributes: attributes)
68-
middle.foregroundColor = .orange
69-
return AttributedString(prefix, attributes: attributes) + middle + AttributedString(suffix, attributes: attributes)
93+
return [prefix, match.line[match.range], suffix]
7094
}
7195
}
7296

Sources/PulseUI/Features/Search/Services/ConsoleSearchOperation.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ final class ConsoleSearchOperation {
160160
var lineCount = 0
161161
content.enumerateLines { line, stop in
162162
lineCount += 1
163-
for range in line.ranges(of: term.text, options: term.options) {
163+
for range in line.ranges(of: term.text, options: term.options, limit: ConsoleSearchMatch.limit) {
164164
let match = ConsoleSearchMatch(line: line, lineNumber: lineCount, range: range, term: term)
165165
matches.append(match)
166166
}
@@ -195,7 +195,7 @@ package struct ConsoleSearchMatch {
195195
package let range: Range<String.Index>
196196
package let term: ConsoleSearchTerm
197197

198-
package static let limit = 1000
198+
package static let limit = 6
199199

200200
package init(line: String, lineNumber: Int, range: Range<String.Index>, term: ConsoleSearchTerm) {
201201
self.line = line

Sources/PulseUI/Features/Search/Views/ConsoleSearchResultsSectionView.swift

+4-39
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ struct ConsoleSearchResultDetailsView: View {
114114
}
115115
}
116116

117+
#endif
118+
119+
#if os(iOS) || os(visionOS) || os(macOS)
120+
117121
@available(iOS 16, visionOS 1, *)
118122
package struct PlainListGroupSeparator: View {
119123
package init() {}
@@ -127,10 +131,6 @@ package struct PlainListGroupSeparator: View {
127131
}
128132
}
129133

130-
#endif
131-
132-
#if os(iOS) || os(visionOS) || os(macOS)
133-
134134
@available(iOS 16, macOS 13, visionOS 1, *)
135135
package struct PlainListSectionHeader<Content: View>: View {
136136
package var title: String?
@@ -171,39 +171,4 @@ extension PlainListSectionHeader where Content == Text {
171171
}
172172
}
173173

174-
@available(iOS 16, visionOS 1, *)
175-
package struct PlainListSeeAllView: View {
176-
let count: Int
177-
178-
package init(count: Int) {
179-
self.count = count
180-
}
181-
182-
package var body: some View {
183-
(Text("Show All").foregroundColor(.accentColor) +
184-
Text(" (\(count))"))
185-
.font(.subheadline)
186-
.foregroundColor(.secondary)
187-
.frame(maxWidth: .infinity, alignment: .leading)
188-
}
189-
}
190-
191-
@available(iOS 16, visionOS 1, *)
192-
package struct PlainListSectionHeaderSeparator: View {
193-
let title: String
194-
195-
package init(title: String) {
196-
self.title = title
197-
}
198-
199-
package var body: some View {
200-
HStack(alignment: .bottom, spacing: 0) {
201-
Text(title)
202-
.foregroundColor(.secondary)
203-
.font(.subheadline.weight(.medium))
204-
Spacer()
205-
}
206-
}
207-
}
208-
209174
#endif

0 commit comments

Comments
 (0)