Skip to content

Commit

Permalink
feat: Create a block list to block a specific sender in a thread (#1530)
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinperignon authored Sep 11, 2024
2 parents 2ad413d + 97b6bb1 commit 2d0bdcd
Show file tree
Hide file tree
Showing 15 changed files with 372 additions and 44 deletions.
76 changes: 76 additions & 0 deletions Mail/Views/Alerts/ConfirmationBlockRecipientView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
Infomaniak Mail - iOS App
Copyright (C) 2024 Infomaniak Network SA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import Foundation
import InfomaniakCoreUI
import InfomaniakDI
import MailCore
import MailCoreUI
import MailResources
import SwiftUI

struct ConfirmationBlockRecipientView: View {
@LazyInjectService private var matomo: MatomoUtils

@EnvironmentObject private var mailboxManager: MailboxManager
@EnvironmentObject private var actionsManager: ActionsManager

let recipient: Recipient
let reportedMessage: Message
let origin: ActionOrigin
var onDismiss: (() -> Void)?

private var contact: CommonContact {
return CommonContactCache.getOrCreateContact(contactConfiguration: .correspondent(
correspondent: recipient,
contextMailboxManager: mailboxManager
))
}

var body: some View {
VStack(alignment: .leading, spacing: 0) {
Text(MailResourcesStrings.Localizable.blockExpeditorTitle(contact.fullName))
.textStyle(.bodyMedium)
.padding(.bottom, IKPadding.alertTitleBottom)

Text(MailResourcesStrings.Localizable.confirmationToBlockAnExpeditorText(recipient.email))
.textStyle(.body)
.padding(.bottom, IKPadding.alertDescriptionBottom)

ModalButtonsView(primaryButtonTitle: MailResourcesStrings.Localizable.buttonBlockAnExpeditor) {
Task {
matomo.track(eventWithCategory: .blockUserAction, name: "confirmSelectedUser")
try await actionsManager.performAction(
target: [reportedMessage],
action: .block,
origin: origin
)
onDismiss?()
}
}
}
}
}

#Preview {
ConfirmationBlockRecipientView(
recipient: PreviewHelper.sampleRecipient1,
reportedMessage: PreviewHelper.sampleMessage,
origin: .floatingPanel(source: .threadList)
)
}
24 changes: 20 additions & 4 deletions Mail/Views/Bottom sheets/Actions/ActionsPanelViewModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import Foundation
import MailCore
import MailResources
import SwiftModalPresentation
import SwiftUI

