Skip to content

Commit

Permalink
Use a custom view controller for T&C.
Browse files Browse the repository at this point in the history
  • Loading branch information
samsymons committed Nov 16, 2023
1 parent ae5065c commit e31ad36
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 58 deletions.
4 changes: 4 additions & 0 deletions DuckDuckGo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@
4BCD14632B05AF2B000B1E4C /* NetworkProtectionAccessController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCD14622B05AF2B000B1E4C /* NetworkProtectionAccessController.swift */; };
4BCD14672B05B682000B1E4C /* NetworkProtectionTermsAndConditionsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCD14662B05B682000B1E4C /* NetworkProtectionTermsAndConditionsStore.swift */; };
4BCD14692B05BDD5000B1E4C /* AppDelegate+Waitlists.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCD14682B05BDD5000B1E4C /* AppDelegate+Waitlists.swift */; };
4BCD146B2B05C4B5000B1E4C /* VPNWaitlistTermsAndConditionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCD146A2B05C4B5000B1E4C /* VPNWaitlistTermsAndConditionsViewController.swift */; };
4BE2756827304F57006B20B0 /* URLRequestExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE27566272F878F006B20B0 /* URLRequestExtension.swift */; };
4BEF65692989C2FC00B650CB /* AdapterSocketEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 021D307A2989C0C400918636 /* AdapterSocketEvent.swift */; };
4BEF656A2989C2FC00B650CB /* ProxyServerEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 021D307C2989C0C600918636 /* ProxyServerEvent.swift */; };
Expand Down Expand Up @@ -1331,6 +1332,7 @@
4BCD14622B05AF2B000B1E4C /* NetworkProtectionAccessController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionAccessController.swift; sourceTree = "<group>"; };
4BCD14662B05B682000B1E4C /* NetworkProtectionTermsAndConditionsStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionTermsAndConditionsStore.swift; sourceTree = "<group>"; };
4BCD14682B05BDD5000B1E4C /* AppDelegate+Waitlists.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Waitlists.swift"; sourceTree = "<group>"; };
4BCD146A2B05C4B5000B1E4C /* VPNWaitlistTermsAndConditionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNWaitlistTermsAndConditionsViewController.swift; sourceTree = "<group>"; };
4BE27566272F878F006B20B0 /* URLRequestExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = URLRequestExtension.swift; path = ../DuckDuckGo/URLRequestExtension.swift; sourceTree = "<group>"; };
4BFB911A29B7D9530014D4B7 /* AppTrackingProtectionStoringModelPerformanceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTrackingProtectionStoringModelPerformanceTests.swift; sourceTree = "<group>"; };
56244C1C2A137B1900EDF259 /* WaitlistViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistViews.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -3479,6 +3481,7 @@
4BBBBA892B031B4200D965DA /* VPNWaitlistDebugViewController.swift */,
4BBBBA8B2B031B4200D965DA /* VPNWaitlistView.swift */,
4BBBBA8A2B031B4200D965DA /* VPNWaitlistViewController.swift */,
4BCD146A2B05C4B5000B1E4C /* VPNWaitlistTermsAndConditionsViewController.swift */,
);
name = VPN;
sourceTree = "<group>";
Expand Down Expand Up @@ -6425,6 +6428,7 @@
85AE6690209724120014CF04 /* NotificationView.swift in Sources */,
1EA51376286596A000493C6A /* PrivacyIconLogic.swift in Sources */,
980891A92238504B00313A70 /* UILabelExtension.swift in Sources */,
4BCD146B2B05C4B5000B1E4C /* VPNWaitlistTermsAndConditionsViewController.swift in Sources */,
984D035A24ACCC7D0066CFB8 /* TabViewCell.swift in Sources */,
31951E8E2823003200CAF535 /* AutofillLoginDetailsHeaderView.swift in Sources */,
F194FAED1F14E2B3009B4DF8 /* UIFontExtension.swift in Sources */,
Expand Down
3 changes: 0 additions & 3 deletions DuckDuckGo/MacWaitlistViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@ extension MacWaitlistViewController: WaitlistViewModelDelegate {
}
}

