From 92096698c62670c6b71d2c7c5b996d0561a81abe Mon Sep 17 00:00:00 2001 From: Philippe Weidmann Date: Wed, 7 Feb 2024 10:56:30 +0100 Subject: [PATCH] feat: Add command bar for macOS --- Mail/Commands/CustomCommands.swift | 75 +++++++++++++++++++++++++ Mail/Commands/NewMessageCommand.swift | 50 +++++++++++++++++ Mail/Commands/OpenSettingsCommand.swift | 44 +++++++++++++++ Mail/Commands/PrintMessageCommand.swift | 45 +++++++++++++++ Mail/UserAccountScene.swift | 3 + MailCore/Utils/Matomo+Extension.swift | 1 + MailResources/Mail.entitlements | 2 + 7 files changed, 220 insertions(+) create mode 100644 Mail/Commands/CustomCommands.swift create mode 100644 Mail/Commands/NewMessageCommand.swift create mode 100644 Mail/Commands/OpenSettingsCommand.swift create mode 100644 Mail/Commands/PrintMessageCommand.swift diff --git a/Mail/Commands/CustomCommands.swift b/Mail/Commands/CustomCommands.swift new file mode 100644 index 0000000000..ff4f3d317b --- /dev/null +++ b/Mail/Commands/CustomCommands.swift @@ -0,0 +1,75 @@ +/* + 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 . + */ + +import InfomaniakCore +import InfomaniakCoreUI +import InfomaniakDI +import MailCore +import MailResources +import SwiftUI + +struct CustomCommands: Commands { + @LazyInjectService private var matomo: MatomoUtils + + @ObservedObject var rootViewState: RootViewState + + var mainViewState: MainViewState? { + if case .mainView(let mainViewState) = rootViewState.state { + return mainViewState + } else { + return nil + } + } + + var body: some Commands { + CommandGroup(replacing: .newItem) { + if #available(iOS 16.0, *) { + NewMessageCommand(mailboxManager: mainViewState?.mailboxManager) + } + } + + CommandGroup(after: .newItem) { + Button(MailResourcesStrings.Localizable.shortcutRefreshAction) { + guard let mainViewState else { return } + refresh(mailboxManager: mainViewState.mailboxManager, currentFolder: mainViewState.selectedFolder) + } + .keyboardShortcut("n", modifiers: [.shift, .command]) + .disabled(mainViewState == nil) + } + + CommandGroup(replacing: .printItem) { + if let mainViewState { + PrintMessageCommand(mainViewState: mainViewState) + } + } + + CommandGroup(replacing: .appSettings) { + if #available(iOS 16.0, *) { + OpenSettingsCommand() + .disabled(mainViewState == nil) + } + } + } + + func refresh(mailboxManager: MailboxManager, currentFolder: Folder) { + matomo.track(eventWithCategory: .menuAction, name: "refresh") + Task { + await mailboxManager.refreshFolderContent(currentFolder) + } + } +} diff --git a/Mail/Commands/NewMessageCommand.swift b/Mail/Commands/NewMessageCommand.swift new file mode 100644 index 0000000000..18a64c2be2 --- /dev/null +++ b/Mail/Commands/NewMessageCommand.swift @@ -0,0 +1,50 @@ +/* + 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 . + */ + +import InfomaniakCore +import InfomaniakCoreUI +import InfomaniakDI +import MailCore +import MailResources +import SwiftUI + +@available(iOS 16.0, *) +struct NewMessageCommand: View { + @LazyInjectService private var matomo: MatomoUtils + + @Environment(\.openWindow) private var openWindow + + let mailboxManager: MailboxManager? + + var body: some View { + Button(MailResourcesStrings.Localizable.buttonNewMessage) { + guard let mailboxManager else { return } + newMessage(mailboxManager: mailboxManager) + } + .keyboardShortcut("n") + .disabled(mailboxManager == nil) + } + + func newMessage(mailboxManager: MailboxManager) { + matomo.track(eventWithCategory: .menuAction, name: "newMessage") + openWindow( + id: DesktopWindowIdentifier.composeWindowIdentifier, + value: ComposeMessageIntent.new(originMailboxManager: mailboxManager) + ) + } +} diff --git a/Mail/Commands/OpenSettingsCommand.swift b/Mail/Commands/OpenSettingsCommand.swift new file mode 100644 index 0000000000..4372af41ad --- /dev/null +++ b/Mail/Commands/OpenSettingsCommand.swift @@ -0,0 +1,44 @@ +/* + 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 . + */ + +import InfomaniakCoreUI +import InfomaniakDI +import MailCore +import MailResources +import SwiftUI + +@available(iOS 16.0, *) +struct OpenSettingsCommand: View { + @LazyInjectService private var matomo: MatomoUtils + + @Environment(\.openWindow) private var openWindow + + var body: some View { + Button(MailResourcesStrings.Localizable.settingsTitle) { + openSettings() + } + } + + func openSettings() { + matomo.track(eventWithCategory: .menuAction, name: "settings") + openWindow( + id: DesktopWindowIdentifier.settingsWindowIdentifier, + value: SettingsViewConfig(baseNavigationPath: []) + ) + } +} diff --git a/Mail/Commands/PrintMessageCommand.swift b/Mail/Commands/PrintMessageCommand.swift new file mode 100644 index 0000000000..cbc13c3e31 --- /dev/null +++ b/Mail/Commands/PrintMessageCommand.swift @@ -0,0 +1,45 @@ +/* + 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 . + */ + +import InfomaniakCore +import InfomaniakCoreUI +import InfomaniakDI +import MailCore +import MailResources +import SwiftUI + +struct PrintMessageCommand: View { + @LazyInjectService private var matomo: MatomoUtils + + @ObservedObject var mainViewState: MainViewState + + var body: some View { + Button(MailResourcesStrings.Localizable.actionPrint) { + printCurrentMessage(mainViewState: mainViewState) + } + .keyboardShortcut("p") + .disabled(mainViewState.selectedThread?.lastMessageFromFolder == nil) + } + + func printCurrentMessage(mainViewState: MainViewState) { + matomo.track(eventWithCategory: .menuAction, name: "print") + + guard let message = mainViewState.selectedThread?.lastMessageFromFolder else { return } + NotificationCenter.default.post(name: Notification.Name.printNotification, object: message) + } +} diff --git a/Mail/UserAccountScene.swift b/Mail/UserAccountScene.swift index 8cb2f8240a..def29c4967 100644 --- a/Mail/UserAccountScene.swift +++ b/Mail/UserAccountScene.swift @@ -67,6 +67,9 @@ struct UserAccountScene: Scene { refreshCacheData() } } + .commands { + CustomCommands(rootViewState: rootViewState) + } .defaultAppStorage(.shared) if #available(iOS 16.0, *) { diff --git a/MailCore/Utils/Matomo+Extension.swift b/MailCore/Utils/Matomo+Extension.swift index 6542697f5e..af0d227cc0 100644 --- a/MailCore/Utils/Matomo+Extension.swift +++ b/MailCore/Utils/Matomo+Extension.swift @@ -71,6 +71,7 @@ public extension MatomoUtils.EventCategory { static let notificationActions = MatomoUtils.EventCategory(displayName: "notificationActions") static let threadActions = MatomoUtils.EventCategory(displayName: "threadActions") static let swipeActions = MatomoUtils.EventCategory(displayName: "swipeActions") + static let menuAction = MatomoUtils.EventCategory(displayName: "menuAction") // Settings diff --git a/MailResources/Mail.entitlements b/MailResources/Mail.entitlements index dbd0f2e8e3..2902391e14 100644 --- a/MailResources/Mail.entitlements +++ b/MailResources/Mail.entitlements @@ -17,6 +17,8 @@ com.apple.security.network.client + com.apple.security.print + com.apple.security.personal-information.addressbook com.apple.security.personal-information.photos-library