Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Onboarding

  • Loading branch information
Tim Palade authored and mahmoud-adam85 committed Sep 4, 2018
1 parent 7498553 commit 0ec670de876e913149730581c822f1a56d9db473
Showing with 9,941 additions and 51 deletions.
  1. +4 −0 Client.xcodeproj/project.pbxproj
  2. +132 −24 Cliqz/Intro/CliqzIntroViewController.swift
  3. +64 −0 Cliqz/Privacy/AdAndTrackingProtection/BlockListManager/Operations/ChangeTrackersOperation.swift
  4. +13 −13 Cliqz/Privacy/AdAndTrackingProtection/TrackingManagement/TrackerList.swift
  5. +1 −1 Cliqz/Privacy/AdAndTrackingProtection/UserPreferences.swift
  6. +54 −6 Cliqz/Privacy/UI/ControlCenter/OverviewViewController.swift
  7. BIN Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-Adblock.imageset/Ad & Tracker Blocking.png
  8. BIN Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-Adblock.imageset/Ad & Tracker Blocking@2x.png
  9. +2 −0 Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-Adblock.imageset/Contents.json
  10. +2 −0 Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-CliqzTab.imageset/Contents.json
  11. BIN Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-CliqzTab.imageset/Start Tab.png
  12. BIN Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-CliqzTab.imageset/Start Tab@2x.png
  13. +2 −0 Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-Introduction.imageset/Contents.json
  14. BIN Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-Introduction.imageset/Introducing.png
  15. BIN Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-Introduction.imageset/Introducing@2x.png
  16. +2 −0 Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-QuickSearch.imageset/Contents.json
  17. BIN Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-QuickSearch.imageset/Quick Search.png
  18. BIN Cliqz/Resources/Cliqz.xcassets/Intro/ghostery-QuickSearch.imageset/Quick Search@2x.png
  19. +6 −7 Cliqz/Storage/PrivacyStore/TrackerStateStore.swift
  20. +9,659 −0 yarn.lock
@@ -480,6 +480,7 @@
A93067E81D0FE18E00C49C6E /* NightModeHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = A93067E71D0FE18E00C49C6E /* NightModeHelper.swift */; };
AF03AA1A20BC117600A9D097 /* LoadTrackerListOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF03AA1920BC117600A9D097 /* LoadTrackerListOperation.swift */; };
AF03AA2A20BC129A00A9D097 /* ApplyDefaultsOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF03AA2920BC129A00A9D097 /* ApplyDefaultsOperation.swift */; };
AF235043213D482900A0CB8A /* ChangeTrackersOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF235042213D482800A0CB8A /* ChangeTrackersOperation.swift */; };
AF28D3D8207E32250065FF86 /* PermissionManagerModule.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF28D3D7207E32250065FF86 /* PermissionManagerModule.swift */; };
AF28D3DB207E325F0065FF86 /* PermissionManagerModuleBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = AF28D3DA207E325F0065FF86 /* PermissionManagerModuleBridge.m */; };
AF28D3DD207E378E0065FF86 /* GeoLocationBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = AF28D3DC207E378E0065FF86 /* GeoLocationBridge.m */; };
@@ -1816,6 +1817,7 @@
A93067E71D0FE18E00C49C6E /* NightModeHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NightModeHelper.swift; sourceTree = "<group>"; };
AF03AA1920BC117600A9D097 /* LoadTrackerListOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadTrackerListOperation.swift; sourceTree = "<group>"; };
AF03AA2920BC129A00A9D097 /* ApplyDefaultsOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplyDefaultsOperation.swift; sourceTree = "<group>"; };
AF235042213D482800A0CB8A /* ChangeTrackersOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChangeTrackersOperation.swift; sourceTree = "<group>"; };
AF28D3D7207E32250065FF86 /* PermissionManagerModule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionManagerModule.swift; sourceTree = "<group>"; };
AF28D3DA207E325F0065FF86 /* PermissionManagerModuleBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PermissionManagerModuleBridge.m; sourceTree = "<group>"; };
AF28D3DC207E378E0065FF86 /* GeoLocationBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GeoLocationBridge.m; sourceTree = "<group>"; };
@@ -3551,6 +3553,7 @@
AFD165B520C6C03B00379381 /* UpdateOperation.swift */,
AF03AA1920BC117600A9D097 /* LoadTrackerListOperation.swift */,
AF03AA2920BC129A00A9D097 /* ApplyDefaultsOperation.swift */,
AF235042213D482800A0CB8A /* ChangeTrackersOperation.swift */,
);
path = Operations;
sourceTree = "<group>";
@@ -6150,6 +6153,7 @@
1E2C202020AEDFBA00AA00B5 /* CliqzSiteTableViewCell.swift in Sources */,
1EEA36D72063F87C003B6AD5 /* URLExtension.swift in Sources */,
E69E06C91C76198000D0F926 /* AuthenticationManagerConstants.swift in Sources */,
AF235043213D482900A0CB8A /* ChangeTrackersOperation.swift in Sources */,
392ED7E61D0AEFEF009D9B62 /* HomePageAccessors.swift in Sources */,
AF6FA99220652D4600D7F9F0 /* TrieNode.swift in Sources */,
4F4033D82086575500AD2A8D /* OverviewViewController.swift in Sources */,
@@ -11,6 +11,7 @@ import Shared

