Skip to content

Commit

Permalink
WIP POC
Browse files Browse the repository at this point in the history
  • Loading branch information
Bunn committed Nov 8, 2024
1 parent 708bab3 commit 5214318
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 25 deletions.
20 changes: 16 additions & 4 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@
316931D927BD22A80095F5ED /* DownloadActionMessageViewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316931D827BD22A80095F5ED /* DownloadActionMessageViewHelper.swift */; };
3170048227A9504F00C03F35 /* DownloadMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3170048127A9504F00C03F35 /* DownloadMocks.swift */; };
317045C02858C6B90016ED1F /* AutofillInterfaceEmailTruncatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317045BF2858C6B90016ED1F /* AutofillInterfaceEmailTruncatorTests.swift */; };
317F2FBB2CDE59850019592C /* AIChatViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317F2FBA2CDE597B0019592C /* AIChatViewController.swift */; };
317F5F982C94A9EB0081666F /* MarketplaceAdPostbackStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 317F5F972C94A9EB0081666F /* MarketplaceAdPostbackStorage.swift */; };
31860A5B2C57ED2D005561F5 /* DuckPlayerStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31860A5A2C57ED2D005561F5 /* DuckPlayerStorage.swift */; };
31951E8E2823003200CAF535 /* AutofillLoginDetailsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31951E8D2823003200CAF535 /* AutofillLoginDetailsHeaderView.swift */; };
Expand Down Expand Up @@ -1481,6 +1482,7 @@
3170048127A9504F00C03F35 /* DownloadMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadMocks.swift; sourceTree = "<group>"; };
317045BF2858C6B90016ED1F /* AutofillInterfaceEmailTruncatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillInterfaceEmailTruncatorTests.swift; sourceTree = "<group>"; };
31794BFF2821DFB600F18633 /* DuckUI */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = DuckUI; sourceTree = "<group>"; };
317F2FBA2CDE597B0019592C /* AIChatViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIChatViewController.swift; sourceTree = "<group>"; };
317F5F972C94A9EB0081666F /* MarketplaceAdPostbackStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarketplaceAdPostbackStorage.swift; sourceTree = "<group>"; };
31860A5A2C57ED2D005561F5 /* DuckPlayerStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DuckPlayerStorage.swift; sourceTree = "<group>"; };
31951E8D2823003200CAF535 /* AutofillLoginDetailsHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillLoginDetailsHeaderView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1640,9 +1642,9 @@
6FBF0F8A2BD7C0A900136CF0 /* AllProtectedCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllProtectedCell.swift; sourceTree = "<group>"; };
6FD0C41E2C5BF097000561C9 /* NewTabPageIntroMessageSetupTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTabPageIntroMessageSetupTests.swift; sourceTree = "<group>"; };
6FD0C4202C5BF774000561C9 /* NewTabPageViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTabPageViewModelTests.swift; sourceTree = "<group>"; };
6FD1BAE12B87A107000C475C /* AdAttributionPixelReporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdAttributionPixelReporter.swift; path = AdAttribution/AdAttributionPixelReporter.swift; sourceTree = "<group>"; };
6FD1BAE22B87A107000C475C /* AdAttributionReporterStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdAttributionReporterStorage.swift; path = AdAttribution/AdAttributionReporterStorage.swift; sourceTree = "<group>"; };
6FD1BAE32B87A107000C475C /* AdAttributionFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdAttributionFetcher.swift; path = AdAttribution/AdAttributionFetcher.swift; sourceTree = "<group>"; };
6FD1BAE12B87A107000C475C /* AdAttributionPixelReporter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdAttributionPixelReporter.swift; path = ../AdAttribution/AdAttributionPixelReporter.swift; sourceTree = "<group>"; };
6FD1BAE22B87A107000C475C /* AdAttributionReporterStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdAttributionReporterStorage.swift; path = ../AdAttribution/AdAttributionReporterStorage.swift; sourceTree = "<group>"; };
6FD1BAE32B87A107000C475C /* AdAttributionFetcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AdAttributionFetcher.swift; path = ../AdAttribution/AdAttributionFetcher.swift; sourceTree = "<group>"; };
6FD3AEE12B8DFBB80060FCCC /* AdAttributionPixelReporterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdAttributionPixelReporterTests.swift; sourceTree = "<group>"; };
6FD3F80E2C3EF4F000DA5797 /* DeviceOrientationEnvironmentValue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceOrientationEnvironmentValue.swift; sourceTree = "<group>"; };
6FD3F8122C3EFDA200DA5797 /* FavoritesPreviewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesPreviewDataSource.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3581,6 +3583,15 @@
name = Utils;
sourceTree = "<group>";
};
317F2FB92CDE59720019592C /* AIChat */ = {
isa = PBXGroup;
children = (
317F2FBA2CDE597B0019592C /* AIChatViewController.swift */,
6FD1BAE02B87A0E8000C475C /* AdAttribution */,
);
path = AIChat;
sourceTree = "<group>";
};
31951E9328230D8900CAF535 /* Shared */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -4213,7 +4224,7 @@
84E341941E2F7EFB00BDBA6F /* DuckDuckGo */ = {
isa = PBXGroup;
children = (
6FD1BAE02B87A0E8000C475C /* AdAttribution */,
317F2FB92CDE59720019592C /* AIChat */,
AA4D6A8023DE4973007E8790 /* AppIcon */,
F1C5ECF31E37812900C599A4 /* Application */,
9817C9C121EF58BA00884F65 /* AutoClear */,
Expand Down Expand Up @@ -7809,6 +7820,7 @@
F1C4A70E1E57725800A6CA1B /* OmniBar.swift in Sources */,
981CA7EA2617797500E119D5 /* MainViewController+AddFavoriteFlow.swift in Sources */,
373608902ABB1E6C00629E7F /* FavoritesDisplayModeStorage.swift in Sources */,
317F2FBB2CDE59850019592C /* AIChatViewController.swift in Sources */,
9872D205247DCAC100CEF398 /* TabPreviewsSource.swift in Sources */,
4B0F3F502B9BFF2100392892 /* NetworkProtectionFAQView.swift in Sources */,
F130D73A1E5776C500C45811 /* OmniBarDelegate.swift in Sources */,
Expand Down
77 changes: 77 additions & 0 deletions DuckDuckGo/AIChat/AIChatViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
//
// AIChatViewController.swift
// DuckDuckGo
//
// Copyright © 2024 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 UIKit
import WebKit

final class AIChatViewController: UIViewController {
private let url: URL
private var webView: WKWebView!
private var closeButton: UIButton!

init(url: URL) {
self.url = url
super.init(nibName: nil, bundle: nil)
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()

webView = WKWebView(frame: .zero)

view.addSubview(webView)

webView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
webView.topAnchor.constraint(equalTo: view.topAnchor),
webView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])

let request = URLRequest(url: url)
webView.load(request)

closeButton = UIButton(type: .system)
closeButton.setTitle("X", for: .normal)
closeButton.setTitleColor(.white, for: .normal)
closeButton.backgroundColor = UIColor.black.withAlphaComponent(0.5)
closeButton.layer.cornerRadius = 15
closeButton.clipsToBounds = true
closeButton.addTarget(self, action: #selector(closeButtonTapped), for: .touchUpInside)

view.addSubview(closeButton)

closeButton.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
closeButton.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
closeButton.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16),
closeButton.widthAnchor.constraint(equalToConstant: 30),
closeButton.heightAnchor.constraint(equalToConstant: 30)
])
}

