From dd1fdf159b26c241c5e1ffc88b8b1ec2433057d5 Mon Sep 17 00:00:00 2001 From: ericholguin Date: Wed, 4 Sep 2024 11:38:58 -0700 Subject: [PATCH] Reapply and rework "ux: Mute selected text" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit reapplies the "ux: Mute selected text" commit, with some manual rework to solve logical conflicts during merge. Rework testing -------------- PASS Device: iPhone 13 Mini iOS: 17.6.1 Steps: 1. Go to a note 2. Select text and click on the "highlight" button. Ensure that highlight sheet appears with the correct text 3. Select text and click on the "mute" button. Ensure that mute sheet appears with the correct text Original commit: d66315594137b5478909d3e8c751348d7405860f Original author: ericholguin Reworked-by: Daniel D’Aquino Retested-by: Daniel D’Aquino --- damus/Components/SelectableText.swift | 76 ++++++++++++++++++------ damus/Views/Muting/AddMuteItemView.swift | 4 +- damus/Views/Muting/MutelistView.swift | 12 ++-- 3 files changed, 64 insertions(+), 28 deletions(-) diff --git a/damus/Components/SelectableText.swift b/damus/Components/SelectableText.swift index 3e9df355..95c26760 100644 --- a/damus/Components/SelectableText.swift +++ b/damus/Components/SelectableText.swift @@ -13,7 +13,7 @@ struct SelectableText: View { let event: NostrEvent? let attributedString: AttributedString let textAlignment: NSTextAlignment - @State private var highlightPostingState: HighlightPostingState = .hide + @State private var selectedTextActionState: SelectedTextActionState = .hide @State private var selectedTextHeight: CGFloat = .zero @State private var selectedTextWidth: CGFloat = .zero @@ -37,7 +37,10 @@ struct SelectableText: View { textAlignment: self.textAlignment, enableHighlighting: self.enableHighlighting(), postHighlight: { selectedText in - self.highlightPostingState = .show_post_view(highlighted_text: selectedText) + self.selectedTextActionState = .show_highlight_post_view(highlighted_text: selectedText) + }, + muteWord: { selectedText in + self.selectedTextActionState = .show_mute_word_view(highlighted_text: selectedText) }, height: $selectedTextHeight ) @@ -54,11 +57,11 @@ struct SelectableText: View { } } .sheet(isPresented: Binding(get: { - return self.highlightPostingState.show() + return self.selectedTextActionState.should_show_highlight_post_view() }, set: { newValue in - self.highlightPostingState = newValue ? .show_post_view(highlighted_text: self.highlightPostingState.highlighted_text() ?? "") : .hide + self.selectedTextActionState = newValue ? .show_highlight_post_view(highlighted_text: self.selectedTextActionState.highlighted_text() ?? "") : .hide })) { - if let event, case .show_post_view(let highlighted_text) = self.highlightPostingState { + if let event, case .show_highlight_post_view(let highlighted_text) = self.selectedTextActionState { PostView( action: .highlighting(.init(selected_text: highlighted_text, source: .event(event))), damus_state: damus_state @@ -67,6 +70,17 @@ struct SelectableText: View { .presentationDetents([.height(selectedTextHeight + 450), .medium, .large]) } } + .sheet(isPresented: Binding(get: { + return self.selectedTextActionState.should_show_mute_word_view() + }, set: { newValue in + self.selectedTextActionState = newValue ? .show_mute_word_view(highlighted_text: self.selectedTextActionState.highlighted_text() ?? "") : .hide + })) { + if case .show_mute_word_view(let highlighted_text) = selectedTextActionState { + AddMuteItemView(state: damus_state, new_text: .constant(highlighted_text)) + .presentationDragIndicator(.visible) + .presentationDetents([.height(300), .medium, .large]) + } + } .frame(height: selectedTextHeight) } @@ -74,22 +88,28 @@ struct SelectableText: View { self.event != nil } - enum HighlightPostingState { + enum SelectedTextActionState { case hide - case show_post_view(highlighted_text: String) + case show_highlight_post_view(highlighted_text: String) + case show_mute_word_view(highlighted_text: String) - func show() -> Bool { - if case .show_post_view(let highlighted_text) = self { - return true - } - return false + func should_show_highlight_post_view() -> Bool { + guard case .show_highlight_post_view(let highlighted_text) = self else { return false } + return true + } + + func should_show_mute_word_view() -> Bool { + guard case .show_mute_word_view(let highlighted_text) = self else { return false } + return true } func highlighted_text() -> String? { switch self { case .hide: return nil - case .show_post_view(highlighted_text: let highlighted_text): + case .show_mute_word_view(highlighted_text: let highlighted_text): + return highlighted_text + case .show_highlight_post_view(highlighted_text: let highlighted_text): return highlighted_text } } @@ -98,9 +118,11 @@ struct SelectableText: View { fileprivate class TextView: UITextView { var postHighlight: (String) -> Void + var muteWord: (String) -> Void - init(frame: CGRect, textContainer: NSTextContainer?, postHighlight: @escaping (String) -> Void) { + init(frame: CGRect, textContainer: NSTextContainer?, postHighlight: @escaping (String) -> Void, muteWord: @escaping (String) -> Void) { self.postHighlight = postHighlight + self.muteWord = muteWord super.init(frame: frame, textContainer: textContainer) } @@ -112,18 +134,32 @@ fileprivate class TextView: UITextView { if action == #selector(highlightText(_:)) { return true } + + if action == #selector(muteText(_:)) { + return true + } + return super.canPerformAction(action, withSender: sender) } + + func getSelectedText() -> String? { + guard let selectedRange = self.selectedTextRange else { return nil } + return self.text(in: selectedRange) + } @objc public func highlightText(_ sender: Any?) { - guard let selectedRange = self.selectedTextRange else { return } - guard let selectedText = self.text(in: selectedRange) else { return } + guard let selectedText = self.getSelectedText() else { return } self.postHighlight(selectedText) } + + @objc public func muteText(_ sender: Any?) { + guard let selectedText = self.getSelectedText() else { return } + self.muteWord(selectedText) + } } - fileprivate struct TextViewRepresentable: UIViewRepresentable { +fileprivate struct TextViewRepresentable: UIViewRepresentable { let attributedString: AttributedString let textColor: UIColor @@ -132,10 +168,11 @@ fileprivate class TextView: UITextView { let textAlignment: NSTextAlignment let enableHighlighting: Bool let postHighlight: (String) -> Void + let muteWord: (String) -> Void @Binding var height: CGFloat func makeUIView(context: UIViewRepresentableContext) -> TextView { - let view = TextView(frame: .zero, textContainer: nil, postHighlight: postHighlight) + let view = TextView(frame: .zero, textContainer: nil, postHighlight: postHighlight, muteWord: muteWord) view.isEditable = false view.dataDetectorTypes = .all view.isSelectable = true @@ -148,7 +185,8 @@ fileprivate class TextView: UITextView { let menuController = UIMenuController.shared let highlightItem = UIMenuItem(title: "Highlight", action: #selector(view.highlightText(_:))) - menuController.menuItems = self.enableHighlighting ? [highlightItem] : [] + let muteItem = UIMenuItem(title: "Mute", action: #selector(view.muteText(_:))) + menuController.menuItems = self.enableHighlighting ? [highlightItem, muteItem] : [] return view } diff --git a/damus/Views/Muting/AddMuteItemView.swift b/damus/Views/Muting/AddMuteItemView.swift index 73d74260..1302534d 100644 --- a/damus/Views/Muting/AddMuteItemView.swift +++ b/damus/Views/Muting/AddMuteItemView.swift @@ -8,7 +8,7 @@ import SwiftUI struct AddMuteItemView: View { let state: DamusState - @State var new_text: String = "" + @Binding var new_text: String @State var expiration: DamusDuration = .indefinite @Environment(\.dismiss) var dismiss @@ -108,6 +108,6 @@ struct AddMuteItemView: View { struct AddMuteItemView_Previews: PreviewProvider { static var previews: some View { - AddMuteItemView(state: test_damus_state) + AddMuteItemView(state: test_damus_state, new_text: .constant("")) } } diff --git a/damus/Views/Muting/MutelistView.swift b/damus/Views/Muting/MutelistView.swift index fd4973a4..1a9548fa 100644 --- a/damus/Views/Muting/MutelistView.swift +++ b/damus/Views/Muting/MutelistView.swift @@ -15,6 +15,8 @@ struct MutelistView: View { @State var hashtags: [MuteItem] = [] @State var threads: [MuteItem] = [] @State var words: [MuteItem] = [] + + @State var new_text: String = "" func RemoveAction(item: MuteItem) -> some View { Button { @@ -120,13 +122,9 @@ struct MutelistView: View { } } .sheet(isPresented: $show_add_muteitem, onDismiss: { self.show_add_muteitem = false }) { - if #available(iOS 16.0, *) { - AddMuteItemView(state: damus_state) - .presentationDetents([.height(300)]) - .presentationDragIndicator(.visible) - } else { - AddMuteItemView(state: damus_state) - } + AddMuteItemView(state: damus_state, new_text: $new_text) + .presentationDetents([.height(300)]) + .presentationDragIndicator(.visible) } } }