Remove ShareEntitiesView

This commit is contained in:
kean
2023-01-14 15:34:39 -05:00
parent 8da2548cd2
commit 257d45197b
6 changed files with 29 additions and 139 deletions
-4
View File
@@ -78,7 +78,6 @@
0C9F05002884F34A0035239F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0C9F04FF2884F34A0035239F /* Preview Assets.xcassets */; };
0C9F050C2884FA7D0035239F /* repos.json in Resources */ = {isa = PBXBuildFile; fileRef = 0CFF9BD825D6199A0069DB6A /* repos.json */; };
0CCBDDC02610BDBC00DCB60C /* repos.json in Resources */ = {isa = PBXBuildFile; fileRef = 0CFF9BD825D6199A0069DB6A /* repos.json */; };
0CD7E0BB297326EC00A255B7 /* ShareEntitiesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CD7E0BA297326EC00A255B7 /* ShareEntitiesView.swift */; };
0CD7E0BD29732C8E00A255B7 /* ShareStoreTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CD7E0BC29732C8E00A255B7 /* ShareStoreTask.swift */; };
0CDC3BEA2970FA47003BD1FF /* ConsoleSearchListSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CDC3BE92970FA47003BD1FF /* ConsoleSearchListSelectionView.swift */; };
0CDC3BED2971B936003BD1FF /* ConsoleSearchLogLevelsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CDC3BEC2971B936003BD1FF /* ConsoleSearchLogLevelsCell.swift */; };
@@ -528,7 +527,6 @@
0C9F04FC2884F34A0035239F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0C9F04FF2884F34A0035239F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
0C9F05012884F34A0035239F /* Pulse_Demo_macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Pulse_Demo_macOS.entitlements; sourceTree = "<group>"; };
0CD7E0BA297326EC00A255B7 /* ShareEntitiesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareEntitiesView.swift; sourceTree = "<group>"; };
0CD7E0BC29732C8E00A255B7 /* ShareStoreTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareStoreTask.swift; sourceTree = "<group>"; };
0CDC3BE92970FA47003BD1FF /* ConsoleSearchListSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleSearchListSelectionView.swift; sourceTree = "<group>"; };
0CDC3BEC2971B936003BD1FF /* ConsoleSearchLogLevelsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConsoleSearchLogLevelsCell.swift; sourceTree = "<group>"; };
@@ -1180,7 +1178,6 @@
0CF0D59C296F189500EED9D4 /* KeyValueSectionViewModel.swift */,
0CF0D59E296F189500EED9D4 /* WebView.swift */,
0CF0D5A5296F189500EED9D4 /* StoreShareView.swift */,
0CD7E0BA297326EC00A255B7 /* ShareEntitiesView.swift */,
0CF0D5A6296F189500EED9D4 /* SearchBar-ios.swift */,
0CF0D5A7296F189500EED9D4 /* TimingView.swift */,
0CF0D5A8296F189500EED9D4 /* InfoRow.swift */,
@@ -2050,7 +2047,6 @@
0CF0D659296F189600EED9D4 /* ConsoleSettings.swift in Sources */,
0CF0D61B296F189600EED9D4 /* ShareItems.swift in Sources */,
0CF0D683296F189600EED9D4 /* ConsoleMessageTableCell.swift in Sources */,
0CD7E0BB297326EC00A255B7 /* ShareEntitiesView.swift in Sources */,
0CF0D623296F189600EED9D4 /* SearchBar-macos.swift in Sources */,
0CE364F72971D1EA0063DFED /* ConsoleSearchCustomFiltersSection.swift in Sources */,
0C40C0A8296F9CBA009ECF16 /* ConsoleSearchPinsCell.swift in Sources */,
@@ -34,13 +34,18 @@ public struct ConsoleView: View {
Button(action: $0) { Text("Close") }
},
trailing: HStack {
Menu(content: { shareMenu }) {
Image(systemName: "square.and.arrow.up")
if let _ = selectedShareOutput {
ProgressView()
.frame(width: 27, height: 27)
} else {
Menu(content: { shareMenu }) {
Image(systemName: "square.and.arrow.up")
}
.disabled(selectedShareOutput != nil)
}
ConsoleContextMenu(store: viewModel.store, insights: viewModel.insightsViewModel, isShowingAsText: $isShowingAsText)
}
)
.overlay(sharingOverlay) // TODO: use safeAreaInset instead on iOS 15
.sheet(item: $shareItems, content: ShareView.init)
.sheet(isPresented: $isShowingAsText) {
NavigationView {
@@ -53,37 +58,24 @@ public struct ConsoleView: View {
@ViewBuilder
private var shareMenu: some View {
Button(action: { withAnimation { selectedShareOutput = .plainText } }) {
Button(action: { share(as: .plainText) }) {
Label("Share as Text", systemImage: "square.and.arrow.up")
}
Button(action: { withAnimation { selectedShareOutput = .html } }) {
Button(action: { share(as: .html) }) {
Label("Share as HTML", systemImage: "square.and.arrow.up")
}
#if os(iOS)
Button(action: { withAnimation { selectedShareOutput = .pdf} }) {
Button(action: { share(as: .pdf) }) {
Label("Share as PDF", systemImage: "square.and.arrow.up")
}
#endif
}
@ViewBuilder var sharingOverlay: some View {
if let output = selectedShareOutput {
VStack(spacing: 0) {
Spacer()
Divider()
let share = ShareEntitiesView(entities: viewModel.entities, store: viewModel.store, output: output) {
shareItems = $0
withAnimation {
selectedShareOutput = nil
}
}
if #available(iOS 15, *) {
share.background(Material.regular)
} else {
share.background(Color.white)
}
}
.transition(.move(edge: .bottom))
private func share(as output: ShareOutput) {
selectedShareOutput = output
viewModel.prepareForSharing(as: output) { item in
selectedShareOutput = nil
shareItems = item
}
}
@@ -155,6 +155,12 @@ final class ConsoleViewModel: NSObject, NSFetchedResultsControllerDelegate, Obse
table.entities = entities
#endif
}
// MARK: - Sharing
func prepareForSharing(as output: ShareOutput, _ completion: @escaping (ShareItems?) -> Void) {
ShareService.share(entities, store: store, as: output, completion)
}
}
private func makeFetchRequest(for mode: ConsoleViewModel.Mode) -> NSFetchRequest<NSManagedObject> {
+6
View File
@@ -30,6 +30,12 @@ struct ShareItems: Identifiable {
}
enum ShareService {
private static var task: ShareStoreTask?
static func share(_ entities: [NSManagedObject], store: LoggerStore, as output: ShareOutput, _ completion: @escaping (ShareItems?) -> Void) {
ShareStoreTask(entities: entities, store: store, output: output, completion: completion).start()
}
static func share(_ message: LoggerMessageEntity, as output: ShareOutput) -> ShareItems {
share(TextRenderer.share([message]), as: output)
}
+1 -9
View File
@@ -8,8 +8,6 @@ import CoreData
import SwiftUI
import Pulse
#warning("TODO: make store accesor from BlobEntity private")
final class ShareStoreTask: ObservableObject {
@Published var stage: Stage = .preparing
@Published var progress: Float = 0
@@ -36,7 +34,7 @@ final class ShareStoreTask: ObservableObject {
self.completion = completion
}
func cancel() {
func cancel() { // Not yet implemented
isCancelled = true
completion?(nil)
completion = nil
@@ -107,9 +105,6 @@ final class ShareStoreTask: ObservableObject {
let start = index * indices.count / iterations
let end = (index + 1) * indices.count / iterations
#warning("TEMP")
Thread.sleep(forTimeInterval: 0.1)
for index in start..<end {
let job = queue[index]
guard let data = job.value.data() else { continue }
@@ -133,9 +128,6 @@ final class ShareStoreTask: ObservableObject {
continue
}
#warning("TEMP")
Thread.sleep(forTimeInterval: 0.1)
if let task = entity as? NetworkTaskEntity {
renderer.render(task, content: content)
} else if let message = entity as? LoggerMessageEntity {
@@ -1,102 +0,0 @@
// The MIT License (MIT)
//
// Copyright (c) 20202023 Alexander Grebenyuk (github.com/kean).
import SwiftUI
import CoreData
import Pulse
import Combine
struct ShareEntitiesView: View {
@StateObject private var viewModel = ShareEntitiesViewModel()
private let entities: [NSManagedObject]
private let store: LoggerStore
private let output: ShareOutput
private let completion: (ShareItems?) -> Void
init(entities: [NSManagedObject], store: LoggerStore, output: ShareOutput, completion: @escaping (ShareItems?) -> Void) {
self.entities = entities
self.store = store
self.output = output
self.completion = completion
}
var body: some View {
HStack(alignment: .center, spacing: 12) {
ProgressView()
VStack(alignment: .leading) {
Text(viewModel.title)
Text(viewModel.details)
.foregroundColor(.secondary)
}
Spacer()
if viewModel.isProcessing {
Button("Cancel") {
viewModel.cancel()
}
}
}
.padding()
.onAppear {
viewModel.prepare(entities: entities, store: store, output: output, completion: completion)
}
}
}
private final class ShareEntitiesViewModel: ObservableObject {
@Published var title: String = ""
@Published var details: String = ""
@Published var isProcessing = true
// TODO: use as binding
@Published var shareItem: ShareItems?
private var isStarted = false
private var task: ShareStoreTask?
private var cancellables: [AnyCancellable] = []
init() {}
func prepare(entities: [NSManagedObject], store: LoggerStore, output: ShareOutput, completion: @escaping (ShareItems?) -> Void) {
guard !isStarted else { return }
isStarted = true
let task = ShareStoreTask(entities: entities, store: store, output: output, completion: completion)
task.$stage.sink { [weak self] in
guard let self = self else { return }
switch $0 {
case .preparing:
self.title = "Preparing Logs..."
self.details = "This may take some time"
case .rendering:
self.title = "Generating \(output.title)..."
self.details = "This may take some time"
if output == .pdf {
self.details = "This operation blocks the app somt time".
}
case .completed:
break
}
}.store(in: &cancellables)
task.start()
self.task = task
}
#warning("TODO: implenet cancellation")
func cancel() {
self.task?.cancel()
}
}
#if DEBUG
struct ShareEntitiesView_Previews: PreviewProvider {
static var previews: some View {
#if os(iOS)
ShareEntitiesView(entities: try! LoggerStore.mock.allMessages(), store: .mock, output: .html) { _ in }
#else
ShareEntitiesView(entities: try! LoggerStore.mock.allMessages(), store: .mock, output: .html) { _ in }
.frame(width: 300, height: 500)
#endif
}
}
#endif