@objc private func closeButtonTapped() {
dismiss(animated: true, completion: nil)
}
}
18 changes: 18 additions & 0 deletions DuckDuckGo/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ class MainViewController: UIViewController {
return emailManager
}()

private lazy var aiChatViewController = AIChatViewController(url: URL(string: "http://duck.ai")!)
private lazy var gptChatViewController = AIChatViewController(url: URL(string: "http://chatgpt.com")!)

var newTabPageViewController: NewTabPageViewController?
var tabsBarController: TabsBarViewController?
var suggestionTrayController: SuggestionTrayViewController?
Expand Down Expand Up @@ -2296,6 +2299,21 @@ extension MainViewController: TabDelegate {
segueToReportBrokenSite()
}

func tabDidRequestAIChatFullScreen(tab: TabViewController) {
aiChatViewController.modalPresentationStyle = .fullScreen
tab.present(aiChatViewController, animated: true, completion: nil)
}

func tabDidRequestAIChatModal(tab: TabViewController) {
aiChatViewController.modalPresentationStyle = .pageSheet
tab.present(aiChatViewController, animated: true, completion: nil)
}

func tabDidRequestGPT(tab: TabViewController) {
gptChatViewController.modalPresentationStyle = .fullScreen
tab.present(gptChatViewController, animated: true, completion: nil)
}

