mirror of
https://github.com/confirmedcode/Lockdown-iOS.git
synced 2025-12-21 12:14:02 +01:00
639 lines
26 KiB
Swift
639 lines
26 KiB
Swift
//
|
|
// LockdownViewController.swift
|
|
// Lockdown
|
|
//
|
|
// Copyright © 2019 Confirmed Inc. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Foundation
|
|
import CocoaLumberjackSwift
|
|
|
|
final class BlockListViewController: BaseViewController {
|
|
|
|
// MARK: - Properties
|
|
var didMakeChange = false
|
|
|
|
var chosenBlocking = 0
|
|
|
|
var lockdownBlockLists: [LockdownGroup] = []
|
|
var customBlockedDomains: [(String, Bool)] = []
|
|
|
|
var customBlockedLists: [UserBlockListsGroup] = []
|
|
|
|
let curatedBlockedDomainsTableView = StaticTableView()
|
|
let customBlockedListsTableView = StaticTableView()
|
|
let customBlockedDomainsTableView = StaticTableView()
|
|
|
|
private lazy var listsSubmenuView: ListsSubmenuView = {
|
|
let view = ListsSubmenuView()
|
|
view.topButton.addTarget(self, action: #selector(addList), for: .touchUpInside)
|
|
view.bottomButton.addTarget(self, action: #selector(importBlockList), for: .touchUpInside)
|
|
view.isHidden = true
|
|
return view
|
|
}()
|
|
|
|
private lazy var customNavigationView: CustomNavigationView = {
|
|
let view = CustomNavigationView()
|
|
view.title = NSLocalizedString("Configure Blocking", comment: "")
|
|
view.buttonTitle = NSLocalizedString("CLOSE", comment: "")
|
|
view.onButtonPressed { [unowned self] in
|
|
self.close()
|
|
}
|
|
return view
|
|
}()
|
|
|
|
enum Page: CaseIterable {
|
|
case curated
|
|
case custom
|
|
|
|
var localizedTitle: String {
|
|
switch self {
|
|
case .curated:
|
|
return NSLocalizedString("Curated", comment: "")
|
|
case .custom:
|
|
return NSLocalizedString("Custom", comment: "")
|
|
}
|
|
}
|
|
}
|
|
|
|
private lazy var segmented: UISegmentedControl = {
|
|
let view = UISegmentedControl(items: Page.allCases.map(\.localizedTitle))
|
|
view.selectedSegmentIndex = chosenBlocking
|
|
view.setTitleTextAttributes([.font: fontMedium14], for: .normal)
|
|
view.selectedSegmentTintColor = .tunnelsBlue
|
|
view.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
|
|
view.addTarget(self, action: #selector(segmentedControlDidChangeValue), for: .valueChanged)
|
|
return view
|
|
}()
|
|
|
|
private let paragraphLabel: UILabel = {
|
|
let view = UILabel()
|
|
view.font = fontRegular14
|
|
view.numberOfLines = 0
|
|
view.text = NSLocalizedString("Block all your apps from connecting to the domains and sites below. For your convenience, Lockdown also has pre-configured suggestions.", comment: "")
|
|
return view
|
|
}()
|
|
|
|
private lazy var addNewListButton: UIButton = {
|
|
let button = UIButton(type: .system)
|
|
let symbolConfig = UIImage.SymbolConfiguration(pointSize: 14, weight: .bold, scale: .large)
|
|
button.tintColor = .tunnelsBlue
|
|
button.setImage(UIImage(systemName: "plus", withConfiguration: symbolConfig), for: .normal)
|
|
button.addTarget(self, action: #selector(showSubmenu), for: .touchUpInside)
|
|
button.isEnabled = false
|
|
return button
|
|
}()
|
|
|
|
private lazy var listsLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.text = NSLocalizedString("Lists", comment: "")
|
|
label.textColor = .label
|
|
label.font = fontBold18
|
|
return label
|
|
}()
|
|
|
|
private lazy var emptyListsView: EmptyListsView = {
|
|
let view = EmptyListsView()
|
|
view.descriptionLabel.text = NSLocalizedString("No lists yet", comment: "")
|
|
view.addButton.setTitle(NSLocalizedString("Create a list", comment: ""), for: .normal)
|
|
view.addButton.addTarget(self, action: #selector(addList), for: .touchUpInside)
|
|
return view
|
|
}()
|
|
|
|
private lazy var lockedListsView: LockedListsView = {
|
|
let view = LockedListsView()
|
|
return view
|
|
}()
|
|
|
|
private lazy var domainsLabel: UILabel = {
|
|
let label = UILabel()
|
|
label.text = NSLocalizedString("Domains", comment: "")
|
|
label.textColor = .label
|
|
label.font = fontBold18
|
|
return label
|
|
}()
|
|
|
|
private lazy var addNewDomainButton: UIButton = {
|
|
let button = UIButton(type: .system)
|
|
let symbolConfig = UIImage.SymbolConfiguration(pointSize: 14, weight: .bold, scale: .large)
|
|
button.tintColor = .tunnelsBlue
|
|
button.setImage(UIImage(systemName: "plus", withConfiguration: symbolConfig), for: .normal)
|
|
button.addTarget(self, action: #selector(addDomain), for: .touchUpInside)
|
|
return button
|
|
}()
|
|
|
|
private lazy var editDomainButton: UIButton = {
|
|
let button = UIButton(type: .system)
|
|
let symbolConfig = UIImage.SymbolConfiguration(pointSize: 14, weight: .bold, scale: .large)
|
|
button.tintColor = .tunnelsBlue
|
|
button.setImage(UIImage(named: "icn_edit"), for: .normal)
|
|
button.addTarget(self, action: #selector(editDomains), for: .touchUpInside)
|
|
// button.isHidden = true
|
|
return button
|
|
}()
|
|
|
|
private lazy var emptyDomainsView: EmptyListsView = {
|
|
let view = EmptyListsView()
|
|
view.descriptionLabel.text = NSLocalizedString("No custom domains yet", comment: "")
|
|
view.addButton.setTitle(NSLocalizedString("Add a domain", comment: ""), for: .normal)
|
|
view.addButton.addTarget(self, action: #selector(addDomain), for: .touchUpInside)
|
|
return view
|
|
}()
|
|
|
|
// MARK: - Lifecycle
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
view.backgroundColor = .secondarySystemBackground
|
|
|
|
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissView))
|
|
tap.cancelsTouchesInView = false
|
|
view.addGestureRecognizer(tap)
|
|
|
|
configure()
|
|
configureCuratedBlockedDomainsTableView()
|
|
configureCustomBlockedListsTableView()
|
|
configureCustomBlockedDomainsTableView()
|
|
}
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
reloadCustomBlockedLists()
|
|
}
|
|
|
|
private func configure() {
|
|
view.addSubview(customNavigationView)
|
|
customNavigationView.anchors.leading.pin()
|
|
customNavigationView.anchors.trailing.pin()
|
|
customNavigationView.anchors.top.safeAreaPin()
|
|
|
|
view.addSubview(paragraphLabel)
|
|
paragraphLabel.anchors.top.spacing(0, to: customNavigationView.anchors.bottom)
|
|
paragraphLabel.anchors.leading.readableContentPin(inset: 3)
|
|
paragraphLabel.anchors.trailing.readableContentPin(inset: 3)
|
|
paragraphLabel.anchors.height.equal(60)
|
|
|
|
view.addSubview(segmented)
|
|
segmented.anchors.top.spacing(12, to: paragraphLabel.anchors.bottom)
|
|
segmented.anchors.leading.readableContentPin()
|
|
segmented.anchors.trailing.readableContentPin()
|
|
segmented.anchors.height.equal(40)
|
|
}
|
|
|
|
private func configureCuratedBlockedDomainsTableView() {
|
|
addTableView(curatedBlockedDomainsTableView, layout: { tableView in
|
|
tableView.anchors.top.spacing(8, to: segmented.anchors.bottom)
|
|
tableView.anchors.leading.pin()
|
|
tableView.anchors.trailing.pin()
|
|
tableView.anchors.bottom.pin()
|
|
})
|
|
|
|
reloadCuratedBlockDomains()
|
|
chosenBlocking == 0 ? transition(toPage: .curated) : transition(toPage: .custom)
|
|
}
|
|
|
|
private func configureCustomBlockedListsTableView() {
|
|
|
|
view.addSubview(listsLabel)
|
|
listsLabel.anchors.top.spacing(24, to: segmented.anchors.bottom)
|
|
listsLabel.anchors.leading.marginsPin()
|
|
|
|
view.addSubview(addNewListButton)
|
|
addNewListButton.anchors.centerY.equal(listsLabel.anchors.centerY)
|
|
addNewListButton.anchors.trailing.marginsPin()
|
|
|
|
view.addSubview(domainsLabel)
|
|
domainsLabel.anchors.top.spacing(300, to: segmented.anchors.bottom)
|
|
domainsLabel.anchors.height.equal(30)
|
|
domainsLabel.anchors.leading.marginsPin()
|
|
|
|
addTableView(customBlockedListsTableView, layout: { tableView in
|
|
tableView.anchors.top.spacing(8, to: listsLabel.anchors.bottom)
|
|
tableView.anchors.leading.pin()
|
|
tableView.anchors.trailing.pin()
|
|
tableView.anchors.bottom.spacing(8, to: domainsLabel.anchors.top)
|
|
})
|
|
|
|
view.addSubview(listsSubmenuView)
|
|
listsSubmenuView.anchors.trailing.marginsPin()
|
|
listsSubmenuView.anchors.top.spacing(60, to: paragraphLabel.anchors.bottom)
|
|
|
|
customBlockedListsTableView.deselectsCellsAutomatically = true
|
|
}
|
|
|
|
private func configureCustomBlockedDomainsTableView() {
|
|
|
|
view.addSubview(addNewDomainButton)
|
|
addNewDomainButton.anchors.centerY.equal(domainsLabel.anchors.centerY)
|
|
addNewDomainButton.anchors.trailing.marginsPin()
|
|
|
|
// view.addSubview(editDomainButton)
|
|
// editDomainButton.anchors.centerY.equal(domainsLabel.anchors.centerY)
|
|
// editDomainButton.anchors.trailing.spacing(16, to: addNewDomainButton.anchors.leading)
|
|
|
|
addTableView(customBlockedDomainsTableView, layout: { tableView in
|
|
tableView.anchors.top.spacing(8, to: domainsLabel.anchors.bottom)
|
|
tableView.anchors.leading.pin()
|
|
tableView.anchors.trailing.pin()
|
|
tableView.anchors.bottom.safeAreaPin()
|
|
})
|
|
|
|
customBlockedDomainsTableView.deselectsCellsAutomatically = true
|
|
|
|
reloadCustomBlockedDomains()
|
|
}
|
|
|
|
// Curated lists
|
|
func reloadCuratedBlockDomains() {
|
|
curatedBlockedDomainsTableView.clear()
|
|
lockdownBlockLists = {
|
|
let domains = getLockdownBlockedDomains().lockdownDefaults
|
|
let sorted = domains.sorted(by: { $0.key < $1.key })
|
|
return Array(sorted.map(\.value))
|
|
}()
|
|
createCuratedBlockedDomainsRows()
|
|
curatedBlockedDomainsTableView.reloadData()
|
|
}
|
|
|
|
func reloadCustomBlockedLists() {
|
|
customBlockedListsTableView.clear()
|
|
customBlockedLists = {
|
|
let lists = getBlockedLists().userBlockListsDefaults
|
|
let sorted = lists.sorted(by: { $0.key < $1.key })
|
|
return Array(sorted.map(\.value))
|
|
}()
|
|
createCustomBlockedListsRows()
|
|
customBlockedListsTableView.reloadData()
|
|
}
|
|
|
|
func reloadCustomBlockedDomains() {
|
|
customBlockedDomainsTableView.clear()
|
|
customBlockedDomains = {
|
|
let domains = getUserBlockedDomains()
|
|
return domains.sorted(by: { $0.key < $1.key }).map { (key, value) -> (String, Bool) in
|
|
if let status = value as? NSNumber {
|
|
return (key, status.boolValue)
|
|
} else {
|
|
return (key, false)
|
|
}
|
|
}
|
|
}()
|
|
createCustomBlockedDomainsRows()
|
|
customBlockedDomainsTableView.reloadData()
|
|
}
|
|
|
|
// Curated Lists
|
|
func createCuratedBlockedDomainsRows() {
|
|
let tableView = curatedBlockedDomainsTableView
|
|
|
|
for lockdownGroup in lockdownBlockLists {
|
|
|
|
let cell = tableView.addRow { (contentView) in
|
|
let blockListView = BlockListView()
|
|
blockListView.contents = .lockdownGroup(lockdownGroup)
|
|
contentView.addSubview(blockListView)
|
|
blockListView.anchors.edges.pin()
|
|
}.onSelect { [unowned self] in
|
|
if UserDefaults.hasSeenAdvancedPaywall || UserDefaults.hasSeenAnonymousPaywall || UserDefaults.hasSeenUniversalPaywall {
|
|
let storyboard = UIStoryboard.main
|
|
let target = storyboard.instantiate(BlockListGroupViewController.self)
|
|
target.lockdownGroup = lockdownGroup
|
|
// target.blockListVC = self
|
|
self.navigationController?.pushViewController(target, animated: true)
|
|
} else {
|
|
if lockdownGroup.accessLevel == "advanced" {
|
|
let vc = VPNPaywallViewController()
|
|
present(vc, animated: true)
|
|
} else {
|
|
let storyboard = UIStoryboard.main
|
|
let target = storyboard.instantiate(BlockListGroupViewController.self)
|
|
target.lockdownGroup = lockdownGroup
|
|
// target.blockListVC = self
|
|
self.navigationController?.pushViewController(target, animated: true)
|
|
}
|
|
}
|
|
}
|
|
|
|
cell.accessoryType = .disclosureIndicator
|
|
}
|
|
}
|
|
|
|
@objc
|
|
func segmentedControlDidChangeValue() {
|
|
let page = Page.allCases[segmented.selectedSegmentIndex]
|
|
transition(toPage: page)
|
|
}
|
|
|
|
func transition(toPage page: Page) {
|
|
|
|
switch page {
|
|
case .curated:
|
|
customBlockedDomainsTableView.isHidden = true
|
|
customBlockedListsTableView.isHidden = true
|
|
curatedBlockedDomainsTableView.isHidden = false
|
|
listsLabel.isHidden = true
|
|
addNewListButton.isHidden = true
|
|
listsSubmenuView.isHidden = true
|
|
addNewDomainButton.isHidden = true
|
|
domainsLabel.isHidden = true
|
|
editDomainButton.isHidden = true
|
|
case .custom:
|
|
customBlockedListsTableView.isHidden = false
|
|
customBlockedDomainsTableView.isHidden = false
|
|
curatedBlockedDomainsTableView.isHidden = true
|
|
listsLabel.isHidden = false
|
|
addNewListButton.isHidden = false
|
|
addNewDomainButton.isHidden = false
|
|
domainsLabel.isHidden = false
|
|
editDomainButton.isHidden = false
|
|
}
|
|
}
|
|
|
|
func saveNewList(userEnteredListName: String) {
|
|
didMakeChange = true
|
|
DDLogInfo("Adding custom list - \(userEnteredListName)")
|
|
addBlockedList(listName: userEnteredListName)
|
|
reloadCustomBlockedLists()
|
|
}
|
|
|
|
func saveNewDomain(userEnteredDomainName: String) {
|
|
let validation = DomainNameValidator.validate(userEnteredDomainName)
|
|
|
|
switch validation {
|
|
case .valid:
|
|
didMakeChange = true
|
|
|
|
DDLogInfo("Adding custom domain - \(userEnteredDomainName)")
|
|
addUserBlockedDomain(domain: userEnteredDomainName.lowercased())
|
|
reloadCustomBlockedDomains()
|
|
case .notValid(let reason):
|
|
DDLogWarn("Custom domain is not valid - \(userEnteredDomainName), reason - \(reason)")
|
|
showPopupDialog(
|
|
title: NSLocalizedString("Invalid domain", comment: ""),
|
|
message: "\"\(userEnteredDomainName)\"" + NSLocalizedString(" is not a valid entry. Please only enter the host of the domain you want to block. For example, \"google.com\" without \"https://\"", comment: ""),
|
|
acceptButton: NSLocalizedString("Okay", comment: "")
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Functions
|
|
extension BlockListViewController {
|
|
|
|
func createCustomBlockedListsRows() {
|
|
let tableView = customBlockedListsTableView
|
|
let emptyList = emptyListsView
|
|
let lockedList = lockedListsView
|
|
|
|
if UserDefaults.hasSeenAdvancedPaywall || UserDefaults.hasSeenAnonymousPaywall || UserDefaults.hasSeenUniversalPaywall {
|
|
addNewListButton.isEnabled = true
|
|
if customBlockedLists.count == 0 {
|
|
tableView.addRow { (contentView) in
|
|
contentView.addSubview(emptyList)
|
|
emptyListsView.anchors.edges.pin()
|
|
}.onSelect {
|
|
self.addList()
|
|
}
|
|
}
|
|
} else {
|
|
tableView.addRow { (contentView) in
|
|
contentView.addSubview(lockedList)
|
|
lockedList.anchors.edges.pin()
|
|
}.onSelect {
|
|
let vc = VPNPaywallViewController()
|
|
self.present(vc, animated: true)
|
|
}
|
|
}
|
|
|
|
for list in customBlockedLists {
|
|
let blockListView = BlockListView()
|
|
blockListView.contents = .listsBlocked(list)
|
|
|
|
let cell = tableView.addRow { (contentView) in
|
|
contentView.addSubview(blockListView)
|
|
blockListView.anchors.edges.pin()
|
|
}.onSelect { [unowned self] in
|
|
self.didMakeChange = true
|
|
let vc = ListSettingsViewController()
|
|
vc.listName = list.name
|
|
vc.didMakeChange = list.enabled
|
|
vc.blockListVC = self
|
|
navigationController?.pushViewController(vc, animated: true)
|
|
}.onSwipeToDelete { [unowned self] in
|
|
self.didMakeChange = true
|
|
deleteList(list: list.name)
|
|
DDLogInfo("Deleting custom list - \(list.name)")
|
|
}
|
|
cell.accessoryType = .disclosureIndicator
|
|
}
|
|
}
|
|
|
|
// Custom Domains
|
|
func createCustomBlockedDomainsRows() {
|
|
let tableView = customBlockedDomainsTableView
|
|
let emptyDomains = emptyDomainsView
|
|
if customBlockedDomains.count == 0 {
|
|
tableView.addRow { (contentView) in
|
|
contentView.addSubview(emptyDomains)
|
|
emptyDomains.anchors.edges.pin()
|
|
}.onSelect { [unowned self] in
|
|
self.addDomain()
|
|
}
|
|
}
|
|
|
|
for (domain, isEnabled) in customBlockedDomains {
|
|
var currentEnabledStatus = isEnabled
|
|
let blockListView = BlockListView()
|
|
blockListView.contents = .userBlocked(domain: domain, isEnabled: isEnabled)
|
|
|
|
tableView.addRow { (contentView) in
|
|
contentView.addSubview(blockListView)
|
|
blockListView.anchors.edges.pin()
|
|
view.addSubview(editDomainButton)
|
|
editDomainButton.anchors.centerY.equal(domainsLabel.anchors.centerY)
|
|
editDomainButton.anchors.trailing.spacing(16, to: addNewDomainButton.anchors.leading)
|
|
}.onSelect { [unowned blockListView, unowned self] in
|
|
self.didMakeChange = true
|
|
currentEnabledStatus.toggle()
|
|
blockListView.contents = .userBlocked(domain: domain, isEnabled: currentEnabledStatus)
|
|
setUserBlockedDomain(domain: domain, enabled: currentEnabledStatus)
|
|
}.onSwipeToDelete { [unowned self] in
|
|
self.didMakeChange = true
|
|
deleteUserBlockedDomain(domain: domain)
|
|
DDLogInfo("Deleting custom domain - \(domain)")
|
|
}
|
|
}
|
|
}
|
|
|
|
func close() {
|
|
dismiss(animated: true, completion: { [weak self] in
|
|
guard let self else { return }
|
|
if (self.didMakeChange == true) {
|
|
if getIsCombinedBlockListEmpty() {
|
|
FirewallController.shared.setEnabled(false, isUserExplicitToggle: true)
|
|
} else if (FirewallController.shared.status() == .connected) {
|
|
FirewallController.shared.restart()
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
@objc func addList() {
|
|
|
|
let tableView = customBlockedListsTableView
|
|
|
|
let alertController = UIAlertController(title: "Create New List", message: nil, preferredStyle: .alert)
|
|
|
|
let saveAction = UIAlertAction(title: "Save", style: .default) { [weak self] (_) in
|
|
if let txtField = alertController.textFields?.first, let text = txtField.text {
|
|
guard let self else { return }
|
|
self.saveNewList(userEnteredListName: text)
|
|
// if !getBlockedLists().isEmpty {
|
|
// tableView.clear()
|
|
// }
|
|
self.reloadCustomBlockedLists()
|
|
self.listsSubmenuView.isHidden = true
|
|
}
|
|
}
|
|
|
|
saveAction.isEnabled = false
|
|
|
|
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { [weak self] (_) in
|
|
guard let self else { return }
|
|
self.listsSubmenuView.isHidden = true
|
|
}
|
|
|
|
alertController.addTextField { (textField) in
|
|
textField.placeholder = NSLocalizedString("List Name", comment: "")
|
|
}
|
|
|
|
NotificationCenter.default.addObserver(
|
|
forName: UITextField.textDidChangeNotification,
|
|
object: alertController.textFields?.first,
|
|
queue: .main) { (notification) -> Void in
|
|
guard let textFieldText = alertController.textFields?.first?.text else { return }
|
|
saveAction.isEnabled = textFieldText.isValid(.listName)
|
|
}
|
|
|
|
alertController.addAction(saveAction)
|
|
alertController.addAction(cancelAction)
|
|
present(alertController, animated: true, completion: nil)
|
|
}
|
|
|
|
func deleteList(list: String) {
|
|
|
|
let alert = UIAlertController(title: NSLocalizedString("Delete List?", comment: ""),
|
|
message: NSLocalizedString("Are you sure you want to remove this list?", comment: ""),
|
|
preferredStyle: .alert)
|
|
|
|
alert.addAction(UIAlertAction(title: NSLocalizedString("No, Return", comment: ""),
|
|
style: .default,
|
|
handler: { [weak self] (_) in
|
|
guard let self else { return }
|
|
self.reloadCustomBlockedLists()
|
|
}))
|
|
|
|
alert.addAction(UIAlertAction(title: NSLocalizedString("Yes, Delete", comment: ""),
|
|
style: .destructive,
|
|
handler: { [weak self] (_) in
|
|
guard let self else { return }
|
|
deleteBlockedList(listName: list)
|
|
self.customBlockedListsTableView.clear()
|
|
self.reloadCustomBlockedLists()
|
|
}))
|
|
|
|
present(alert, animated: true, completion: nil)
|
|
}
|
|
|
|
@objc func showSubmenu() {
|
|
listsSubmenuView.isHidden = false
|
|
}
|
|
|
|
@objc func dismissView() {
|
|
listsSubmenuView.isHidden = true
|
|
}
|
|
|
|
@objc func importBlockList() {
|
|
listsSubmenuView.isHidden = true
|
|
let vc = ImportBlockListViewController()
|
|
vc.importCompletion = { [unowned self] in
|
|
self.reloadCustomBlockedLists()
|
|
self.showSuccessImportAlert()
|
|
}
|
|
|
|
navigationController?.present(vc, animated: true)
|
|
}
|
|
|
|
@objc func addDomain() {
|
|
let tableView = customBlockedDomainsTableView
|
|
|
|
let alertController = UIAlertController(title: NSLocalizedString("Add a Domain to Block", comment: ""),
|
|
message: nil,
|
|
preferredStyle: .alert)
|
|
|
|
let saveAction = UIAlertAction(title: "Save", style: .default) { [weak self] (_) in
|
|
if let txtField = alertController.textFields?.first, let text = txtField.text {
|
|
guard let self else { return }
|
|
self.saveNewDomain(userEnteredDomainName: text)
|
|
if !getUserBlockedDomains().isEmpty {
|
|
tableView.clear()
|
|
}
|
|
|
|
self.reloadCustomBlockedDomains()
|
|
// self.editDomainButton.isHidden = false
|
|
}
|
|
}
|
|
|
|
saveAction.isEnabled = false
|
|
|
|
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel) { (_) in }
|
|
|
|
alertController.addTextField { (textField) in
|
|
textField.keyboardType = .URL
|
|
textField.placeholder = "domain-to-block"
|
|
}
|
|
|
|
NotificationCenter.default.addObserver(
|
|
forName: UITextField.textDidChangeNotification,
|
|
object: alertController.textFields?.first,
|
|
queue: .main) { (notification) -> Void in
|
|
guard let textFieldText = alertController.textFields?.first?.text else { return }
|
|
saveAction.isEnabled = textFieldText.isValid(.domainName) && !textFieldText.isEmpty
|
|
}
|
|
|
|
alertController.addAction(saveAction)
|
|
alertController.addAction(cancelAction)
|
|
present(alertController, animated: true, completion: nil)
|
|
}
|
|
|
|
@objc func editDomains() {
|
|
if !customBlockedDomains.isEmpty {
|
|
let vc = EditDomainsViewController()
|
|
vc.updateCompletion = { [weak self] in
|
|
self?.reloadCustomBlockedDomains()
|
|
}
|
|
navigationController?.pushViewController(vc, animated: true)
|
|
}
|
|
}
|
|
|
|
func showSuccessImportAlert() {
|
|
let alert = UIAlertController(title: NSLocalizedString("Success!", comment: ""),
|
|
message: NSLocalizedString("The list has been imported successfully. You can start blocking the list's domains", comment: ""),
|
|
preferredStyle: .alert)
|
|
alert.addAction(UIAlertAction(title: NSLocalizedString("Close", comment: ""),
|
|
style: .default,
|
|
handler: nil))
|
|
present(alert, animated: true, completion: nil)
|
|
}
|
|
|
|
func showErrorAlert() {
|
|
let alert = UIAlertController(title: NSLocalizedString("Error", comment: ""),
|
|
message: NSLocalizedString("Unable to import the list. Please try again or contact support for assistance", comment: ""),
|
|
preferredStyle: .alert)
|
|
alert.addAction(UIAlertAction(title: NSLocalizedString("Close", comment: ""),
|
|
style: .default,
|
|
handler: nil))
|
|
present(alert, animated: true, completion: nil)
|
|
}
|
|
}
|