func waitlistViewModelShouldRefreshState(_ viewModel: WaitlistViewModel) -> Bool {
return true
}
}

private final class MacWaitlistLinkMetadata: NSObject, UIActivityItemSource {
Expand Down
4 changes: 0 additions & 4 deletions DuckDuckGo/VPNWaitlist.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,6 @@ final class VPNWaitlist: Waitlist {

}

extension WaitlistViewModel.ViewCustomState {
static var networkProtectionPrivacyPolicyScreen = WaitlistViewModel.ViewCustomState(identifier: "networkProtectionPrivacyPolicyScreen")
}

extension WaitlistViewModel.ViewCustomAction {
static var openNetworkProtectionInviteCodeScreen = WaitlistViewModel.ViewCustomAction(identifier: "openNetworkProtectionInviteCodeScreen")
static var openNetworkProtectionPrivacyPolicyScreen = WaitlistViewModel.ViewCustomAction(identifier: "openNetworkProtectionPrivacyPolicyScreen")
Expand Down
73 changes: 73 additions & 0 deletions DuckDuckGo/VPNWaitlistTermsAndConditionsViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// VPNWaitlistTermsAndConditionsViewController.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.
//

#if NETWORK_PROTECTION

import UIKit
import SwiftUI
import Core
import Waitlist

@available(iOS 15.0, *)
final class VPNWaitlistTermsAndConditionsViewController: UIViewController {

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nil, bundle: nil)
}

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

override func viewDidLoad() {
super.viewDidLoad()

title = UserText.networkProtectionWaitlistJoinTitle
addHostingControllerToViewHierarchy()
}

private func addHostingControllerToViewHierarchy() {
let waitlistView = VPNWaitlistPrivacyPolicyView { _ in
var termsAndConditionsStore = NetworkProtectionTermsAndConditionsUserDefaultsStore()
termsAndConditionsStore.networkProtectionWaitlistTermsAndConditionsAccepted = true

self.navigationController?.popToRootViewController(animated: true)
let networkProtectionViewController = NetworkProtectionRootViewController()
self.navigationController?.pushViewController(networkProtectionViewController, animated: true)
}

let waitlistViewController = UIHostingController(rootView: waitlistView)
waitlistViewController.view.backgroundColor = UIColor(designSystemColor: .background)

addChild(waitlistViewController)
waitlistViewController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(waitlistViewController.view)
waitlistViewController.didMove(toParent: self)

NSLayoutConstraint.activate([
waitlistViewController.view.widthAnchor.constraint(equalTo: view.widthAnchor),
waitlistViewController.view.heightAnchor.constraint(equalTo: view.heightAnchor),
waitlistViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
waitlistViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
}

}

#endif
10 changes: 2 additions & 8 deletions DuckDuckGo/VPNWaitlistView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,6 @@ struct VPNWaitlistView: View {
}
case .waitlistRemoved:
fatalError("State not supported for VPN waitlists")
case .custom(let customState):
if customState == .networkProtectionPrivacyPolicyScreen {
VPNWaitlistPrivacyPolicyView { action in
Task { await viewModel.perform(action: action) }
}
}
}
}
}
Expand Down Expand Up @@ -230,7 +224,7 @@ struct VPNWaitlistInvitedView: View {
),
]

let action: (WaitlistViewModel.ViewAction) -> Void
let action: WaitlistViewActionHandler

@State private var shareButtonFrame: CGRect = .zero

