diff --git a/Sources/NetworkProtection/Status/NetworkProtectionNotificationsPresenter.swift b/Sources/NetworkProtection/Status/UserNotifications/NetworkProtectionNotificationsPresenter.swift similarity index 100% rename from Sources/NetworkProtection/Status/NetworkProtectionNotificationsPresenter.swift rename to Sources/NetworkProtection/Status/UserNotifications/NetworkProtectionNotificationsPresenter.swift diff --git a/Sources/NetworkProtection/Status/UserNotifications/NetworkProtectionNotificationsPresenterTogglableDecorator.swift b/Sources/NetworkProtection/Status/UserNotifications/NetworkProtectionNotificationsPresenterTogglableDecorator.swift new file mode 100644 index 000000000..4e3bff243 --- /dev/null +++ b/Sources/NetworkProtection/Status/UserNotifications/NetworkProtectionNotificationsPresenterTogglableDecorator.swift @@ -0,0 +1,65 @@ +// +// NetworkProtectionNotificationsPresenterTogglableDecorator.swift +// DuckDuckGo +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +final public class NetworkProtectionNotificationsPresenterTogglableDecorator: NetworkProtectionNotificationsPresenter { + private let notificationSettingsStore: NetworkProtectionNotificationsSettingsStore + private let wrappeePresenter: NetworkProtectionNotificationsPresenter + + public init(notificationSettingsStore: NetworkProtectionNotificationsSettingsStore, wrappee: NetworkProtectionNotificationsPresenter) { + self.notificationSettingsStore = notificationSettingsStore + self.wrappeePresenter = wrappee + } + + public func showConnectedNotification(serverLocation: String?) { + guard notificationSettingsStore.alertsEnabled else { + return + } + wrappeePresenter.showConnectedNotification(serverLocation: serverLocation) + } + + public func showReconnectingNotification() { + guard notificationSettingsStore.alertsEnabled else { + return + } + wrappeePresenter.showReconnectingNotification() + } + + public func showConnectionFailureNotification() { + guard notificationSettingsStore.alertsEnabled else { + return + } + wrappeePresenter.showConnectionFailureNotification() + } + + public func showSupersededNotification() { + guard notificationSettingsStore.alertsEnabled else { + return + } + wrappeePresenter.showSupersededNotification() + } + + public func showTestNotification() { + guard notificationSettingsStore.alertsEnabled else { + return + } + wrappeePresenter.showTestNotification() + } +} diff --git a/Sources/NetworkProtection/Storage/NetworkProtectionNotificationsSettingsStore.swift b/Sources/NetworkProtection/Storage/NetworkProtectionNotificationsSettingsStore.swift new file mode 100644 index 000000000..2e4384fed --- /dev/null +++ b/Sources/NetworkProtection/Storage/NetworkProtectionNotificationsSettingsStore.swift @@ -0,0 +1,48 @@ +// +// NetworkProtectionNotificationsSettingsStore.swift +// DuckDuckGo +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation + +public protocol NetworkProtectionNotificationsSettingsStore { + var alertsEnabled: Bool { get set } +} + +final public class NetworkProtectionNotificationsSettingsUserDefaultsStore: NetworkProtectionNotificationsSettingsStore { + private enum Key { + static let alerts = "com.duckduckgo.vpnNotificationSettings.alertsEnabled" + } + + private let userDefaults: UserDefaults + + public init(userDefaults: UserDefaults) { + self.userDefaults = userDefaults + } + + public var alertsEnabled: Bool { + get { + guard self.userDefaults.object(forKey: Key.alerts) != nil else { + return true + } + return self.userDefaults.bool(forKey: Key.alerts) + } + set { + self.userDefaults.set(newValue, forKey: Key.alerts) + } + } +} diff --git a/Sources/NetworkProtectionTestUtils/Storage/MockNetworkProtectionNotificationsSettingsStore.swift b/Sources/NetworkProtectionTestUtils/Storage/MockNetworkProtectionNotificationsSettingsStore.swift new file mode 100644 index 000000000..dcaf3adf3 --- /dev/null +++ b/Sources/NetworkProtectionTestUtils/Storage/MockNetworkProtectionNotificationsSettingsStore.swift @@ -0,0 +1,25 @@ +// +// MockNetworkProtectionNotificationsSettingsStore.swift +// DuckDuckGo +// +// Copyright © 2023 DuckDuckGo. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +import Foundation +import NetworkProtection + +public class MockNetworkProtectionNotificationsSettingsStore: NetworkProtectionNotificationsSettingsStore { + public var alertsEnabled: Bool = false +}