Skip to content

Commit

Permalink
WIP: Debug option
Browse files Browse the repository at this point in the history
  • Loading branch information
Bunn committed Jan 15, 2025
1 parent d8760f5 commit 182f740
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 14 deletions.
8 changes: 8 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@
311BD1AD2836BB3900AEF6C1 /* AutofillItemsEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 311BD1AC2836BB3900AEF6C1 /* AutofillItemsEmptyView.swift */; };
311BD1AF2836BB4200AEF6C1 /* AutofillItemsLockedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 311BD1AE2836BB4200AEF6C1 /* AutofillItemsLockedView.swift */; };
311BD1B12836C0CA00AEF6C1 /* AutofillLoginListAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 311BD1B02836C0CA00AEF6C1 /* AutofillLoginListAuthenticator.swift */; };
31206F702D3804E800A95D76 /* AIChatDebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31206F6F2D3804E800A95D76 /* AIChatDebugView.swift */; };
31206F722D38072100A95D76 /* AIChatDebugSettingsHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31206F712D38071000A95D76 /* AIChatDebugSettingsHandling.swift */; };
312E5746283BB04A00C18FA0 /* AutofillEmptySearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 312E5745283BB04A00C18FA0 /* AutofillEmptySearchView.swift */; };
3132FA2627A0784600DD7A12 /* FilePreviewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3132FA2527A0784600DD7A12 /* FilePreviewHelper.swift */; };
3132FA2827A0788400DD7A12 /* PassKitPreviewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3132FA2727A0788400DD7A12 /* PassKitPreviewHelper.swift */; };
Expand Down Expand Up @@ -1558,6 +1560,8 @@
311BD1AC2836BB3900AEF6C1 /* AutofillItemsEmptyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillItemsEmptyView.swift; sourceTree = "<group>"; };
311BD1AE2836BB4200AEF6C1 /* AutofillItemsLockedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillItemsLockedView.swift; sourceTree = "<group>"; };
311BD1B02836C0CA00AEF6C1 /* AutofillLoginListAuthenticator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillLoginListAuthenticator.swift; sourceTree = "<group>"; };
31206F6F2D3804E800A95D76 /* AIChatDebugView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIChatDebugView.swift; sourceTree = "<group>"; };
31206F712D38071000A95D76 /* AIChatDebugSettingsHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIChatDebugSettingsHandling.swift; sourceTree = "<group>"; };
312E5745283BB04A00C18FA0 /* AutofillEmptySearchView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillEmptySearchView.swift; sourceTree = "<group>"; };
3132FA2527A0784600DD7A12 /* FilePreviewHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilePreviewHelper.swift; sourceTree = "<group>"; };
3132FA2727A0788400DD7A12 /* PassKitPreviewHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PassKitPreviewHelper.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3927,6 +3931,7 @@
31C314A32D2EF9DF009A412A /* UserScript */ = {
isa = PBXGroup;
children = (
31206F712D38071000A95D76 /* AIChatDebugSettingsHandling.swift */,
318C5B482D3022FE00DAA5FC /* AIChatPayloadHandling.swift */,
31C3149B2D2EEB44009A412A /* AIChatScriptUserValues.swift */,
31C3149C2D2EEB44009A412A /* AIChatUserScript.swift */,
Expand Down Expand Up @@ -4758,6 +4763,7 @@
858566E7252E4F56007501B8 /* Debug.storyboard */,
D6F93E3B2B4FFA97004C268D /* SubscriptionDebugViewController.swift */,
8590CB602684D0600089F6BF /* CookieDebugViewController.swift */,
31206F6F2D3804E800A95D76 /* AIChatDebugView.swift */,
4B0295182537BC6700E00CEF /* ConfigurationDebugViewController.swift */,
858566FA252E55D6007501B8 /* ImageCacheDebugViewController.swift */,
8590CB66268A2E520089F6BF /* RootDebugViewController.swift */,
Expand Down Expand Up @@ -8182,6 +8188,7 @@
7B4F87E72D0734090010B18F /* ControlCenterWidget.swift in Sources */,
9F7CFF762C86BB8F0012833E /* OnboardingView+AppIconPickerContent.swift in Sources */,
D68A21442B7EC08500BB372E /* SubscriptionExternalLinkView.swift in Sources */,
31206F702D3804E800A95D76 /* AIChatDebugView.swift in Sources */,
BDD3B3552B8EF8DB005857A8 /* NetworkProtectionUNNotificationPresenter.swift in Sources */,
BD862E0B2B30F9300073E2EE /* VPNFeedbackFormView.swift in Sources */,
850365F323DE087800D0F787 /* UIImageViewExtension.swift in Sources */,
Expand Down Expand Up @@ -8294,6 +8301,7 @@
1DEAADFF2BA7832F00E25A97 /* EmailProtectionView.swift in Sources */,
31C314A22D2EF614009A412A /* AIChatViewControllerManager.swift in Sources */,
988F3DD3237DE8D900AEE34C /* ForgetDataAlert.swift in Sources */,
31206F722D38072100A95D76 /* AIChatDebugSettingsHandling.swift in Sources */,
D6FEB8B12B7498A300C3615F /* HeadlessWebView.swift in Sources */,
9FDEC7BC2C91204900C7A692 /* AppIconPickerViewModel.swift in Sources */,
F1FDC9352BF51E41006B1435 /* VPNSettings+Environment.swift in Sources */,
Expand Down
47 changes: 47 additions & 0 deletions DuckDuckGo/AIChat/UserScript/AIChatDebugSettingsHandling.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// AIChatDebugSettingsHandling.swift
// DuckDuckGo
//
// Copyright © 2025 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

protocol AIChatDebugSettingsHandling {
var messagePolicyHostname: String? { get set }
}

struct AIChatDebugSettings: AIChatDebugSettingsHandling {
private let userDefaultsKey = "aichat.debug.messagePolicyHostname"
private let userDefault: UserDefaults

init(userDefault: UserDefaults = .standard) {
self.userDefault = userDefault
}

var messagePolicyHostname: String? {
get {
let value = userDefault.string(forKey: userDefaultsKey)
return value?.isEmpty == true ? nil : value
}
set {
if let newValue = newValue, !newValue.isEmpty {
userDefault.set(newValue, forKey: userDefaultsKey)
} else {
userDefault.removeObject(forKey: userDefaultsKey)
}
}
}
}
6 changes: 5 additions & 1 deletion DuckDuckGo/AIChat/UserScript/AIChatUserScript.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ final class AIChatUserScript: NSObject, Subfeature {
weak var broker: UserScriptMessageBroker?
private(set) var messageOriginPolicy: MessageOriginPolicy

init(handler: AIChatUserScriptHandling) {
init(handler: AIChatUserScriptHandling, debugSettings: AIChatDebugSettingsHandling) {
self.handler = handler
var rules = [HostnameMatchingRule]()

Expand All @@ -43,6 +43,10 @@ final class AIChatUserScript: NSObject, Subfeature {
rules.append(.exact(hostname: ddgDomain))
}

if let debugHostname = debugSettings.messagePolicyHostname {
rules.append(.exact(hostname: debugHostname))
}

self.messageOriginPolicy = .only(rules: rules)
}

Expand Down
94 changes: 94 additions & 0 deletions DuckDuckGo/AIChatDebugView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// AIChatDebugView.swift
// DuckDuckGo
//
// Copyright © 2025 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 SwiftUI
import Combine

struct AIChatDebugView: View {
@StateObject private var viewModel = AIChatDebugViewModel()

var body: some View {
List {
Section(footer: Text("Stored Hostname: \(viewModel.enteredHostname)")) {
NavigationLink(destination: AIChatDebugHostnameEntryView(viewModel: viewModel)) {
Text("Message policy hostname")
}
}
}
.navigationTitle("AI Chat")
}
}

private final class AIChatDebugViewModel: ObservableObject {
private var debugSettings = AIChatDebugSettings()

@Published var enteredHostname: String {
didSet {
debugSettings.messagePolicyHostname = enteredHostname
}
}

init() {
self.enteredHostname = debugSettings.messagePolicyHostname ?? ""
}

func resetHostname() {
enteredHostname = ""
}
}

private struct AIChatDebugHostnameEntryView: View {
@ObservedObject var viewModel: AIChatDebugViewModel
@State private var policyHostname: String = ""
@Environment(\.presentationMode) var presentationMode

var body: some View {
Form {
Section {
TextField("Hostname", text: $policyHostname)
.autocorrectionDisabled(true)
.textInputAutocapitalization(.never)
}

Button(action: {
viewModel.enteredHostname = policyHostname
presentationMode.wrappedValue.dismiss()
}) {

Check failure on line 73 in DuckDuckGo/AIChatDebugView.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Trailing closure syntax should not be used when passing more than one closure argument (multiple_closures_with_trailing_closure)
Text("Confirm")
}

Button(action: {
viewModel.resetHostname()
policyHostname = ""
presentationMode.wrappedValue.dismiss()
}) {

Check failure on line 81 in DuckDuckGo/AIChatDebugView.swift

View workflow job for this annotation

GitHub Actions / SwiftLint

Trailing closure syntax should not be used when passing more than one closure argument (multiple_closures_with_trailing_closure)
Text("Reset")
}
}
.navigationTitle("Edit Hostname")
.onAppear {
policyHostname = viewModel.enteredHostname
}
}
}

#Preview {
AIChatDebugView()
}
Loading

0 comments on commit 182f740

Please sign in to comment.