Showing
40 changed files
with
610 additions
and
486 deletions
No preview for this file type
| ... | ... | @@ -3,86 +3,4 @@ |
| 3 | 3 | uuid = "7D2BF3CE-0152-4175-98D9-E41B0FA9C333" |
| 4 | 4 | type = "1" |
| 5 | 5 | version = "2.0"> |
| 6 | - <Breakpoints> | |
| 7 | - <BreakpointProxy | |
| 8 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
| 9 | - <BreakpointContent | |
| 10 | - uuid = "F889FE98-5ADA-45D9-9094-5319F398E5D0" | |
| 11 | - shouldBeEnabled = "Yes" | |
| 12 | - ignoreCount = "0" | |
| 13 | - continueAfterRunningActions = "No" | |
| 14 | - filePath = "browser/Models/HistoryToolbarMenuCases.swift" | |
| 15 | - startingColumnNumber = "9223372036854775807" | |
| 16 | - endingColumnNumber = "9223372036854775807" | |
| 17 | - startingLineNumber = "21" | |
| 18 | - endingLineNumber = "21" | |
| 19 | - landmarkName = "action" | |
| 20 | - landmarkType = "24"> | |
| 21 | - </BreakpointContent> | |
| 22 | - </BreakpointProxy> | |
| 23 | - <BreakpointProxy | |
| 24 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
| 25 | - <BreakpointContent | |
| 26 | - uuid = "AF29D2F2-0DE8-426B-B8C0-6E69F97CA3CA" | |
| 27 | - shouldBeEnabled = "No" | |
| 28 | - ignoreCount = "0" | |
| 29 | - continueAfterRunningActions = "No" | |
| 30 | - filePath = "browser/Modules/RemoveAdvert/Controller/RemoveAdvertViewController.swift" | |
| 31 | - startingColumnNumber = "9223372036854775807" | |
| 32 | - endingColumnNumber = "9223372036854775807" | |
| 33 | - startingLineNumber = "82" | |
| 34 | - endingLineNumber = "82" | |
| 35 | - landmarkName = "shieldButtonTapped(_:)" | |
| 36 | - landmarkType = "7"> | |
| 37 | - </BreakpointContent> | |
| 38 | - </BreakpointProxy> | |
| 39 | - <BreakpointProxy | |
| 40 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
| 41 | - <BreakpointContent | |
| 42 | - uuid = "2F610807-91FB-4B53-BAE6-77E3D9664161" | |
| 43 | - shouldBeEnabled = "No" | |
| 44 | - ignoreCount = "0" | |
| 45 | - continueAfterRunningActions = "No" | |
| 46 | - filePath = "browser/Modules/RemoveAdvert/Controller/RemoveAdvertViewController.swift" | |
| 47 | - startingColumnNumber = "9223372036854775807" | |
| 48 | - endingColumnNumber = "9223372036854775807" | |
| 49 | - startingLineNumber = "86" | |
| 50 | - endingLineNumber = "86" | |
| 51 | - landmarkName = "shieldButtonTapped(_:)" | |
| 52 | - landmarkType = "7"> | |
| 53 | - </BreakpointContent> | |
| 54 | - </BreakpointProxy> | |
| 55 | - <BreakpointProxy | |
| 56 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
| 57 | - <BreakpointContent | |
| 58 | - uuid = "3D9602FE-229B-4486-9E84-86F3385737CB" | |
| 59 | - shouldBeEnabled = "No" | |
| 60 | - ignoreCount = "0" | |
| 61 | - continueAfterRunningActions = "No" | |
| 62 | - filePath = "browser/Modules/Home/Controller/BrowserHomeViewController.swift" | |
| 63 | - startingColumnNumber = "9223372036854775807" | |
| 64 | - endingColumnNumber = "9223372036854775807" | |
| 65 | - startingLineNumber = "236" | |
| 66 | - endingLineNumber = "236" | |
| 67 | - landmarkName = "tabsButtonHandler()" | |
| 68 | - landmarkType = "7"> | |
| 69 | - </BreakpointContent> | |
| 70 | - </BreakpointProxy> | |
| 71 | - <BreakpointProxy | |
| 72 | - BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint"> | |
| 73 | - <BreakpointContent | |
| 74 | - uuid = "890732EB-28CC-4180-BED8-D29D0A5F9C6A" | |
| 75 | - shouldBeEnabled = "No" | |
| 76 | - ignoreCount = "0" | |
| 77 | - continueAfterRunningActions = "No" | |
| 78 | - filePath = "browser/Modules/Home/Controller/BrowserHomeViewController.swift" | |
| 79 | - startingColumnNumber = "9223372036854775807" | |
| 80 | - endingColumnNumber = "9223372036854775807" | |
| 81 | - startingLineNumber = "235" | |
| 82 | - endingLineNumber = "235" | |
| 83 | - landmarkName = "tabsButtonHandler()" | |
| 84 | - landmarkType = "7"> | |
| 85 | - </BreakpointContent> | |
| 86 | - </BreakpointProxy> | |
| 87 | - </Breakpoints> | |
| 88 | 6 | </Bucket> | ... | ... |
| ... | ... | @@ -13,29 +13,31 @@ enum menuCases: CaseIterable { |
| 13 | 13 | case todayAndYesterday |
| 14 | 14 | case today |
| 15 | 15 | case lastHour |
| 16 | - //MARK: todo | |
| 17 | 16 | var action: UIAction { |
| 18 | 17 | switch self { |
| 19 | 18 | case .allTime: |
| 20 | 19 | return UIAction(title: "All time") { _ in |
| 21 | 20 | HistoryDBManager.shared.cleanHistory() |
| 22 | - | |
| 23 | 21 | } |
| 22 | + | |
| 24 | 23 | case .lastMonth: |
| 25 | 24 | return UIAction(title: "The last 30 days") { _ in |
| 26 | 25 | let lastMonth = Calendar.current.date(byAdding: .day, value: -30, to: Date()) ?? Date() |
| 27 | 26 | HistoryDBManager.shared.deleteHistoryInRange(startDate: lastMonth) |
| 28 | 27 | } |
| 28 | + | |
| 29 | 29 | case .todayAndYesterday: |
| 30 | 30 | return UIAction(title: "Today and yesterday") { _ in |
| 31 | 31 | let yesterday = Calendar.current.date(byAdding: .day, value: -1, to: Date()) ?? Date() |
| 32 | 32 | HistoryDBManager.shared.deleteHistoryInRange(startDate: yesterday) |
| 33 | 33 | } |
| 34 | + | |
| 34 | 35 | case .today: |
| 35 | 36 | return UIAction(title: "Today") { _ in |
| 36 | 37 | let startOfToday = Calendar.current.startOfDay(for: Date()) |
| 37 | 38 | HistoryDBManager.shared.deleteHistoryInRange(startDate: startOfToday) |
| 38 | 39 | } |
| 40 | + | |
| 39 | 41 | case .lastHour: |
| 40 | 42 | return UIAction(title: "The last hour") { _ in |
| 41 | 43 | let lastHour = Calendar.current.date(byAdding: .hour, value: -1, to: Date()) ?? Date() | ... | ... |
| ... | ... | @@ -4,13 +4,12 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 29.09.2023. |
| 6 | 6 | // |
| 7 | - | |
| 7 | +//MARK: Checked | |
| 8 | 8 | import UIKit |
| 9 | 9 | import RealmSwift |
| 10 | 10 | |
| 11 | 11 | final class HistoryViewController: UIViewController { |
| 12 | 12 | private let mainView = HistoryView() |
| 13 | - | |
| 14 | 13 | private var objectNotificationToken: NotificationToken? |
| 15 | 14 | |
| 16 | 15 | private var historyData: [HistoryElement] = [] { |
| ... | ... | @@ -18,6 +17,7 @@ final class HistoryViewController: UIViewController { |
| 18 | 17 | filteredData = historyData |
| 19 | 18 | } |
| 20 | 19 | } |
| 20 | + | |
| 21 | 21 | private var filteredData: [HistoryElement] = [] { |
| 22 | 22 | didSet { |
| 23 | 23 | mainView.historyTabsTableView.reloadData() |
| ... | ... | @@ -26,12 +26,14 @@ final class HistoryViewController: UIViewController { |
| 26 | 26 | |
| 27 | 27 | override func viewWillAppear(_ animated: Bool) { |
| 28 | 28 | super.viewWillAppear(animated) |
| 29 | + | |
| 29 | 30 | navigationController?.isNavigationBarHidden = false |
| 30 | 31 | navigationItem.title = "History" |
| 31 | 32 | } |
| 32 | 33 | |
| 33 | 34 | override func viewDidLoad() { |
| 34 | 35 | super.viewDidLoad() |
| 36 | + | |
| 35 | 37 | initViewController() |
| 36 | 38 | } |
| 37 | 39 | |
| ... | ... | @@ -39,20 +41,21 @@ final class HistoryViewController: UIViewController { |
| 39 | 41 | setupTableView() |
| 40 | 42 | addTargets() |
| 41 | 43 | setupSearchBar() |
| 42 | - historyData = HistoryDBManager.shared.getHistoryDataForTableView() | |
| 43 | 44 | historyChangesObserve() |
| 44 | 45 | } |
| 45 | 46 | |
| 46 | 47 | override func loadView() { |
| 47 | 48 | view = mainView |
| 48 | 49 | view.backgroundColor = .white |
| 50 | + | |
| 49 | 51 | navigationController?.isNavigationBarHidden = false |
| 50 | 52 | navigationItem.title = "History" |
| 51 | - // historyChangesObserve() | |
| 52 | 53 | } |
| 53 | 54 | |
| 54 | 55 | init() { |
| 55 | 56 | super.init(nibName: nil, bundle: nil) |
| 57 | + | |
| 58 | + historyData = HistoryDBManager.shared.getHistoryDataForTableView() | |
| 56 | 59 | } |
| 57 | 60 | |
| 58 | 61 | required init?(coder: NSCoder) { |
| ... | ... | @@ -76,8 +79,8 @@ extension HistoryViewController: UITableViewDelegate, UITableViewDataSource { |
| 76 | 79 | } |
| 77 | 80 | |
| 78 | 81 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
| 79 | - guard let cell = tableView.dequeueReusableCell(withIdentifier: "HistoryTableViewCell", for: indexPath) as? HistoryTableViewCell else { | |
| 80 | - return HistoryTableViewCell() | |
| 82 | + guard let cell = tableView.dequeueReusableCell(withIdentifier: HistoryTableViewCell.tabID, for: indexPath) as? HistoryTableViewCell else { | |
| 83 | + return UITableViewCell() | |
| 81 | 84 | } |
| 82 | 85 | let row = indexPath.row |
| 83 | 86 | let section = indexPath.section |
| ... | ... | @@ -97,6 +100,7 @@ extension HistoryViewController: UITableViewDelegate, UITableViewDataSource { |
| 97 | 100 | let section = indexPath.section |
| 98 | 101 | let historyCellData = filteredData[section].stories[row] |
| 99 | 102 | let tabId = historyCellData.historyCellId |
| 103 | + | |
| 100 | 104 | HistoryDBManager.shared.deleteHistoryCell(tabId: tabId) |
| 101 | 105 | filteredData[section].stories.remove(at: row) |
| 102 | 106 | mainView.historyTabsTableView.reloadData() |
| ... | ... | @@ -107,6 +111,7 @@ extension HistoryViewController: UITableViewDelegate, UITableViewDataSource { |
| 107 | 111 | let section = indexPath.section |
| 108 | 112 | let index = indexPath.row |
| 109 | 113 | let urlForFunc = historyData[section].stories[index].siteUrl |
| 114 | + | |
| 110 | 115 | if let navigationController = presentingViewController as? NavigationViewController { |
| 111 | 116 | for viewController in navigationController.viewControllers { |
| 112 | 117 | if let browserHomeViewController = viewController as? BrowserHomeViewController { |
| ... | ... | @@ -116,16 +121,9 @@ extension HistoryViewController: UITableViewDelegate, UITableViewDataSource { |
| 116 | 121 | dismiss(animated: true) |
| 117 | 122 | } |
| 118 | 123 | } |
| 119 | - | |
| 120 | - func setupTableView() { | |
| 121 | - mainView.historyTabsTableView.dataSource = self | |
| 122 | - mainView.historyTabsTableView.delegate = self | |
| 123 | - mainView.historyTabsTableView.register(HistoryTableViewCell.self, forCellReuseIdentifier: StringConstants.historyTableViewCell) | |
| 124 | - } | |
| 125 | 124 | } |
| 126 | 125 | |
| 127 | 126 | |
| 128 | - | |
| 129 | 127 | //MARK: Helper |
| 130 | 128 | extension HistoryViewController { |
| 131 | 129 | private func addTargets() { |
| ... | ... | @@ -136,12 +134,18 @@ extension HistoryViewController { |
| 136 | 134 | private func addToolbarTargets() { |
| 137 | 135 | mainView.historyToolbarView.action = didTabButtonTapped |
| 138 | 136 | } |
| 137 | + | |
| 138 | + private func setupTableView() { | |
| 139 | + mainView.historyTabsTableView.dataSource = self | |
| 140 | + mainView.historyTabsTableView.delegate = self | |
| 141 | + mainView.historyTabsTableView.register(HistoryTableViewCell.self, forCellReuseIdentifier: HistoryTableViewCell.tabID) | |
| 142 | + } | |
| 139 | 143 | } |
| 140 | 144 | |
| 141 | 145 | |
| 142 | 146 | //MARK: Targets |
| 143 | 147 | extension HistoryViewController { |
| 144 | - func didTabButtonTapped(type: historyToolbarElementType) { | |
| 148 | + private func didTabButtonTapped(type: historyToolbarElementType) { | |
| 145 | 149 | if type == .clean { |
| 146 | 150 | HistoryDBManager.shared.cleanHistory() |
| 147 | 151 | historyData.removeAll() |
| ... | ... | @@ -159,7 +163,8 @@ extension HistoryViewController { |
| 159 | 163 | filteredData = historyData |
| 160 | 164 | } |
| 161 | 165 | |
| 162 | - @objc private func searchBarTextChanged() { | |
| 166 | + @objc | |
| 167 | + private func searchBarTextChanged() { | |
| 163 | 168 | if let text = mainView.historySearchBar.searchTextFieldView.text { |
| 164 | 169 | if text.isEmpty { |
| 165 | 170 | filteredData = historyData |
| ... | ... | @@ -178,14 +183,14 @@ extension HistoryViewController: UITextFieldDelegate { |
| 178 | 183 | mainView.historySearchBar.searchTextFieldView.textColor = .black |
| 179 | 184 | } |
| 180 | 185 | |
| 181 | - func setupSearchBar() { | |
| 186 | + private func setupSearchBar() { | |
| 182 | 187 | mainView.historySearchBar.searchTextFieldView.delegate = self |
| 183 | 188 | } |
| 184 | 189 | } |
| 185 | 190 | |
| 186 | 191 | //MARK: History DB observe |
| 187 | 192 | extension HistoryViewController { |
| 188 | - func historyChangesObserve() { | |
| 193 | + private func historyChangesObserve() { | |
| 189 | 194 | let historyObjects = HistoryDBManager.shared.getHistory() |
| 190 | 195 | for historyObject in historyObjects { |
| 191 | 196 | objectNotificationToken = historyObject.observe { [self] changes in |
| ... | ... | @@ -195,7 +200,6 @@ extension HistoryViewController { |
| 195 | 200 | case .change(_, _): |
| 196 | 201 | break |
| 197 | 202 | case .deleted: |
| 198 | - print("Object deleted in Realm") | |
| 199 | 203 | self.historyData = HistoryDBManager.shared.getHistoryDataForTableView() |
| 200 | 204 | self.mainView.historyTabsTableView.reloadData() |
| 201 | 205 | } | ... | ... |
| ... | ... | @@ -4,18 +4,21 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 29.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | import SnapKit |
| 10 | 11 | |
| 11 | -class HistoryTableViewCell: UITableViewCell { | |
| 12 | +final class HistoryTableViewCell: UITableViewCell { | |
| 13 | + static let tabID = String(describing: HistoryTableViewCell.self) | |
| 14 | + | |
| 12 | 15 | var model: HistoryDataBase? { |
| 13 | 16 | didSet { |
| 14 | 17 | handleUI() |
| 15 | 18 | } |
| 16 | 19 | } |
| 17 | 20 | |
| 18 | - let searchImageLogo: UIImageView = { | |
| 21 | + private let searchImageLogo: UIImageView = { | |
| 19 | 22 | let obj = UIImageView() |
| 20 | 23 | obj.image = UIImage(systemName: "magnifyingglass") |
| 21 | 24 | obj.tintColor = .gray |
| ... | ... | @@ -23,20 +26,20 @@ class HistoryTableViewCell: UITableViewCell { |
| 23 | 26 | return obj |
| 24 | 27 | }() |
| 25 | 28 | |
| 26 | - let lastVisitSiteLabel: UILabel = { | |
| 29 | + private let lastVisitSiteLabel: UILabel = { | |
| 27 | 30 | let obj = UILabel() |
| 28 | 31 | obj.font = FontConstants.regularFont_14 |
| 29 | 32 | return obj |
| 30 | 33 | }() |
| 31 | 34 | |
| 32 | - let lastVisitSiteUrlLabel: UILabel = { | |
| 35 | + private let lastVisitSiteUrlLabel: UILabel = { | |
| 33 | 36 | let obj = UILabel() |
| 34 | 37 | obj.textColor = .gray |
| 35 | 38 | obj.font = FontConstants.regularFont_12 |
| 36 | 39 | return obj |
| 37 | 40 | }() |
| 38 | 41 | |
| 39 | - let lastVisitDateLabel: UILabel = { | |
| 42 | + private let lastVisitDateLabel: UILabel = { | |
| 40 | 43 | let obj = UILabel() |
| 41 | 44 | obj.font = FontConstants.regularFont_12 |
| 42 | 45 | obj.textColor = .gray |
| ... | ... | @@ -45,6 +48,7 @@ class HistoryTableViewCell: UITableViewCell { |
| 45 | 48 | |
| 46 | 49 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
| 47 | 50 | super.init(style: style, reuseIdentifier: reuseIdentifier) |
| 51 | + | |
| 48 | 52 | setup() |
| 49 | 53 | } |
| 50 | 54 | |
| ... | ... | @@ -57,6 +61,7 @@ class HistoryTableViewCell: UITableViewCell { |
| 57 | 61 | contentView.addSubview(lastVisitSiteLabel) |
| 58 | 62 | contentView.addSubview(lastVisitSiteUrlLabel) |
| 59 | 63 | contentView.addSubview(lastVisitDateLabel) |
| 64 | + | |
| 60 | 65 | setupConstraints() |
| 61 | 66 | } |
| 62 | 67 | |
| ... | ... | @@ -67,15 +72,18 @@ class HistoryTableViewCell: UITableViewCell { |
| 67 | 72 | make.height.equalTo(18.sizeW) |
| 68 | 73 | make.width.equalTo(18.sizeW) |
| 69 | 74 | } |
| 75 | + | |
| 70 | 76 | lastVisitSiteLabel.snp.makeConstraints { make in |
| 71 | 77 | make.leading.equalTo(searchImageLogo.snp.trailing).offset(8.sizeW) |
| 72 | 78 | make.trailing.equalTo(lastVisitDateLabel.snp.leading).offset(-8.sizeW) |
| 73 | 79 | make.top.equalToSuperview().inset(8.sizeH) |
| 74 | 80 | } |
| 81 | + | |
| 75 | 82 | lastVisitDateLabel.snp.makeConstraints { make in |
| 76 | 83 | make.trailing.equalToSuperview().inset(8.sizeW) |
| 77 | 84 | make.top.equalToSuperview().inset(8.sizeH) |
| 78 | 85 | } |
| 86 | + | |
| 79 | 87 | lastVisitSiteUrlLabel.snp.makeConstraints { make in |
| 80 | 88 | make.leading.equalToSuperview().offset(34.sizeW) |
| 81 | 89 | make.top.equalTo(lastVisitSiteLabel.snp.bottom).offset(4.sizeH) |
| ... | ... | @@ -88,6 +96,7 @@ class HistoryTableViewCell: UITableViewCell { |
| 88 | 96 | extension HistoryTableViewCell { |
| 89 | 97 | private func handleUI() { |
| 90 | 98 | let dateForLabel = DateManager.shared.getTimeFromDB(model?.lastVisit) |
| 99 | + | |
| 91 | 100 | lastVisitDateLabel.text = dateForLabel |
| 92 | 101 | lastVisitSiteLabel.text = model?.siteTitle |
| 93 | 102 | lastVisitSiteUrlLabel.text = model?.siteUrl | ... | ... |
| ... | ... | @@ -4,11 +4,12 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 01.10.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | 11 | final class HistorySearchBarView: UIView { |
| 11 | - let searchImageView: UIImageView = { | |
| 12 | + private let searchImageView: UIImageView = { | |
| 12 | 13 | let obj = UIImageView() |
| 13 | 14 | let magnifyImage = UIImage(systemName: "magnifyingglass")?.withTintColor(.gray, renderingMode: .alwaysOriginal) |
| 14 | 15 | obj.image = magnifyImage |
| ... | ... | @@ -25,17 +26,19 @@ final class HistorySearchBarView: UIView { |
| 25 | 26 | |
| 26 | 27 | override init(frame: CGRect) { |
| 27 | 28 | super.init(frame: frame) |
| 28 | - setup() | |
| 29 | - setupConstraints() | |
| 29 | + | |
| 30 | + setupUI() | |
| 30 | 31 | } |
| 31 | 32 | |
| 32 | 33 | required init?(coder: NSCoder) { |
| 33 | 34 | fatalError("init(coder:) has not been implemented") |
| 34 | 35 | } |
| 35 | 36 | |
| 36 | - private func setup() { | |
| 37 | + private func setupUI() { | |
| 37 | 38 | addSubview(searchImageView) |
| 38 | 39 | addSubview(searchTextFieldView) |
| 40 | + | |
| 41 | + setupConstraints() | |
| 39 | 42 | } |
| 40 | 43 | |
| 41 | 44 | private func setupConstraints() { | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 29.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| ... | ... | @@ -14,7 +15,7 @@ enum historyToolbarElementType { |
| 14 | 15 | final class HistoryToolbarView: UIView { |
| 15 | 16 | var action: ((historyToolbarElementType) -> Void)? |
| 16 | 17 | |
| 17 | - let cleanHistoryButton: UIButton = { | |
| 18 | + private let cleanHistoryButton: UIButton = { | |
| 18 | 19 | let obj = UIButton() |
| 19 | 20 | obj.setTitle("Clean", for: .normal) |
| 20 | 21 | obj.setTitleColor(.systemBlue, for: .normal) |
| ... | ... | @@ -26,17 +27,18 @@ final class HistoryToolbarView: UIView { |
| 26 | 27 | |
| 27 | 28 | override init(frame: CGRect) { |
| 28 | 29 | super.init(frame: frame) |
| 29 | - setup() | |
| 30 | - setupConstraints() | |
| 30 | + setupUI() | |
| 31 | 31 | } |
| 32 | 32 | |
| 33 | 33 | required init?(coder: NSCoder) { |
| 34 | 34 | fatalError("init(coder:) has not been implemented") |
| 35 | 35 | } |
| 36 | 36 | |
| 37 | - private func setup() { | |
| 37 | + private func setupUI() { | |
| 38 | 38 | backgroundColor = .white |
| 39 | + | |
| 39 | 40 | addSubview(cleanHistoryButton) |
| 41 | + setupConstraints() | |
| 40 | 42 | } |
| 41 | 43 | |
| 42 | 44 | private func setupConstraints() { | ... | ... |
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 29.09.2023. |
| 6 | 6 | // |
| 7 | - | |
| 7 | +//MARK: Checked | |
| 8 | 8 | import UIKit |
| 9 | 9 | |
| 10 | 10 | final class HistoryView: UIView { |
| ... | ... | @@ -28,15 +28,16 @@ final class HistoryView: UIView { |
| 28 | 28 | |
| 29 | 29 | override init(frame: CGRect) { |
| 30 | 30 | super.init(frame: frame) |
| 31 | - setup() | |
| 31 | + setupUI() | |
| 32 | 32 | } |
| 33 | 33 | |
| 34 | 34 | required init?(coder: NSCoder) { |
| 35 | 35 | fatalError("init(coder:) has not been implemented") |
| 36 | 36 | } |
| 37 | 37 | |
| 38 | - private func setup() { | |
| 38 | + private func setupUI() { | |
| 39 | 39 | backgroundColor = .gray.withAlphaComponent(0.1) |
| 40 | + | |
| 40 | 41 | addSubview(historySearchBar) |
| 41 | 42 | addSubview(historyTabsTableView) |
| 42 | 43 | addSubview(historyToolbarView) |
| ... | ... | @@ -51,13 +52,14 @@ final class HistoryView: UIView { |
| 51 | 52 | |
| 52 | 53 | historyTabsTableView.snp.makeConstraints { make in |
| 53 | 54 | make.top.equalTo(historySearchBar.snp.bottom).offset(32.sizeH) |
| 54 | - make.bottom.equalTo(historyToolbarView.snp.top).inset(7.sizeH) | |
| 55 | 55 | make.leading.trailing.equalToSuperview().inset(16.sizeW) |
| 56 | + make.bottom.equalTo(historyToolbarView.snp.top).inset(7.sizeH) | |
| 56 | 57 | make.height.equalTo(600.sizeH) |
| 57 | 58 | } |
| 59 | + | |
| 58 | 60 | historyToolbarView.snp.makeConstraints { make in |
| 59 | - make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom) | |
| 60 | 61 | make.leading.trailing.equalToSuperview() |
| 62 | + make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom) | |
| 61 | 63 | } |
| 62 | 64 | } |
| 63 | 65 | } | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 25.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | import SnapKit |
| ... | ... | @@ -12,19 +13,20 @@ import Combine |
| 12 | 13 | import Realm |
| 13 | 14 | |
| 14 | 15 | final class BrowserHomeViewController: UIViewController { |
| 16 | + let mainView = BrowserHomeView() | |
| 17 | + | |
| 18 | + private let searchingViewController: SearchingViewController | |
| 19 | + private let searchResultViewController: SearchResultViewController | |
| 20 | + private let tabsViewController: TabsViewController | |
| 21 | + | |
| 22 | + private var subscriptions: Set<AnyCancellable> | |
| 23 | + private var searchRequestURL: String | |
| 15 | 24 | private let images = StringConstants.browserHomeVCImages |
| 16 | - private let searchingViewController = SearchingViewController(dataForReq: []) | |
| 17 | - private let searchResultViewController = SearchResultViewController(searchLink: String()) | |
| 18 | - private var subscriptions: Set<AnyCancellable> = [] | |
| 19 | - private var finalSearchRequest = URLConstants.googleURL | |
| 20 | - private let tabsViewController = TabsViewController() | |
| 21 | 25 | private var currentTabId: Int? |
| 22 | 26 | |
| 23 | - let mainView = BrowserHomeView() | |
| 24 | - | |
| 25 | 27 | private var url: String? { |
| 26 | 28 | didSet { |
| 27 | - finalSearchRequest = url ?? String() | |
| 29 | + searchRequestURL = url ?? String() | |
| 28 | 30 | openSearchResult() |
| 29 | 31 | } |
| 30 | 32 | } |
| ... | ... | @@ -32,6 +34,7 @@ final class BrowserHomeViewController: UIViewController { |
| 32 | 34 | override func viewDidLoad() { |
| 33 | 35 | super.viewDidLoad() |
| 34 | 36 | view.backgroundColor = ColorConstants.lightGray |
| 37 | + | |
| 35 | 38 | initViewController() |
| 36 | 39 | } |
| 37 | 40 | |
| ... | ... | @@ -56,6 +59,13 @@ final class BrowserHomeViewController: UIViewController { |
| 56 | 59 | } |
| 57 | 60 | |
| 58 | 61 | init(url: String?, currentTabId: Int?) { |
| 62 | + searchResultViewController = SearchResultViewController(searchLink: String()) | |
| 63 | + searchingViewController = SearchingViewController(dataForReq: []) | |
| 64 | + tabsViewController = TabsViewController() | |
| 65 | + | |
| 66 | + subscriptions = [] | |
| 67 | + searchRequestURL = URLConstants.googleURL | |
| 68 | + | |
| 59 | 69 | super.init(nibName: nil, bundle: nil) |
| 60 | 70 | self.url = url |
| 61 | 71 | self.currentTabId = currentTabId |
| ... | ... | @@ -79,41 +89,36 @@ extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionVie |
| 79 | 89 | } |
| 80 | 90 | |
| 81 | 91 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { |
| 82 | - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TabCollectionViewCell", for: indexPath) as? TabCollectionViewCell else { | |
| 92 | + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TabCollectionViewCell.cellID, for: indexPath) as? TabCollectionViewCell else { | |
| 83 | 93 | return TabCollectionViewCell() |
| 84 | 94 | } |
| 85 | 95 | let finalCell = setupCellForCollectionView(cell, indexPath) |
| 96 | + | |
| 86 | 97 | return finalCell |
| 87 | 98 | } |
| 88 | 99 | |
| 89 | - private func setupCellForCollectionView(_ cell: TabCollectionViewCell, _ indexPath: IndexPath) -> TabCollectionViewCell { | |
| 100 | + func setupCellForCollectionView(_ cell: TabCollectionViewCell, _ indexPath: IndexPath) -> TabCollectionViewCell { | |
| 90 | 101 | let imageName = images[indexPath.item] |
| 91 | 102 | cell.tabCellImage.image = UIImage(named: imageName) |
| 92 | 103 | cell.tabCellLabel.text = imageName |
| 93 | - cell.backgroundColor = .white | |
| 104 | + | |
| 94 | 105 | return cell |
| 95 | 106 | } |
| 96 | 107 | |
| 97 | 108 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { |
| 98 | - return CGSize(width: 72.sizeW, height: 94.sizeH) | |
| 109 | + return CGSize(width: 72.sizeW, height: 104.sizeH) | |
| 99 | 110 | } |
| 100 | 111 | |
| 101 | 112 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { |
| 102 | - finalSearchRequest = StringConstants.browserHomeVCurl[indexPath.row] | |
| 113 | + searchRequestURL = StringConstants.browserHomeVCurl[indexPath.row] | |
| 103 | 114 | openSearchResult() |
| 104 | 115 | } |
| 105 | - | |
| 106 | - private func setupCollectionView() { | |
| 107 | - mainView.frequentlyVisitedCollectionView.dataSource = self | |
| 108 | - mainView.frequentlyVisitedCollectionView.delegate = self | |
| 109 | - mainView.frequentlyVisitedCollectionView.register(TabCollectionViewCell.self, forCellWithReuseIdentifier: "TabCollectionViewCell") | |
| 110 | - } | |
| 111 | 116 | } |
| 112 | 117 | |
| 113 | 118 | |
| 114 | 119 | //MARK: - Keyboard extention |
| 115 | 120 | extension BrowserHomeViewController { |
| 116 | - func keyboardObserver() { | |
| 121 | + private func keyboardObserver() { | |
| 117 | 122 | NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear), name: UIResponder.keyboardWillHideNotification, object: nil) |
| 118 | 123 | NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil) |
| 119 | 124 | } |
| ... | ... | @@ -122,29 +127,39 @@ extension BrowserHomeViewController { |
| 122 | 127 | |
| 123 | 128 | //MARK: - Action |
| 124 | 129 | extension BrowserHomeViewController { |
| 125 | - @objc private func searchResultAction() { | |
| 126 | - removeChildViewController() | |
| 127 | - mainView.searchBarContainer.searchBarView.searchTextFieldView.text = nil | |
| 128 | - mainView.searchBarContainer.searchBarView.cleanTextFieldButton.isHidden = true | |
| 130 | + @objc | |
| 131 | + private func searchBarTextChanged() { | |
| 132 | + if let text = mainView.searchBarContainer.searchBarView.searchTextFieldView.text { | |
| 133 | + searchRequestURL = text | |
| 134 | + mainView.searchBarContainer.searchBarView.cleanTextFieldButton.isHidden = false | |
| 135 | + if searchRequestURL.isEmpty { | |
| 136 | + searchResultAction() | |
| 137 | + } else { | |
| 138 | + Task { | |
| 139 | + await searchAndReloadTableView() | |
| 140 | + } | |
| 141 | + } | |
| 142 | + } | |
| 129 | 143 | } |
| 130 | 144 | |
| 131 | - func searchAndReloadTableView() async { | |
| 132 | - let sitesFromSearch: [String] = await BrowserSearchService().searchSuggest(finalSearchRequest) | |
| 133 | - if !sitesFromSearch.isEmpty { | |
| 134 | - searchingViewController.dataForReq = sitesFromSearch | |
| 135 | - } | |
| 136 | - addingSearchingViewController(searchingViewController) | |
| 145 | + @objc | |
| 146 | + private func searchResultAction() { | |
| 147 | + mainView.searchBarContainer.searchBarView.searchTextFieldView.text = nil | |
| 148 | + mainView.searchBarContainer.searchBarView.cleanTextFieldButton.isHidden = true | |
| 149 | + | |
| 150 | + removeChildViewController() | |
| 137 | 151 | } |
| 138 | 152 | |
| 139 | 153 | @objc |
| 140 | - func keyboardWillShow(_ notification: Notification) { | |
| 141 | - guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } | |
| 154 | + private func keyboardWillShow(_ notification: Notification) { | |
| 155 | + guard let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return | |
| 156 | + } | |
| 142 | 157 | let keyboardHeight = keyboardFrame.height |
| 143 | 158 | self.mainView.animateSearchBar(keyboardHeight) |
| 144 | 159 | } |
| 145 | 160 | |
| 146 | 161 | @objc |
| 147 | - func keyboardWillDisappear() { | |
| 162 | + private func keyboardWillDisappear() { | |
| 148 | 163 | mainView.animateSearchBarDismiss() |
| 149 | 164 | } |
| 150 | 165 | |
| ... | ... | @@ -164,8 +179,12 @@ extension BrowserHomeViewController { |
| 164 | 179 | private func removeSearchingViewController(_ sender: UIButton) { |
| 165 | 180 | searchResultAction() |
| 166 | 181 | } |
| 167 | - | |
| 168 | - func didTabButtonTapped(type: ToolbarElementType) { | |
| 182 | +} | |
| 183 | + | |
| 184 | + | |
| 185 | +//MARK: - Helpers | |
| 186 | +extension BrowserHomeViewController { | |
| 187 | + private func didTabButtonTapped(type: ToolbarElementType) { | |
| 169 | 188 | switch type { |
| 170 | 189 | case .history: |
| 171 | 190 | let historyViewController = HistoryViewController() |
| ... | ... | @@ -181,17 +200,27 @@ extension BrowserHomeViewController { |
| 181 | 200 | searchResultViewController.mainView.searchResultView.goForward() |
| 182 | 201 | break |
| 183 | 202 | case .share: |
| 184 | - let items = [URL(string: finalSearchRequest)] | |
| 203 | + let items = [URL(string: searchRequestURL)] | |
| 185 | 204 | let shareView = UIActivityViewController(activityItems: items as [Any], applicationActivities: nil) |
| 186 | 205 | present(shareView, animated: true) |
| 187 | 206 | break |
| 188 | 207 | } |
| 189 | 208 | } |
| 190 | -} | |
| 191 | - | |
| 192 | - | |
| 193 | -//MARK: - Helpers | |
| 194 | -extension BrowserHomeViewController { | |
| 209 | + | |
| 210 | + private func searchAndReloadTableView() async { | |
| 211 | + let sitesFromSearch: [String] = await BrowserSearchService().searchSuggest(searchRequestURL) | |
| 212 | + if !sitesFromSearch.isEmpty { | |
| 213 | + searchingViewController.searchRequestData = sitesFromSearch | |
| 214 | + } | |
| 215 | + addingSearchingViewController(searchingViewController) | |
| 216 | + } | |
| 217 | + | |
| 218 | + private func setupCollectionView() { | |
| 219 | + mainView.frequentlyVisitedCollectionView.dataSource = self | |
| 220 | + mainView.frequentlyVisitedCollectionView.delegate = self | |
| 221 | + mainView.frequentlyVisitedCollectionView.register(TabCollectionViewCell.self, forCellWithReuseIdentifier: TabCollectionViewCell.cellID) | |
| 222 | + } | |
| 223 | + | |
| 195 | 224 | private func addTargets() { |
| 196 | 225 | mainView.settingButton.addTarget(self, action: #selector(settingButtonTapped(_ :)), for: .touchUpInside) |
| 197 | 226 | mainView.removeAddButton.addTarget(self, action: #selector(removeAdButtonTapped(_ :)), for: .touchUpInside) |
| ... | ... | @@ -214,23 +243,22 @@ extension BrowserHomeViewController { |
| 214 | 243 | guard let cell = cell as? SearchingTableViewCell else { |
| 215 | 244 | return |
| 216 | 245 | } |
| 217 | - finalSearchRequest = "https://www.google.com/search?q=" + (cell.searchLabel.text ?? "") | |
| 246 | + searchRequestURL = "https://www.google.com/search?q=" + (cell.searchLabel.text ?? "") | |
| 218 | 247 | openSearchResult() |
| 219 | 248 | mainView.searchBarContainer.searchBarView.searchTextFieldView.endEditing(true) |
| 220 | 249 | } |
| 221 | 250 | } |
| 222 | 251 | |
| 223 | 252 | private func openSearchResult() { |
| 224 | - let finalSearchRequest = finalSearchRequest.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) | |
| 253 | + let finalSearchRequest = searchRequestURL.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) | |
| 225 | 254 | searchResultViewController.searchLink = finalSearchRequest ?? "" |
| 226 | 255 | if let localUrl = URL(string: finalSearchRequest ?? "") { |
| 227 | 256 | let request = URLRequest(url: localUrl) |
| 228 | - print(request) | |
| 229 | 257 | searchResultViewController.mainView.searchResultView.load(request) |
| 230 | 258 | } |
| 231 | 259 | addingSearchingViewController(searchResultViewController) |
| 232 | 260 | } |
| 233 | - | |
| 261 | + | |
| 234 | 262 | private func tabsButtonHandler() { |
| 235 | 263 | if currentTabId == nil { |
| 236 | 264 | addNewTab() |
| ... | ... | @@ -263,36 +291,36 @@ extension BrowserHomeViewController { |
| 263 | 291 | } |
| 264 | 292 | } |
| 265 | 293 | |
| 266 | - private func updateCurrentTab() { | |
| 267 | - let allTabs = TabManager.shared.getAllTabs() | |
| 268 | - let chosenTab = allTabs[self.currentTabId ?? Int()] | |
| 269 | - let gottedCellId = chosenTab.tabId | |
| 270 | - let imageForUpdatedTab = SnapshotService.shared.makeSnapshot(self.mainView) | |
| 271 | - if let childViewController = self.children.first as? SearchResultViewController { | |
| 272 | - guard let siteTitle = childViewController.mainView.searchResultView.title else { | |
| 273 | - return | |
| 274 | - } | |
| 275 | - guard let siteUrl = childViewController.mainView.searchResultView.url?.absoluteString else { | |
| 276 | - return | |
| 277 | - } | |
| 278 | - let lastDate = DateManager.shared.currentDate | |
| 279 | - | |
| 280 | - TabManager.shared.updateTab(tabId: gottedCellId, newTabTitle: siteTitle, newSnapshotImage: imageForUpdatedTab, newTabUrl: siteUrl) { result in | |
| 281 | - self.navigationController?.popViewController(animated: true) | |
| 282 | - } | |
| 283 | - HistoryDBManager.shared.saveToHistory(siteTitle: siteTitle, siteUrl: siteUrl, lastVisit: lastDate) | |
| 284 | - } else { | |
| 285 | - TabManager.shared.updateTab(tabId: gottedCellId, newTabTitle: "Start Page", newSnapshotImage: imageForUpdatedTab, newTabUrl: "homeUrl") { result in | |
| 286 | - self.navigationController?.popViewController(animated: true) | |
| 287 | - } | |
| 288 | - } | |
| 289 | - } | |
| 294 | + private func updateCurrentTab() { | |
| 295 | + let allTabs = TabManager.shared.getAllTabs() | |
| 296 | + let chosenTab = allTabs[self.currentTabId ?? Int()] | |
| 297 | + let gottedCellId = chosenTab.tabId | |
| 298 | + let imageForUpdatedTab = SnapshotService.shared.makeSnapshot(self.mainView) | |
| 299 | + if let childViewController = self.children.first as? SearchResultViewController { | |
| 300 | + guard let siteTitle = childViewController.mainView.searchResultView.title else { | |
| 301 | + return | |
| 302 | + } | |
| 303 | + guard let siteUrl = childViewController.mainView.searchResultView.url?.absoluteString else { | |
| 304 | + return | |
| 305 | + } | |
| 306 | + let lastDate = DateManager.shared.currentDate | |
| 307 | + | |
| 308 | + TabManager.shared.updateTab(tabId: gottedCellId, newTabTitle: siteTitle, newSnapshotImage: imageForUpdatedTab, newTabUrl: siteUrl) { result in | |
| 309 | + self.navigationController?.popViewController(animated: true) | |
| 310 | + } | |
| 311 | + HistoryDBManager.shared.saveToHistory(siteTitle: siteTitle, siteUrl: siteUrl, lastVisit: lastDate) | |
| 312 | + } else { | |
| 313 | + TabManager.shared.updateTab(tabId: gottedCellId, newTabTitle: "Start Page", newSnapshotImage: imageForUpdatedTab, newTabUrl: "homeUrl") { result in | |
| 314 | + self.navigationController?.popViewController(animated: true) | |
| 315 | + } | |
| 316 | + } | |
| 317 | + } | |
| 290 | 318 | } |
| 291 | 319 | |
| 292 | 320 | |
| 293 | 321 | //MARK: - ChildVC actions |
| 294 | 322 | extension BrowserHomeViewController { |
| 295 | - func addingSearchingViewController(_ childViewController: UIViewController) { | |
| 323 | + private func addingSearchingViewController(_ childViewController: UIViewController) { | |
| 296 | 324 | if self.children.isEmpty { |
| 297 | 325 | addNewChildViewController(childViewController) |
| 298 | 326 | } else { |
| ... | ... | @@ -301,13 +329,14 @@ extension BrowserHomeViewController { |
| 301 | 329 | } |
| 302 | 330 | } |
| 303 | 331 | |
| 304 | - func addNewChildViewController(_ child: UIViewController) { | |
| 305 | - addChild(child) | |
| 332 | + private func addNewChildViewController(_ child: UIViewController) { | |
| 306 | 333 | mainView.addSearchView(child.view) |
| 307 | 334 | child.didMove(toParent: self) |
| 335 | + | |
| 336 | + addChild(child) | |
| 308 | 337 | } |
| 309 | 338 | |
| 310 | - func removeChildViewController() { | |
| 339 | + private func removeChildViewController() { | |
| 311 | 340 | if let childViewController = self.children.first as? SearchingViewController { |
| 312 | 341 | childViewController.view.removeFromSuperview() |
| 313 | 342 | childViewController.willMove(toParent: nil) |
| ... | ... | @@ -324,93 +353,81 @@ extension BrowserHomeViewController { |
| 324 | 353 | |
| 325 | 354 | //MARK: - SearchBar extention |
| 326 | 355 | extension BrowserHomeViewController: UITextFieldDelegate { |
| 327 | - @objc | |
| 328 | - func searchBarTextChanged() { | |
| 329 | - if let text = mainView.searchBarContainer.searchBarView.searchTextFieldView.text { | |
| 330 | - finalSearchRequest = text | |
| 331 | - mainView.searchBarContainer.searchBarView.cleanTextFieldButton.isHidden = false | |
| 332 | - if finalSearchRequest.isEmpty { | |
| 333 | - searchResultAction() | |
| 334 | - } else { | |
| 335 | - Task { | |
| 336 | - await searchAndReloadTableView() | |
| 337 | - } | |
| 338 | - } | |
| 339 | - } | |
| 340 | - } | |
| 341 | - | |
| 342 | 356 | func textFieldDidBeginEditing(_ textField: UITextField) { |
| 343 | 357 | mainView.searchBarContainer.searchBarView.searchTextFieldView.text = nil |
| 344 | 358 | mainView.searchBarContainer.searchBarView.searchTextFieldView.textColor = .black |
| 345 | 359 | } |
| 346 | 360 | |
| 347 | 361 | func textFieldShouldReturn(_ textField: UITextField) -> Bool { |
| 348 | - finalSearchRequest = "https://www.google.com/search?q=" + (textField.text ?? "") | |
| 349 | - openSearchResult() | |
| 350 | 362 | textField.resignFirstResponder() |
| 363 | + | |
| 364 | + searchRequestURL = "https://www.google.com/search?q=" + (textField.text ?? "") | |
| 365 | + openSearchResult() | |
| 366 | + | |
| 351 | 367 | return true |
| 352 | 368 | } |
| 353 | 369 | |
| 354 | 370 | func setupSearchBarComponentsAction() { |
| 355 | 371 | mainView.searchBarContainer.searchBarView.searchTextFieldView.autocorrectionType = .no |
| 356 | - isButtonClickable() | |
| 357 | 372 | mainView.searchBarContainer.searchBarView.searchTextFieldView.delegate = self |
| 358 | 373 | mainView.searchBarContainer.searchBarView.cleanTextFieldButton.addTarget(self, action: #selector(searchResultAction), for: .touchUpInside) |
| 374 | + buttonObserver() | |
| 359 | 375 | } |
| 360 | 376 | } |
| 361 | 377 | |
| 362 | 378 | |
| 363 | 379 | //MARK: - WebView extention |
| 364 | 380 | extension BrowserHomeViewController { |
| 365 | - func isButtonClickable() { | |
| 366 | - searchResultViewController.mainView.searchResultView | |
| 367 | - .publisher(for: \.canGoBack) | |
| 368 | - .sink { [weak self] canGoBack in | |
| 369 | - self?.mainView.toolbarView.backBarButtonItem.isEnabled = canGoBack | |
| 370 | - } | |
| 371 | - .store(in: &subscriptions) | |
| 372 | - | |
| 373 | - searchResultViewController.mainView.searchResultView | |
| 374 | - .publisher(for: \.canGoForward) | |
| 375 | - .sink { [weak self] canGoForward in | |
| 376 | - self?.mainView.toolbarView.forwardBarButtonItem.isEnabled = canGoForward | |
| 377 | - } | |
| 378 | - .store(in: &subscriptions) | |
| 379 | - | |
| 380 | - searchResultViewController.mainView.searchResultView | |
| 381 | - .publisher(for: \.isLoading) | |
| 382 | - .sink { [weak self] isLoading in | |
| 383 | - guard let self = self else { return } | |
| 384 | - if let url = self.searchResultViewController.mainView.searchResultView.url { | |
| 385 | - self.finalSearchRequest = url.absoluteString | |
| 386 | - } | |
| 381 | + private func buttonObserver() { | |
| 382 | + searchResultViewController.mainView.searchResultView | |
| 383 | + .publisher(for: \.canGoBack) | |
| 384 | + .sink { [weak self] canGoBack in | |
| 385 | + self?.mainView.toolbarView.backBarButtonItem.isEnabled = canGoBack | |
| 386 | + } | |
| 387 | + .store(in: &subscriptions) | |
| 388 | + | |
| 389 | + searchResultViewController.mainView.searchResultView | |
| 390 | + .publisher(for: \.canGoForward) | |
| 391 | + .sink { [weak self] canGoForward in | |
| 392 | + self?.mainView.toolbarView.forwardBarButtonItem.isEnabled = canGoForward | |
| 393 | + } | |
| 394 | + .store(in: &subscriptions) | |
| 395 | + | |
| 396 | + searchResultViewController.mainView.searchResultView | |
| 397 | + .publisher(for: \.isLoading) | |
| 398 | + .sink { [weak self] isLoading in | |
| 399 | + guard let self = self else { return } | |
| 400 | + if let url = self.searchResultViewController.mainView.searchResultView.url { | |
| 401 | + self.searchRequestURL = url.absoluteString | |
| 387 | 402 | } |
| 388 | - .store(in: &subscriptions) | |
| 389 | - } | |
| 390 | - | |
| 391 | - private func progressObserver() { | |
| 392 | - searchResultViewController.mainView.searchResultView | |
| 393 | - .publisher(for: \.estimatedProgress) | |
| 394 | - .sink { [weak self] progress in | |
| 395 | - guard let self = self else { return } | |
| 396 | - self.mainView.searchBarContainer.searchBarView.progressBar.progress = Float(progress) | |
| 397 | - if progress == 1 { | |
| 398 | - self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = true | |
| 399 | - self.mainView.toolbarView.shareBarButtonItem.isEnabled = true | |
| 400 | - } else if progress == 0 { | |
| 401 | - self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = true | |
| 402 | - } else { | |
| 403 | - self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = false | |
| 404 | - self.mainView.toolbarView.shareBarButtonItem.isEnabled = false | |
| 405 | - } | |
| 403 | + } | |
| 404 | + .store(in: &subscriptions) | |
| 405 | + } | |
| 406 | + | |
| 407 | + private func progressObserver() { | |
| 408 | + searchResultViewController.mainView.searchResultView | |
| 409 | + .publisher(for: \.estimatedProgress) | |
| 410 | + .sink { [weak self] progress in | |
| 411 | + guard let self = self else { return } | |
| 412 | + self.mainView.searchBarContainer.searchBarView.progressBar.progress = Float(progress) | |
| 413 | + if progress == 1 { | |
| 414 | + self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = true | |
| 415 | + self.mainView.toolbarView.shareBarButtonItem.isEnabled = true | |
| 416 | + } else if progress == 0 { | |
| 417 | + self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = true | |
| 418 | + } else { | |
| 419 | + self.mainView.searchBarContainer.searchBarView.progressBar.isHidden = false | |
| 420 | + self.mainView.toolbarView.shareBarButtonItem.isEnabled = false | |
| 406 | 421 | } |
| 407 | - .store(in: &subscriptions) | |
| 408 | - } | |
| 422 | + } | |
| 423 | + .store(in: &subscriptions) | |
| 409 | 424 | } |
| 425 | +} | |
| 410 | 426 | |
| 427 | +//MARK: Url managment | |
| 411 | 428 | extension BrowserHomeViewController { |
| 412 | 429 | func urlManagment(_ url: String) { |
| 413 | - finalSearchRequest = url | |
| 430 | + searchRequestURL = url | |
| 414 | 431 | openSearchResult() |
| 415 | 432 | } |
| 416 | 433 | } | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 25.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | import SnapKit |
| ... | ... | @@ -21,19 +22,22 @@ final class BrowserHomeView: UIView { |
| 21 | 22 | obj.contentEdgeInsets = UIEdgeInsets(top: 10.sizeW, left: 10.sizeW, bottom: 10.sizeW, right: 10.sizeW) |
| 22 | 23 | obj.clipsToBounds = true |
| 23 | 24 | obj.layer.masksToBounds = false |
| 25 | + | |
| 24 | 26 | return obj |
| 25 | 27 | }() |
| 26 | 28 | |
| 27 | 29 | let settingButton: UIButton = { |
| 28 | 30 | let obj = UIButton() |
| 29 | 31 | obj.setImage(UIImage(named: "Settings")?.withTintColor(.systemBlue), for: .normal) |
| 32 | + | |
| 30 | 33 | return obj |
| 31 | 34 | }() |
| 32 | 35 | |
| 33 | - let titleLabel: UILabel = { | |
| 36 | + private let titleLabel: UILabel = { | |
| 34 | 37 | let obj = UILabel() |
| 35 | 38 | obj.text = StringConstants.frequentlyVisited |
| 36 | 39 | obj.font = FontConstants.semiboldFont_18 |
| 40 | + | |
| 37 | 41 | return obj |
| 38 | 42 | }() |
| 39 | 43 | |
| ... | ... | @@ -46,24 +50,27 @@ final class BrowserHomeView: UIView { |
| 46 | 50 | let collectionView = UICollectionView(frame: .zero, collectionViewLayout: obj) |
| 47 | 51 | collectionView.backgroundColor = .clear |
| 48 | 52 | collectionView.showsHorizontalScrollIndicator = false |
| 53 | + | |
| 49 | 54 | return collectionView |
| 50 | 55 | }() |
| 51 | 56 | |
| 52 | 57 | let toolbarView: ToolbarView = { |
| 53 | 58 | let obj = ToolbarView() |
| 59 | + | |
| 54 | 60 | return obj |
| 55 | 61 | }() |
| 56 | 62 | |
| 57 | 63 | let searchBarContainer: SearchBarContainer = { |
| 58 | 64 | let obj = SearchBarContainer() |
| 59 | 65 | obj.backgroundColor = .clear |
| 66 | + | |
| 60 | 67 | return obj |
| 61 | 68 | }() |
| 62 | 69 | |
| 63 | 70 | override init(frame: CGRect) { |
| 64 | 71 | super.init(frame: frame) |
| 72 | + | |
| 65 | 73 | setup() |
| 66 | - setupConstraints() | |
| 67 | 74 | } |
| 68 | 75 | |
| 69 | 76 | required init?(coder: NSCoder) { |
| ... | ... | @@ -77,6 +84,8 @@ final class BrowserHomeView: UIView { |
| 77 | 84 | addSubview(settingButton) |
| 78 | 85 | addSubview(searchBarContainer) |
| 79 | 86 | addSubview(toolbarView) |
| 87 | + | |
| 88 | + setupConstraints() | |
| 80 | 89 | } |
| 81 | 90 | |
| 82 | 91 | private func setupConstraints() { |
| ... | ... | @@ -86,29 +95,29 @@ final class BrowserHomeView: UIView { |
| 86 | 95 | make.trailing.equalToSuperview().offset(-158.sizeW) |
| 87 | 96 | } |
| 88 | 97 | settingButton.snp.makeConstraints { make in |
| 89 | - make.centerY.equalTo(removeAddButton) | |
| 98 | + make.trailing.equalToSuperview().offset(-16.sizeW) | |
| 90 | 99 | make.height.equalTo(24.sizeH) |
| 91 | 100 | make.width.equalTo(24.sizeH) |
| 92 | - make.trailing.equalToSuperview().offset(-16.sizeW) | |
| 101 | + make.centerY.equalTo(removeAddButton) | |
| 93 | 102 | } |
| 94 | 103 | titleLabel.snp.makeConstraints { make in |
| 95 | 104 | make.top.equalTo(removeAddButton.snp.bottom).offset(64.sizeH) |
| 96 | 105 | make.leading.equalTo(safeAreaLayoutGuide.snp.leading).offset(16.sizeW) |
| 97 | 106 | } |
| 98 | 107 | frequentlyVisitedCollectionView.snp.makeConstraints { make in |
| 108 | + make.top.equalTo(titleLabel.snp.bottom).offset(8.sizeH) | |
| 99 | 109 | make.leading.trailing.equalToSuperview().inset(24.sizeW) |
| 100 | 110 | make.height.equalTo(120.sizeH) |
| 101 | - make.top.equalTo(titleLabel.snp.bottom).offset(8.sizeH) | |
| 102 | 111 | } |
| 103 | 112 | toolbarView.snp.makeConstraints { make in |
| 104 | 113 | make.leading.equalToSuperview() |
| 105 | - make.trailing.equalToSuperview() | |
| 106 | 114 | make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom) |
| 115 | + make.trailing.equalToSuperview() | |
| 107 | 116 | } |
| 108 | 117 | searchBarContainer.snp.makeConstraints { make in |
| 109 | 118 | make.leading.equalToSuperview() |
| 110 | - make.trailing.equalToSuperview() | |
| 111 | 119 | make.bottom.equalToSuperview().offset(-90.sizeH) |
| 120 | + make.trailing.equalToSuperview() | |
| 112 | 121 | } |
| 113 | 122 | } |
| 114 | 123 | } |
| ... | ... | @@ -117,6 +126,7 @@ final class BrowserHomeView: UIView { |
| 117 | 126 | extension BrowserHomeView { |
| 118 | 127 | func addSearchView(_ childView: UIView){ |
| 119 | 128 | addSubview(childView) |
| 129 | + | |
| 120 | 130 | childView.snp.makeConstraints { make in |
| 121 | 131 | make.top.equalToSuperview() |
| 122 | 132 | make.leading.trailing.equalToSuperview() | ... | ... |
| ... | ... | @@ -4,13 +4,17 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 25.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | 11 | final class TabCollectionViewCell: UICollectionViewCell { |
| 12 | + static let cellID = String(describing: TabCollectionViewCell.self) | |
| 13 | + | |
| 11 | 14 | let tabCellImage: UIImageView = { |
| 12 | 15 | let obj = UIImageView() |
| 13 | 16 | obj.contentMode = .scaleToFill |
| 17 | + | |
| 14 | 18 | return obj |
| 15 | 19 | }() |
| 16 | 20 | |
| ... | ... | @@ -18,11 +22,13 @@ final class TabCollectionViewCell: UICollectionViewCell { |
| 18 | 22 | let obj = UILabel() |
| 19 | 23 | obj.textColor = .black |
| 20 | 24 | obj.font = FontConstants.regularFont_14 |
| 25 | + | |
| 21 | 26 | return obj |
| 22 | 27 | }() |
| 23 | 28 | |
| 24 | 29 | override init(frame: CGRect) { |
| 25 | 30 | super.init(frame: frame) |
| 31 | + | |
| 26 | 32 | setup() |
| 27 | 33 | } |
| 28 | 34 | |
| ... | ... | @@ -30,13 +36,14 @@ final class TabCollectionViewCell: UICollectionViewCell { |
| 30 | 36 | fatalError("init(coder:) has not been implemented") |
| 31 | 37 | } |
| 32 | 38 | |
| 33 | - func setup() { | |
| 34 | - | |
| 39 | + private func setup() { | |
| 40 | + backgroundColor = .white | |
| 35 | 41 | layer.cornerRadius = 10 |
| 36 | 42 | contentView.backgroundColor = UIColor(red: 0.867, green: 0.867, blue: 0.863, alpha: 0.4) |
| 37 | 43 | contentView.layer.cornerRadius = 10 |
| 38 | 44 | contentView.addSubview(tabCellImage) |
| 39 | 45 | contentView.addSubview(tabCellLabel) |
| 46 | + | |
| 40 | 47 | setupConstraints() |
| 41 | 48 | } |
| 42 | 49 | |
| ... | ... | @@ -48,13 +55,14 @@ final class TabCollectionViewCell: UICollectionViewCell { |
| 48 | 55 | } |
| 49 | 56 | |
| 50 | 57 | tabCellLabel.snp.makeConstraints { make in |
| 51 | - make.centerX.equalToSuperview() | |
| 52 | 58 | make.top.equalTo(tabCellImage.snp.bottom).offset(8.sizeH) |
| 59 | + make.centerX.equalToSuperview() | |
| 53 | 60 | } |
| 54 | 61 | } |
| 55 | 62 | |
| 56 | 63 | override func layoutSubviews() { |
| 57 | 64 | super.layoutSubviews() |
| 65 | + | |
| 58 | 66 | shadowSetup() |
| 59 | 67 | } |
| 60 | 68 | } | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 12.10.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| ... | ... | @@ -16,13 +17,14 @@ final class SearchBarContainer: UIView { |
| 16 | 17 | obj.layer.shadowOpacity = 1 |
| 17 | 18 | obj.layer.shadowRadius = 10 |
| 18 | 19 | obj.layer.shadowOffset = CGSize(width: 0, height: 4.sizeW) |
| 20 | + | |
| 19 | 21 | return obj |
| 20 | 22 | }() |
| 21 | 23 | |
| 22 | 24 | override init(frame: CGRect) { |
| 23 | 25 | super.init(frame: frame) |
| 26 | + | |
| 24 | 27 | setup() |
| 25 | - setupConstraints() | |
| 26 | 28 | } |
| 27 | 29 | |
| 28 | 30 | required init?(coder: NSCoder) { |
| ... | ... | @@ -31,14 +33,16 @@ final class SearchBarContainer: UIView { |
| 31 | 33 | |
| 32 | 34 | private func setup() { |
| 33 | 35 | addSubview(searchBarView) |
| 36 | + | |
| 37 | + setupConstraints() | |
| 34 | 38 | } |
| 35 | 39 | |
| 36 | 40 | private func setupConstraints() { |
| 37 | 41 | searchBarView.snp.makeConstraints { make in |
| 38 | 42 | make.top.equalToSuperview().offset(4.sizeH) |
| 39 | 43 | make.leading.equalToSuperview().offset(16.sizeW) |
| 40 | - make.trailing.equalToSuperview().offset(-16.sizeW) | |
| 41 | 44 | make.bottom.equalToSuperview().offset(-6.sizeH) |
| 45 | + make.trailing.equalToSuperview().offset(-16.sizeW) | |
| 42 | 46 | } |
| 43 | 47 | } |
| 44 | 48 | } | ... | ... |
| ... | ... | @@ -4,14 +4,16 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 26.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | 11 | final class SearchBarView: UIView { |
| 11 | - let searchImageView: UIImageView = { | |
| 12 | + private let searchImageView: UIImageView = { | |
| 12 | 13 | let obj = UIImageView() |
| 13 | 14 | let magnifyImage = UIImage(systemName: "magnifyingglass")?.withTintColor(.gray, renderingMode: .alwaysOriginal) |
| 14 | 15 | obj.image = magnifyImage |
| 16 | + | |
| 15 | 17 | return obj |
| 16 | 18 | }() |
| 17 | 19 | |
| ... | ... | @@ -19,6 +21,7 @@ final class SearchBarView: UIView { |
| 19 | 21 | let obj = UITextField() |
| 20 | 22 | obj.text = "Search" |
| 21 | 23 | obj.textColor = ColorConstants.gray |
| 24 | + | |
| 22 | 25 | return obj |
| 23 | 26 | }() |
| 24 | 27 | |
| ... | ... | @@ -27,6 +30,7 @@ final class SearchBarView: UIView { |
| 27 | 30 | obj.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal) |
| 28 | 31 | obj.tintColor = .black |
| 29 | 32 | obj.isHidden = true |
| 33 | + | |
| 30 | 34 | return obj |
| 31 | 35 | }() |
| 32 | 36 | |
| ... | ... | @@ -35,13 +39,14 @@ final class SearchBarView: UIView { |
| 35 | 39 | obj.progressTintColor = .systemIndigo |
| 36 | 40 | obj.progress = 0 |
| 37 | 41 | obj.translatesAutoresizingMaskIntoConstraints = false |
| 42 | + | |
| 38 | 43 | return obj |
| 39 | 44 | }() |
| 40 | 45 | |
| 41 | 46 | override init(frame: CGRect) { |
| 42 | 47 | super.init(frame: frame) |
| 48 | + | |
| 43 | 49 | setup() |
| 44 | - setupConstraints() | |
| 45 | 50 | } |
| 46 | 51 | |
| 47 | 52 | required init?(coder: NSCoder) { |
| ... | ... | @@ -53,25 +58,30 @@ final class SearchBarView: UIView { |
| 53 | 58 | addSubview(searchImageView) |
| 54 | 59 | addSubview(searchTextFieldView) |
| 55 | 60 | addSubview(cleanTextFieldButton) |
| 61 | + | |
| 62 | + setupConstraints() | |
| 56 | 63 | } |
| 57 | 64 | |
| 58 | 65 | private func setupConstraints() { |
| 59 | 66 | searchImageView.snp.makeConstraints { make in |
| 60 | - make.leading.equalToSuperview().offset(16.sizeW) | |
| 61 | 67 | make.top.bottom.equalToSuperview().inset(8.sizeH) |
| 68 | + make.leading.equalToSuperview().offset(16.sizeW) | |
| 62 | 69 | } |
| 70 | + | |
| 63 | 71 | searchTextFieldView.snp.makeConstraints { make in |
| 72 | + make.top.bottom.equalToSuperview().inset(8.sizeH) | |
| 64 | 73 | make.leading.equalTo(searchImageView).offset(32.sizeW) |
| 65 | 74 | make.trailing.equalToSuperview().offset(-16.sizeW) |
| 66 | - make.top.bottom.equalToSuperview().inset(8.sizeH) | |
| 67 | 75 | } |
| 76 | + | |
| 68 | 77 | cleanTextFieldButton.snp.makeConstraints { make in |
| 69 | - make.trailing.equalToSuperview().offset(-16.sizeW) | |
| 70 | 78 | make.top.bottom.equalToSuperview().inset(8.sizeH) |
| 79 | + make.trailing.equalToSuperview().offset(-16.sizeW) | |
| 71 | 80 | } |
| 81 | + | |
| 72 | 82 | progressBar.snp.makeConstraints { make in |
| 73 | - make.bottom.equalToSuperview().inset(2.sizeH) | |
| 74 | 83 | make.leading.trailing.equalToSuperview() |
| 84 | + make.bottom.equalToSuperview().inset(2.sizeH) | |
| 75 | 85 | make.height.equalTo(2) |
| 76 | 86 | } |
| 77 | 87 | } | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 27.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| ... | ... | @@ -18,11 +19,12 @@ enum ToolbarElementType { |
| 18 | 19 | final class ToolbarView: UIView { |
| 19 | 20 | var action: ((ToolbarElementType) -> Void)? |
| 20 | 21 | |
| 21 | - let toolbar: UIToolbar = { | |
| 22 | + private let toolbar: UIToolbar = { | |
| 22 | 23 | let obj = UIToolbar() |
| 23 | 24 | obj.sizeToFit() |
| 24 | 25 | obj.barTintColor = ColorConstants.lightGray |
| 25 | 26 | obj.clipsToBounds = true |
| 27 | + | |
| 26 | 28 | return obj |
| 27 | 29 | }() |
| 28 | 30 | |
| ... | ... | @@ -30,6 +32,7 @@ final class ToolbarView: UIView { |
| 30 | 32 | let obj = UIBarButtonItem() |
| 31 | 33 | obj.isEnabled = false |
| 32 | 34 | obj.image = UIImage(systemName: "chevron.backward") |
| 35 | + | |
| 33 | 36 | return obj |
| 34 | 37 | }() |
| 35 | 38 | |
| ... | ... | @@ -37,6 +40,7 @@ final class ToolbarView: UIView { |
| 37 | 40 | let obj = UIBarButtonItem() |
| 38 | 41 | obj.isEnabled = false |
| 39 | 42 | obj.image = UIImage(systemName: "chevron.forward") |
| 43 | + | |
| 40 | 44 | return obj |
| 41 | 45 | }() |
| 42 | 46 | |
| ... | ... | @@ -44,23 +48,27 @@ final class ToolbarView: UIView { |
| 44 | 48 | let obj = UIBarButtonItem() |
| 45 | 49 | obj.isEnabled = false |
| 46 | 50 | obj.image = UIImage(systemName: "square.and.arrow.up") |
| 51 | + | |
| 47 | 52 | return obj |
| 48 | 53 | }() |
| 49 | 54 | |
| 50 | - let historyBarButtonItem: UIBarButtonItem = { | |
| 55 | + private let historyBarButtonItem: UIBarButtonItem = { | |
| 51 | 56 | let obj = UIBarButtonItem() |
| 52 | 57 | obj.image = UIImage(systemName: "book") |
| 58 | + | |
| 53 | 59 | return obj |
| 54 | 60 | }() |
| 55 | 61 | |
| 56 | - let tabsBarButtonItem: UIBarButtonItem = { | |
| 62 | + private let tabsBarButtonItem: UIBarButtonItem = { | |
| 57 | 63 | let obj = UIBarButtonItem() |
| 58 | 64 | obj.image = UIImage(systemName: "square.on.square") |
| 65 | + | |
| 59 | 66 | return obj |
| 60 | 67 | }() |
| 61 | 68 | |
| 62 | 69 | override init(frame: CGRect) { |
| 63 | 70 | super.init(frame: frame) |
| 71 | + | |
| 64 | 72 | setup() |
| 65 | 73 | } |
| 66 | 74 | |
| ... | ... | @@ -70,18 +78,8 @@ final class ToolbarView: UIView { |
| 70 | 78 | |
| 71 | 79 | private func setup() { |
| 72 | 80 | addSubview(toolbar) |
| 73 | - let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) | |
| 74 | - toolbar.items = [ | |
| 75 | - backBarButtonItem, | |
| 76 | - flexibleSpace, | |
| 77 | - forwardBarButtonItem, | |
| 78 | - flexibleSpace, | |
| 79 | - shareBarButtonItem, | |
| 80 | - flexibleSpace, | |
| 81 | - historyBarButtonItem, | |
| 82 | - flexibleSpace, | |
| 83 | - tabsBarButtonItem, | |
| 84 | - ] | |
| 81 | + | |
| 82 | + setupToolbar() | |
| 85 | 83 | initActions() |
| 86 | 84 | setupConstraints() |
| 87 | 85 | } |
| ... | ... | @@ -100,15 +98,34 @@ extension ToolbarView { |
| 100 | 98 | private func initActions() { |
| 101 | 99 | backBarButtonItem.action = #selector(didItemTapped(_:)) |
| 102 | 100 | backBarButtonItem.target = self |
| 101 | + | |
| 103 | 102 | forwardBarButtonItem.action = #selector(didItemTapped(_:)) |
| 104 | 103 | forwardBarButtonItem.target = self |
| 104 | + | |
| 105 | 105 | shareBarButtonItem.action = #selector(didItemTapped(_:)) |
| 106 | 106 | shareBarButtonItem.target = self |
| 107 | + | |
| 107 | 108 | historyBarButtonItem.action = #selector(didItemTapped(_:)) |
| 108 | 109 | historyBarButtonItem.target = self |
| 110 | + | |
| 109 | 111 | tabsBarButtonItem.action = #selector(didItemTapped(_:)) |
| 110 | 112 | tabsBarButtonItem.target = self |
| 111 | 113 | } |
| 114 | + | |
| 115 | + private func setupToolbar() { | |
| 116 | + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) | |
| 117 | + toolbar.items = [ | |
| 118 | + backBarButtonItem, | |
| 119 | + flexibleSpace, | |
| 120 | + forwardBarButtonItem, | |
| 121 | + flexibleSpace, | |
| 122 | + shareBarButtonItem, | |
| 123 | + flexibleSpace, | |
| 124 | + historyBarButtonItem, | |
| 125 | + flexibleSpace, | |
| 126 | + tabsBarButtonItem, | |
| 127 | + ] | |
| 128 | + } | |
| 112 | 129 | } |
| 113 | 130 | |
| 114 | 131 | // MARK: - Actions | ... | ... |
| ... | ... | @@ -4,23 +4,26 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 25.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | 11 | final class PayloadViewController: UIViewController { |
| 11 | 12 | private let mainView = PayloadView() |
| 12 | - private let data = StringConstants.payloadViewControllerData | |
| 13 | + private let payloadTableViewData: [String] | |
| 13 | 14 | |
| 14 | 15 | override func viewDidLoad() { |
| 15 | 16 | super.viewDidLoad() |
| 16 | 17 | view.backgroundColor = ColorConstants.lightGray |
| 18 | + | |
| 17 | 19 | initViewController() |
| 18 | 20 | } |
| 19 | 21 | |
| 20 | 22 | private func initViewController() { |
| 23 | + navigationController?.isNavigationBarHidden = true | |
| 24 | + | |
| 21 | 25 | setupTableView() |
| 22 | 26 | addTargets() |
| 23 | - navigationController?.isNavigationBarHidden = true | |
| 24 | 27 | } |
| 25 | 28 | |
| 26 | 29 | override func loadView() { |
| ... | ... | @@ -28,37 +31,36 @@ final class PayloadViewController: UIViewController { |
| 28 | 31 | } |
| 29 | 32 | |
| 30 | 33 | init(){ |
| 34 | + payloadTableViewData = StringConstants.payloadViewControllerData | |
| 35 | + | |
| 31 | 36 | super.init(nibName: nil, bundle: nil) |
| 32 | 37 | } |
| 38 | + | |
| 33 | 39 | required init?(coder: NSCoder) { |
| 34 | 40 | fatalError("init(coder:) has not been implemented") |
| 35 | 41 | } |
| 36 | 42 | |
| 37 | 43 | override func viewWillDisappear(_ animated: Bool) { |
| 38 | 44 | super.viewWillDisappear(animated) |
| 45 | + | |
| 39 | 46 | NotificationCenter.default.removeObserver(self) |
| 40 | 47 | } |
| 41 | 48 | } |
| 42 | 49 | |
| 43 | 50 | extension PayloadViewController: UITableViewDelegate, UITableViewDataSource { |
| 44 | 51 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
| 45 | - return data.count | |
| 52 | + return payloadTableViewData.count | |
| 46 | 53 | } |
| 47 | 54 | |
| 48 | 55 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
| 49 | - guard let cell = tableView.dequeueReusableCell(withIdentifier: "AdvantagesTableViewCell") as? | |
| 56 | + guard let cell = tableView.dequeueReusableCell(withIdentifier: AdvantagesTableViewCell.cellID) as? | |
| 50 | 57 | AdvantagesTableViewCell else { |
| 51 | - return UITableViewCell() } | |
| 52 | - cell.advantagesCellLabel.text = data[indexPath.row] | |
| 53 | - cell.selectionStyle = .none | |
| 58 | + return UITableViewCell() | |
| 59 | + } | |
| 60 | + cell.advantagesCellLabel.text = payloadTableViewData[indexPath.row] | |
| 61 | + | |
| 54 | 62 | return cell |
| 55 | 63 | } |
| 56 | - | |
| 57 | - private func setupTableView() { | |
| 58 | - mainView.advantagesTableView.dataSource = self | |
| 59 | - mainView.advantagesTableView.delegate = self | |
| 60 | - mainView.advantagesTableView.register(AdvantagesTableViewCell.self, forCellReuseIdentifier: StringConstants.advantagesTableViewCell) | |
| 61 | - } | |
| 62 | 64 | } |
| 63 | 65 | |
| 64 | 66 | |
| ... | ... | @@ -73,9 +75,13 @@ extension PayloadViewController { |
| 73 | 75 | private func textPressed(_ sender: UITapGestureRecognizer) { |
| 74 | 76 | let termsViewController = TermsViewController() |
| 75 | 77 | termsViewController.modalPresentationStyle = .fullScreen |
| 78 | + | |
| 76 | 79 | present(termsViewController, animated: true) |
| 77 | 80 | } |
| 78 | - | |
| 81 | +} | |
| 82 | + | |
| 83 | +//MARK: Helpers | |
| 84 | +extension PayloadViewController { | |
| 79 | 85 | private func addTargets() { |
| 80 | 86 | mainView.getStartedButton.addTarget(self, action: #selector(getStartedButtonTapped(_ :)), for: .touchUpInside) |
| 81 | 87 | mainView.privacyLabelView.isUserInteractionEnabled = true |
| ... | ... | @@ -88,6 +94,11 @@ extension PayloadViewController { |
| 88 | 94 | let tapGesture = UITapGestureRecognizer(target: self, action: #selector(textPressed(_ :))) |
| 89 | 95 | mainView.infoLabel.addGestureRecognizer(tapGesture) |
| 90 | 96 | } |
| 97 | + | |
| 98 | + private func setupTableView() { | |
| 99 | + mainView.advantagesTableView.dataSource = self | |
| 100 | + mainView.advantagesTableView.delegate = self | |
| 101 | + mainView.advantagesTableView.register(AdvantagesTableViewCell.self, forCellReuseIdentifier: AdvantagesTableViewCell.cellID) | |
| 102 | + } | |
| 91 | 103 | } |
| 92 | 104 | |
| 93 | - | ... | ... |
| ... | ... | @@ -4,54 +4,59 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 26.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | 11 | final class AdvantagesTableViewCell: UITableViewCell { |
| 12 | + static let cellID = String(describing: AdvantagesTableViewCell.self) | |
| 13 | + | |
| 11 | 14 | let advantagesCellLabel: UILabel = { |
| 12 | 15 | let obj = UILabel() |
| 13 | 16 | obj.font = FontConstants.semiboldFont_14 |
| 17 | + | |
| 14 | 18 | return obj |
| 15 | 19 | }() |
| 16 | 20 | |
| 17 | - let advantagesCellImage: UIImageView = { | |
| 21 | + private let advantagesCellImage: UIImageView = { | |
| 18 | 22 | let obj = UIImageView() |
| 19 | 23 | let checkmarkImg = UIImage(systemName: "checkmark")?.withTintColor(.blue, renderingMode: .alwaysOriginal) |
| 20 | 24 | obj.image = checkmarkImg |
| 21 | 25 | obj.contentMode = .scaleToFill |
| 26 | + | |
| 22 | 27 | return obj |
| 23 | 28 | }() |
| 24 | 29 | |
| 25 | 30 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
| 26 | 31 | super.init(style: style, reuseIdentifier: reuseIdentifier) |
| 27 | - setup() | |
| 28 | 32 | |
| 33 | + setup() | |
| 29 | 34 | } |
| 30 | 35 | |
| 31 | 36 | required init?(coder: NSCoder) { |
| 32 | 37 | fatalError("init(coder:) has not been implemented") |
| 33 | 38 | } |
| 34 | 39 | |
| 35 | - | |
| 36 | - | |
| 37 | - func setup() { | |
| 40 | + private func setup() { | |
| 41 | + selectionStyle = .none | |
| 42 | + backgroundColor = .clear | |
| 38 | 43 | contentView.addSubview(advantagesCellLabel) |
| 39 | 44 | contentView.addSubview(advantagesCellImage) |
| 45 | + | |
| 40 | 46 | setupConstraints() |
| 41 | - backgroundColor = .clear | |
| 42 | 47 | } |
| 43 | 48 | |
| 44 | 49 | private func setupConstraints() { |
| 45 | 50 | advantagesCellImage.snp.makeConstraints { make in |
| 46 | 51 | make.top.equalToSuperview().inset(5.sizeH) |
| 47 | - make.bottom.equalToSuperview().inset(5.sizeH) | |
| 48 | 52 | make.leading.equalToSuperview() |
| 53 | + make.bottom.equalToSuperview().inset(5.sizeH) | |
| 49 | 54 | make.trailing.equalTo(advantagesCellLabel.snp.leading).offset(-8.sizeW) |
| 50 | 55 | } |
| 51 | 56 | advantagesCellLabel.snp.makeConstraints { make in |
| 52 | 57 | make.top.equalToSuperview().inset(5.sizeH) |
| 53 | - make.bottom.equalToSuperview().inset(5.sizeH) | |
| 54 | 58 | make.leading.equalTo(advantagesCellImage.snp.trailing) |
| 59 | + make.bottom.equalToSuperview().inset(5.sizeH) | |
| 55 | 60 | make.trailing.equalToSuperview() |
| 56 | 61 | } |
| 57 | 62 | } | ... | ... |
| ... | ... | @@ -4,29 +4,32 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 25.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | 11 | final class PayloadView: UIView { |
| 11 | - | |
| 12 | - let logoImageView: UIImageView = { | |
| 12 | + private let logoImageView: UIImageView = { | |
| 13 | 13 | let obj = UIImageView() |
| 14 | 14 | obj.image = UIImage(named: "Gotoweb") |
| 15 | 15 | obj.contentMode = .scaleAspectFit |
| 16 | + | |
| 16 | 17 | return obj |
| 17 | 18 | }() |
| 18 | 19 | |
| 19 | - let phoneImageView: UIImageView = { | |
| 20 | + private let phoneImageView: UIImageView = { | |
| 20 | 21 | let obj = UIImageView() |
| 21 | 22 | obj.image = UIImage(named: "Phone") |
| 22 | 23 | obj.contentMode = .scaleAspectFit |
| 24 | + | |
| 23 | 25 | return obj |
| 24 | 26 | }() |
| 25 | 27 | |
| 26 | - let zoomedTabImageView: UIImageView = { | |
| 28 | + private let zoomedTabImageView: UIImageView = { | |
| 27 | 29 | let obj = UIImageView() |
| 28 | 30 | obj.image = UIImage(named: "ZoomedTab") |
| 29 | 31 | obj.contentMode = .scaleAspectFit |
| 32 | + | |
| 30 | 33 | return obj |
| 31 | 34 | }() |
| 32 | 35 | |
| ... | ... | @@ -35,6 +38,7 @@ final class PayloadView: UIView { |
| 35 | 38 | obj.text = StringConstants.ourBrowser |
| 36 | 39 | obj.font = FontConstants.regularFont_12 |
| 37 | 40 | obj.numberOfLines = 0 |
| 41 | + | |
| 38 | 42 | return obj |
| 39 | 43 | }() |
| 40 | 44 | |
| ... | ... | @@ -43,10 +47,11 @@ final class PayloadView: UIView { |
| 43 | 47 | obj.backgroundColor = .clear |
| 44 | 48 | obj.isScrollEnabled = false |
| 45 | 49 | obj.separatorStyle = .none |
| 50 | + | |
| 46 | 51 | return obj |
| 47 | 52 | }() |
| 48 | 53 | |
| 49 | - let gradientLayer = CAGradientLayer() | |
| 54 | + private let gradientLayer = CAGradientLayer() | |
| 50 | 55 | |
| 51 | 56 | let getStartedButton: UIButton = { |
| 52 | 57 | let obj = UIButton() |
| ... | ... | @@ -55,6 +60,7 @@ final class PayloadView: UIView { |
| 55 | 60 | obj.setTitleColor(.white, for: .normal) |
| 56 | 61 | obj.layer.cornerRadius = 10 |
| 57 | 62 | obj.layer.masksToBounds = true |
| 63 | + | |
| 58 | 64 | return obj |
| 59 | 65 | }() |
| 60 | 66 | |
| ... | ... | @@ -64,17 +70,20 @@ final class PayloadView: UIView { |
| 64 | 70 | |
| 65 | 71 | let fullText = "By starting, you agree to our Terms and Condition and Privacy Policy." |
| 66 | 72 | let attributedText = NSMutableAttributedString(string: fullText) |
| 73 | + | |
| 67 | 74 | attributedText.addAttribute(.foregroundColor, value: UIColor(red: 0.349, green: 0.565, blue: 1, alpha: 1).cgColor, range: NSRange(location: fullText.range(of: "Terms and Condition")?.lowerBound.utf16Offset(in: fullText) ?? 0, length: "Terms and Condition".count)) |
| 68 | 75 | attributedText.addAttribute(.foregroundColor, value: UIColor(red: 0.349, green: 0.565, blue: 1, alpha: 1).cgColor, range: NSRange(location: fullText.range(of: "Privacy Policy")?.lowerBound.utf16Offset(in: fullText) ?? 0, length: "Privacy Policy".count)) |
| 69 | 76 | obj.attributedText = attributedText |
| 70 | 77 | obj.font = FontConstants.regularFont_12 |
| 71 | 78 | obj.numberOfLines = 0 |
| 72 | 79 | obj.isUserInteractionEnabled = true |
| 80 | + | |
| 73 | 81 | return obj |
| 74 | 82 | }() |
| 75 | 83 | |
| 76 | 84 | override init (frame: CGRect) { |
| 77 | 85 | super.init(frame: frame) |
| 86 | + | |
| 78 | 87 | setup() |
| 79 | 88 | } |
| 80 | 89 | |
| ... | ... | @@ -84,6 +93,7 @@ final class PayloadView: UIView { |
| 84 | 93 | |
| 85 | 94 | override func layoutSubviews() { |
| 86 | 95 | super.layoutSubviews() |
| 96 | + | |
| 87 | 97 | gradientLayer.frame = getStartedButton.bounds |
| 88 | 98 | } |
| 89 | 99 | |
| ... | ... | @@ -95,11 +105,12 @@ final class PayloadView: UIView { |
| 95 | 105 | addSubview(advantagesTableView) |
| 96 | 106 | addSubview(getStartedButton) |
| 97 | 107 | addSubview(privacyLabelView) |
| 108 | + | |
| 98 | 109 | setupConstraints() |
| 99 | 110 | gradientSetup() |
| 100 | 111 | } |
| 101 | 112 | |
| 102 | - func setupConstraints() { | |
| 113 | + private func setupConstraints() { | |
| 103 | 114 | logoImageView.snp.makeConstraints { make in |
| 104 | 115 | make.top.equalTo(safeAreaLayoutGuide.snp.top).offset(16.sizeH) |
| 105 | 116 | make.leading.trailing.equalToSuperview().inset(143.sizeW) |
| ... | ... | @@ -115,8 +126,8 @@ final class PayloadView: UIView { |
| 115 | 126 | zoomedTabImageView.snp.makeConstraints { make in |
| 116 | 127 | make.top.equalTo(phoneImageView.snp.top).offset(119.sizeH) |
| 117 | 128 | make.leading.equalTo(phoneImageView.snp.leading).offset(91.sizeW) |
| 118 | - make.trailing.equalToSuperview().offset(-71) | |
| 119 | 129 | make.bottom.equalTo(phoneImageView.snp.bottom).offset(-104.sizeH) |
| 130 | + make.trailing.equalToSuperview().offset(-71) | |
| 120 | 131 | } |
| 121 | 132 | |
| 122 | 133 | infoLabel.snp.makeConstraints { make in |
| ... | ... | @@ -127,8 +138,8 @@ final class PayloadView: UIView { |
| 127 | 138 | advantagesTableView.snp.makeConstraints { make in |
| 128 | 139 | make.top.equalTo(infoLabel.snp.bottom).offset(16.sizeH) |
| 129 | 140 | make.leading.equalToSuperview().offset(55.sizeW) |
| 130 | - make.trailing.equalToSuperview().offset(-92.sizeW) | |
| 131 | 141 | make.bottom.equalTo(getStartedButton.snp.top).offset(-38.sizeH) |
| 142 | + make.trailing.equalToSuperview().offset(-92.sizeW) | |
| 132 | 143 | } |
| 133 | 144 | |
| 134 | 145 | getStartedButton.snp.makeConstraints { make in | ... | ... |
| ... | ... | @@ -4,21 +4,23 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 27.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | 11 | final class RemoveAdvertViewController: UIViewController { |
| 11 | - | |
| 12 | 12 | private let mainView = RemoveAdvertView() |
| 13 | - let data = StringConstants.removeAdvertTableViewData | |
| 13 | + private let removeTableViewCellsData: [String] | |
| 14 | 14 | |
| 15 | 15 | override func viewDidLoad() { |
| 16 | 16 | super.viewDidLoad() |
| 17 | - view.backgroundColor = ColorConstants.lightGray | |
| 17 | + | |
| 18 | 18 | initViewController() |
| 19 | 19 | } |
| 20 | 20 | |
| 21 | 21 | private func initViewController() { |
| 22 | + view.backgroundColor = ColorConstants.lightGray | |
| 23 | + | |
| 22 | 24 | setupTableView() |
| 23 | 25 | addTargets() |
| 24 | 26 | } |
| ... | ... | @@ -27,7 +29,9 @@ final class RemoveAdvertViewController: UIViewController { |
| 27 | 29 | view = mainView |
| 28 | 30 | } |
| 29 | 31 | |
| 30 | - init(){ | |
| 32 | + init() { | |
| 33 | + removeTableViewCellsData = StringConstants.removeAdvertTableViewData | |
| 34 | + | |
| 31 | 35 | super.init(nibName: nil, bundle: nil) |
| 32 | 36 | } |
| 33 | 37 | |
| ... | ... | @@ -40,35 +44,25 @@ final class RemoveAdvertViewController: UIViewController { |
| 40 | 44 | //MARK: - Table View |
| 41 | 45 | extension RemoveAdvertViewController: UITableViewDelegate, UITableViewDataSource { |
| 42 | 46 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
| 43 | - return data.count | |
| 47 | + return removeTableViewCellsData.count | |
| 44 | 48 | } |
| 45 | 49 | |
| 46 | 50 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
| 47 | - guard let cell = tableView.dequeueReusableCell(withIdentifier: "RemoveAdvertTableViewCell") as? | |
| 51 | + guard let cell = tableView.dequeueReusableCell(withIdentifier: RemoveAdvertTableViewCell.cellID) as? | |
| 48 | 52 | RemoveAdvertTableViewCell else { |
| 49 | - return UITableViewCell() } | |
| 50 | - | |
| 51 | - cell.advantagesCellLabel.text = data[indexPath.row] | |
| 53 | + return UITableViewCell() | |
| 54 | + } | |
| 55 | + | |
| 56 | + cell.advantagesCellLabel.text = removeTableViewCellsData[indexPath.row] | |
| 52 | 57 | cell.selectionStyle = .none |
| 53 | 58 | |
| 54 | 59 | return cell |
| 55 | 60 | } |
| 56 | - | |
| 57 | - private func setupTableView() { | |
| 58 | - mainView.advantagesTableView.dataSource = self | |
| 59 | - mainView.advantagesTableView.delegate = self | |
| 60 | - mainView.advantagesTableView.register(RemoveAdvertTableViewCell.self, forCellReuseIdentifier: StringConstants.removeAdvertTableViewCell) | |
| 61 | - } | |
| 62 | 61 | } |
| 63 | 62 | |
| 64 | 63 | |
| 65 | 64 | //MARK: - Action |
| 66 | 65 | extension RemoveAdvertViewController { |
| 67 | - private func addTargets() { | |
| 68 | - mainView.shieldView.addTarget(self, action: #selector(shieldButtonTapped(_ :)), for: .touchUpInside) | |
| 69 | - mainView.closeButton.addTarget(self, action: #selector(closeViewController(_ :)), for: .touchUpInside) | |
| 70 | - } | |
| 71 | - | |
| 72 | 66 | @objc |
| 73 | 67 | private func shieldButtonTapped(_ sender: UIButton) { |
| 74 | 68 | UIView.animate(withDuration: 0.2) { |
| ... | ... | @@ -76,6 +70,7 @@ extension RemoveAdvertViewController { |
| 76 | 70 | sender.alpha = 0.7 |
| 77 | 71 | } |
| 78 | 72 | let userDefaultsAdBlockerValue = CachingManager.shared.isAdBlocking |
| 73 | + | |
| 79 | 74 | if userDefaultsAdBlockerValue { |
| 80 | 75 | mainView.shieldView.setImage(.shieldInactive, for: .normal) |
| 81 | 76 | mainView.tapActionLabel.text = StringConstants.turnOff |
| ... | ... | @@ -96,3 +91,17 @@ extension RemoveAdvertViewController { |
| 96 | 91 | dismiss(animated: true, completion: nil) |
| 97 | 92 | } |
| 98 | 93 | } |
| 94 | + | |
| 95 | +//MARK: Helpers | |
| 96 | +extension RemoveAdvertViewController { | |
| 97 | + private func addTargets() { | |
| 98 | + mainView.shieldView.addTarget(self, action: #selector(shieldButtonTapped(_ :)), for: .touchUpInside) | |
| 99 | + mainView.closeButton.addTarget(self, action: #selector(closeViewController(_ :)), for: .touchUpInside) | |
| 100 | + } | |
| 101 | + | |
| 102 | + private func setupTableView() { | |
| 103 | + mainView.advantagesTableView.dataSource = self | |
| 104 | + mainView.advantagesTableView.delegate = self | |
| 105 | + mainView.advantagesTableView.register(RemoveAdvertTableViewCell.self, forCellReuseIdentifier: RemoveAdvertTableViewCell.cellID) | |
| 106 | + } | |
| 107 | +} | ... | ... |
| ... | ... | @@ -4,53 +4,58 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 01.10.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | - | |
| 11 | 11 | final class RemoveAdvertTableViewCell: UITableViewCell { |
| 12 | + static let cellID = String(describing: RemoveAdvertTableViewCell.self) | |
| 13 | + | |
| 12 | 14 | let advantagesCellLabel: UILabel = { |
| 13 | 15 | let obj = UILabel() |
| 14 | 16 | obj.font = FontConstants.regularFont_14 |
| 17 | + | |
| 15 | 18 | return obj |
| 16 | 19 | }() |
| 17 | 20 | |
| 18 | - let advantagesCellImage: UIImageView = { | |
| 21 | + private let advantagesCellImage: UIImageView = { | |
| 19 | 22 | let obj = UIImageView() |
| 20 | 23 | let checkmarkImg = UIImage(systemName: "checkmark")?.withTintColor(.blue, renderingMode: .alwaysOriginal) |
| 21 | 24 | obj.image = checkmarkImg |
| 22 | 25 | obj.contentMode = .scaleToFill |
| 26 | + | |
| 23 | 27 | return obj |
| 24 | 28 | }() |
| 25 | 29 | |
| 26 | 30 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
| 27 | 31 | super.init(style: style, reuseIdentifier: reuseIdentifier) |
| 28 | - setup() | |
| 29 | 32 | |
| 33 | + setup() | |
| 30 | 34 | } |
| 31 | 35 | |
| 32 | 36 | required init?(coder: NSCoder) { |
| 33 | 37 | fatalError("init(coder:) has not been implemented") |
| 34 | 38 | } |
| 35 | 39 | |
| 36 | - func setup() { | |
| 40 | + private func setup() { | |
| 41 | + backgroundColor = .clear | |
| 37 | 42 | contentView.addSubview(advantagesCellLabel) |
| 38 | 43 | contentView.addSubview(advantagesCellImage) |
| 39 | - backgroundColor = .clear | |
| 44 | + | |
| 40 | 45 | setupConstraints() |
| 41 | 46 | } |
| 42 | 47 | |
| 43 | 48 | private func setupConstraints() { |
| 44 | 49 | advantagesCellImage.snp.makeConstraints { make in |
| 45 | 50 | make.top.equalToSuperview().inset(5.sizeH) |
| 46 | - make.bottom.equalToSuperview().inset(5.sizeH) | |
| 47 | 51 | make.leading.equalToSuperview() |
| 52 | + make.bottom.equalToSuperview().inset(5.sizeH) | |
| 48 | 53 | make.trailing.equalTo(advantagesCellLabel.snp.leading).offset(-8.sizeW) |
| 49 | 54 | } |
| 50 | 55 | advantagesCellLabel.snp.makeConstraints { make in |
| 51 | 56 | make.top.equalToSuperview().inset(5.sizeH) |
| 52 | - make.bottom.equalToSuperview().inset(5.sizeH) | |
| 53 | 57 | make.leading.equalTo(advantagesCellImage.snp.trailing) |
| 58 | + make.bottom.equalToSuperview().inset(5.sizeH) | |
| 54 | 59 | make.trailing.equalToSuperview() |
| 55 | 60 | } |
| 56 | 61 | } | ... | ... |
| ... | ... | @@ -4,17 +4,18 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 29.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | import SnapKit |
| 10 | 11 | |
| 11 | 12 | final class RemoveAdvertView: UIView { |
| 12 | - | |
| 13 | 13 | let closeButton: UIButton = { |
| 14 | 14 | let obj = UIButton() |
| 15 | 15 | obj.setImage(UIImage(systemName: "xmark"), for: .normal) |
| 16 | 16 | obj.contentMode = .scaleToFill |
| 17 | 17 | obj.tintColor = .gray |
| 18 | + | |
| 18 | 19 | return obj |
| 19 | 20 | }() |
| 20 | 21 | |
| ... | ... | @@ -24,22 +25,21 @@ final class RemoveAdvertView: UIView { |
| 24 | 25 | |
| 25 | 26 | if userDefaultsValue { |
| 26 | 27 | obj.setImage(UIImage(named: "ShieldActive"), for: .normal) |
| 27 | - print(userDefaultsValue) | |
| 28 | 28 | } else { |
| 29 | 29 | obj.setImage(UIImage(named: "ShieldInactive"), for: .normal) |
| 30 | - print(userDefaultsValue) | |
| 31 | 30 | } |
| 32 | - | |
| 33 | 31 | obj.contentMode = .scaleAspectFit |
| 32 | + | |
| 34 | 33 | return obj |
| 35 | 34 | }() |
| 36 | 35 | |
| 37 | - let gradientLayer = CAGradientLayer() | |
| 36 | + private let gradientLayer = CAGradientLayer() | |
| 38 | 37 | |
| 39 | - let abvertBlockerModeLabel: UILabel = { | |
| 38 | + private let abvertBlockerModeLabel: UILabel = { | |
| 40 | 39 | let obj = UILabel() |
| 41 | 40 | obj.text = StringConstants.advertMode |
| 42 | 41 | obj.font = FontConstants.semiboldFont_18 |
| 42 | + | |
| 43 | 43 | return obj |
| 44 | 44 | }() |
| 45 | 45 | |
| ... | ... | @@ -47,6 +47,7 @@ final class RemoveAdvertView: UIView { |
| 47 | 47 | let obj = UILabel() |
| 48 | 48 | obj.text = StringConstants.turnOff |
| 49 | 49 | obj.font = FontConstants.semiboldFont_14 |
| 50 | + | |
| 50 | 51 | return obj |
| 51 | 52 | }() |
| 52 | 53 | |
| ... | ... | @@ -55,24 +56,27 @@ final class RemoveAdvertView: UIView { |
| 55 | 56 | obj.backgroundColor = .clear |
| 56 | 57 | obj.isScrollEnabled = false |
| 57 | 58 | obj.separatorStyle = .none |
| 59 | + | |
| 58 | 60 | return obj |
| 59 | 61 | }() |
| 60 | 62 | |
| 61 | - let claimOfferLabel: UILabel = { | |
| 63 | + private let claimOfferLabel: UILabel = { | |
| 62 | 64 | let obj = UILabel() |
| 63 | 65 | obj.text = StringConstants.claimOffer |
| 64 | 66 | obj.font = FontConstants.regularFont_12 |
| 67 | + | |
| 65 | 68 | return obj |
| 66 | 69 | }() |
| 67 | 70 | |
| 68 | - let priceLabel: UILabel = { | |
| 71 | + private let priceLabel: UILabel = { | |
| 69 | 72 | let obj = UILabel() |
| 70 | 73 | obj.text = StringConstants.price |
| 71 | 74 | obj.font = FontConstants.regularFont_18 |
| 75 | + | |
| 72 | 76 | return obj |
| 73 | 77 | }() |
| 74 | 78 | |
| 75 | - let subscribeButton: UIButton = { | |
| 79 | + private let subscribeButton: UIButton = { | |
| 76 | 80 | let obj = UIButton() |
| 77 | 81 | obj.backgroundColor = .systemIndigo |
| 78 | 82 | obj.setTitle(StringConstants.subscribe, for: .normal) |
| ... | ... | @@ -80,32 +84,37 @@ final class RemoveAdvertView: UIView { |
| 80 | 84 | obj.setTitleColor(.white, for: .normal) |
| 81 | 85 | obj.layer.cornerRadius = 10 |
| 82 | 86 | obj.layer.masksToBounds = true |
| 87 | + | |
| 83 | 88 | return obj |
| 84 | 89 | }() |
| 85 | 90 | |
| 86 | - let freeTrialLabel: UILabel = { | |
| 91 | + private let freeTrialLabel: UILabel = { | |
| 87 | 92 | let obj = UILabel() |
| 88 | 93 | obj.textAlignment = .center |
| 89 | 94 | obj.font = FontConstants.semiboldFont_12 |
| 90 | 95 | obj.text = StringConstants.freeTrial |
| 96 | + | |
| 91 | 97 | return obj |
| 92 | 98 | }() |
| 93 | 99 | |
| 94 | - let discountLabel: UILabel = { | |
| 100 | + private let discountLabel: UILabel = { | |
| 95 | 101 | let obj = UILabel() |
| 96 | 102 | obj.textAlignment = .center |
| 97 | 103 | obj.text = StringConstants.yourDiscount |
| 98 | 104 | obj.font = FontConstants.regularFont_12 |
| 105 | + | |
| 99 | 106 | return obj |
| 100 | 107 | }() |
| 101 | 108 | |
| 102 | 109 | override init (frame: CGRect) { |
| 103 | 110 | super.init(frame: frame) |
| 111 | + | |
| 104 | 112 | setup() |
| 105 | 113 | } |
| 106 | 114 | |
| 107 | 115 | override func layoutSubviews() { |
| 108 | 116 | super.layoutSubviews() |
| 117 | + | |
| 109 | 118 | gradientLayer.frame = subscribeButton.bounds |
| 110 | 119 | } |
| 111 | 120 | |
| ... | ... | @@ -124,61 +133,70 @@ final class RemoveAdvertView: UIView { |
| 124 | 133 | addSubview(subscribeButton) |
| 125 | 134 | addSubview(freeTrialLabel) |
| 126 | 135 | addSubview(discountLabel) |
| 136 | + | |
| 127 | 137 | setupConstraints() |
| 128 | 138 | gradientSetup() |
| 129 | 139 | } |
| 130 | 140 | |
| 131 | - func setupConstraints() { | |
| 141 | + private func setupConstraints() { | |
| 132 | 142 | closeButton.snp.makeConstraints { make in |
| 133 | 143 | make.top.equalTo(safeAreaLayoutGuide.snp.top).offset(16.sizeH) |
| 134 | - make.height.equalTo(24.sizeH) | |
| 135 | 144 | make.trailing.equalToSuperview().inset(16.sizeW) |
| 145 | + make.height.equalTo(24.sizeH) | |
| 136 | 146 | } |
| 137 | 147 | |
| 138 | 148 | shieldView.snp.makeConstraints { make in |
| 139 | 149 | make.top.equalTo(closeButton.snp.top).offset(8.sizeH) |
| 140 | - make.height.equalTo(280.sizeH) | |
| 141 | 150 | make.leading.trailing.equalToSuperview().inset(47.sizeW) |
| 151 | + make.height.equalTo(280.sizeH) | |
| 142 | 152 | } |
| 153 | + | |
| 143 | 154 | abvertBlockerModeLabel.snp.makeConstraints { make in |
| 144 | 155 | make.top.equalTo(shieldView.snp.bottom).offset(16.sizeH) |
| 145 | 156 | make.centerX.equalToSuperview() |
| 146 | 157 | } |
| 158 | + | |
| 147 | 159 | tapActionLabel.snp.makeConstraints { make in |
| 148 | 160 | make.top.equalTo(abvertBlockerModeLabel.snp.bottom).offset(8.sizeH) |
| 149 | 161 | make.centerX.equalToSuperview() |
| 150 | 162 | } |
| 163 | + | |
| 151 | 164 | advantagesTableView.snp.makeConstraints { make in |
| 152 | 165 | make.top.equalTo(tapActionLabel.snp.bottom).offset(26.sizeH) |
| 153 | - make.bottom.equalTo(claimOfferLabel.snp.top).offset(-24.sizeH) | |
| 154 | 166 | make.leading.equalToSuperview().offset(80.sizeW) |
| 167 | + make.bottom.equalTo(claimOfferLabel.snp.top).offset(-24.sizeH) | |
| 155 | 168 | make.trailing.equalToSuperview().offset(-86.sizeW) |
| 156 | 169 | } |
| 170 | + | |
| 157 | 171 | claimOfferLabel.snp.makeConstraints { make in |
| 158 | 172 | make.bottom.equalTo(priceLabel.snp.top).offset(-4.sizeH) |
| 159 | 173 | make.centerX.equalToSuperview() |
| 160 | 174 | } |
| 175 | + | |
| 161 | 176 | priceLabel.snp.makeConstraints { make in |
| 162 | 177 | make.bottom.equalTo(subscribeButton.snp.top).offset(-16.sizeH) |
| 163 | 178 | make.centerX.equalToSuperview() |
| 164 | 179 | } |
| 180 | + | |
| 165 | 181 | subscribeButton.snp.makeConstraints { make in |
| 166 | - make.bottom.equalTo(freeTrialLabel.snp.top).offset(-16.sizeH) | |
| 167 | 182 | make.leading.trailing.equalToSuperview().inset(32.sizeW) |
| 183 | + make.bottom.equalTo(freeTrialLabel.snp.top).offset(-16.sizeH) | |
| 168 | 184 | make.height.equalTo(40.sizeH) |
| 169 | 185 | } |
| 186 | + | |
| 170 | 187 | freeTrialLabel.snp.makeConstraints { make in |
| 171 | 188 | make.bottom.equalTo(discountLabel.snp.top).offset(-8.sizeH) |
| 172 | 189 | make.centerX.equalToSuperview() |
| 173 | 190 | } |
| 191 | + | |
| 174 | 192 | discountLabel.snp.makeConstraints { make in |
| 175 | - make.centerX.equalToSuperview() | |
| 176 | 193 | make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom).offset(-24.sizeH) |
| 194 | + make.centerX.equalToSuperview() | |
| 177 | 195 | } |
| 178 | 196 | } |
| 179 | 197 | } |
| 180 | 198 | |
| 181 | -//MARK: gradient | |
| 199 | +//MARK: Gradient | |
| 182 | 200 | extension RemoveAdvertView { |
| 183 | 201 | private func gradientSetup() { |
| 184 | 202 | subscribeButton.layer.insertSublayer(gradientLayer, at: 0) | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 05.10.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | import WebKit |
| ... | ... | @@ -14,6 +15,7 @@ final class SearchResultViewController: UIViewController { |
| 14 | 15 | |
| 15 | 16 | init(searchLink: String) { |
| 16 | 17 | self.searchLink = searchLink |
| 18 | + | |
| 17 | 19 | super.init(nibName: nil, bundle: nil) |
| 18 | 20 | } |
| 19 | 21 | |
| ... | ... | @@ -27,11 +29,13 @@ final class SearchResultViewController: UIViewController { |
| 27 | 29 | |
| 28 | 30 | override func viewDidLoad() { |
| 29 | 31 | super.viewDidLoad() |
| 32 | + | |
| 30 | 33 | initViewController() |
| 31 | 34 | } |
| 32 | 35 | |
| 33 | 36 | private func initViewController() { |
| 34 | 37 | view.backgroundColor = ColorConstants.lightGray |
| 38 | + | |
| 35 | 39 | urlChecker(searchLink) |
| 36 | 40 | setupAdBlocker() |
| 37 | 41 | } |
| ... | ... | @@ -42,7 +46,7 @@ final class SearchResultViewController: UIViewController { |
| 42 | 46 | } |
| 43 | 47 | |
| 44 | 48 | extension SearchResultViewController { |
| 45 | - func urlChecker(_ url: String) { | |
| 49 | + private func urlChecker(_ url: String) { | |
| 46 | 50 | let request = URLRequest(url: URL(string: url) ?? URL(fileURLWithPath: "")) |
| 47 | 51 | mainView.searchResultView.load(request) |
| 48 | 52 | } |
| ... | ... | @@ -51,7 +55,7 @@ extension SearchResultViewController { |
| 51 | 55 | |
| 52 | 56 | //MARK: AdBlocker |
| 53 | 57 | extension SearchResultViewController { |
| 54 | - func setupAdBlocker() { | |
| 58 | + private func setupAdBlocker() { | |
| 55 | 59 | let userDefaultsValue = CachingManager.shared.isAdBlocking |
| 56 | 60 | if userDefaultsValue { |
| 57 | 61 | WKContentRuleListStore.default().getAvailableContentRuleListIdentifiers { res in | ... | ... |
| ... | ... | @@ -4,7 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 05.10.2023. |
| 6 | 6 | // |
| 7 | - | |
| 7 | +//MARK: Checked | |
| 8 | 8 | import UIKit |
| 9 | 9 | import WebKit |
| 10 | 10 | |
| ... | ... | @@ -18,6 +18,7 @@ final class SearchResultView: UIView { |
| 18 | 18 | |
| 19 | 19 | override init(frame: CGRect) { |
| 20 | 20 | super.init(frame: frame) |
| 21 | + | |
| 21 | 22 | setup() |
| 22 | 23 | } |
| 23 | 24 | |
| ... | ... | @@ -26,9 +27,10 @@ final class SearchResultView: UIView { |
| 26 | 27 | } |
| 27 | 28 | |
| 28 | 29 | private func setup() { |
| 30 | + backgroundColor = .white | |
| 31 | + | |
| 29 | 32 | addSubview(searchResultView) |
| 30 | 33 | setupConstaraints() |
| 31 | - backgroundColor = .white | |
| 32 | 34 | } |
| 33 | 35 | |
| 34 | 36 | private func setupConstaraints() { | ... | ... |
| ... | ... | @@ -4,12 +4,14 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 29.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | 11 | final class SearchingViewController: UIViewController { |
| 11 | 12 | let mainView = SearchingView() |
| 12 | - var dataForReq: [String] { | |
| 13 | + | |
| 14 | + var searchRequestData: [String] { | |
| 13 | 15 | didSet { |
| 14 | 16 | mainView.searchTableView.reloadData() |
| 15 | 17 | } |
| ... | ... | @@ -17,7 +19,8 @@ final class SearchingViewController: UIViewController { |
| 17 | 19 | var searchCell: ((UITableViewCell) -> Void)? |
| 18 | 20 | |
| 19 | 21 | init(dataForReq: [String]) { |
| 20 | - self.dataForReq = dataForReq | |
| 22 | + self.searchRequestData = dataForReq | |
| 23 | + | |
| 21 | 24 | super.init(nibName: nil, bundle: nil) |
| 22 | 25 | } |
| 23 | 26 | |
| ... | ... | @@ -31,6 +34,7 @@ final class SearchingViewController: UIViewController { |
| 31 | 34 | |
| 32 | 35 | override func viewDidLoad() { |
| 33 | 36 | super.viewDidLoad() |
| 37 | + | |
| 34 | 38 | view.backgroundColor = ColorConstants.lightGray |
| 35 | 39 | initViewController() |
| 36 | 40 | } |
| ... | ... | @@ -40,16 +44,17 @@ final class SearchingViewController: UIViewController { |
| 40 | 44 | } |
| 41 | 45 | } |
| 42 | 46 | |
| 47 | +//MARK: Setup TableView | |
| 43 | 48 | extension SearchingViewController: UITableViewDelegate, UITableViewDataSource { |
| 44 | 49 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { |
| 45 | - return dataForReq.count | |
| 50 | + return searchRequestData.count | |
| 46 | 51 | } |
| 47 | 52 | |
| 48 | 53 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { |
| 49 | - guard let cell = tableView.dequeueReusableCell(withIdentifier: "SearchingTableViewCell", for: indexPath) as? SearchingTableViewCell else { | |
| 50 | - return SearchingTableViewCell() | |
| 54 | + guard let cell = tableView.dequeueReusableCell(withIdentifier: SearchingTableViewCell.cellID, for: indexPath) as? SearchingTableViewCell else { | |
| 55 | + return UITableViewCell() | |
| 51 | 56 | } |
| 52 | - let searchCellData = dataForReq[indexPath.row] | |
| 57 | + let searchCellData = searchRequestData[indexPath.row] | |
| 53 | 58 | cell.model = searchCellData |
| 54 | 59 | return cell |
| 55 | 60 | } |
| ... | ... | @@ -58,11 +63,15 @@ extension SearchingViewController: UITableViewDelegate, UITableViewDataSource { |
| 58 | 63 | guard let tappedCell = tableView.cellForRow(at: indexPath) else { return } |
| 59 | 64 | searchCell?(tappedCell) |
| 60 | 65 | } |
| 61 | - | |
| 62 | - func setupTableView() { | |
| 66 | +} | |
| 67 | + | |
| 68 | + | |
| 69 | +//MARK: Helper | |
| 70 | +extension SearchingViewController { | |
| 71 | + private func setupTableView() { | |
| 63 | 72 | mainView.searchTableView.dataSource = self |
| 64 | 73 | mainView.searchTableView.delegate = self |
| 65 | - mainView.searchTableView.register(SearchingTableViewCell.self, forCellReuseIdentifier: StringConstants.searchTableViewCell) | |
| 74 | + mainView.searchTableView.register(SearchingTableViewCell.self, forCellReuseIdentifier: SearchingTableViewCell.cellID) | |
| 66 | 75 | } |
| 67 | 76 | } |
| 68 | 77 | ... | ... |
| ... | ... | @@ -4,44 +4,52 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 29.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | -class SearchingTableViewCell: UITableViewCell { | |
| 11 | +final class SearchingTableViewCell: UITableViewCell { | |
| 12 | + static let cellID = String(describing: SearchingTableViewCell.self) | |
| 13 | + | |
| 11 | 14 | var model: String? { |
| 12 | 15 | didSet { |
| 13 | 16 | handleUI() |
| 14 | 17 | } |
| 15 | 18 | } |
| 16 | 19 | |
| 17 | - var searchImage: UIImageView = { | |
| 20 | + private var searchImage: UIImageView = { | |
| 18 | 21 | let obj = UIImageView() |
| 19 | 22 | obj.image = UIImage(systemName: "magnifyingglass") |
| 20 | 23 | obj.tintColor = .gray |
| 24 | + | |
| 21 | 25 | return obj |
| 22 | 26 | }() |
| 23 | 27 | |
| 24 | 28 | var searchLabel: UILabel = { |
| 25 | 29 | let obj = UILabel() |
| 26 | 30 | obj.font = FontConstants.regularFont_14 |
| 31 | + | |
| 27 | 32 | return obj |
| 28 | 33 | }() |
| 29 | 34 | |
| 30 | - var siteLogoImage: UIImageView = { | |
| 35 | + private var siteLogoImage: UIImageView = { | |
| 31 | 36 | let obj = UIImageView() |
| 37 | + | |
| 32 | 38 | return obj |
| 33 | 39 | }() |
| 34 | 40 | |
| 35 | - var linkImage: UIImageView = { | |
| 41 | + private var linkImage: UIImageView = { | |
| 36 | 42 | let obj = UIImageView() |
| 37 | 43 | obj.image = UIImage(systemName: "arrow.up.left") |
| 38 | 44 | obj.tintColor = .gray |
| 45 | + | |
| 39 | 46 | return obj |
| 40 | 47 | }() |
| 41 | 48 | |
| 42 | 49 | |
| 43 | 50 | override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { |
| 44 | 51 | super.init(style: style, reuseIdentifier: reuseIdentifier) |
| 52 | + | |
| 45 | 53 | setup() |
| 46 | 54 | } |
| 47 | 55 | |
| ... | ... | @@ -49,7 +57,7 @@ class SearchingTableViewCell: UITableViewCell { |
| 49 | 57 | fatalError("init(coder:) has not been implemented") |
| 50 | 58 | } |
| 51 | 59 | |
| 52 | - func setup() { | |
| 60 | + private func setup() { | |
| 53 | 61 | contentView.addSubview(searchImage) |
| 54 | 62 | contentView.addSubview(searchLabel) |
| 55 | 63 | contentView.addSubview(siteLogoImage) | ... | ... |
| ... | ... | @@ -4,13 +4,14 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 29.09.2023. |
| 6 | 6 | // |
| 7 | - | |
| 7 | +//MARK: Checked | |
| 8 | 8 | import UIKit |
| 9 | 9 | |
| 10 | 10 | final class SearchingView: UIView, UITextFieldDelegate { |
| 11 | 11 | let searchingButton: UIButton = { |
| 12 | 12 | let obj = UIButton() |
| 13 | 13 | obj.setImage(UIImage(systemName: "arrow.left"), for: .normal) |
| 14 | + | |
| 14 | 15 | return obj |
| 15 | 16 | }() |
| 16 | 17 | |
| ... | ... | @@ -18,6 +19,7 @@ final class SearchingView: UIView, UITextFieldDelegate { |
| 18 | 19 | let obj = UILabel() |
| 19 | 20 | obj.text = "Searching" |
| 20 | 21 | obj.font = FontConstants.semiboldFont_18 |
| 22 | + | |
| 21 | 23 | return obj |
| 22 | 24 | }() |
| 23 | 25 | |
| ... | ... | @@ -25,11 +27,13 @@ final class SearchingView: UIView, UITextFieldDelegate { |
| 25 | 27 | let obj = UITableView() |
| 26 | 28 | obj.backgroundColor = .clear |
| 27 | 29 | obj.separatorStyle = .none |
| 30 | + | |
| 28 | 31 | return obj |
| 29 | 32 | }() |
| 30 | 33 | |
| 31 | 34 | override init(frame: CGRect) { |
| 32 | 35 | super.init(frame: frame) |
| 36 | + | |
| 33 | 37 | setup() |
| 34 | 38 | } |
| 35 | 39 | |
| ... | ... | @@ -38,11 +42,12 @@ final class SearchingView: UIView, UITextFieldDelegate { |
| 38 | 42 | } |
| 39 | 43 | |
| 40 | 44 | private func setup() { |
| 45 | + backgroundColor = .white | |
| 46 | + | |
| 41 | 47 | addSubview(searchingButton) |
| 42 | 48 | addSubview(searchingLabel) |
| 43 | 49 | addSubview(searchTableView) |
| 44 | 50 | setupConstaraints() |
| 45 | - backgroundColor = .white | |
| 46 | 51 | } |
| 47 | 52 | |
| 48 | 53 | private func setupConstaraints() { | ... | ... |
| ... | ... | @@ -12,6 +12,7 @@ final class PrivacyViewController: UIViewController { |
| 12 | 12 | |
| 13 | 13 | override func viewDidLoad() { |
| 14 | 14 | super.viewDidLoad() |
| 15 | + | |
| 15 | 16 | initViewController() |
| 16 | 17 | } |
| 17 | 18 | |
| ... | ... | @@ -19,14 +20,6 @@ final class PrivacyViewController: UIViewController { |
| 19 | 20 | view = mainView |
| 20 | 21 | } |
| 21 | 22 | |
| 22 | - init() { | |
| 23 | - super.init(nibName: nil, bundle: nil) | |
| 24 | - } | |
| 25 | - | |
| 26 | - required init?(coder: NSCoder) { | |
| 27 | - fatalError("init(coder:) has not been implemented") | |
| 28 | - } | |
| 29 | - | |
| 30 | 23 | private func initViewController() { |
| 31 | 24 | addTargets() |
| 32 | 25 | mainView.backgroundColor = .white |
| ... | ... | @@ -34,10 +27,9 @@ final class PrivacyViewController: UIViewController { |
| 34 | 27 | } |
| 35 | 28 | } |
| 36 | 29 | |
| 37 | - | |
| 38 | 30 | //MARK: Helper |
| 39 | 31 | extension PrivacyViewController { |
| 40 | - func addTargets() { | |
| 32 | + private func addTargets() { | |
| 41 | 33 | mainView.privacyButton.addTarget(self, action: #selector(privacyButtonPressed), for: .touchUpInside) |
| 42 | 34 | } |
| 43 | 35 | } |
| ... | ... | @@ -45,7 +37,7 @@ extension PrivacyViewController { |
| 45 | 37 | //MARK: Targets |
| 46 | 38 | extension PrivacyViewController { |
| 47 | 39 | @objc |
| 48 | - func privacyButtonPressed() { | |
| 40 | + private func privacyButtonPressed() { | |
| 49 | 41 | self.dismiss(animated: true) |
| 50 | 42 | } |
| 51 | 43 | } | ... | ... |
| ... | ... | @@ -4,10 +4,10 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 08.11.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| 10 | - | |
| 11 | 11 | final class PrivacyView: UIView { |
| 12 | 12 | private let privacyHeaderLabel: UILabel = { |
| 13 | 13 | let obj = UILabel() |
| ... | ... | @@ -49,6 +49,7 @@ final class PrivacyView: UIView { |
| 49 | 49 | |
| 50 | 50 | override init(frame: CGRect) { |
| 51 | 51 | super.init(frame: frame) |
| 52 | + | |
| 52 | 53 | setup() |
| 53 | 54 | } |
| 54 | 55 | |
| ... | ... | @@ -57,11 +58,13 @@ final class PrivacyView: UIView { |
| 57 | 58 | } |
| 58 | 59 | |
| 59 | 60 | private func setup() { |
| 60 | - addSubview(privacyHeaderLabel) | |
| 61 | - addSubview(privacyButton) | |
| 62 | 61 | privacyStackView.addSubview(privacyMainInfoLabel) |
| 63 | 62 | privacyScrollView.addSubview(privacyStackView) |
| 63 | + | |
| 64 | + addSubview(privacyHeaderLabel) | |
| 65 | + addSubview(privacyButton) | |
| 64 | 66 | addSubview(privacyScrollView) |
| 67 | + | |
| 65 | 68 | setupConstraints() |
| 66 | 69 | } |
| 67 | 70 | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 08.11.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| ... | ... | @@ -12,6 +13,7 @@ final class TermsViewController: UIViewController { |
| 12 | 13 | |
| 13 | 14 | override func viewDidLoad() { |
| 14 | 15 | super.viewDidLoad() |
| 16 | + | |
| 15 | 17 | initViewController() |
| 16 | 18 | } |
| 17 | 19 | |
| ... | ... | @@ -19,25 +21,17 @@ final class TermsViewController: UIViewController { |
| 19 | 21 | view = mainView |
| 20 | 22 | } |
| 21 | 23 | |
| 22 | - init() { | |
| 23 | - super.init(nibName: nil, bundle: nil) | |
| 24 | - } | |
| 25 | - | |
| 26 | - required init?(coder: NSCoder) { | |
| 27 | - fatalError("init(coder:) has not been implemented") | |
| 28 | - } | |
| 29 | - | |
| 30 | 24 | private func initViewController() { |
| 31 | - addTargets() | |
| 32 | 25 | mainView.backgroundColor = .white |
| 33 | 26 | |
| 27 | + addTargets() | |
| 34 | 28 | } |
| 35 | 29 | } |
| 36 | 30 | |
| 37 | 31 | |
| 38 | 32 | //MARK: Helper |
| 39 | 33 | extension TermsViewController { |
| 40 | - func addTargets() { | |
| 34 | + private func addTargets() { | |
| 41 | 35 | mainView.termsButton.addTarget(self, action: #selector(privacyButtonPressed), for: .touchUpInside) |
| 42 | 36 | } |
| 43 | 37 | } |
| ... | ... | @@ -45,7 +39,7 @@ extension TermsViewController { |
| 45 | 39 | //MARK: Targets |
| 46 | 40 | extension TermsViewController { |
| 47 | 41 | @objc |
| 48 | - func privacyButtonPressed() { | |
| 42 | + private func privacyButtonPressed() { | |
| 49 | 43 | self.dismiss(animated: true) |
| 50 | 44 | } |
| 51 | 45 | } | ... | ... |
| ... | ... | @@ -4,6 +4,8 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 08.11.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 8 | + | |
| 7 | 9 | |
| 8 | 10 | import UIKit |
| 9 | 11 | |
| ... | ... | @@ -14,6 +16,7 @@ final class TermsView: UIView { |
| 14 | 16 | obj.numberOfLines = 0 |
| 15 | 17 | obj.textAlignment = .center |
| 16 | 18 | obj.font = FontConstants.semiboldFont_18 |
| 19 | + | |
| 17 | 20 | return obj |
| 18 | 21 | }() |
| 19 | 22 | |
| ... | ... | @@ -22,6 +25,7 @@ final class TermsView: UIView { |
| 22 | 25 | obj.text = StringConstants.settingTerms |
| 23 | 26 | obj.numberOfLines = 0 |
| 24 | 27 | obj.font = FontConstants.regularFont_18 |
| 28 | + | |
| 25 | 29 | return obj |
| 26 | 30 | }() |
| 27 | 31 | |
| ... | ... | @@ -31,23 +35,27 @@ final class TermsView: UIView { |
| 31 | 35 | obj.layer.cornerRadius = 10 |
| 32 | 36 | obj.setTitle(StringConstants.settingAgreeButtonText, for: .normal) |
| 33 | 37 | obj.setTitleColor(.black, for: .normal) |
| 38 | + | |
| 34 | 39 | return obj |
| 35 | 40 | }() |
| 36 | 41 | |
| 37 | 42 | private let termsStackView: UIStackView = { |
| 38 | 43 | let obj = UIStackView() |
| 39 | 44 | obj.axis = .vertical |
| 45 | + | |
| 40 | 46 | return obj |
| 41 | 47 | }() |
| 42 | 48 | |
| 43 | 49 | private let termsScrollView: UIScrollView = { |
| 44 | 50 | let obj = UIScrollView() |
| 45 | 51 | obj.showsVerticalScrollIndicator = false |
| 52 | + | |
| 46 | 53 | return obj |
| 47 | 54 | }() |
| 48 | 55 | |
| 49 | 56 | override init(frame: CGRect) { |
| 50 | 57 | super.init(frame: frame) |
| 58 | + | |
| 51 | 59 | setup() |
| 52 | 60 | } |
| 53 | 61 | |
| ... | ... | @@ -56,11 +64,13 @@ final class TermsView: UIView { |
| 56 | 64 | } |
| 57 | 65 | |
| 58 | 66 | private func setup() { |
| 59 | - addSubview(termsHeaderLabel) | |
| 60 | - addSubview(termsButton) | |
| 61 | 67 | termsStackView.addSubview(termsMainInfoLabel) |
| 62 | 68 | termsScrollView.addSubview(termsStackView) |
| 69 | + | |
| 70 | + addSubview(termsHeaderLabel) | |
| 71 | + addSubview(termsButton) | |
| 63 | 72 | addSubview(termsScrollView) |
| 73 | + | |
| 64 | 74 | setupConstraints() |
| 65 | 75 | } |
| 66 | 76 | ... | ... |
| ... | ... | @@ -4,27 +4,29 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 28.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | import RealmSwift |
| 10 | 11 | import Realm |
| 11 | 12 | |
| 12 | - | |
| 13 | - | |
| 14 | 13 | final class TabsViewController: UIViewController { |
| 15 | 14 | private var tabsData: [BrowserTabDataBase] = [] |
| 15 | + | |
| 16 | 16 | var cellIndexPathForTransition: IndexPath? |
| 17 | 17 | let mainView = TabsView() |
| 18 | 18 | |
| 19 | 19 | override func viewDidLoad() { |
| 20 | 20 | super.viewDidLoad() |
| 21 | + | |
| 21 | 22 | initViewController() |
| 22 | 23 | } |
| 23 | 24 | |
| 24 | 25 | private func initViewController() { |
| 26 | + view.backgroundColor = UIColor(red: 0.984, green: 0.984, blue: 0.984, alpha: 1) | |
| 27 | + | |
| 25 | 28 | setupCollectionView() |
| 26 | 29 | addTargets() |
| 27 | - view.backgroundColor = UIColor(red: 0.984, green: 0.984, blue: 0.984, alpha: 1) | |
| 28 | 30 | } |
| 29 | 31 | |
| 30 | 32 | override func viewWillAppear(_ animated: Bool) { |
| ... | ... | @@ -32,22 +34,15 @@ final class TabsViewController: UIViewController { |
| 32 | 34 | } |
| 33 | 35 | |
| 34 | 36 | override func viewIsAppearing(_ animated: Bool) { |
| 37 | + navigationController?.isNavigationBarHidden = true | |
| 38 | + | |
| 35 | 39 | refreshData() |
| 36 | 40 | setCountOfTabs() |
| 37 | - navigationController?.isNavigationBarHidden = true | |
| 38 | 41 | } |
| 39 | 42 | |
| 40 | 43 | override func loadView() { |
| 41 | 44 | view = mainView |
| 42 | 45 | } |
| 43 | - | |
| 44 | - init() { | |
| 45 | - super.init(nibName: nil, bundle: nil) | |
| 46 | - } | |
| 47 | - | |
| 48 | - required init?(coder: NSCoder) { | |
| 49 | - fatalError("init(coder:) has not been implemented") | |
| 50 | - } | |
| 51 | 46 | } |
| 52 | 47 | |
| 53 | 48 | |
| ... | ... | @@ -59,12 +54,13 @@ extension TabsViewController: UICollectionViewDataSource, UICollectionViewDelega |
| 59 | 54 | |
| 60 | 55 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { |
| 61 | 56 | let tab = tabsData[indexPath.row] |
| 62 | - guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "OpenedTabsCollectionViewCell", for: indexPath) as? OpenedTabsCollectionViewCell else { | |
| 63 | - return OpenedTabsCollectionViewCell() | |
| 57 | + guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: OpenedTabsCollectionViewCell.cellID, for: indexPath) as? OpenedTabsCollectionViewCell else { | |
| 58 | + return UICollectionViewCell() | |
| 64 | 59 | } |
| 65 | 60 | cell.model = tab |
| 66 | 61 | cell.delegate = self |
| 67 | 62 | cell.closeTabButton.addTarget(self, action: #selector(closeTab(_:)), for: .touchUpInside) |
| 63 | + | |
| 68 | 64 | return cell |
| 69 | 65 | } |
| 70 | 66 | |
| ... | ... | @@ -77,30 +73,30 @@ extension TabsViewController: UICollectionViewDataSource, UICollectionViewDelega |
| 77 | 73 | pushSelectedTab(indexPath) |
| 78 | 74 | } |
| 79 | 75 | |
| 80 | - private func setupCollectionView() { | |
| 81 | - mainView.openedTabsCollectionView.dataSource = self | |
| 82 | - mainView.openedTabsCollectionView.delegate = self | |
| 83 | - mainView.openedTabsCollectionView.register(OpenedTabsCollectionViewCell.self, forCellWithReuseIdentifier: "OpenedTabsCollectionViewCell") | |
| 84 | - } | |
| 85 | 76 | } |
| 86 | 77 | |
| 87 | 78 | |
| 88 | 79 | //MARK: - Action |
| 89 | 80 | extension TabsViewController { |
| 90 | - func didTabButtonTapped(type: HistoryToolbarElementType) { | |
| 81 | + private func didTabButtonTapped(type: HistoryToolbarElementType) { | |
| 91 | 82 | switch type { |
| 92 | 83 | case .add: |
| 93 | 84 | addNewDefaultTab() |
| 94 | 85 | refreshData() |
| 86 | + | |
| 95 | 87 | let lastIndex = tabsData.endIndex - 1 |
| 96 | 88 | let lastIndexPath = IndexPath(row: lastIndex, section: 0) |
| 89 | + | |
| 97 | 90 | cellIndexPathForTransition = lastIndexPath |
| 98 | 91 | pushSelectedTab(lastIndexPath) |
| 99 | 92 | break |
| 93 | + | |
| 100 | 94 | case .done: |
| 101 | 95 | refreshData() |
| 96 | + | |
| 102 | 97 | let lastIndex = tabsData.endIndex - 1 |
| 103 | 98 | let lastIndexPath = IndexPath(row: lastIndex, section: 0) |
| 99 | + | |
| 104 | 100 | cellIndexPathForTransition = lastIndexPath |
| 105 | 101 | pushSelectedTab(lastIndexPath) |
| 106 | 102 | break |
| ... | ... | @@ -117,6 +113,12 @@ extension TabsViewController { |
| 117 | 113 | |
| 118 | 114 | //MARK: - Helpers |
| 119 | 115 | extension TabsViewController { |
| 116 | + private func setupCollectionView() { | |
| 117 | + mainView.openedTabsCollectionView.dataSource = self | |
| 118 | + mainView.openedTabsCollectionView.delegate = self | |
| 119 | + mainView.openedTabsCollectionView.register(OpenedTabsCollectionViewCell.self, forCellWithReuseIdentifier: OpenedTabsCollectionViewCell.cellID) | |
| 120 | + } | |
| 121 | + | |
| 120 | 122 | private func addTargets() { |
| 121 | 123 | addToolbarTargets() |
| 122 | 124 | } |
| ... | ... | @@ -129,8 +131,9 @@ extension TabsViewController { |
| 129 | 131 | return cellIndexPathForTransition ?? IndexPath(row: tabsData.count - 1, section: 0) |
| 130 | 132 | } |
| 131 | 133 | |
| 132 | - func addNewDefaultTab() { | |
| 134 | + private func addNewDefaultTab() { | |
| 133 | 135 | let defaultImage = UIImage(named: "defaultImage") |
| 136 | + | |
| 134 | 137 | TabManager.shared.saveTabWithComplition(tabTitle: "Start Page", snapshotImage: defaultImage, tabUrl: "homeUrl") { [weak self] result in |
| 135 | 138 | switch result { |
| 136 | 139 | default: |
| ... | ... | @@ -139,19 +142,22 @@ extension TabsViewController { |
| 139 | 142 | } |
| 140 | 143 | } |
| 141 | 144 | |
| 142 | - func pushSelectedTab(_ indexPath: IndexPath) { | |
| 145 | + private func pushSelectedTab(_ indexPath: IndexPath) { | |
| 143 | 146 | let index = indexPath.row |
| 147 | + | |
| 144 | 148 | if tabsData[index].TabUrl != "homeUrl" { |
| 145 | 149 | let browserHomeViewController = BrowserHomeViewController(url: tabsData[index].TabUrl, currentTabId: index) |
| 146 | 150 | browserHomeViewController.urlManagment(tabsData[index].TabUrl) |
| 151 | + | |
| 147 | 152 | navigationController?.pushViewController(browserHomeViewController, animated: true) |
| 148 | 153 | } else { |
| 149 | 154 | let browserHomeViewController = BrowserHomeViewController(url: tabsData[index].TabUrl, currentTabId: index) |
| 155 | + | |
| 150 | 156 | navigationController?.pushViewController(browserHomeViewController, animated: true) |
| 151 | 157 | } |
| 152 | 158 | } |
| 153 | 159 | |
| 154 | - func refreshData() { | |
| 160 | + private func refreshData() { | |
| 155 | 161 | tabsData = TabManager.shared.getAllTabs() |
| 156 | 162 | mainView.openedTabsCollectionView.reloadData() |
| 157 | 163 | } |
| ... | ... | @@ -163,20 +169,24 @@ extension TabsViewController: OpenedTabsCellDelegate { |
| 163 | 169 | guard let indexPath = mainView.openedTabsCollectionView.indexPath(for: cell) else { |
| 164 | 170 | return |
| 165 | 171 | } |
| 172 | + | |
| 166 | 173 | tabsData.remove(at: indexPath.row) |
| 174 | + | |
| 167 | 175 | mainView.openedTabsCollectionView.performBatchUpdates({ |
| 168 | 176 | mainView.openedTabsCollectionView.deleteItems(at: [indexPath]) |
| 169 | 177 | }, completion: { _ in |
| 170 | 178 | if self.tabsData.isEmpty { |
| 171 | 179 | self.addNewDefaultTab() |
| 172 | 180 | let browserHomeViewController = BrowserHomeViewController(url: "homeUrl", currentTabId: self.tabsData.count - 1) |
| 181 | + | |
| 173 | 182 | self.navigationController?.pushViewController(browserHomeViewController, animated: true) |
| 183 | + | |
| 174 | 184 | self.cellIndexPathForTransition = IndexPath(row: self.tabsData.count - 1, section: 0) |
| 175 | 185 | } |
| 176 | 186 | self.setCountOfTabs() |
| 177 | 187 | }) |
| 178 | 188 | } |
| 179 | - func setCountOfTabs() { | |
| 180 | - mainView.tabsToolbarView.showTabToolbarButtonItem.title = "\(tabsData.count) Tabs" | |
| 189 | + private func setCountOfTabs() { | |
| 190 | + mainView.tabsToolbarView.showedCountOfTabs.title = "\(tabsData.count) Tabs" | |
| 181 | 191 | } |
| 182 | 192 | } | ... | ... |
| 1 | +// | |
| 2 | +// OpenedTabsCellDelegate.swift | |
| 3 | +// browser | |
| 4 | +// | |
| 5 | +// Created by Artem Talko on 28.09.2023. | |
| 6 | +// | |
| 7 | +//MARK: Checked | |
| 8 | + | |
| 1 | 9 | import UIKit |
| 2 | 10 | import SnapKit |
| 3 | 11 | |
| ... | ... | @@ -6,6 +14,8 @@ protocol OpenedTabsCellDelegate: AnyObject { |
| 6 | 14 | } |
| 7 | 15 | |
| 8 | 16 | final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
| 17 | + static let cellID = String(describing: OpenedTabsCollectionViewCell.self) | |
| 18 | + | |
| 9 | 19 | var model: BrowserTabDataBase? { |
| 10 | 20 | didSet { |
| 11 | 21 | handleUI() |
| ... | ... | @@ -14,20 +24,20 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
| 14 | 24 | |
| 15 | 25 | weak var delegate: OpenedTabsCellDelegate? |
| 16 | 26 | |
| 17 | - let siteNameLabel: UILabel = { | |
| 27 | + private let siteNameLabel: UILabel = { | |
| 18 | 28 | let obj = UILabel() |
| 19 | 29 | obj.font = FontConstants.regularFont_14 |
| 20 | 30 | return obj |
| 21 | 31 | }() |
| 22 | 32 | |
| 23 | - let sitePreviewImageContainer: UIView = { | |
| 33 | + private let sitePreviewImageContainer: UIView = { | |
| 24 | 34 | let obj = UIView() |
| 25 | 35 | obj.clipsToBounds = true |
| 26 | 36 | obj.layer.cornerRadius = 10 |
| 27 | 37 | return obj |
| 28 | 38 | }() |
| 29 | 39 | |
| 30 | - let sitePreviewImage: UIImageView = { | |
| 40 | + private let sitePreviewImage: UIImageView = { | |
| 31 | 41 | let obj = UIImageView() |
| 32 | 42 | obj.contentMode = .scaleAspectFill |
| 33 | 43 | return obj |
| ... | ... | @@ -41,10 +51,11 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
| 41 | 51 | return obj |
| 42 | 52 | }() |
| 43 | 53 | |
| 44 | - var panGestureRecognizer: UIPanGestureRecognizer! | |
| 54 | + private var panGestureRecognizer: UIPanGestureRecognizer! | |
| 45 | 55 | |
| 46 | 56 | override init(frame: CGRect) { |
| 47 | 57 | super.init(frame: frame) |
| 58 | + | |
| 48 | 59 | setup() |
| 49 | 60 | } |
| 50 | 61 | |
| ... | ... | @@ -52,14 +63,16 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
| 52 | 63 | fatalError("init(coder:) has not been implemented") |
| 53 | 64 | } |
| 54 | 65 | |
| 55 | - func setup() { | |
| 66 | + private func setup() { | |
| 56 | 67 | self.backgroundColor = .white |
| 57 | 68 | layer.cornerRadius = 10 |
| 58 | - shadowSetup() | |
| 59 | 69 | contentView.addSubview(siteNameLabel) |
| 60 | 70 | contentView.addSubview(closeTabButton) |
| 61 | 71 | contentView.addSubview(sitePreviewImageContainer) |
| 72 | + | |
| 62 | 73 | sitePreviewImageContainer.addSubview(sitePreviewImage) |
| 74 | + | |
| 75 | + shadowSetup() | |
| 63 | 76 | setupConstraints() |
| 64 | 77 | addingTargets() |
| 65 | 78 | setupPanGesture() |
| ... | ... | @@ -81,8 +94,8 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
| 81 | 94 | |
| 82 | 95 | sitePreviewImageContainer.snp.makeConstraints { make in |
| 83 | 96 | make.top.equalTo(closeTabButton.snp.bottom).offset(8) |
| 84 | - make.bottom.equalToSuperview().offset(-8) | |
| 85 | 97 | make.leading.trailing.equalToSuperview().inset(8) |
| 98 | + make.bottom.equalToSuperview().offset(-8) | |
| 86 | 99 | } |
| 87 | 100 | |
| 88 | 101 | sitePreviewImage.snp.makeConstraints { make in |
| ... | ... | @@ -92,6 +105,7 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
| 92 | 105 | |
| 93 | 106 | override func layoutSubviews() { |
| 94 | 107 | super.layoutSubviews() |
| 108 | + | |
| 95 | 109 | shadowSetup() |
| 96 | 110 | } |
| 97 | 111 | } |
| ... | ... | @@ -100,17 +114,11 @@ final class OpenedTabsCollectionViewCell: UICollectionViewCell { |
| 100 | 114 | |
| 101 | 115 | //MARK: Helpers |
| 102 | 116 | extension OpenedTabsCollectionViewCell { |
| 103 | - func setupPanGesture() { | |
| 117 | + private func setupPanGesture() { | |
| 104 | 118 | panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(_:))) |
| 105 | 119 | addGestureRecognizer(panGestureRecognizer) |
| 106 | 120 | } |
| 107 | 121 | |
| 108 | - func gestureRecognizer() { | |
| 109 | - let swipeRightGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(handleSwipe)) | |
| 110 | - swipeRightGestureRecognizer.direction = .right | |
| 111 | - addGestureRecognizer(swipeRightGestureRecognizer) | |
| 112 | - } | |
| 113 | - | |
| 114 | 122 | private func shadowSetup() { |
| 115 | 123 | layer.shadowColor = UIColor.black.withAlphaComponent(0.1).cgColor |
| 116 | 124 | layer.shadowOpacity = 1 |
| ... | ... | @@ -118,10 +126,9 @@ extension OpenedTabsCollectionViewCell { |
| 118 | 126 | layer.shadowOffset = CGSize(width: 0, height: 0) |
| 119 | 127 | } |
| 120 | 128 | |
| 121 | - func addingTargets() { | |
| 129 | + private func addingTargets() { | |
| 122 | 130 | closeTabButton.addTarget(self, action: #selector(deleteTab), for: .touchUpInside) |
| 123 | 131 | } |
| 124 | - | |
| 125 | 132 | } |
| 126 | 133 | |
| 127 | 134 | |
| ... | ... | @@ -139,17 +146,13 @@ extension OpenedTabsCollectionViewCell { |
| 139 | 146 | @objc |
| 140 | 147 | private func deleteTab() { |
| 141 | 148 | delegate?.deleteTabDelegateFunc(cell: self) |
| 149 | + | |
| 142 | 150 | if let tabId = model?.tabId { |
| 143 | 151 | TabManager.shared.deleteTab(tabId: tabId) |
| 144 | 152 | } |
| 145 | 153 | } |
| 146 | 154 | |
| 147 | 155 | @objc |
| 148 | - private func handleSwipe() { | |
| 149 | - deleteTab() | |
| 150 | - } | |
| 151 | - | |
| 152 | - @objc | |
| 153 | 156 | private func handlePan(_ gesture: UIPanGestureRecognizer) { |
| 154 | 157 | let translation = gesture.translation(in: self) |
| 155 | 158 | let width = self.frame.width | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 28.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | |
| ... | ... | @@ -16,34 +17,39 @@ enum HistoryToolbarElementType { |
| 16 | 17 | final class TabsToolbarView: UIView { |
| 17 | 18 | var action: ((HistoryToolbarElementType) -> Void)? |
| 18 | 19 | |
| 19 | - let toolbar: UIToolbar = { | |
| 20 | + private let toolbar: UIToolbar = { | |
| 20 | 21 | let obj = UIToolbar() |
| 21 | 22 | obj.barTintColor = .white |
| 23 | + | |
| 22 | 24 | return obj |
| 23 | 25 | }() |
| 24 | 26 | |
| 25 | - let newTabToolbarButtonItem: UIBarButtonItem = { | |
| 27 | + private let newTabToolbarButtonItem: UIBarButtonItem = { | |
| 26 | 28 | let obj = UIBarButtonItem() |
| 27 | 29 | obj.image = UIImage(systemName: "plus") |
| 28 | 30 | obj.tintColor = .gray |
| 31 | + | |
| 29 | 32 | return obj |
| 30 | 33 | }() |
| 31 | 34 | |
| 32 | - | |
| 33 | - let showTabToolbarButtonItem: UIBarButtonItem = { | |
| 35 | + | |
| 36 | + let showedCountOfTabs: UIBarButtonItem = { | |
| 34 | 37 | let obj = UIBarButtonItem() |
| 35 | 38 | obj.tintColor = .gray |
| 39 | + | |
| 36 | 40 | return obj |
| 37 | 41 | }() |
| 38 | 42 | |
| 39 | - let doneTabToolbarButtonItem: UIBarButtonItem = { | |
| 43 | + private let doneTabToolbarButtonItem: UIBarButtonItem = { | |
| 40 | 44 | let obj = UIBarButtonItem() |
| 41 | 45 | obj.title = "Done" |
| 46 | + | |
| 42 | 47 | return obj |
| 43 | 48 | }() |
| 44 | 49 | |
| 45 | 50 | override init(frame: CGRect) { |
| 46 | 51 | super.init(frame: frame) |
| 52 | + | |
| 47 | 53 | setup() |
| 48 | 54 | } |
| 49 | 55 | |
| ... | ... | @@ -53,12 +59,8 @@ final class TabsToolbarView: UIView { |
| 53 | 59 | |
| 54 | 60 | private func setup() { |
| 55 | 61 | addSubview(toolbar) |
| 56 | - let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) | |
| 57 | - toolbar.items = [ newTabToolbarButtonItem, | |
| 58 | - flexibleSpace, showTabToolbarButtonItem, | |
| 59 | - flexibleSpace, doneTabToolbarButtonItem ] | |
| 60 | 62 | |
| 61 | - toolbar.backgroundColor = .white | |
| 63 | + setupToolbar() | |
| 62 | 64 | initActions() |
| 63 | 65 | setupConstraints() |
| 64 | 66 | } |
| ... | ... | @@ -78,11 +80,21 @@ extension TabsToolbarView { |
| 78 | 80 | private func initActions() { |
| 79 | 81 | newTabToolbarButtonItem.target = self |
| 80 | 82 | newTabToolbarButtonItem.action = #selector(didItemTapped(_:)) |
| 81 | - showTabToolbarButtonItem.target = self | |
| 82 | - showTabToolbarButtonItem.action = #selector(didItemTapped(_:)) | |
| 83 | + | |
| 84 | + showedCountOfTabs.target = self | |
| 85 | + showedCountOfTabs.action = #selector(didItemTapped(_:)) | |
| 86 | + | |
| 83 | 87 | doneTabToolbarButtonItem.target = self |
| 84 | 88 | doneTabToolbarButtonItem.action = #selector(didItemTapped(_:)) |
| 85 | 89 | } |
| 90 | + | |
| 91 | + private func setupToolbar() { | |
| 92 | + let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil) | |
| 93 | + toolbar.items = [ newTabToolbarButtonItem, | |
| 94 | + flexibleSpace, showedCountOfTabs, | |
| 95 | + flexibleSpace, doneTabToolbarButtonItem ] | |
| 96 | + toolbar.backgroundColor = .white | |
| 97 | + } | |
| 86 | 98 | } |
| 87 | 99 | |
| 88 | 100 | // MARK: - Actions |
| ... | ... | @@ -93,14 +105,14 @@ extension TabsToolbarView { |
| 93 | 105 | return |
| 94 | 106 | } |
| 95 | 107 | switch sender { |
| 96 | - case newTabToolbarButtonItem: | |
| 97 | - action(.add) | |
| 98 | - case showTabToolbarButtonItem: | |
| 99 | - action(.tabs) | |
| 100 | - case doneTabToolbarButtonItem: | |
| 101 | - action(.done) | |
| 102 | - default: | |
| 103 | - break | |
| 108 | + case newTabToolbarButtonItem: | |
| 109 | + action(.add) | |
| 110 | + case showedCountOfTabs: | |
| 111 | + action(.tabs) | |
| 112 | + case doneTabToolbarButtonItem: | |
| 113 | + action(.done) | |
| 114 | + default: | |
| 115 | + break | |
| 104 | 116 | } |
| 105 | 117 | } |
| 106 | 118 | } | ... | ... |
| ... | ... | @@ -4,6 +4,7 @@ |
| 4 | 4 | // |
| 5 | 5 | // Created by Artem Talko on 28.09.2023. |
| 6 | 6 | // |
| 7 | +//MARK: Checked | |
| 7 | 8 | |
| 8 | 9 | import UIKit |
| 9 | 10 | import SnapKit |
| ... | ... | @@ -13,31 +14,35 @@ final class TabsView: UIView { |
| 13 | 14 | let obj = UICollectionViewFlowLayout() |
| 14 | 15 | obj.minimumInteritemSpacing = 4.sizeW |
| 15 | 16 | obj.sectionInset = UIEdgeInsets(top: 16.sizeH, left: 16.sizeW, bottom: 16.sizeH, right: 16.sizeW) |
| 17 | + | |
| 16 | 18 | let collectionView = UICollectionView(frame: .zero, collectionViewLayout: obj) |
| 17 | 19 | collectionView.showsVerticalScrollIndicator = false |
| 18 | 20 | collectionView.backgroundColor = .clear |
| 21 | + | |
| 19 | 22 | return collectionView |
| 20 | 23 | }() |
| 21 | 24 | |
| 22 | - let tabsToolbarView: TabsToolbarView = { | |
| 25 | + let tabsToolbarView: TabsToolbarView = { | |
| 23 | 26 | let obj = TabsToolbarView() |
| 24 | 27 | obj.backgroundColor = ColorConstants.lightGray |
| 28 | + | |
| 25 | 29 | return obj |
| 26 | 30 | }() |
| 27 | 31 | |
| 28 | 32 | override init(frame: CGRect) { |
| 29 | 33 | super.init(frame: frame) |
| 30 | - setup() | |
| 31 | - setupConstraints() | |
| 34 | + setupUI() | |
| 32 | 35 | } |
| 33 | 36 | |
| 34 | 37 | required init?(coder: NSCoder) { |
| 35 | 38 | fatalError("init(coder:) has not been implemented") |
| 36 | 39 | } |
| 37 | 40 | |
| 38 | - private func setup() { | |
| 41 | + private func setupUI() { | |
| 39 | 42 | addSubview(openedTabsCollectionView) |
| 40 | 43 | addSubview(tabsToolbarView) |
| 44 | + | |
| 45 | + setupConstraints() | |
| 41 | 46 | } |
| 42 | 47 | |
| 43 | 48 | private func setupConstraints() { |
| ... | ... | @@ -48,8 +53,8 @@ final class TabsView: UIView { |
| 48 | 53 | } |
| 49 | 54 | tabsToolbarView.snp.makeConstraints { make in |
| 50 | 55 | make.leading.equalToSuperview() |
| 51 | - make.trailing.equalToSuperview() | |
| 52 | 56 | make.bottom.equalTo(safeAreaLayoutGuide.snp.bottom) |
| 57 | + make.trailing.equalToSuperview() | |
| 53 | 58 | } |
| 54 | 59 | } |
| 55 | 60 | } | ... | ... |
| ... | ... | @@ -8,7 +8,6 @@ |
| 8 | 8 | import Foundation |
| 9 | 9 | |
| 10 | 10 | struct StringConstants { |
| 11 | - //static let shared = StringConstants() | |
| 12 | 11 | |
| 13 | 12 | ///PayloadView |
| 14 | 13 | static let ourBrowser = "Our browser lets you quickly and safely access \nthe internet. You can use it to look at web \npages, find information, and chat with friends." | ... | ... |
| ... | ... | @@ -18,7 +18,7 @@ |
| 18 | 18 | <subviews> |
| 19 | 19 | <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" image="Gotoweb" translatesAutoresizingMaskIntoConstraints="NO" id="M9l-6x-NJv"> |
| 20 | 20 | <rect key="frame" x="128" y="395" width="136" height="62"/> |
| 21 | - <autoresizingMask key="autoresizingMask"/> | |
| 21 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | |
| 22 | 22 | <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/> |
| 23 | 23 | </imageView> |
| 24 | 24 | </subviews> | ... | ... |
| ... | ... | @@ -12,6 +12,8 @@ final class SnapshotService { |
| 12 | 12 | static let shared = SnapshotService() |
| 13 | 13 | let snapshotConfiguration = WKSnapshotConfiguration() |
| 14 | 14 | |
| 15 | + private init() {} | |
| 16 | + | |
| 15 | 17 | func makeSnapshot(_ viewForSnap: UIView) -> UIImage { |
| 16 | 18 | let renderer = UIGraphicsImageRenderer(size: viewForSnap.bounds.size) |
| 17 | 19 | let siteSnapshotImage = renderer.image { (context) in | ... | ... |
Please
register
or
login
to post a comment