From 6ba82c8c3989bdbe7a0d9e5fd5d4f0054113f187 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 19 Jun 2024 13:49:44 +0400 Subject: [PATCH] ios: check preferences before forward (#4336) * ios: check preferences before forward * rework * clean up * shorter message --------- Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com> --- .../Views/Chat/ChatItemForwardingView.swift | 62 +++++++++++++++---- .../Chat/ComposeMessage/ComposeView.swift | 7 ++- apps/ios/SimpleXChat/ChatTypes.swift | 9 +++ 3 files changed, 65 insertions(+), 13 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/ChatItemForwardingView.swift b/apps/ios/Shared/Views/Chat/ChatItemForwardingView.swift index 7237711a2a..fd89c7e3ec 100644 --- a/apps/ios/Shared/Views/Chat/ChatItemForwardingView.swift +++ b/apps/ios/Shared/Views/Chat/ChatItemForwardingView.swift @@ -19,6 +19,7 @@ struct ChatItemForwardingView: View { @State private var searchText: String = "" @FocusState private var searchFocused + @State private var alert: SomeAlert? = nil var body: some View { NavigationView { @@ -35,6 +36,12 @@ struct ChatItemForwardingView: View { } } } + .alert(item: $alert) { a in + switch a { + case let .someAlert(alert, _): + return alert + } + } } @ViewBuilder private func forwardListView() -> some View { @@ -49,7 +56,7 @@ struct ChatItemForwardingView: View { let chats = s == "" ? chatsToForwardTo : chatsToForwardTo.filter { filterChatSearched($0, s) } ForEach(chats) { chat in Divider() - forwardListNavLinkView(chat) + forwardListChatView(chat) .disabled(chatModel.deletedChats.contains(chat.chatInfo.id)) } } @@ -102,31 +109,62 @@ struct ChatItemForwardingView: View { } } + private func prohibitedByPref(_ chat: Chat) -> Bool { + // preference checks should match checks in compose view + let simplexLinkProhibited = hasSimplexLink && !chat.groupFeatureEnabled(.simplexLinks) + let fileProhibited = (ci.content.msgContent?.isMediaOrFileAttachment ?? false) && !chat.groupFeatureEnabled(.files) + let voiceProhibited = (ci.content.msgContent?.isVoice ?? false) && !chat.chatInfo.featureEnabled(.voice) + return switch chat.chatInfo { + case .direct: voiceProhibited + case .group: simplexLinkProhibited || fileProhibited || voiceProhibited + case .local: false + case .contactRequest: false + case .contactConnection: false + case .invalidJSON: false + } + } + + private var hasSimplexLink: Bool { + guard let mcText = ci.content.msgContent?.text else { return false } + guard let parsedMsg = parseSimpleXMarkdown(mcText) else { return false } + return parsedMsgHasSimplexLink(parsedMsg) + } + private func emptyList() -> some View { Text("No filtered chats") .foregroundColor(.secondary) .frame(maxWidth: .infinity) } - @ViewBuilder private func forwardListNavLinkView(_ chat: Chat) -> some View { + @ViewBuilder private func forwardListChatView(_ chat: Chat) -> some View { Button { - dismiss() - if chat.id == fromChatInfo.id { - composeState = ComposeState( - message: composeState.message, - preview: composeState.linkPreview != nil ? composeState.preview : .noPreview, - contextItem: .forwardingItem(chatItem: ci, fromChatInfo: fromChatInfo) - ) + if prohibitedByPref(chat) { + alert = .someAlert( + alert: mkAlert( + title: "Cannot forward message", + message: "Selected chat preferences prohibit this message." + ), + id: "forward prohibited by preferences" + ) } else { - composeState = ComposeState.init(forwardingItem: ci, fromChatInfo: fromChatInfo) - chatModel.chatId = chat.id + dismiss() + if chat.id == fromChatInfo.id { + composeState = ComposeState( + message: composeState.message, + preview: composeState.linkPreview != nil ? composeState.preview : .noPreview, + contextItem: .forwardingItem(chatItem: ci, fromChatInfo: fromChatInfo) + ) + } else { + composeState = ComposeState.init(forwardingItem: ci, fromChatInfo: fromChatInfo) + chatModel.chatId = chat.id + } } } label: { HStack { ChatInfoImage(chat: chat, size: 30) .padding(.trailing, 2) Text(chat.chatInfo.chatViewName) - .foregroundColor(.primary) + .foregroundColor(prohibitedByPref(chat) ? .secondary : .primary) .lineLimit(1) if chat.chatInfo.incognito { Spacer() diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift index 3f1824cd6a..8a0ad9a023 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ComposeView.swift @@ -286,6 +286,7 @@ struct ComposeView: View { if chat.chatInfo.contact?.nextSendGrpInv ?? false { ContextInvitingContactMemberView() } + // preference checks should match checks in forwarding list let simplexLinkProhibited = hasSimplexLink && !chat.groupFeatureEnabled(.simplexLinks) let fileProhibited = composeState.attachmentPreview && !chat.groupFeatureEnabled(.files) let voiceProhibited = composeState.voicePreview && !chat.chatInfo.featureEnabled(.voice) @@ -1065,7 +1066,7 @@ struct ComposeView: View { } else { nil } - let simplexLink = parsedMsg.contains(where: { ft in ft.format?.isSimplexLink ?? false }) + let simplexLink = parsedMsgHasSimplexLink(parsedMsg) return (url, simplexLink) } @@ -1105,6 +1106,10 @@ struct ComposeView: View { } } +func parsedMsgHasSimplexLink(_ parsedMsg: [FormattedText]) -> Bool { + parsedMsg.contains(where: { ft in ft.format?.isSimplexLink ?? false }) +} + struct ComposeView_Previews: PreviewProvider { static var previews: some View { let chat = Chat(chatInfo: ChatInfo.sampleData.direct, chatItems: []) diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index 4c62fe4c8b..1f58ee2363 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -3438,6 +3438,15 @@ public enum MsgContent: Equatable { } } + public var isMediaOrFileAttachment: Bool { + switch self { + case .image: true + case .video: true + case .file: true + default: false + } + } + var cmdString: String { "json \(encodeJSON(self))" }