Commit a66b8be6b3b58e45ef9b8dea3b8fb5f8c48022a5

Authored by Artem Talko
1 parent 5545d0b4

fixes

Showing 27 changed files with 266 additions and 225 deletions
... ... @@ -43,7 +43,6 @@
43 43 197534762B10968E000818D3 /* SubscriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197534752B10968E000818D3 /* SubscriptionViewController.swift */; };
44 44 197534782B1096A7000818D3 /* SubscriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197534772B1096A7000818D3 /* SubscriptionView.swift */; };
45 45 1975347B2B109A37000818D3 /* SubscriptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1975347A2B109A37000818D3 /* SubscriptionTableViewCell.swift */; };
46   - 197C2A242B0E3A7B0010B386 /* AdBlockButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A232B0E3A7B0010B386 /* AdBlockButton.swift */; };
47 46 197C2A282B0F65840010B386 /* OpenBrowserHomeTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A272B0F65830010B386 /* OpenBrowserHomeTransition.swift */; };
48 47 197C2A2D2B0F9EEB0010B386 /* SubscriptionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */; };
49 48 197FC3EF2AC21E1F007F429C /* PayloadViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197FC3EE2AC21E1F007F429C /* PayloadViewController.swift */; };
... ... @@ -146,7 +145,6 @@
146 145 197534752B10968E000818D3 /* SubscriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionViewController.swift; sourceTree = "<group>"; };
147 146 197534772B1096A7000818D3 /* SubscriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionView.swift; sourceTree = "<group>"; };
148 147 1975347A2B109A37000818D3 /* SubscriptionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionTableViewCell.swift; sourceTree = "<group>"; };
149   - 197C2A232B0E3A7B0010B386 /* AdBlockButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdBlockButton.swift; sourceTree = "<group>"; };
150 148 197C2A272B0F65830010B386 /* OpenBrowserHomeTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenBrowserHomeTransition.swift; sourceTree = "<group>"; };
151 149 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionManager.swift; sourceTree = "<group>"; };
152 150 197FC3EE2AC21E1F007F429C /* PayloadViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayloadViewController.swift; sourceTree = "<group>"; };
... ... @@ -223,7 +221,6 @@
223 221 isa = PBXGroup;
224 222 children = (
225 223 194206C62B10DFAF000C1263 /* Cell */,
226   - 197C2A222B0E3A420010B386 /* Components */,
227 224 191BB8802AC6FF6600A2DEB9 /* RemoveAdvertView.swift */,
228 225 );
229 226 path = View;
... ... @@ -468,14 +465,6 @@
468 465 path = Cell;
469 466 sourceTree = "<group>";
470 467 };
471   - 197C2A222B0E3A420010B386 /* Components */ = {
472   - isa = PBXGroup;
473   - children = (
474   - 197C2A232B0E3A7B0010B386 /* AdBlockButton.swift */,
475   - );
476   - path = Components;
477   - sourceTree = "<group>";
478   - };
479 468 197FC3F02AC2AF8A007F429C /* Cell */ = {
480 469 isa = PBXGroup;
481 470 children = (
... ... @@ -973,7 +962,6 @@
973 962 191BB8692AC6A66900A2DEB9 /* SearchingTableViewCell.swift in Sources */,
974 963 1990C69C2AEFDF89004AF856 /* UICollectionViewCell+convertFrameToScreenCoordinates.swift in Sources */,
975 964 19FCBF222AC1727800F83A7F /* AppDelegate.swift in Sources */,
976   - 197C2A242B0E3A7B0010B386 /* AdBlockButton.swift in Sources */,
977 965 197C2A282B0F65840010B386 /* OpenBrowserHomeTransition.swift in Sources */,
978 966 19D1F2E02AC1EF3200510506 /* PayloadView.swift in Sources */,
979 967 19FFD6BF2AE64A7B00D0F768 /* SnapshotService.swift in Sources */,
... ...
... ... @@ -23,4 +23,3 @@ final class HistoryDataBase: Object {
23 23 self.lastVisit = lastVisit
24 24 }
25 25 }
26   -
... ...
... ... @@ -7,7 +7,6 @@
7 7
8 8 import UIKit
9 9
10   -
11 10 extension BinaryFloatingPoint {
12 11 private var size: CGSize {
13 12 return CGSize(width: 375, height: 812)
... ...
... ... @@ -45,6 +45,3 @@ final class DateManager {
45 45 }
46 46 }
47 47 }
48   -
49   -
50   -
... ...
... ... @@ -21,7 +21,6 @@ final class HistoryDBManager {
21 21 }
22 22 }
23 23
24   - //MARK: ADDING
25 24 func saveToHistory(siteTitle: String, siteUrl: String, lastVisit: Date) {
26 25 let historyCell = HistoryDataBase(siteTitle: siteTitle, siteUrl: siteUrl, lastVisit: lastVisit)
27 26 do {
... ... @@ -34,7 +33,6 @@ final class HistoryDBManager {
34 33 }
35 34 }
36 35
37   - //MARK: GETTING
38 36 func getHistory(sorted: Bool = false) -> [HistoryDataBase] {
39 37 if sorted {
40 38 let history = realm.objects(HistoryDataBase.self).sorted(byKeyPath: "lastVisit", ascending: false)
... ... @@ -74,7 +72,6 @@ final class HistoryDBManager {
74 72 return createHistoryData(elements: filteredHistory)
75 73 }
76 74
77   - //MARK: DELETING
78 75 func cleanHistory() {
79 76 do {
80 77 let history = realm.objects(HistoryDataBase.self)
... ... @@ -111,7 +108,5 @@ final class HistoryDBManager {
111 108 }
112 109 }
113 110 }
114   -
115   -
116 111 }
117 112
... ...
... ... @@ -35,7 +35,7 @@ final class SubscriptionManager: ObservableObject {
35 35 updateListenerTask?.cancel()
36 36 }
37 37
38   - func listenForTransactions() -> Task<Void, Error> {
  38 + private func listenForTransactions() -> Task<Void, Error> {
39 39 return Task.detached {
40 40 for await result in Transaction.updates {
41 41 do {
... ... @@ -49,7 +49,7 @@ final class SubscriptionManager: ObservableObject {
49 49 }
50 50 }
51 51
52   - func requestProducts() async {
  52 + private func requestProducts() async {
53 53 do {
54 54 storeProducts = try await Product.products(for: productDict.values)
55 55
... ... @@ -58,7 +58,7 @@ final class SubscriptionManager: ObservableObject {
58 58 }
59 59 }
60 60
61   - func checkVerified<T>(_ result: VerificationResult<T>) throws -> T {
  61 + private func checkVerified<T>(_ result: VerificationResult<T>) throws -> T {
62 62 switch result {
63 63 case .unverified:
64 64 throw StoreError.failedVerification
... ... @@ -68,7 +68,7 @@ final class SubscriptionManager: ObservableObject {
68 68 }
69 69
70 70 @MainActor
71   - func updateCustomerProductStatus() async {
  71 + private func updateCustomerProductStatus() async {
72 72 var purchasedCourses: [Product] = []
73 73
74 74 for await result in Transaction.currentEntitlements {
... ... @@ -101,10 +101,6 @@ final class SubscriptionManager: ObservableObject {
101 101 }
102 102 }
103 103
104   - func isPurchased(_ product: Product) async throws -> Bool {
105   - return purchasedSubscriptions.contains(product)
106   - }
107   -
108 104 func restorePurchase() async throws {
109 105 try await AppStore.sync()
110 106 }
... ...
... ... @@ -31,7 +31,6 @@ struct StringConstants {
31 31 static let removeAdvertTableViewData = ["Unlimited blocks & uploads", "Enhanced User Experience", "Faster Page Load Times", "Privacy and Security"]
32 32 static let search = "Search"
33 33
34   -
35 34 ///RemoveAdvertView
36 35 static let yourDiscount = "You save 91% - normally US $9,99"
37 36 static let freeTrial = "3-day free trial"
... ... @@ -45,10 +44,8 @@ struct StringConstants {
45 44 ///setting cell detail info
46 45 static let settingPolicy = "GoToWeb Safe Browser Privacy Policy\nCreative Tech LLC built the GoToWeb Safe Browser app as a Commercial app. This SERVICE is provided by Creative Tech LLC and is intended for use as is.\n\nThis page is used to inform visitors regarding our policies with the collection, use, and disclosure of Personal Information if anyone decided to use our Service.\n\nIf you choose to use our Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that we collect is used for providing and improving the Service. We will not use or share your information with anyone except as described in this Privacy Policy.\n\nThe terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which are accessible at GoToWeb Safe Browser unless otherwise defined in this Privacy Policy.\n\nInformation Collection and Use\n\nFor a better experience, while using our Service, we may require you to provide us with certain personally identifiable information. The information that we request will be retained by us and used as described in this privacy policy.\n\nThe app does use third-party services that may collect information used to identify you.\n\nLink to the privacy policy of third-party service providers used by the app\n\nGoogle Analytics for Firebase\nFirebase Crashlytics\nFacebook\nUnity\nAppLovin\n\nLog Data\n\nWe want to inform you that whenever you use our Service, in a case of an error in the app we collect data and information (through third-party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing our Service, the time and date of your use of the Service, and other statistics.\n\nCookies\n\nCookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory.\n\nThis Service does not use these “cookies” explicitly. However, the app may use third-party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service.\n\nService Providers\n\nWe may employ third-party companies and individuals due to the following reasons:\n\nTo facilitate our Service;\nTo provide the Service on our behalf;\nTo perform Service-related services; or\nTo assist us in analyzing how our Service is used.\nWe want to inform users of this Service that these third parties have access to their Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose.\n\nSecurity\n\nWe value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and we cannot guarantee its absolute security.\n\nLinks to Other Sites\n\nThis Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by us. Therefore, we strongly advise you to review the Privacy Policy of these websites. We have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services.\n\nChildren’s Privacy\n\nThese Services do not address anyone under the age of 13. We do not knowingly collect personally identifiable information from children under 13 years of age. In the case we discover that a child under 13 has provided us with personal information, we immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact us so that we will be able to do the necessary actions.\n\nChanges to This Privacy Policy\n\nWe may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. We will notify you of any changes by posting the new Privacy Policy on this page.\n\nThis policy is effective as of 2023-11-24\n\nContact Us\n\nIf you have any questions or suggestions about our Privacy Policy, do not hesitate to contact us at creattechllc@gmail.com.\n\n\n"
47 46
48   -
49 47 static let settingTerms = "GoToWeb safe browser Terms & Conditions\nBy downloading or using the app, these terms will automatically apply to you – you should make sure therefore that you read them carefully before using the app. You’re not allowed to copy or modify the app, any part of the app, or our trademarks in any way. You’re not allowed to attempt to extract the source code of the app, and you also shouldn’t try to translate the app into other languages or make derivative versions. The app itself, and all the trademarks, copyright, database rights, and other intellectual property rights related to it, still belong to Creative Tech LLC.\n\nCreative Tech LLC is committed to ensuring that the app is as useful and efficient as possible. For that reason, we reserve the right to make changes to the app or to charge for its services, at any time and for any reason. We will never charge you for the app or its services without making it very clear to you exactly what you’re paying for.\n\nThe GoToWeb safe browser app stores and processes personal data that you have provided to us, to provide our Service. It’s your responsibility to keep your phone and access to the app secure. We therefore recommend that you do not jailbreak or root your phone, which is the process of removing software restrictions and limitations imposed by the official operating system of your device. It could make your phone vulnerable to malware/viruses/malicious programs, compromise your phone’s security features and it could mean that the GoToWeb safe browser app won’t work properly or at all.\n\nThe app does use third-party services that declare their Terms and Conditions.\n\nLink to Terms and Conditions of third-party service providers used by the app\n\nGoogle Analytics for Firebase\nFirebase Crashlytics\nFacebook\nUnity\nAppLovin\n\nYou should be aware that there are certain things that Creative Tech LLC will not take responsibility for. Certain functions of the app will require the app to have an active internet connection. The connection can be Wi-Fi or provided by your mobile network provider, but Creative Tech LLC cannot take responsibility for the app not working at full functionality if you don’t have access to Wi-Fi, and you don’t have any of your data allowance left.\n\nIf you’re using the app outside of an area with Wi-Fi, you should remember that the terms of the agreement with your mobile network provider will still apply. As a result, you may be charged by your mobile provider for the cost of data for the duration of the connection while accessing the app, or other third-party charges. In using the app, you’re accepting responsibility for any such charges, including roaming data charges if you use the app outside of your home territory (i.e. region or country) without turning off data roaming. If you are not the bill payer for the device on which you’re using the app, please be aware that we assume that you have received permission from the bill payer for using the app.\n\nAlong the same lines, Creative Tech LLC cannot always take responsibility for the way you use the app i.e. You need to make sure that your device stays charged – if it runs out of battery and you can’t turn it on to avail the Service, Creative Tech LLC cannot accept responsibility.\n\nWith respect to Creative Tech LLC’s responsibility for your use of the app, when you’re using the app, it’s important to bear in mind that although we endeavor to ensure that it is updated and correct at all times, we do rely on third parties to provide information to us so that we can make it available to you. Creative Tech LLC accepts no liability for any loss, direct or indirect, you experience as a result of relying wholly on this functionality of the app.\n\nAt some point, we may wish to update the app. The app is currently available on iOS – the requirements for the system(and for any additional systems we decide to extend the availability of the app to) may change, and you’ll need to download the updates if you want to keep using the app. Creative Tech LLC does not promise that it will always update the app so that it is relevant to you and/or works with the iOS version that you have installed on your device. However, you promise to always accept updates to the application when offered to you, We may also wish to stop providing the app, and may terminate use of it at any time without giving notice of termination to you. Unless we tell you otherwise, upon any termination, (a) the rights and licenses granted to you in these terms will end; (b) you must stop using the app, and (if needed) delete it from your device.\n\nChanges to This Terms and Conditions\n\nWe may update our Terms and Conditions from time to time. Thus, you are advised to review this page periodically for any changes. We will notify you of any changes by posting the new Terms and Conditions on this page.\n\nThese terms and conditions are effective as of 2023-11-24\n\nContact Us\n\nIf you have any questions or suggestions about our Terms and Conditions, do not hesitate to contact us at creattechllc@gmail.com \n\n\n"
50 48
51   -
52 49 static let settingHeader = "Terms\nand conditions"
53 50 static let settingAgreeButtonText = "Agree & Continue"
54 51 static let privacyHeaderText = "Your Privacy\n is our top priority"
... ... @@ -73,5 +70,8 @@ struct StringConstants {
73 70 ]
74 71 static let notificationTitle = "Gotoweb Notification"
75 72 static let notificationIdentifier = "browser-notification"
  73 +
  74 + static let segmentedControlItems = ["AdBlock", "Browser"]
  75 +
76 76 }
77 77
... ...
1 1 {
2 2 "images" : [
3 3 {
4   - "filename" : "Group 1adBlockButtonOff.pdf",
  4 + "filename" : "Play.pdf",
5 5 "idiom" : "universal"
6 6 }
7 7 ],
... ...
1 1 {
2 2 "images" : [
3 3 {
4   - "filename" : "Group 1.png",
  4 + "filename" : "Play.png",
5 5 "idiom" : "universal"
6 6 }
7 7 ],
... ...
  1 +{
  2 + "images" : [
  3 + {
  4 + "filename" : "Back-arrow-for-dark-theme.pdf",
  5 + "idiom" : "universal"
  6 + }
  7 + ],
  8 + "info" : {
  9 + "author" : "xcode",
  10 + "version" : 1
  11 + }
  12 +}
... ...
... ... @@ -10,7 +10,6 @@ import WebKit
10 10
11 11 final class SnapshotService {
12 12 static let shared = SnapshotService()
13   - let snapshotConfiguration = WKSnapshotConfiguration()
14 13
15 14 private init() {}
16 15
... ...
... ... @@ -20,7 +20,7 @@ final class BrowserHomeViewController: UIViewController {
20 20
21 21 private var subscriptions: Set<AnyCancellable>
22 22 private var searchRequestURL: String
23   - private let images = StringConstants.browserHomeVCImages
  23 + private let frequentlyVisitedTabsImages: [String]
24 24 private var currentTabId: Int?
25 25
26 26 private var url: String? {
... ... @@ -33,57 +33,56 @@ final class BrowserHomeViewController: UIViewController {
33 33 init(url: String?, currentTabId: Int?) {
34 34 searchResultViewController = SearchResultViewController(searchLink: String())
35 35 searchingViewController = SearchingViewController(dataForReq: [])
36   - subscriptions = []
37 36 searchRequestURL = URLConstants.googleURL
  37 + frequentlyVisitedTabsImages = StringConstants.browserHomeVCImages
  38 + subscriptions = []
38 39
39   - super.init(nibName: nil, bundle: nil)
40 40 self.url = url
41 41 self.currentTabId = currentTabId
  42 +
  43 + super.init(nibName: nil, bundle: nil)
42 44 }
43 45
44 46 required init?(coder: NSCoder) {
45 47 fatalError("init(coder:) has not been implemented")
46 48 }
47 49
  50 + override func loadView() {
  51 + view = mainView
  52 + }
  53 +
48 54 override func viewDidLoad() {
49 55 super.viewDidLoad()
50   - view.backgroundColor = ColorConstants.lightGray
  56 +
51 57 initViewController()
52 58 }
53 59
54 60 override func viewWillAppear(_ animated: Bool) {
55   - keyboardObserver()
56   - }
57   -
58   - private func initViewController() {
59   - setupCollectionView()
60   - addTargets()
61   - setupSearchBarComponentsAction()
62   - setupSearchingViewController()
63   - progressObserver()
64   - }
65   -
66   - override func viewIsAppearing(_ animated: Bool) {
67 61 navigationController?.isNavigationBarHidden = true
68 62
69 63 tabsViewController = getTabsViewController()
  64 + keyboardObserver()
70 65 }
71   -
72   - override func loadView() {
73   - view = mainView
74   - }
75   -
  66 +
76 67 override func viewWillDisappear(_ animated: Bool) {
77 68 super.viewWillDisappear(animated)
  69 +
78 70 NotificationCenter.default.removeObserver(self)
79 71 }
  72 +
  73 + private func initViewController() {
  74 + setupSearchBarComponentsAction()
  75 + setupSearchingViewController()
  76 + setupCollectionView()
  77 + progressObserver()
  78 + addTargets()
  79 + }
80 80 }
81 81
82   -
83 82 //MARK: CollectionView Setup
84 83 extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
85 84 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
86   - images.count
  85 + frequentlyVisitedTabsImages.count
87 86 }
88 87
89 88 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
... ... @@ -96,7 +95,7 @@ extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionVie
96 95 }
97 96
98 97 func setupCellForCollectionView(_ cell: TabCollectionViewCell, _ indexPath: IndexPath) -> TabCollectionViewCell {
99   - let imageName = images[indexPath.item]
  98 + let imageName = frequentlyVisitedTabsImages[indexPath.item]
100 99 cell.tabCellImage.image = UIImage(named: imageName)
101 100 cell.tabCellLabel.text = imageName
102 101
... ... @@ -113,7 +112,6 @@ extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionVie
113 112 }
114 113 }
115 114
116   -
117 115 //MARK: - Keyboard extention
118 116 extension BrowserHomeViewController {
119 117 private func keyboardObserver() {
... ... @@ -122,7 +120,6 @@ extension BrowserHomeViewController {
122 120 }
123 121 }
124 122
125   -
126 123 //MARK: - Action
127 124 extension BrowserHomeViewController {
128 125 @objc
... ... @@ -177,6 +174,8 @@ extension BrowserHomeViewController {
177 174 private func removeSearchingViewController(_ sender: UIButton) {
178 175 searchResultAction()
179 176 }
  177 +
  178 +
180 179 }
181 180
182 181 //MARK: - Helpers
... ... @@ -217,7 +216,7 @@ extension BrowserHomeViewController {
217 216 if !sitesFromSearch.isEmpty {
218 217 searchingViewController.searchRequestData = sitesFromSearch
219 218 }
220   - addingSearchingViewController(searchingViewController)
  219 + childViewControllerHandler(searchingViewController)
221 220 }
222 221
223 222 private func setupCollectionView() {
... ... @@ -230,7 +229,8 @@ extension BrowserHomeViewController {
230 229 mainView.settingButton.addTarget(self, action: #selector(settingButtonTapped(_ :)), for: .touchUpInside)
231 230 mainView.removeAdvertSegmentControl.addTarget(self, action: #selector(advertSegmantControlStateHandler), for: .valueChanged)
232 231 mainView.searchBarContainer.searchBarView.searchTextFieldView.addTarget(self, action: #selector(searchBarTextChanged), for: .editingChanged)
233   - searchingViewController.mainView.searchingButton.addTarget(self, action: #selector(removeSearchingViewController(_ :)), for: .touchUpInside)
  232 +
  233 + searchingViewControllerAction()
234 234 addToolbarTargets()
235 235 }
236 236
... ... @@ -238,6 +238,10 @@ extension BrowserHomeViewController {
238 238 mainView.toolbarView.action = didTabButtonTapped
239 239 }
240 240
  241 + private func searchingViewControllerAction() {
  242 + searchingViewController.mainView.searchingButton.addTarget(self, action: #selector(removeSearchingViewController(_ :)), for: .touchUpInside)
  243 + }
  244 +
241 245 private func openAdditionViewController(_ viewController: UIViewController) {
242 246 viewController.modalPresentationStyle = .fullScreen
243 247 present(viewController, animated: true, completion: nil)
... ... @@ -249,8 +253,8 @@ extension BrowserHomeViewController {
249 253 return
250 254 }
251 255 searchRequestURL = "https://www.google.com/search?q=" + (cell.searchLabel.text ?? "")
252   - openSearchResult()
253 256 mainView.searchBarContainer.searchBarView.searchTextFieldView.endEditing(true)
  257 + openSearchResult()
254 258 }
255 259 }
256 260
... ... @@ -261,7 +265,10 @@ extension BrowserHomeViewController {
261 265 let request = URLRequest(url: localUrl)
262 266 searchResultViewController.mainView.searchResultView.load(request)
263 267 }
264   - addingSearchingViewController(searchResultViewController)
  268 + searchResultViewController.onCloseButtonTapped = { [weak self] in
  269 + self?.removeChildViewController()
  270 + }
  271 + childViewControllerHandler(searchResultViewController)
265 272 }
266 273
267 274 private func tabsButtonHandler() {
... ... @@ -283,18 +290,17 @@ extension BrowserHomeViewController {
283 290 let finalUrl = siteUrl.absoluteString
284 291 let lastVisit = DateManager.shared.currentDate
285 292 let homeViewSnapshot = SnapshotService.shared.makeSnapshot(mainView)
286   - navigationController?.popViewController(animated: true)
287 293 TabManager.shared.saveTab(tabTitle: siteTitle, snapshotImage: homeViewSnapshot, tabUrl: finalUrl)
  294 + HistoryDBManager.shared.saveToHistory(siteTitle: siteTitle, siteUrl: finalUrl, lastVisit: lastVisit)
288 295 self.currentTabId = tabsViewController?.getCellIndex().row
289 296
290   - HistoryDBManager.shared.saveToHistory(siteTitle: siteTitle, siteUrl: finalUrl, lastVisit: lastVisit)
291   -
  297 + navigationController?.popViewController(animated: true)
292 298 } else {
293 299 let homeViewSnapshot = SnapshotService.shared.makeSnapshot(mainView)
294   - navigationController?.popViewController(animated: true)
295 300 TabManager.shared.saveTab(tabTitle: "Start Page", snapshotImage: homeViewSnapshot, tabUrl: "homeUrl")
296   -
297 301 currentTabId = tabsViewController?.getCellIndex().row
  302 +
  303 + navigationController?.popViewController(animated: true)
298 304 }
299 305 }
300 306
... ... @@ -325,10 +331,9 @@ extension BrowserHomeViewController {
325 331 }
326 332 }
327 333
328   -
329 334 //MARK: - ChildVC actions
330 335 extension BrowserHomeViewController {
331   - private func addingSearchingViewController(_ childViewController: UIViewController) {
  336 + private func childViewControllerHandler(_ childViewController: UIViewController) {
332 337 if self.children.isEmpty {
333 338 addNewChildViewController(childViewController)
334 339 } else {
... ... @@ -345,12 +350,7 @@ extension BrowserHomeViewController {
345 350 }
346 351
347 352 private func removeChildViewController() {
348   - if let childViewController = self.children.first as? SearchingViewController {
349   - childViewController.view.removeFromSuperview()
350   - childViewController.willMove(toParent: nil)
351   - childViewController.removeFromParent()
352   - }
353   - if let childViewController = self.children.first as? SearchResultViewController {
  353 + if let childViewController = self.children.first {
354 354 childViewController.view.removeFromSuperview()
355 355 childViewController.willMove(toParent: nil)
356 356 childViewController.removeFromParent()
... ... @@ -358,7 +358,6 @@ extension BrowserHomeViewController {
358 358 }
359 359 }
360 360
361   -
362 361 //MARK: - SearchBar extention
363 362 extension BrowserHomeViewController: UITextFieldDelegate {
364 363 func textFieldDidBeginEditing(_ textField: UITextField) {
... ... @@ -368,7 +367,6 @@ extension BrowserHomeViewController: UITextFieldDelegate {
368 367
369 368 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
370 369 textField.resignFirstResponder()
371   -
372 370 searchRequestURL = "https://www.google.com/search?q=" + (textField.text ?? "")
373 371 openSearchResult()
374 372
... ... @@ -379,11 +377,11 @@ extension BrowserHomeViewController: UITextFieldDelegate {
379 377 mainView.searchBarContainer.searchBarView.searchTextFieldView.autocorrectionType = .no
380 378 mainView.searchBarContainer.searchBarView.searchTextFieldView.delegate = self
381 379 mainView.searchBarContainer.searchBarView.cleanTextFieldButton.addTarget(self, action: #selector(searchResultAction), for: .touchUpInside)
  380 +
382 381 buttonObserver()
383 382 }
384 383 }
385 384
386   -
387 385 //MARK: - WebView extention
388 386 extension BrowserHomeViewController {
389 387 private func buttonObserver() {
... ...
... ... @@ -10,7 +10,8 @@ import SnapKit
10 10
11 11 final class BrowserHomeView: GradientView {
12 12 let removeAdvertSegmentControl: UISegmentedControl = {
13   - let items = ["AdBlock", "Browser"]
  13 + let items = StringConstants.segmentedControlItems
  14 +
14 15 let obj = UISegmentedControl(items: items)
15 16 obj.selectedSegmentIndex = 1
16 17 obj.backgroundColor = ColorConstants.segmentControlBackground
... ... @@ -86,32 +87,37 @@ final class BrowserHomeView: GradientView {
86 87 }
87 88
88 89 private func setupConstraints() {
89   - removeAdvertSegmentControl.snp.makeConstraints { make in
  90 + removeAdvertSegmentControl.snp.makeConstraints { make in
90 91 make.top.equalTo(safeAreaLayoutGuide.snp.top).offset(16.sizeH)
91 92 make.leading.equalToSuperview().offset(54.sizeW)
92 93 make.trailing.equalTo(settingButton.snp.leading).offset(-15.sizeW)
93 94 make.height.equalTo(34.sizeH)
94 95 }
  96 +
95 97 settingButton.snp.makeConstraints { make in
96 98 make.trailing.equalToSuperview().offset(-16.sizeW)
97 99 make.height.equalTo(24.sizeH)
98 100 make.width.equalTo(24.sizeH)
99 101 make.centerY.equalTo(removeAdvertSegmentControl)
100 102 }
  103 +
101 104 titleLabel.snp.makeConstraints { make in
102 105 make.top.equalTo(removeAdvertSegmentControl.snp.bottom).offset(64.sizeH)
103 106 make.leading.equalTo(safeAreaLayoutGuide.snp.leading).offset(16.sizeW)
104 107 }
  108 +
105 109 frequentlyVisitedCollectionView.snp.makeConstraints { make in
106 110 make.top.equalTo(titleLabel.snp.bottom).offset(8.sizeH)
107 111 make.leading.trailing.equalToSuperview().inset(24.sizeW)
108 112 make.height.equalTo(120.sizeH)
109 113 }
  114 +
110 115 toolbarView.snp.makeConstraints { make in
111 116 make.leading.equalToSuperview()
112 117 make.bottom.equalToSuperview()
113 118 make.trailing.equalToSuperview()
114 119 }
  120 +
115 121 searchBarContainer.snp.makeConstraints { make in
116 122 make.leading.equalToSuperview()
117 123 make.bottom.equalToSuperview().offset(-90.sizeH)
... ...
... ... @@ -19,7 +19,7 @@ final class SearchBarView: UIView {
19 19 let searchTextFieldView: UITextField = {
20 20 let obj = UITextField()
21 21 obj.text = "Search"
22   - obj.textColor = ColorConstants.SearchbarTintBlue
  22 + obj.textColor = ColorConstants.SearchbarTintBlue
23 23
24 24 return obj
25 25 }()
... ...
... ... @@ -9,9 +9,10 @@ import UIKit
9 9
10 10 final class PayloadViewController: UIViewController {
11 11 private let mainView = PayloadView()
  12 +
12 13 private let payloadTableViewData: [String]
13 14
14   - init(){
  15 + init() {
15 16 payloadTableViewData = StringConstants.payloadViewControllerData
16 17
17 18 super.init(nibName: nil, bundle: nil)
... ... @@ -21,6 +22,10 @@ final class PayloadViewController: UIViewController {
21 22 fatalError("init(coder:) has not been implemented")
22 23 }
23 24
  25 + override func loadView() {
  26 + view = mainView
  27 + }
  28 +
24 29 override func viewDidLoad() {
25 30 super.viewDidLoad()
26 31
... ... @@ -34,10 +39,6 @@ final class PayloadViewController: UIViewController {
34 39 addTargets()
35 40 }
36 41
37   - override func loadView() {
38   - view = mainView
39   - }
40   -
41 42 override func viewWillDisappear(_ animated: Bool) {
42 43 super.viewWillDisappear(animated)
43 44
... ...
... ... @@ -26,16 +26,16 @@ final class RemoveAdvertViewController: UIViewController {
26 26 fatalError("init(coder:) has not been implemented")
27 27 }
28 28
  29 + override func loadView() {
  30 + view = mainView
  31 + }
  32 +
29 33 override func viewDidLoad() {
30 34 super.viewDidLoad()
31 35
32 36 initViewController()
33 37 }
34 38
35   - override func loadView() {
36   - view = mainView
37   - }
38   -
39 39 private func initViewController() {
40 40 addTargets()
41 41 setupTableView()
... ... @@ -51,7 +51,6 @@ extension RemoveAdvertViewController {
51 51 } else {
52 52 subscriptionHandler()
53 53 }
54   -
55 54 }
56 55
57 56 @objc
... ... @@ -128,6 +127,7 @@ extension RemoveAdvertViewController {
128 127 let okAction = UIAlertAction(title: "OK", style: .default)
129 128 alert.addAction(okAction)
130 129 present(alert, animated: true)
  130 +
131 131 turnOnAdBlocker()
132 132 }
133 133
... ... @@ -138,7 +138,7 @@ extension RemoveAdvertViewController {
138 138 }
139 139
140 140 private func turnOnAdBlocker() {
141   - mainView.adBlockButton.buttonImageView.image = .adBlockOnState
  141 + mainView.adBlockButton.setImage(.adBlockOnState, for: .normal)
142 142 mainView.tapActionLabel.textColor = ColorConstants.SearchbarTintBlue
143 143 mainView.tapActionLabel.text = StringConstants.turnOff
144 144
... ... @@ -146,7 +146,7 @@ extension RemoveAdvertViewController {
146 146 }
147 147
148 148 private func turnOffAdBlocker() {
149   - mainView.adBlockButton.buttonImageView.image = .adBlockOffState
  149 + mainView.adBlockButton.setImage(.adBlockOffState, for: .normal)
150 150 mainView.tapActionLabel.textColor = ColorConstants.customPink
151 151 mainView.tapActionLabel.text = StringConstants.turnOn
152 152
... ...
1   -//
2   -// AdBlockButton.swift
3   -// browser
4   -//
5   -// Created by Artem Talko on 22.11.2023.
6   -//
7   -
8   -import UIKit
9   -
10   -final class AdBlockButton: UIButton {
11   - var buttonImageView: UIImageView = {
12   - let obj = UIImageView()
13   - let userDefaultsAdBlockingValue = CachingManager.shared.adBlockerState
14   -
15   - if userDefaultsAdBlockingValue {
16   - obj.image = .adBlockOnState
17   - } else {
18   - obj.image = .adBlockOffState
19   - }
20   - obj.contentMode = .scaleAspectFit
21   -
22   - return obj
23   - }()
24   -
25   - override init (frame: CGRect) {
26   - super.init(frame: frame)
27   -
28   - setup()
29   - }
30   -
31   - required init?(coder: NSCoder) {
32   - fatalError("init(coder:) has not been implemented")
33   - }
34   -
35   - private func setup() {
36   - addSubview(buttonImageView)
37   -
38   - setupConstraints()
39   - }
40   -
41   - private func setupConstraints() {
42   - buttonImageView.snp.makeConstraints { make in
43   - make.top.equalToSuperview()
44   - make.leading.equalToSuperview()
45   - make.bottom.equalToSuperview()
46   - make.trailing.equalToSuperview()
47   - }
48   - }
49   -}
... ... @@ -18,22 +18,33 @@ final class RemoveAdvertView: GradientView {
18 18 return obj
19 19 }()
20 20
21   - let adBlockButton: AdBlockButton = {
22   - let obj = AdBlockButton()
  21 + let adBlockButton: UIButton = {
  22 + let obj = UIButton()
  23 + let userDefaultsAdBlockingValue = CachingManager.shared.adBlockerState
  24 + obj.layer.cornerRadius = 0.5 * 171.sizeH
  25 + obj.layer.masksToBounds = true
  26 + obj.layer.borderWidth = 2.0
  27 + obj.setBackgroundImage(.backgroundGradient, for: .normal)
  28 + obj.layer.borderColor = UIColor.white.cgColor
  29 + if userDefaultsAdBlockingValue {
  30 + obj.setImage(.adBlockOnState, for: .normal)
  31 + } else {
  32 + obj.setImage(.adBlockOffState, for: .normal)
  33 + }
23 34
24 35 return obj
25 36 }()
26 37
27 38 let removeAdvertSegmentControl: UISegmentedControl = {
28   - let items = ["AdBlock", "Browser"]
  39 + let items = StringConstants.segmentedControlItems
29 40 let obj = UISegmentedControl(items: items)
30 41 obj.selectedSegmentIndex = 0
31   - obj.backgroundColor = ColorConstants.segmentControlBackground
32 42 obj.layer.cornerRadius = 10
  43 + obj.backgroundColor = ColorConstants.segmentControlBackground
33 44 obj.selectedSegmentTintColor = UIColor(red: 0.349, green: 0.565, blue: 1, alpha: 1)
34 45 obj.setTitleTextAttributes([.foregroundColor: UIColor.black], for: .normal)
35 46 obj.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
36   -
  47 +
37 48 return obj
38 49 }()
39 50
... ... @@ -54,13 +65,13 @@ final class RemoveAdvertView: GradientView {
54 65 let tapActionLabel: UILabel = {
55 66 let obj = UILabel()
56 67 let userDefaultsAdBlockerValue = CachingManager.shared.adBlockerState
57   -
58   - obj.text = StringConstants.turnOn
59 68 obj.font = FontConstants.semiboldFont_24
60 69 if userDefaultsAdBlockerValue {
61 70 obj.textColor = ColorConstants.SearchbarTintBlue
  71 + obj.text = StringConstants.turnOff
62 72 } else {
63 73 obj.textColor = ColorConstants.customPink
  74 + obj.text = StringConstants.turnOn
64 75 }
65 76
66 77 return obj
... ... @@ -92,7 +103,7 @@ final class RemoveAdvertView: GradientView {
92 103 required init?(coder: NSCoder) {
93 104 fatalError("init(coder:) has not been implemented")
94 105 }
95   -
  106 +
96 107 private func setup() {
97 108 addSubview(appLogoImageView)
98 109 addSubview(adBlockButton)
... ... @@ -102,7 +113,7 @@ final class RemoveAdvertView: GradientView {
102 113 addSubview(rightDecorativeSquareImageView)
103 114 addSubview(protectFromLabel)
104 115 addSubview(adBlockTableView)
105   -
  116 +
106 117 setupConstraints()
107 118 }
108 119
... ... @@ -130,9 +141,10 @@ final class RemoveAdvertView: GradientView {
130 141 }
131 142
132 143 adBlockButton.snp.makeConstraints { make in
133   - make.top.equalTo(removeAdvertSegmentControl.snp.bottom).offset(84.sizeH)
134   - make.leading.trailing.equalToSuperview().inset(47.sizeW)
  144 + make.centerY.equalToSuperview()
  145 + make.centerX.equalToSuperview()
135 146 make.height.equalTo(171.sizeH)
  147 + make.width.equalTo(171.sizeH)
136 148 }
137 149
138 150 tapActionLabel.snp.makeConstraints { make in
... ...
... ... @@ -5,13 +5,14 @@
5 5 // Created by Artem Talko on 05.10.2023.
6 6 //
7 7
8   -
9 8 import UIKit
10 9 import WebKit
11 10
12 11 final class SearchResultViewController: UIViewController {
13 12 let mainView = SearchResultView()
  13 +
14 14 var searchLink: String
  15 + var onCloseButtonTapped: (() -> Void)?
15 16
16 17 init(searchLink: String) {
17 18 self.searchLink = searchLink
... ... @@ -34,10 +35,9 @@ final class SearchResultViewController: UIViewController {
34 35 }
35 36
36 37 private func initViewController() {
37   - view.backgroundColor = ColorConstants.lightGray
38   -
39 38 urlChecker(searchLink)
40 39 setupAdBlocker()
  40 + addTargets()
41 41 }
42 42
43 43 override func viewIsAppearing(_ animated: Bool) {
... ... @@ -45,14 +45,26 @@ final class SearchResultViewController: UIViewController {
45 45 }
46 46 }
47 47
48   -//MARK: URL handling
  48 +//MARK: Helper
49 49 extension SearchResultViewController {
  50 + private func addTargets() {
  51 + mainView.closeWebViewButton.addTarget(self, action: #selector(closeWebViewTapped(_ :)), for: .touchUpInside)
  52 + }
  53 +
50 54 private func urlChecker(_ url: String) {
51 55 let request = URLRequest(url: URL(string: url) ?? URL(fileURLWithPath: ""))
52 56 mainView.searchResultView.load(request)
53 57 }
54 58 }
55 59
  60 +//MARK: Action
  61 +extension SearchResultViewController {
  62 + @objc
  63 + private func closeWebViewTapped(_ sender: UIButton) {
  64 + onCloseButtonTapped?()
  65 + }
  66 +}
  67 +
56 68
57 69 //MARK: AdBlocker
58 70 extension SearchResultViewController {
... ...
... ... @@ -9,6 +9,17 @@ import UIKit
9 9 import WebKit
10 10
11 11 final class SearchResultView: UIView {
  12 + let closeWebViewButton: UIButton = {
  13 + let obj = UIButton()
  14 + obj.backgroundColor = .white.withAlphaComponent(0.2)
  15 + obj.layer.borderWidth = 1
  16 + obj.layer.borderColor = UIColor.blue.withAlphaComponent(0.3).cgColor
  17 + obj.layer.cornerRadius = 10
  18 + obj.setImage(UIImage(systemName: "arrow.backward"), for: .normal)
  19 +
  20 + return obj
  21 + }()
  22 +
12 23 let searchResultView: WKWebView = {
13 24 let obj = WKWebView()
14 25 obj.allowsBackForwardNavigationGestures = true
... ... @@ -30,11 +41,18 @@ final class SearchResultView: UIView {
30 41 private func setup() {
31 42 backgroundColor = .white
32 43 addSubview(searchResultView)
  44 + addSubview(closeWebViewButton)
33 45
34 46 setupConstaraints()
35 47 }
36 48
37 49 private func setupConstaraints() {
  50 + closeWebViewButton.snp.makeConstraints { make in
  51 + make.height.width.equalTo(24.sizeH)
  52 + make.top.equalTo(safeAreaLayoutGuide).offset(16.sizeH)
  53 + make.leading.equalToSuperview().offset(16.sizeW)
  54 + }
  55 +
38 56 searchResultView.snp.makeConstraints { make in
39 57 make.top.equalTo(safeAreaLayoutGuide.snp.top)
40 58 make.leading.trailing.equalToSuperview()
... ...
... ... @@ -112,17 +112,9 @@ extension SettingViewController {
112 112 break
113 113 }
114 114 }
115   -}
116   -
117   -//MARK: - Action
118   -extension SettingViewController {
119   - func addTargets() {
120   - mainView.backButton.addTarget(self, action: #selector(closeViewController(_ :)), for: .touchUpInside)
121   - }
122 115
123   - @objc
124   - private func closeViewController(_ sender: UIButton) {
125   - dismiss(animated: true, completion: nil)
  116 + private func addTargets() {
  117 + mainView.backButton.addTarget(self, action: #selector(closeViewController(_ :)), for: .touchUpInside)
126 118 }
127 119
128 120 private func shareButtonPressed() {
... ... @@ -139,6 +131,14 @@ extension SettingViewController {
139 131 }
140 132 }
141 133
  134 +//MARK: - Action
  135 +extension SettingViewController {
  136 + @objc
  137 + private func closeViewController(_ sender: UIButton) {
  138 + dismiss(animated: true, completion: nil)
  139 + }
  140 +}
  141 +
142 142 //MARK: Mail helper
143 143 extension SettingViewController: MFMailComposeViewControllerDelegate {
144 144 func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
... ...
... ... @@ -27,10 +27,9 @@ extension NavigationViewController {
27 27 private func setStartControllers() {
28 28 let payloadViewController = PayloadViewController()
29 29 let removeAdvertViewController = RemoveAdvertViewController()
30   -
31 30 let cachingManager = CachingManager.shared
32 31
33   - if cachingManager.isFirstAppLoad == false {
  32 + if !cachingManager.isFirstAppLoad {
34 33 setViewControllers([removeAdvertViewController, payloadViewController], animated: true)
35 34 cachingManager.isFirstAppLoad.toggle()
36 35 } else {
... ...
Please register or login to post a comment