func tab(_ tab: TabViewController, didRequestToggleReportWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
segueToReportBrokenSite(entryPoint: .toggleReport(completionHandler: completionHandler))
}
Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/TabDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ protocol TabDelegate: AnyObject {
func tab(_ tab: TabViewController, didChangePrivacyInfo privacyInfo: PrivacyInfo?)

func tabDidRequestReportBrokenSite(tab: TabViewController)
func tabDidRequestAIChatFullScreen(tab: TabViewController)
func tabDidRequestAIChatModal(tab: TabViewController)
func tabDidRequestGPT(tab: TabViewController)

func tab(_ tab: TabViewController, didRequestToggleReportWithCompletionHandler completionHandler: @escaping (Bool) -> Void)

Expand Down
41 changes: 20 additions & 21 deletions DuckDuckGo/TabViewControllerBrowsingMenuExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,30 +39,17 @@ extension TabViewController {
self?.onNewTabAction()
}))

entries.append(BrowsingMenuEntry.regular(name: UserText.actionShare, image: UIImage(named: "Share-24")!, action: { [weak self] in
guard let self = self else { return }
guard let menu = self.chromeDelegate?.omniBar.menuButton else { return }
Pixel.fire(pixel: .browsingMenuShare)
self.onShareAction(forLink: self.link!, fromView: menu)
}))
entries.append(BrowsingMenuEntry.regular(name: "GPT", image: UIImage(named: "Share-24")!, action: { [weak self] in
self?.openGPT()

entries.append(BrowsingMenuEntry.regular(name: UserText.actionCopy, image: UIImage(named: "Copy-24")!, action: { [weak self] in
guard let strongSelf = self else { return }
if !strongSelf.isError, let url = strongSelf.webView.url {
strongSelf.onCopyAction(forUrl: url)
} else if let text = self?.chromeDelegate?.omniBar.textField.text {
strongSelf.onCopyAction(for: text)
}
}))

Pixel.fire(pixel: .browsingMenuCopy)
let addressBarBottom = strongSelf.appSettings.currentAddressBarPosition.isBottom
ActionMessageView.present(message: UserText.actionCopyMessage,
presentationLocation: .withBottomBar(andAddressBarBottom: addressBarBottom))
entries.append(BrowsingMenuEntry.regular(name: "Modal", image: UIImage(named: "Copy-24")!, action: { [weak self] in
self?.openAIChatTabModal()
}))

entries.append(BrowsingMenuEntry.regular(name: UserText.actionPrint, image: UIImage(named: "Print-24")!, action: { [weak self] in
Pixel.fire(pixel: .browsingMenuPrint)
self?.print()
entries.append(BrowsingMenuEntry.regular(name: "Full", image: UIImage(named: "Print-24")!, action: { [weak self] in
self?.openAIChatTabFullScreen()
}))

return entries
Expand Down Expand Up @@ -166,7 +153,19 @@ extension TabViewController {

return entries
}


private func openAIChatTabFullScreen() {
delegate?.tabDidRequestAIChatFullScreen(tab: self)
}

private func openAIChatTabModal() {
delegate?.tabDidRequestAIChatModal(tab: self)
}

private func openGPT() {
delegate?.tabDidRequestGPT(tab: self)
}

private func buildKeepSignInEntry(forLink link: Link) -> BrowsingMenuEntry? {
guard let domain = link.url.host, !link.url.isDuckDuckGo else { return nil }
let isFireproofed = PreserveLogins.shared.isAllowed(cookieDomain: domain)
Expand Down

0 comments on commit 5214318

Please sign in to comment.