Expand All @@ -40,9 +41,11 @@ extension View {
struct ActionsPanelViewModifier: ViewModifier {
@EnvironmentObject private var mailboxManager: MailboxManager

@ModalState private var reportForJunkMessage: Message?
@ModalState private var reportForJunkMessages: [Message]?
@ModalState private var reportedForDisplayProblemMessage: Message?
@ModalState private var reportedForPhishingMessage: Message?
@ModalState private var blockSenderAlert: BlockRecipientAlertState?
@ModalState private var blockSendersList: BlockRecipientState?
@ModalState private var messagesToMove: [Message]?
@ModalState private var flushAlert: FlushAlertState?
@ModalState private var shareMailLink: ShareMailLinkResult?
Expand All @@ -59,7 +62,9 @@ struct ActionsPanelViewModifier: ViewModifier {
originFolder: originFolder?.freezeIfNeeded(),
nearestFlushAlert: $flushAlert,
nearestMessagesToMoveSheet: $messagesToMove,
nearestReportJunkMessageActionsPanel: $reportForJunkMessage,
nearestBlockSenderAlert: $blockSenderAlert,
nearestBlockSendersList: $blockSendersList,
nearestReportJunkMessageActionsPanel: $reportForJunkMessages,
nearestReportedForPhishingMessageAlert: $reportedForPhishingMessage,
nearestReportedForDisplayProblemMessageAlert: $reportedForDisplayProblemMessage,
nearestShareMailLinkPanel: $shareMailLink
Expand All @@ -79,8 +84,19 @@ struct ActionsPanelViewModifier: ViewModifier {
)
.sheetViewStyle()
}
.floatingPanel(item: $reportForJunkMessage) { reportForJunkMessage in
ReportJunkView(reportedMessage: reportForJunkMessage, origin: origin)
.floatingPanel(item: $reportForJunkMessages) { reportForJunkMessages in
ReportJunkView(reportedMessages: reportForJunkMessages, origin: origin)
}
.floatingPanel(item: $blockSendersList,
title: MailResourcesStrings.Localizable.blockAnExpeditorTitle) { blockSenderState in
BlockSenderView(recipientsToMessage: blockSenderState.recipientsToMessage, origin: origin)
}
.customAlert(item: $blockSenderAlert) { blockSenderState in
ConfirmationBlockRecipientView(
recipient: blockSenderState.recipient,
reportedMessage: blockSenderState.message,
origin: origin
)
}
.customAlert(item: $reportedForDisplayProblemMessage) { message in
ReportDisplayProblemView(message: message)
Expand Down
81 changes: 81 additions & 0 deletions Mail/Views/Bottom sheets/Actions/BlockSenderView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
Infomaniak Mail - iOS App
Copyright (C) 2024 Infomaniak Network SA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import InfomaniakCore
import InfomaniakCoreUI
import InfomaniakDI
import MailCore
import MailCoreUI
import MailResources
import SwiftModalPresentation
import SwiftUI

struct BlockSenderView: View {
@LazyInjectService private var matomo: MatomoUtils

@Environment(\.dismiss) private var dismiss

@State private var selectedRecipient: Recipient?
@State private var recipients = [Recipient]()

let recipientsToMessage: [Recipient: Message]
let origin: ActionOrigin

var body: some View {
VStack(spacing: 0) {
ForEach(recipients) { recipient in
Button {
selectedRecipient = recipient
matomo.track(eventWithCategory: .blockUserAction, name: "selectUser")
} label: {
RecipientCell(recipient: recipient)
.padding(.horizontal, value: .medium)
.padding(.vertical, value: .small)
}
if recipient != recipients.last {
IKDivider()
}
}
}
.customAlert(item: $selectedRecipient) { recipient in
ConfirmationBlockRecipientView(
recipient: recipient,
reportedMessage: recipientsToMessage[recipient]!,
origin: origin
) {
dismiss()
}
}
.onAppear {
recipients = recipientsToMessage.keys
.sorted {
let name1 = ($0.name.isEmpty ? $0.email : $0.name)
let name2 = ($1.name.isEmpty ? $1.email : $1.name)
return name1.caseInsensitiveCompare(name2) == .orderedAscending
}
}
}
}

#Preview {
BlockSenderView(
recipientsToMessage: PreviewHelper.sampleRecipientWithMessage,
origin: .floatingPanel(source: .threadList)
)
.accentColor(AccentColor.pink.primary.swiftUIColor)
}
24 changes: 17 additions & 7 deletions Mail/Views/Bottom sheets/Actions/ReportJunkView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,23 @@ import SwiftUI
struct ReportJunkView: View {
@LazyInjectService private var platformDetector: PlatformDetectable

@EnvironmentObject private var mailboxManager: MailboxManager
@Environment(\.dismiss) private var dismiss

let reportedMessage: Message
let actions: [Action] = [.spam, .phishing, .block]
let reportedMessages: [Message]
let origin: ActionOrigin

private var filteredActions: [Action] {
let currentUserEmail = mailboxManager.mailbox.email
let uniqueSenders = Set(reportedMessages.compactMap { $0.from.first?.email })

if uniqueSenders == [currentUserEmail] {
return [.spam, .phishing]
} else {
return [.spam, .phishing, .blockList]
}
}

var body: some View {
VStack(alignment: .leading, spacing: 0) {
if platformDetector.isMac {
Expand All @@ -42,19 +53,18 @@ struct ReportJunkView: View {
.padding(.horizontal, value: .medium)
}

ForEach(actions) { action in
if action != actions.first {
ForEach(filteredActions) { action in
if action != filteredActions.first {
IKDivider()
}

MessageActionView(targetMessages: [reportedMessage], action: action, origin: origin)
MessageActionView(targetMessages: reportedMessages, action: action, origin: origin)
}
}
.matomoView(view: [MatomoUtils.View.bottomSheet.displayName, "ReportJunkView"])
}
}

#Preview {
ReportJunkView(reportedMessage: PreviewHelper.sampleMessage, origin: .floatingPanel(source: .threadList))
ReportJunkView(reportedMessages: PreviewHelper.sampleMessages, origin: .floatingPanel(source: .threadList))
.accentColor(AccentColor.pink.primary.swiftUIColor)
}
10 changes: 8 additions & 2 deletions MailCore/Cache/Actions/Action+List.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ extension Action: CaseIterable {
let star = messages.allSatisfy(\.flagged)

let listActions: [Action] = [
spam ? .nonSpam : .spam,
spam ? .nonSpam : .reportJunk,
star ? .unstar : .star
]

Expand All @@ -125,7 +125,7 @@ extension Action: CaseIterable {
let showUnstar = messages.contains { $0.flagged }

let spam = originFolder?.role == .spam
let spamAction: Action? = spam ? .nonSpam : .spam
let spamAction: Action? = spam ? .nonSpam : .reportJunk

let tempListActions: [Action?] = [
.openMovePanel,
Expand Down Expand Up @@ -278,6 +278,12 @@ public extension Action {
iconResource: MailResourcesAsset.blockUser,
matomoName: "blockUser"
)
static let blockList = Action(
id: "blockList",
title: MailResourcesStrings.Localizable.actionBlockSender,
iconResource: MailResourcesAsset.blockUser,
matomoName: "blockUser"
)
static let phishing = Action(
id: "phishing",
title: MailResourcesStrings.Localizable.actionPhishing,
Expand Down
16 changes: 13 additions & 3 deletions MailCore/Cache/Actions/ActionOrigin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ public struct ActionOrigin {
private(set) var nearestMessagesActionsPanel: Binding<[Message]?>?
private(set) var nearestFlushAlert: Binding<FlushAlertState?>?
private(set) var nearestMessagesToMoveSheet: Binding<[Message]?>?
private(set) var nearestReportJunkMessageActionsPanel: Binding<Message?>?
private(set) var nearestBlockSenderAlert: Binding<BlockRecipientAlertState?>?
private(set) var nearestBlockSendersList: Binding<BlockRecipientState?>?
private(set) var nearestReportJunkMessageActionsPanel: Binding<[Message]?>?
private(set) var nearestReportedForPhishingMessageAlert: Binding<Message?>?
private(set) var nearestReportedForDisplayProblemMessageAlert: Binding<Message?>?
private(set) var nearestShareMailLinkPanel: Binding<ShareMailLinkResult?>?
Expand All @@ -50,7 +52,9 @@ public struct ActionOrigin {
nearestMessagesActionsPanel: Binding<[Message]?>? = nil,
nearestFlushAlert: Binding<FlushAlertState?>? = nil,
nearestMessagesToMoveSheet: Binding<[Message]?>? = nil,
nearestReportJunkMessageActionsPanel: Binding<Message?>? = nil,
nearestBlockSenderAlert: Binding<BlockRecipientAlertState?>? = nil,
nearestBlockSendersList: Binding<BlockRecipientState?>? = nil,
nearestReportJunkMessageActionsPanel: Binding<[Message]?>? = nil,
nearestReportedForPhishingMessageAlert: Binding<Message?>? = nil,
nearestReportedForDisplayProblemMessageAlert: Binding<Message?>? = nil,
nearestShareMailLinkPanel: Binding<ShareMailLinkResult?>? = nil
Expand All @@ -60,6 +64,8 @@ public struct ActionOrigin {
self.nearestMessagesActionsPanel = nearestMessagesActionsPanel
self.nearestFlushAlert = nearestFlushAlert
self.nearestMessagesToMoveSheet = nearestMessagesToMoveSheet
self.nearestBlockSenderAlert = nearestBlockSenderAlert
self.nearestBlockSendersList = nearestBlockSendersList
self.nearestReportJunkMessageActionsPanel = nearestReportJunkMessageActionsPanel
self.nearestReportedForPhishingMessageAlert = nearestReportedForPhishingMessageAlert
self.nearestReportedForDisplayProblemMessageAlert = nearestReportedForDisplayProblemMessageAlert
Expand All @@ -75,7 +81,9 @@ public struct ActionOrigin {
originFolder: Folder? = nil,
nearestFlushAlert: Binding<FlushAlertState?>? = nil,
nearestMessagesToMoveSheet: Binding<[Message]?>? = nil,
nearestReportJunkMessageActionsPanel: Binding<Message?>? = nil,
nearestBlockSenderAlert: Binding<BlockRecipientAlertState?>? = nil,
nearestBlockSendersList: Binding<BlockRecipientState?>? = nil,
nearestReportJunkMessageActionsPanel: Binding<[Message]?>? = nil,
nearestReportedForPhishingMessageAlert: Binding<Message?>? = nil,
nearestReportedForDisplayProblemMessageAlert: Binding<Message?>? = nil,
nearestShareMailLinkPanel: Binding<ShareMailLinkResult?>? = nil) -> ActionOrigin {
Expand All @@ -84,6 +92,8 @@ public struct ActionOrigin {
folder: originFolder,
nearestFlushAlert: nearestFlushAlert,
nearestMessagesToMoveSheet: nearestMessagesToMoveSheet,
nearestBlockSenderAlert: nearestBlockSenderAlert,
nearestBlockSendersList: nearestBlockSendersList,
nearestReportJunkMessageActionsPanel: nearestReportJunkMessageActionsPanel,
nearestReportedForPhishingMessageAlert: nearestReportedForPhishingMessageAlert,
nearestReportedForDisplayProblemMessageAlert: nearestReportedForDisplayProblemMessageAlert,
Expand Down
Loading

0 comments on commit 2d0bdcd

Please sign in to comment.