Expand Down Expand Up @@ -275,7 +269,7 @@ struct VPNWaitlistInvitedView: View {
@available(iOS 15.0, *)
struct VPNWaitlistPrivacyPolicyView: View {

let action: (WaitlistViewModel.ViewAction) -> Void
let action: WaitlistViewActionHandler

var body: some View {
ScrollView {
Expand Down
17 changes: 2 additions & 15 deletions DuckDuckGo/VPNWaitlistViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import UIKit
import SwiftUI
import LinkPresentation
import Core
import Waitlist

Expand Down Expand Up @@ -132,16 +131,8 @@ extension VPNWaitlistViewController: WaitlistViewModelDelegate {
}

if action == .openNetworkProtectionPrivacyPolicyScreen {
self.viewModel.set(customState: .networkProtectionPrivacyPolicyScreen)
}

if action == .acceptNetworkProtectionTerms {
var termsAndConditionsStore = NetworkProtectionTermsAndConditionsUserDefaultsStore()
termsAndConditionsStore.networkProtectionWaitlistTermsAndConditionsAccepted = true

self.navigationController?.popViewController(animated: true)
let networkProtectionViewController = NetworkProtectionRootViewController()
self.navigationController?.pushViewController(networkProtectionViewController, animated: true)
let termsAndConditionsViewController = VPNWaitlistTermsAndConditionsViewController()
self.navigationController?.pushViewController(termsAndConditionsViewController, animated: true)
}
}

Expand All @@ -153,10 +144,6 @@ extension VPNWaitlistViewController: WaitlistViewModelDelegate {
// The VPN waitlist doesn't support the share sheet
}

func waitlistViewModelShouldRefreshState(_ viewModel: WaitlistViewModel) -> Bool {
return viewModel.viewState != .custom(.networkProtectionPrivacyPolicyScreen)
}

}

#endif
2 changes: 0 additions & 2 deletions DuckDuckGo/WindowsBrowserWaitlistView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@ struct WindowsBrowserWaitlistView: View {
WaitlistDownloadBrowserContentView(platform: .windows) { action in
Task { await viewModel.perform(action: action) }
}
case .custom:
fatalError("Tried to use custom state without supporting one")
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions DuckDuckGo/WindowsWaitlistViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,6 @@ extension WindowsWaitlistViewController: WaitlistViewModelDelegate {
}
}

func waitlistViewModelShouldRefreshState(_ viewModel: WaitlistViewModel) -> Bool {
return true
}

}

private final class WindowsWaitlistLinkMetadata: NSObject, UIActivityItemSource {
Expand Down
18 changes: 0 additions & 18 deletions LocalPackages/Waitlist/Sources/Waitlist/WaitlistViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public protocol WaitlistViewModelDelegate: AnyObject {
func waitlistViewModelDidOpenInviteCodeShareSheet(_ viewModel: WaitlistViewModel, inviteCode: String, senderFrame: CGRect)
func waitlistViewModelDidOpenDownloadURLShareSheet(_ viewModel: WaitlistViewModel, senderFrame: CGRect)
func waitlistViewModel(_ viewModel: WaitlistViewModel, didTriggerCustomAction action: WaitlistViewModel.ViewCustomAction)
func waitlistViewModelShouldRefreshState(_ viewModel: WaitlistViewModel) -> Bool
}

@MainActor
Expand All @@ -40,15 +39,6 @@ public final class WaitlistViewModel: ObservableObject {
case joinedQueue(NotificationPermissionState)
case invited(inviteCode: String)
case waitlistRemoved
case custom(ViewCustomState)
}

public struct ViewCustomState: Equatable {
public let identifier: String

public init(identifier: String) {
self.identifier = identifier
}
}

public enum ViewAction: Equatable {
Expand Down Expand Up @@ -104,10 +94,6 @@ public final class WaitlistViewModel: ObservableObject {
}

public func updateViewState() async {
guard delegate?.waitlistViewModelShouldRefreshState(self) ?? true else {
return
}

guard viewState != .waitlistRemoved else {
return
}
Expand All @@ -133,10 +119,6 @@ public final class WaitlistViewModel: ObservableObject {
}
}

public func set(customState: ViewCustomState) {
self.viewState = .custom(customState)
}

// MARK: - Private

private func checkNotificationPermissions() async {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,4 @@ public class MockWaitlistViewModelDelegate: WaitlistViewModelDelegate {
didTriggerCustomActionCalled = true
}

public func waitlistViewModelShouldRefreshState(_ viewModel: WaitlistViewModel) -> Bool {
return true
}

}

0 comments on commit e31ad36

Please sign in to comment.