From e5db2b58320cc69560b231d1cb75ea0a79606426 Mon Sep 17 00:00:00 2001 From: Sjmarf <78750526+Sjmarf@users.noreply.github.com> Date: Wed, 5 Feb 2025 19:34:01 +0000 Subject: [PATCH] Update --- .../ActorIdentifiable+Extensions.swift | 20 ++++++++++++++- .../Post1Providing+Extensions.swift | 6 ++++- .../MessageFeedView+Logic.swift | 5 ++++ .../MessageFeedView/MessageFeedView.swift | 25 +++++++++++++------ .../Shared/Navigation/NavigationLayer.swift | 4 +++ .../Navigation/NavigationPage+View.swift | 9 +++++-- .../Shared/Navigation/NavigationPage.swift | 10 ++++++-- Mlem/Localizable.xcstrings | 5 +++- 8 files changed, 70 insertions(+), 14 deletions(-) diff --git a/Mlem/App/Utility/Extensions/Content Models/ActorIdentifiable+Extensions.swift b/Mlem/App/Utility/Extensions/Content Models/ActorIdentifiable+Extensions.swift index 37f4ffc20..03d9682e7 100644 --- a/Mlem/App/Utility/Extensions/Content Models/ActorIdentifiable+Extensions.swift +++ b/Mlem/App/Utility/Extensions/Content Models/ActorIdentifiable+Extensions.swift @@ -10,7 +10,25 @@ import MlemMiddleware extension ActorIdentifiable { func shareAction() -> ShareAction { - .init(id: "share\(actorId)", url: actorId.url) + .init(id: "share\(actorId)", url: actorId.url, actions: [sendLinkInPrivateMessageAction()]) + } + + func sendLinkInPrivateMessageAction() -> BasicAction { + .init( + id: "sendLinkInPrivateMessage\(actorId)", + appearance: .init( + label: "Send to Lemmy User", + color: Palette.main.accent, + icon: Icons.personCircle + ), + callback: { + NavigationModel.main.openSheet(.personPicker(callback: { person, navigation in + navigation.push( + .messageFeed(person, messageContent: String(describing: actorId), focusTextField: true) + ) + })) + } + ) } func openInstanceAction(navigation: NavigationLayer?) -> BasicAction { diff --git a/Mlem/App/Utility/Extensions/Content Models/Post1Providing+Extensions.swift b/Mlem/App/Utility/Extensions/Content Models/Post1Providing+Extensions.swift index e76a13344..8b9d84c5a 100644 --- a/Mlem/App/Utility/Extensions/Content Models/Post1Providing+Extensions.swift +++ b/Mlem/App/Utility/Extensions/Content Models/Post1Providing+Extensions.swift @@ -314,7 +314,11 @@ extension Post1Providing { // Overrides the `ActorIdentifiable+Extensions` implementation func shareAction() -> ShareAction { - .init(id: "share\(actorId)", url: actorId.url, actions: [crossPostAction()]) + .init( + id: "share\(actorId)", + url: actorId.url, + actions: [crossPostAction(), sendLinkInPrivateMessageAction()] + ) } func crossPostAction() -> BasicAction { diff --git a/Mlem/App/Views/Pages/MessageFeedView/MessageFeedView+Logic.swift b/Mlem/App/Views/Pages/MessageFeedView/MessageFeedView+Logic.swift index e37c53350..dba0aca42 100644 --- a/Mlem/App/Views/Pages/MessageFeedView/MessageFeedView+Logic.swift +++ b/Mlem/App/Views/Pages/MessageFeedView/MessageFeedView+Logic.swift @@ -10,6 +10,11 @@ import MlemMiddleware import SwiftUI extension MessageFeedView { + var shouldDelayBecomeFirstResponder: Bool { + // Only delay the keyboard opening if being pushed onto the navigation stack rather than opening in sheet + !navigation.isAtRoot + } + func sendMessage(_ scrollProxy: ScrollViewProxy) async { do { guard let person = person.wrappedValue as? any Person, !textView.text.isEmpty else { return } diff --git a/Mlem/App/Views/Pages/MessageFeedView/MessageFeedView.swift b/Mlem/App/Views/Pages/MessageFeedView/MessageFeedView.swift index fece19346..ee77c7082 100644 --- a/Mlem/App/Views/Pages/MessageFeedView/MessageFeedView.swift +++ b/Mlem/App/Views/Pages/MessageFeedView/MessageFeedView.swift @@ -8,6 +8,7 @@ import MlemMiddleware import SwiftUI +// swiftlint:disable:next type_body_length struct MessageFeedView: View { @Environment(AppState.self) var appState @Environment(NavigationLayer.self) var navigation @@ -20,15 +21,18 @@ struct MessageFeedView: View { let timer = Timer.publish(every: 5, on: .main, in: .common).autoconnect() - init(person: AnyPerson, focusTextField: Bool, editing: (any Message)?) { + init( + person: AnyPerson, + messageContent: String = "", + focusTextField: Bool, + editing: (any Message)? + ) { self.person = person self.focusTextField = focusTextField self._editing = .init(wrappedValue: editing) - if let editing { - let textView = UITextView() - textView.text = editing.content - _textView = .init(wrappedValue: textView) - } + let textView = UITextView() + textView.text = editing?.content ?? messageContent + _textView = .init(wrappedValue: textView) } @State var feedLoader: MessageFeedLoader? @@ -235,7 +239,7 @@ struct MessageFeedView: View { bottom: Constants.main.standardSpacing, right: Constants.main.standardSpacing ), - firstResponder: focusTextField, + firstResponder: focusTextField && !shouldDelayBecomeFirstResponder, sizingOffset: 5, content: { MarkdownEditorToolbarView( @@ -249,6 +253,13 @@ struct MessageFeedView: View { maxWidth: .infinity, minHeight: minTextEditorHeight ) + .onAppear { + if focusTextField, shouldDelayBecomeFirstResponder { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) { + textView.becomeFirstResponder() + } + } + } } @ViewBuilder diff --git a/Mlem/App/Views/Shared/Navigation/NavigationLayer.swift b/Mlem/App/Views/Shared/Navigation/NavigationLayer.swift index dcf8ae304..2073ee0f8 100644 --- a/Mlem/App/Views/Shared/Navigation/NavigationLayer.swift +++ b/Mlem/App/Views/Shared/Navigation/NavigationLayer.swift @@ -64,6 +64,8 @@ class NavigationLayer: Identifiable { @MainActor func push(_ page: NavigationPage) { if hasNavigationStack { + // This prevents keyboard animation glitches when navigating whilst the keyboard is open + UIApplication.shared.firstKeyWindow?.endEditing(true) path.append(page) } else { openSheet(page) @@ -99,6 +101,8 @@ class NavigationLayer: Identifiable { path.removeAll() } + var isAtRoot: Bool { path.isEmpty } + /// Open a new sheet, optionally with navigation enabled. If `nil` is specified for `hasNavigationStack`, the value of `page.hasNavigationStack` will be used. @MainActor func openSheet(_ page: NavigationPage, hasNavigationStack: Bool? = nil) { diff --git a/Mlem/App/Views/Shared/Navigation/NavigationPage+View.swift b/Mlem/App/Views/Shared/Navigation/NavigationPage+View.swift index 74ad9261b..133578695 100644 --- a/Mlem/App/Views/Shared/Navigation/NavigationPage+View.swift +++ b/Mlem/App/Views/Shared/Navigation/NavigationPage+View.swift @@ -161,8 +161,13 @@ extension NavigationPage { AdvancedSortView(selectedSort: sort.wrappedValue) case let .votesList(target): VotesListView(target: target) - case let .messageFeed(person, focusTextField: focusTextField, editing: editing): - MessageFeedView(person: person, focusTextField: focusTextField, editing: editing?.wrappedValue) + case let .messageFeed(person, messageContent: messageContent, focusTextField: focusTextField, editing: editing): + MessageFeedView( + person: person, + messageContent: messageContent, + focusTextField: focusTextField, + editing: editing?.wrappedValue + ) case let .modlog(target): ModlogView(initialTarget: target) case let .denyApplication(application): diff --git a/Mlem/App/Views/Shared/Navigation/NavigationPage.swift b/Mlem/App/Views/Shared/Navigation/NavigationPage.swift index 079225726..0a600a34f 100644 --- a/Mlem/App/Views/Shared/Navigation/NavigationPage.swift +++ b/Mlem/App/Views/Shared/Navigation/NavigationPage.swift @@ -28,7 +28,7 @@ enum NavigationPage: Hashable { case person(_ person: AnyPerson, visitContext: VisitHistory.VisitContext) case instance(_ instance: InstanceHashWrapper, visitContext: VisitHistory.VisitContext) case instanceOpinionList(instance: InstanceHashWrapper, opinionType: FediseerOpinionType, data: FediseerData) - case messageFeed(_ person: AnyPerson, focusTextField: Bool, editing: MessageHashWrapper?) + case messageFeed(_ person: AnyPerson, messageContent: String, focusTextField: Bool, editing: MessageHashWrapper?) case fediseerInfo case externalApiInfo(api: ApiClient, actorId: ActorIdentifier) case imageViewer(_ url: URL) @@ -133,6 +133,7 @@ enum NavigationPage: Hashable { static func messageFeed( _ person: any PersonStubProviding, + messageContent: String = "", focusTextField: Bool = false, editing: (any Message1Providing)? = nil ) -> NavigationPage { @@ -140,7 +141,12 @@ enum NavigationPage: Hashable { if let editing { editingWrapper = .init(wrappedValue: editing) } - return messageFeed(.init(person), focusTextField: focusTextField, editing: editingWrapper) + return messageFeed( + .init(person), + messageContent: messageContent, + focusTextField: focusTextField, + editing: editingWrapper + ) } static func instance( diff --git a/Mlem/Localizable.xcstrings b/Mlem/Localizable.xcstrings index fc4b403ec..2b36ea4ff 100644 --- a/Mlem/Localizable.xcstrings +++ b/Mlem/Localizable.xcstrings @@ -2070,6 +2070,9 @@ }, "Send Notifications to Email" : { + }, + "Send to Lemmy User" : { + }, "Sent %@" : { @@ -2805,4 +2808,4 @@ } }, "version" : "1.0" -} +} \ No newline at end of file