struct CliqzIntroUX {
static let imageHeight: CGFloat = 290
static let PagerCenterOffsetFromScrollViewBottom = UIScreen.main.bounds.width <= 320 ? 10 : 30
}

class CliqzIntroViewController: UIViewController {
@@ -20,6 +21,14 @@ class CliqzIntroViewController: UIViewController {
var cardViews = [CliqzCardView]()
var cards = CliqzIntroCard.defaultCards()

enum BlockOption {
case none
case all
case recommended
}

var blockOptionSelected: BlockOption = .recommended //default
lazy fileprivate var startBrowsingButton: UIButton = {
let button = UIButton()
button.backgroundColor = UIColor.cliqzBluePrimary
@@ -77,15 +86,6 @@ class CliqzIntroViewController: UIViewController {
assert(cards.count > 1, "Intro is empty. At least 2 cards are required")
view.backgroundColor = UIColor.clear
imagesBackgroundView.backgroundColor = UIColor.clear

// Gradient Background
let gradient: CAGradientLayer = CAGradientLayer()

gradient.colors = [UIColor(red:0.31, green:0.67, blue:0.91, alpha:1.00).cgColor, UIColor.black.cgColor]
gradient.locations = [0.0 , 1.0]
gradient.frame = CGRect(x: 0.0, y: 0.0, width: self.view.frame.size.width, height: self.view.frame.size.height)

self.view.layer.insertSublayer(gradient, at: 0)

// Add Views
view.addSubview(pageControl)
@@ -100,12 +100,13 @@ class CliqzIntroViewController: UIViewController {
}
imageViewContainer.snp.makeConstraints { make in
make.top.equalTo(self.view)
make.height.equalTo(CliqzIntroUX.imageHeight)
let height = (290 / 375) * self.view.frame.width
make.height.equalTo(height)
}
startBrowsingButton.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.width.equalToSuperview().dividedBy(2.2)
make.bottom.equalTo(self.view.safeArea.bottom).offset(-IntroUX.PagerCenterOffsetFromScrollViewBottom)
make.bottom.equalTo(self.view.safeArea.bottom).offset(-CliqzIntroUX.PagerCenterOffsetFromScrollViewBottom)
make.height.equalTo(45)
}
scrollView.snp.makeConstraints { make in
@@ -115,7 +116,7 @@ class CliqzIntroViewController: UIViewController {

pageControl.snp.makeConstraints { make in
make.centerX.equalTo(self.scrollView)
make.centerY.equalTo(self.startBrowsingButton.snp.top).offset(-IntroUX.PagerCenterOffsetFromScrollViewBottom)
make.centerY.equalTo(self.startBrowsingButton.snp.top).offset(-20)
}

createSlides()
@@ -157,9 +158,17 @@ class CliqzIntroViewController: UIViewController {
make.width.equalTo(self.view.snp.width)
}

let cardView = CliqzCardView(verticleSpacing: verticalPadding)
let cardView: CliqzCardView
// In case there are tick buttons everything needs to be closer together
if card.tickButtons != nil {
cardView = CliqzCardView(verticleSpacing: 10.0)
}
else {
cardView = CliqzCardView(verticleSpacing: verticalPadding)
}
cardView.configureWith(card: card)

//assumption: Only one card with tickButtons
if let tickButtons = cardView.tickButtons {
for i in 0..<tickButtons.count {
let tickButton = tickButtons[i]
@@ -198,9 +207,66 @@ class CliqzIntroViewController: UIViewController {
}

sender.isSelected = true

// Show next card
// DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in
// if (self?.pageControl.currentPage ?? 0) + 1 <= (self?.pageControl.numberOfPages ?? 0) {
// self?.pageControl.currentPage += 1
// self?.changePage()
// }
// }
//assumption: Only one card with tickButtons, the Antitracking card
if sender.tag == 1 { // Block Nothing
blockOptionSelected = .none
}
else if sender.tag == 2 { //Block Recommended
blockOptionSelected = .recommended
}
else if sender.tag == 3 { //BlockEverything
blockOptionSelected = .all
}
}

@objc func startBrowsing() {
// Start the necessary stuff for antitracking
let populateOp = PopulateBlockedTrackersOperation()

var loadOp: LoadTrackerListOperation? = nil

let loadOperations = GlobalPrivacyQueue.shared.operations.filter { (op) -> Bool in
return op is LoadTrackerListOperation && !(op.isFinished || op.isCancelled)
}

if !loadOperations.isEmpty, let loadOperation = loadOperations.first as? LoadTrackerListOperation {
loadOp = loadOperation
}

func addOp(operation: Operation) {
if let loadOperation = loadOp {
operation.addDependency(loadOperation)
}

populateOp.addDependency(operation)

GlobalPrivacyQueue.shared.addOperation(operation)
GlobalPrivacyQueue.shared.addOperation(populateOp)
}

if blockOptionSelected != .recommended {
let blockOption: ChangeTrackersOperation.BlockOption = blockOptionSelected == .all ? .blockAll : .unblockAll

let operation = ChangeTrackersOperation(blockOption: blockOption)
addOp(operation: operation)
}
else {
let applyDefaultsOp = ApplyDefaultsOperation()
addOp(operation: applyDefaultsOp)
UserDefaults.standard.set(true, forKey: trackersDefaultsAreAppliedKey)
UserDefaults.standard.synchronize()
}

delegate?.introViewControllerDidFinish(self, requestToLogin: false)
}

@@ -263,6 +329,29 @@ extension CliqzIntroViewController {
extension CliqzIntroViewController {
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

// Gradient Background
let gradient: CAGradientLayer = CAGradientLayer()

gradient.colors = [UIColor(red:0.31, green:0.67, blue:0.91, alpha:1.00).cgColor, UIColor.black.cgColor]
gradient.locations = [0.0 , 1.0]
let width: CGFloat
let height: CGFloat

//Fix for gradient bug when the intro is shown while the device is in landscape.
if UIDevice.current.getDeviceAndOrientation().1 == .portrait && self.view.frame.size.width > self.view.frame.size.height {
width = self.view.frame.size.height
height = self.view.frame.size.width
}
else {
width = self.view.frame.width
height = self.view.frame.height
}

gradient.frame = CGRect(x: 0.0, y: 0.0, width: width, height: height)

self.view.layer.insertSublayer(gradient, at: 0)

NotificationCenter.default.addObserver(self, selector: #selector(dynamicFontChanged(_:)), name: .DynamicFontChanged, object: nil)
}

@@ -358,9 +447,16 @@ class CliqzCardView: UIView {
return optInView
}()


var tickButtons: [TickButton]? = nil

var tickButtonHeight: CGFloat {
return UIScreen.main.bounds.width <= 320 ? 40 : 50
}

var tickButtonTitleHeight: CGFloat {
return UIScreen.main.bounds.width <= 320 ? 14 : 16
}

func createTickButton(info: TickButtonInfo) -> TickButton {

var subtitle: Bool = false
@@ -426,14 +522,14 @@ class CliqzCardView: UIView {
buttonStackView.addArrangedSubview(tickButton)
tickButton.snp.makeConstraints { (make) in
make.left.right.equalToSuperview()
make.height.equalTo(50)
make.height.equalTo(tickButtonHeight)
}
if i != tickButtonsInfo.count - 1 {
tickButton.bottomSep.isHidden = true
}
tickButton.label.textColor = .white
tickButton.subtitleLabel.textColor = .white
tickButton.label.font = UIFont.systemFont(ofSize: 16)
tickButton.labelTextColor = .white
tickButton.subtitleLabelTextColor = .white
tickButton.label.font = UIFont.systemFont(ofSize: tickButtonTitleHeight)
tickButton.subtitleLabel.font = UIFont.systemFont(ofSize: 12)
tickButton.sepColor = UIColor.white.withAlphaComponent(0.2)
tickButton.bgColorSelected = UIColor.white.withAlphaComponent(0.2)
@@ -446,12 +542,24 @@ class CliqzCardView: UIView {
}

// Allows the scrollView to scroll while the CardView is in front
// override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
// if let buttonSV = optInView.superview {
// return convert(optInView.frame, from: buttonSV).contains(point)
// }
// return false
// }
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
if let buttonSV = optInView.superview {
return convert(optInView.frame, from: buttonSV).contains(point)
}
if let tickButtons = tickButtons, !tickButtons.isEmpty, let SV = tickButtons.first!.superview {
var values: [Bool] = Array.init(repeating: false, count: tickButtons.count)
for i in 0..<tickButtons.count {
let button = tickButtons[i]
values[i] = convert(button.frame, from: SV).contains(point)
}

return !(values.filter { (a) -> Bool in
return a == true
}.isEmpty)
}

return false
}

required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
@@ -0,0 +1,64 @@
//
// ChangeTrackersOperation.swift
// Client
//
// Created by Tim Palade on 9/3/18.
// Copyright © 2018 Cliqz. All rights reserved.
//
import Storage

public class ChangeTrackersOperation: Operation {

public enum BlockOption {
case blockAll
case unblockAll
}

var blockOption: BlockOption = .blockAll

private var _executing: Bool = false
override public var isExecuting: Bool {
get {
return _executing
}
set {
if _executing != newValue {
willChangeValue(forKey: "isExecuting")
_executing = newValue
didChangeValue(forKey: "isExecuting")
}
}
}

private var _finished: Bool = false;
override public var isFinished: Bool {
get {
return _finished
}
set {
if _finished != newValue {
willChangeValue(forKey: "isFinished")
_finished = newValue
didChangeValue(forKey: "isFinished")
}
}
}

public init(blockOption: BlockOption) {
super.init()
self.blockOption = blockOption
}

override public func main() {
self.isExecuting = true
if blockOption == .blockAll {
TrackerStateStore.change(appIds: TrackerList.instance.appsList.map{app in return app.appId}, toState: .blocked)
}
else if blockOption == .unblockAll {
TrackerStateStore.change(appIds: TrackerList.instance.appsList.map{app in return app.appId}, toState: .empty)
}
self.isFinished = true
}
}

@@ -65,21 +65,21 @@ let trackersLoadedNotification = Notification.Name(rawValue:"TrackersLoadedNotif
// To ensure this, loadTrackerList should be called before any calls to a coordinatedUpdate.
let loadOperation = LoadTrackerListOperation()

if UserDefaults.standard.bool(forKey: trackersDefaultsAreAppliedKey) == false {
applyDefaultsOp = ApplyDefaultsOperation()
applyDefaultsOp!.addDependency(loadOperation)
populateOp.addDependency(applyDefaultsOp!)
UserDefaults.standard.set(true, forKey: trackersDefaultsAreAppliedKey)
UserDefaults.standard.synchronize()
}
else {
populateOp.addDependency(loadOperation)
}
// if UserDefaults.standard.bool(forKey: trackersDefaultsAreAppliedKey) == false {
// applyDefaultsOp = ApplyDefaultsOperation()
// applyDefaultsOp!.addDependency(loadOperation)
// populateOp.addDependency(applyDefaultsOp!)
// UserDefaults.standard.set(true, forKey: trackersDefaultsAreAppliedKey)
// UserDefaults.standard.synchronize()
// }
// else {
populateOp.addDependency(loadOperation)
// }
GlobalPrivacyQueue.shared.addOperation(loadOperation)
if let applyOp = applyDefaultsOp {
GlobalPrivacyQueue.shared.addOperation(applyOp)
}
// if let applyOp = applyDefaultsOp {
// GlobalPrivacyQueue.shared.addOperation(applyOp)
// }
GlobalPrivacyQueue.shared.addOperation(populateOp)
}

@@ -36,7 +36,7 @@ import Storage
NotificationCenter.default.removeObserver(self)
}

@objc func updateAntitrackingPref(_ notificaion: Notification) {
@objc func updateAntitrackingPref(_ sender: Any?) {
if TrackerStateStore.shared.blockedTrackers.count == TrackerList.instance.appsList.count, self._antitrackingMode != .blockAll {
self._antitrackingMode = .blockAll
self.writeToDisk()

0 comments on commit 0ec670d

Please sign in to comment.