Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate native callback #3286

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions DuckDuckGo/DBP/DataBrokerProtectionManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,8 @@ extension DataBrokerProtectionManager: DataBrokerProtectionDataManagerDelegate {
public func dataBrokerProtectionDataManagerDidDeleteData() {
loginItemInterface.dataDeleted()
}

public func dataBrokerProtectionDataManagerWillOpenSendFeedbackForm() {
NotificationCenter.default.post(name: .OpenUnifiedFeedbackForm, object: nil, userInfo: UnifiedFeedbackSource.userInfo(source: .pir))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,9 @@ final class NavigationBarViewController: NSViewController {
}

func listenToFeedbackFormNotifications() {
feedbackFormCancellable = NotificationCenter.default.publisher(for: .OpenUnifiedFeedbackForm).receive(on: DispatchQueue.main).sink { _ in
WindowControllersManager.shared.showShareFeedbackModal(source: .ppro)
feedbackFormCancellable = NotificationCenter.default.publisher(for: .OpenUnifiedFeedbackForm).receive(on: DispatchQueue.main).sink { notification in
quanganhdo marked this conversation as resolved.
Show resolved Hide resolved
let source = UnifiedFeedbackSource(userInfo: notification.userInfo)
WindowControllersManager.shared.showShareFeedbackModal(source: source)
}
}

Expand Down
4 changes: 3 additions & 1 deletion DuckDuckGo/Preferences/View/PreferencesRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ enum Preferences {
PixelKit.fire(PrivacyProPixel.privacyProVPNSettings)
NotificationCenter.default.post(name: .ToggleNetworkProtectionInMainWindow, object: self, userInfo: nil)
case .openFeedback:
NotificationCenter.default.post(name: .OpenUnifiedFeedbackForm, object: self, userInfo: nil)
NotificationCenter.default.post(name: .OpenUnifiedFeedbackForm,
object: self,
userInfo: UnifiedFeedbackSource.userInfo(source: .ppro))
case .openDB:
PixelKit.fire(PrivacyProPixel.privacyProPersonalInformationRemovalSettings)
WindowControllersManager.shared.showTab(with: .dataBrokerProtection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ extension IdentityTheftRestorationPagesUserScript: WKScriptMessageHandler {
///
final class IdentityTheftRestorationPagesFeature: Subfeature {
weak var broker: UserScriptMessageBroker?
private let subscriptionFeatureAvailability: SubscriptionFeatureAvailability

var featureName = "useIdentityTheftRestoration"

Expand All @@ -79,13 +80,19 @@ final class IdentityTheftRestorationPagesFeature: Subfeature {
.exact(hostname: "abrown.duckduckgo.com")
])

init(subscriptionFeatureAvailability: SubscriptionFeatureAvailability = DefaultSubscriptionFeatureAvailability()) {
self.subscriptionFeatureAvailability = subscriptionFeatureAvailability
}

func with(broker: UserScriptMessageBroker) {
self.broker = broker
}

func handler(forMethodNamed methodName: String) -> Subfeature.Handler? {
switch methodName {
case "getAccessToken": return getAccessToken
case "getFeatureConfig": return getFeatureConfig
case "openSendFeedbackModal": return openSendFeedbackModal
default:
return nil
}
Expand All @@ -98,4 +105,13 @@ final class IdentityTheftRestorationPagesFeature: Subfeature {
return [String: String]()
}
}

func getFeatureConfig(params: Any, original: WKScriptMessage) async throws -> Encodable? {
[PrivacyProSubfeature.useUnifiedFeedback.rawValue: subscriptionFeatureAvailability.usesUnifiedFeedbackForm]
}

func openSendFeedbackModal(params: Any, original: WKScriptMessage) async throws -> Encodable? {
NotificationCenter.default.post(name: .OpenUnifiedFeedbackForm, object: nil, userInfo: UnifiedFeedbackSource.userInfo(source: .itr))
return nil
}
}
14 changes: 14 additions & 0 deletions DuckDuckGo/UnifiedFeedbackForm/UnifiedFeedbackSender.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,20 @@ import PixelKit
enum UnifiedFeedbackSource: String, StringRepresentable {
case settings, ppro, vpn, pir, itr, unknown
static var `default` = UnifiedFeedbackSource.unknown

private static let sourceKey = "source"

static func userInfo(source: UnifiedFeedbackSource) -> [String: Any] {
return [sourceKey: source.rawValue]
}

init(userInfo: [AnyHashable: Any]?) {
if let userInfo = userInfo as? [String: Any], let source = userInfo[Self.sourceKey] as? String {
self = UnifiedFeedbackSource(rawValue: source) ?? .default
} else {
self = .default
}
}
}

protocol UnifiedFeedbackSender {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public protocol DataBrokerProtectionDataManaging {
public protocol DataBrokerProtectionDataManagerDelegate: AnyObject {
func dataBrokerProtectionDataManagerDidUpdateData()
func dataBrokerProtectionDataManagerDidDeleteData()
func dataBrokerProtectionDataManagerWillOpenSendFeedbackForm()
}

public class DataBrokerProtectionDataManager: DataBrokerProtectionDataManaging {
Expand Down Expand Up @@ -132,11 +133,16 @@ extension DataBrokerProtectionDataManager: InMemoryDataCacheDelegate {

delegate?.dataBrokerProtectionDataManagerDidDeleteData()
}

public func willOpenSendFeedbackForm() {
delegate?.dataBrokerProtectionDataManagerWillOpenSendFeedbackForm()
}
}

public protocol InMemoryDataCacheDelegate: AnyObject {
func saveCachedProfileToDatabase(_ profile: DataBrokerProtectionProfile) async throws
func removeAllData() throws
func willOpenSendFeedbackForm()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This being part of the InMemoryDataCacheDelegate feels weird. It should belong to another delegate.

I know this is because of the DBP architecture, and does not need to change now, but it is something that I wanted to call out.

Copy link
Member Author

@quanganhdo quanganhdo Sep 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. This feels bad to write, thanks for calling out.

}

public final class InMemoryDataCache {
Expand Down Expand Up @@ -340,4 +346,8 @@ extension InMemoryDataCache: DBPUICommunicationDelegate {

return mapper.mapToUIDebugMetadata(metadata: metadata, brokerProfileQueryData: brokerProfileQueryData)
}

func openSendFeedbackModal() async {
delegate?.willOpenSendFeedbackForm()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ protocol DBPUICommunicationDelegate: AnyObject {
func getMaintananceScanState() async -> DBPUIScanAndOptOutMaintenanceState
func getDataBrokers() async -> [DBPUIDataBroker]
func getBackgroundAgentMetadata() async -> DBPUIDebugMetadata
func openSendFeedbackModal() async
}

enum DBPUIReceivedMethodName: String {
Expand All @@ -58,6 +59,8 @@ enum DBPUIReceivedMethodName: String {
case maintenanceScanStatus
case getDataBrokers
case getBackgroundAgentMetadata
case getFeatureConfig
case openSendFeedbackModal
}

enum DBPUISendableMethodName: String {
Expand All @@ -66,6 +69,7 @@ enum DBPUISendableMethodName: String {

struct DBPUICommunicationLayer: Subfeature {
private let webURLSettings: DataBrokerProtectionWebUIURLSettingsRepresentable
private let privacyConfig: PrivacyConfigurationManaging

var messageOriginPolicy: MessageOriginPolicy
var featureName: String = "dbpuiCommunication"
Expand All @@ -74,11 +78,13 @@ struct DBPUICommunicationLayer: Subfeature {
weak var delegate: DBPUICommunicationDelegate?

private enum Constants {
static let version = 4
static let version = 5
}

internal init(webURLSettings: DataBrokerProtectionWebUIURLSettingsRepresentable) {
internal init(webURLSettings: DataBrokerProtectionWebUIURLSettingsRepresentable,
privacyConfig: PrivacyConfigurationManaging) {
self.webURLSettings = webURLSettings
self.privacyConfig = privacyConfig
self.messageOriginPolicy = .only(rules: [
.exact(hostname: webURLSettings.selectedURLHostname)
])
Expand Down Expand Up @@ -107,6 +113,8 @@ struct DBPUICommunicationLayer: Subfeature {
case .maintenanceScanStatus: return maintenanceScanStatus
case .getDataBrokers: return getDataBrokers
case .getBackgroundAgentMetadata: return getBackgroundAgentMetadata
case .getFeatureConfig: return getFeatureConfig
case .openSendFeedbackModal: return openSendFeedbackModal
}

}
Expand Down Expand Up @@ -291,4 +299,13 @@ struct DBPUICommunicationLayer: Subfeature {
func sendMessageToUI(method: DBPUISendableMethodName, params: DBPUISendableMessage, into webView: WKWebView) {
broker?.push(method: method.rawValue, params: params, for: self, into: webView)
}

func getFeatureConfig(params: Any, original: WKScriptMessage) async throws -> Encodable? {
[PrivacyProSubfeature.useUnifiedFeedback.rawValue: privacyConfig.privacyConfig.isSubfeatureEnabled(PrivacyProSubfeature.useUnifiedFeedback)]
}

func openSendFeedbackModal(params: Any, original: WKScriptMessage) async throws -> Encodable? {
await delegate?.openSendFeedbackModal()
return nil
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ final class DBPUIUserScript: UserScriptsProvider {
self.webUISettings = webUISettings
contentScopeUserScriptIsolated = ContentScopeUserScript(privacyConfig, properties: prefs, isIsolated: false)
contentScopeUserScriptIsolated.messageNames = ["dbpui"]
dbpUICommunicationLayer = DBPUICommunicationLayer(webURLSettings: webUISettings)
dbpUICommunicationLayer = DBPUICommunicationLayer(webURLSettings: webUISettings, privacyConfig: privacyConfig)
dbpUICommunicationLayer.delegate = delegate
dbpUICommunicationLayer.broker = contentScopeUserScriptIsolated.broker
contentScopeUserScriptIsolated.registerSubfeature(delegate: dbpUICommunicationLayer)
Expand Down
Loading