From c76c90e00554531be956dba1c5ae4cbeed7cefd1 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 31 Jan 2023 18:42:52 +0800 Subject: [PATCH] Allow exporting highlights and notes as markdown --- .../Views/Highlights/HighlightsListCard.swift | 9 +++++++ .../Views/Highlights/HighlightsListView.swift | 26 +++++++++++++++++-- .../Highlights/HighlightsListViewModel.swift | 13 ++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListCard.swift b/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListCard.swift index c2eb00567..b312afc4f 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListCard.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListCard.swift @@ -7,6 +7,7 @@ struct HighlightsListCard: View { @State var annotation = String() @State var showAnnotationModal = false + let viewModel: HighlightsListViewModel let highlightParams: HighlightListItemParams @Binding var hasHighlightMutations: Bool let onSaveAnnotation: (String) -> Void @@ -15,6 +16,7 @@ struct HighlightsListCard: View { @State var errorAlertMessage: String? @State var showErrorAlertMessage = false + @State var showShareView = false var contextMenuView: some View { Group { @@ -40,6 +42,10 @@ struct HighlightsListCard: View { }, label: { Label(LocalText.labelsGeneric, systemImage: "tag") } ) + Button( + action: { showShareView = true }, + label: { Label("Export", systemImage: "square.and.arrow.up") } + ) Button( action: onDeleteHighlight, label: { Label("Delete", systemImage: "trash") } @@ -166,5 +172,8 @@ struct HighlightsListCard: View { showErrorAlertMessage: $showErrorAlertMessage ) } + .formSheet(isPresented: $showShareView) { + ShareSheet(activityItems: [viewModel.highlightAsMarkdown(item: self.highlightParams)]) + } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListView.swift b/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListView.swift index 3432f73a1..aa52abd77 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListView.swift @@ -12,6 +12,7 @@ struct HighlightsListView: View { let itemObjectID: NSManagedObjectID @Binding var hasHighlightMutations: Bool @State var setLabelsHighlight: Highlight? + @State var showShareView: Bool = false var emptyView: some View { Text(LocalText.highlightCardNoHighlightsOnPage) @@ -26,9 +27,14 @@ struct HighlightsListView: View { #if os(iOS) .navigationBarTitleDisplayMode(.inline) .toolbar { - ToolbarItem(placement: .navigationBarTrailing) { + ToolbarItem(placement: .navigationBarLeading) { dismissButton } + ToolbarItem(placement: .navigationBarTrailing) { + actionsMenu + } + }.formSheet(isPresented: $showShareView) { + ShareSheet(activityItems: [viewModel.highlightsAsMarkdown()]) } #else .toolbar { @@ -44,6 +50,7 @@ struct HighlightsListView: View { Section { ForEach(viewModel.highlightItems) { highlightParams in HighlightsListCard( + viewModel: self.viewModel, highlightParams: highlightParams, hasHighlightMutations: $hasHighlightMutations, onSaveAnnotation: { @@ -82,7 +89,22 @@ struct HighlightsListView: View { var dismissButton: some View { Button( action: { presentationMode.wrappedValue.dismiss() }, - label: { Text(LocalText.doneGeneric).foregroundColor(.appGrayTextContrast) } + label: { Text(LocalText.genericClose) } + ) + } + + var actionsMenu: some View { + Menu( + content: { + Button( + action: { showShareView = true }, + label: { Label("Export", systemImage: "square.and.arrow.up") } + ) + }, + label: { + Image(systemName: "ellipsis") + .foregroundColor(.appGrayTextContrast) + } ) } diff --git a/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListViewModel.swift index 7a251029b..86a7a53dc 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Highlights/HighlightsListViewModel.swift @@ -58,6 +58,19 @@ struct HighlightListItemParams: Identifiable { } } + func highlightAsMarkdown(item: HighlightListItemParams) -> String { + var buffer = "> \(item.quote)" + if !item.annotation.isEmpty { + buffer += "\n\n\(item.annotation)" + } + buffer += "\n" + return buffer + } + + func highlightsAsMarkdown() -> String { + highlightItems.map { highlightAsMarkdown(item: $0) }.lazy.joined(separator: "\n\n") + } + private func loadHighlights(item: LinkedItem) { let unsortedHighlights = item.highlights.asArray(of: Highlight.self)