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,7 +43,6 @@
43 197534762B10968E000818D3 /* SubscriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197534752B10968E000818D3 /* SubscriptionViewController.swift */; }; 43 197534762B10968E000818D3 /* SubscriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197534752B10968E000818D3 /* SubscriptionViewController.swift */; };
44 197534782B1096A7000818D3 /* SubscriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197534772B1096A7000818D3 /* SubscriptionView.swift */; }; 44 197534782B1096A7000818D3 /* SubscriptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197534772B1096A7000818D3 /* SubscriptionView.swift */; };
45 1975347B2B109A37000818D3 /* SubscriptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1975347A2B109A37000818D3 /* SubscriptionTableViewCell.swift */; }; 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 197C2A282B0F65840010B386 /* OpenBrowserHomeTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A272B0F65830010B386 /* OpenBrowserHomeTransition.swift */; }; 46 197C2A282B0F65840010B386 /* OpenBrowserHomeTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A272B0F65830010B386 /* OpenBrowserHomeTransition.swift */; };
48 197C2A2D2B0F9EEB0010B386 /* SubscriptionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */; }; 47 197C2A2D2B0F9EEB0010B386 /* SubscriptionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */; };
49 197FC3EF2AC21E1F007F429C /* PayloadViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197FC3EE2AC21E1F007F429C /* PayloadViewController.swift */; }; 48 197FC3EF2AC21E1F007F429C /* PayloadViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197FC3EE2AC21E1F007F429C /* PayloadViewController.swift */; };
@@ -146,7 +145,6 @@ @@ -146,7 +145,6 @@
146 197534752B10968E000818D3 /* SubscriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionViewController.swift; sourceTree = "<group>"; }; 145 197534752B10968E000818D3 /* SubscriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionViewController.swift; sourceTree = "<group>"; };
147 197534772B1096A7000818D3 /* SubscriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionView.swift; sourceTree = "<group>"; }; 146 197534772B1096A7000818D3 /* SubscriptionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionView.swift; sourceTree = "<group>"; };
148 1975347A2B109A37000818D3 /* SubscriptionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionTableViewCell.swift; sourceTree = "<group>"; }; 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 197C2A272B0F65830010B386 /* OpenBrowserHomeTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenBrowserHomeTransition.swift; sourceTree = "<group>"; }; 148 197C2A272B0F65830010B386 /* OpenBrowserHomeTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenBrowserHomeTransition.swift; sourceTree = "<group>"; };
151 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionManager.swift; sourceTree = "<group>"; }; 149 197C2A2C2B0F9EEB0010B386 /* SubscriptionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionManager.swift; sourceTree = "<group>"; };
152 197FC3EE2AC21E1F007F429C /* PayloadViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayloadViewController.swift; sourceTree = "<group>"; }; 150 197FC3EE2AC21E1F007F429C /* PayloadViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PayloadViewController.swift; sourceTree = "<group>"; };
@@ -223,7 +221,6 @@ @@ -223,7 +221,6 @@
223 isa = PBXGroup; 221 isa = PBXGroup;
224 children = ( 222 children = (
225 194206C62B10DFAF000C1263 /* Cell */, 223 194206C62B10DFAF000C1263 /* Cell */,
226 - 197C2A222B0E3A420010B386 /* Components */,  
227 191BB8802AC6FF6600A2DEB9 /* RemoveAdvertView.swift */, 224 191BB8802AC6FF6600A2DEB9 /* RemoveAdvertView.swift */,
228 ); 225 );
229 path = View; 226 path = View;
@@ -468,14 +465,6 @@ @@ -468,14 +465,6 @@
468 path = Cell; 465 path = Cell;
469 sourceTree = "<group>"; 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 197FC3F02AC2AF8A007F429C /* Cell */ = { 468 197FC3F02AC2AF8A007F429C /* Cell */ = {
480 isa = PBXGroup; 469 isa = PBXGroup;
481 children = ( 470 children = (
@@ -973,7 +962,6 @@ @@ -973,7 +962,6 @@
973 191BB8692AC6A66900A2DEB9 /* SearchingTableViewCell.swift in Sources */, 962 191BB8692AC6A66900A2DEB9 /* SearchingTableViewCell.swift in Sources */,
974 1990C69C2AEFDF89004AF856 /* UICollectionViewCell+convertFrameToScreenCoordinates.swift in Sources */, 963 1990C69C2AEFDF89004AF856 /* UICollectionViewCell+convertFrameToScreenCoordinates.swift in Sources */,
975 19FCBF222AC1727800F83A7F /* AppDelegate.swift in Sources */, 964 19FCBF222AC1727800F83A7F /* AppDelegate.swift in Sources */,
976 - 197C2A242B0E3A7B0010B386 /* AdBlockButton.swift in Sources */,  
977 197C2A282B0F65840010B386 /* OpenBrowserHomeTransition.swift in Sources */, 965 197C2A282B0F65840010B386 /* OpenBrowserHomeTransition.swift in Sources */,
978 19D1F2E02AC1EF3200510506 /* PayloadView.swift in Sources */, 966 19D1F2E02AC1EF3200510506 /* PayloadView.swift in Sources */,
979 19FFD6BF2AE64A7B00D0F768 /* SnapshotService.swift in Sources */, 967 19FFD6BF2AE64A7B00D0F768 /* SnapshotService.swift in Sources */,
@@ -23,4 +23,3 @@ final class HistoryDataBase: Object { @@ -23,4 +23,3 @@ final class HistoryDataBase: Object {
23 self.lastVisit = lastVisit 23 self.lastVisit = lastVisit
24 } 24 }
25 } 25 }
26 -  
@@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
7 7
8 import UIKit 8 import UIKit
9 9
10 -  
11 extension BinaryFloatingPoint { 10 extension BinaryFloatingPoint {
12 private var size: CGSize { 11 private var size: CGSize {
13 return CGSize(width: 375, height: 812) 12 return CGSize(width: 375, height: 812)
@@ -45,6 +45,3 @@ final class DateManager { @@ -45,6 +45,3 @@ final class DateManager {
45 } 45 }
46 } 46 }
47 } 47 }
48 -  
49 -  
50 -  
@@ -21,7 +21,6 @@ final class HistoryDBManager { @@ -21,7 +21,6 @@ final class HistoryDBManager {
21 } 21 }
22 } 22 }
23 23
24 - //MARK: ADDING  
25 func saveToHistory(siteTitle: String, siteUrl: String, lastVisit: Date) { 24 func saveToHistory(siteTitle: String, siteUrl: String, lastVisit: Date) {
26 let historyCell = HistoryDataBase(siteTitle: siteTitle, siteUrl: siteUrl, lastVisit: lastVisit) 25 let historyCell = HistoryDataBase(siteTitle: siteTitle, siteUrl: siteUrl, lastVisit: lastVisit)
27 do { 26 do {
@@ -34,7 +33,6 @@ final class HistoryDBManager { @@ -34,7 +33,6 @@ final class HistoryDBManager {
34 } 33 }
35 } 34 }
36 35
37 - //MARK: GETTING  
38 func getHistory(sorted: Bool = false) -> [HistoryDataBase] { 36 func getHistory(sorted: Bool = false) -> [HistoryDataBase] {
39 if sorted { 37 if sorted {
40 let history = realm.objects(HistoryDataBase.self).sorted(byKeyPath: "lastVisit", ascending: false) 38 let history = realm.objects(HistoryDataBase.self).sorted(byKeyPath: "lastVisit", ascending: false)
@@ -74,7 +72,6 @@ final class HistoryDBManager { @@ -74,7 +72,6 @@ final class HistoryDBManager {
74 return createHistoryData(elements: filteredHistory) 72 return createHistoryData(elements: filteredHistory)
75 } 73 }
76 74
77 - //MARK: DELETING  
78 func cleanHistory() { 75 func cleanHistory() {
79 do { 76 do {
80 let history = realm.objects(HistoryDataBase.self) 77 let history = realm.objects(HistoryDataBase.self)
@@ -111,7 +108,5 @@ final class HistoryDBManager { @@ -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,7 +35,7 @@ final class SubscriptionManager: ObservableObject {
35 updateListenerTask?.cancel() 35 updateListenerTask?.cancel()
36 } 36 }
37 37
38 - func listenForTransactions() -> Task<Void, Error> { 38 + private func listenForTransactions() -> Task<Void, Error> {
39 return Task.detached { 39 return Task.detached {
40 for await result in Transaction.updates { 40 for await result in Transaction.updates {
41 do { 41 do {
@@ -49,7 +49,7 @@ final class SubscriptionManager: ObservableObject { @@ -49,7 +49,7 @@ final class SubscriptionManager: ObservableObject {
49 } 49 }
50 } 50 }
51 51
52 - func requestProducts() async { 52 + private func requestProducts() async {
53 do { 53 do {
54 storeProducts = try await Product.products(for: productDict.values) 54 storeProducts = try await Product.products(for: productDict.values)
55 55
@@ -58,7 +58,7 @@ final class SubscriptionManager: ObservableObject { @@ -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 switch result { 62 switch result {
63 case .unverified: 63 case .unverified:
64 throw StoreError.failedVerification 64 throw StoreError.failedVerification
@@ -68,7 +68,7 @@ final class SubscriptionManager: ObservableObject { @@ -68,7 +68,7 @@ final class SubscriptionManager: ObservableObject {
68 } 68 }
69 69
70 @MainActor 70 @MainActor
71 - func updateCustomerProductStatus() async { 71 + private func updateCustomerProductStatus() async {
72 var purchasedCourses: [Product] = [] 72 var purchasedCourses: [Product] = []
73 73
74 for await result in Transaction.currentEntitlements { 74 for await result in Transaction.currentEntitlements {
@@ -101,10 +101,6 @@ final class SubscriptionManager: ObservableObject { @@ -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 func restorePurchase() async throws { 104 func restorePurchase() async throws {
109 try await AppStore.sync() 105 try await AppStore.sync()
110 } 106 }
@@ -31,7 +31,6 @@ struct StringConstants { @@ -31,7 +31,6 @@ struct StringConstants {
31 static let removeAdvertTableViewData = ["Unlimited blocks & uploads", "Enhanced User Experience", "Faster Page Load Times", "Privacy and Security"] 31 static let removeAdvertTableViewData = ["Unlimited blocks & uploads", "Enhanced User Experience", "Faster Page Load Times", "Privacy and Security"]
32 static let search = "Search" 32 static let search = "Search"
33 33
34 -  
35 ///RemoveAdvertView 34 ///RemoveAdvertView
36 static let yourDiscount = "You save 91% - normally US $9,99" 35 static let yourDiscount = "You save 91% - normally US $9,99"
37 static let freeTrial = "3-day free trial" 36 static let freeTrial = "3-day free trial"
@@ -45,10 +44,8 @@ struct StringConstants { @@ -45,10 +44,8 @@ struct StringConstants {
45 ///setting cell detail info 44 ///setting cell detail info
46 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" 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 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" 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 static let settingHeader = "Terms\nand conditions" 49 static let settingHeader = "Terms\nand conditions"
53 static let settingAgreeButtonText = "Agree & Continue" 50 static let settingAgreeButtonText = "Agree & Continue"
54 static let privacyHeaderText = "Your Privacy\n is our top priority" 51 static let privacyHeaderText = "Your Privacy\n is our top priority"
@@ -73,5 +70,8 @@ struct StringConstants { @@ -73,5 +70,8 @@ struct StringConstants {
73 ] 70 ]
74 static let notificationTitle = "Gotoweb Notification" 71 static let notificationTitle = "Gotoweb Notification"
75 static let notificationIdentifier = "browser-notification" 72 static let notificationIdentifier = "browser-notification"
  73 +
  74 + static let segmentedControlItems = ["AdBlock", "Browser"]
  75 +
76 } 76 }
77 77
1 { 1 {
2 "images" : [ 2 "images" : [
3 { 3 {
4 - "filename" : "Group 1adBlockButtonOff.pdf", 4 + "filename" : "Play.pdf",
5 "idiom" : "universal" 5 "idiom" : "universal"
6 } 6 }
7 ], 7 ],
1 { 1 {
2 "images" : [ 2 "images" : [
3 { 3 {
4 - "filename" : "Group 1.png", 4 + "filename" : "Play.png",
5 "idiom" : "universal" 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,7 +10,6 @@ import WebKit
10 10
11 final class SnapshotService { 11 final class SnapshotService {
12 static let shared = SnapshotService() 12 static let shared = SnapshotService()
13 - let snapshotConfiguration = WKSnapshotConfiguration()  
14 13
15 private init() {} 14 private init() {}
16 15
@@ -20,7 +20,7 @@ final class BrowserHomeViewController: UIViewController { @@ -20,7 +20,7 @@ final class BrowserHomeViewController: UIViewController {
20 20
21 private var subscriptions: Set<AnyCancellable> 21 private var subscriptions: Set<AnyCancellable>
22 private var searchRequestURL: String 22 private var searchRequestURL: String
23 - private let images = StringConstants.browserHomeVCImages 23 + private let frequentlyVisitedTabsImages: [String]
24 private var currentTabId: Int? 24 private var currentTabId: Int?
25 25
26 private var url: String? { 26 private var url: String? {
@@ -33,57 +33,56 @@ final class BrowserHomeViewController: UIViewController { @@ -33,57 +33,56 @@ final class BrowserHomeViewController: UIViewController {
33 init(url: String?, currentTabId: Int?) { 33 init(url: String?, currentTabId: Int?) {
34 searchResultViewController = SearchResultViewController(searchLink: String()) 34 searchResultViewController = SearchResultViewController(searchLink: String())
35 searchingViewController = SearchingViewController(dataForReq: []) 35 searchingViewController = SearchingViewController(dataForReq: [])
36 - subscriptions = []  
37 searchRequestURL = URLConstants.googleURL 36 searchRequestURL = URLConstants.googleURL
  37 + frequentlyVisitedTabsImages = StringConstants.browserHomeVCImages
  38 + subscriptions = []
38 39
39 - super.init(nibName: nil, bundle: nil)  
40 self.url = url 40 self.url = url
41 self.currentTabId = currentTabId 41 self.currentTabId = currentTabId
  42 +
  43 + super.init(nibName: nil, bundle: nil)
42 } 44 }
43 45
44 required init?(coder: NSCoder) { 46 required init?(coder: NSCoder) {
45 fatalError("init(coder:) has not been implemented") 47 fatalError("init(coder:) has not been implemented")
46 } 48 }
47 49
  50 + override func loadView() {
  51 + view = mainView
  52 + }
  53 +
48 override func viewDidLoad() { 54 override func viewDidLoad() {
49 super.viewDidLoad() 55 super.viewDidLoad()
50 - view.backgroundColor = ColorConstants.lightGray 56 +
51 initViewController() 57 initViewController()
52 } 58 }
53 59
54 override func viewWillAppear(_ animated: Bool) { 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 navigationController?.isNavigationBarHidden = true 61 navigationController?.isNavigationBarHidden = true
68 62
69 tabsViewController = getTabsViewController() 63 tabsViewController = getTabsViewController()
  64 + keyboardObserver()
70 } 65 }
71 -  
72 - override func loadView() {  
73 - view = mainView  
74 - }  
75 - 66 +
76 override func viewWillDisappear(_ animated: Bool) { 67 override func viewWillDisappear(_ animated: Bool) {
77 super.viewWillDisappear(animated) 68 super.viewWillDisappear(animated)
  69 +
78 NotificationCenter.default.removeObserver(self) 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 //MARK: CollectionView Setup 82 //MARK: CollectionView Setup
84 extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { 83 extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
85 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 84 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
86 - images.count 85 + frequentlyVisitedTabsImages.count
87 } 86 }
88 87
89 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 88 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
@@ -96,7 +95,7 @@ extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionVie @@ -96,7 +95,7 @@ extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionVie
96 } 95 }
97 96
98 func setupCellForCollectionView(_ cell: TabCollectionViewCell, _ indexPath: IndexPath) -> TabCollectionViewCell { 97 func setupCellForCollectionView(_ cell: TabCollectionViewCell, _ indexPath: IndexPath) -> TabCollectionViewCell {
99 - let imageName = images[indexPath.item] 98 + let imageName = frequentlyVisitedTabsImages[indexPath.item]
100 cell.tabCellImage.image = UIImage(named: imageName) 99 cell.tabCellImage.image = UIImage(named: imageName)
101 cell.tabCellLabel.text = imageName 100 cell.tabCellLabel.text = imageName
102 101
@@ -113,7 +112,6 @@ extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionVie @@ -113,7 +112,6 @@ extension BrowserHomeViewController: UICollectionViewDataSource, UICollectionVie
113 } 112 }
114 } 113 }
115 114
116 -  
117 //MARK: - Keyboard extention 115 //MARK: - Keyboard extention
118 extension BrowserHomeViewController { 116 extension BrowserHomeViewController {
119 private func keyboardObserver() { 117 private func keyboardObserver() {
@@ -122,7 +120,6 @@ extension BrowserHomeViewController { @@ -122,7 +120,6 @@ extension BrowserHomeViewController {
122 } 120 }
123 } 121 }
124 122
125 -  
126 //MARK: - Action 123 //MARK: - Action
127 extension BrowserHomeViewController { 124 extension BrowserHomeViewController {
128 @objc 125 @objc
@@ -177,6 +174,8 @@ extension BrowserHomeViewController { @@ -177,6 +174,8 @@ extension BrowserHomeViewController {
177 private func removeSearchingViewController(_ sender: UIButton) { 174 private func removeSearchingViewController(_ sender: UIButton) {
178 searchResultAction() 175 searchResultAction()
179 } 176 }
  177 +
  178 +
180 } 179 }
181 180
182 //MARK: - Helpers 181 //MARK: - Helpers
@@ -217,7 +216,7 @@ extension BrowserHomeViewController { @@ -217,7 +216,7 @@ extension BrowserHomeViewController {
217 if !sitesFromSearch.isEmpty { 216 if !sitesFromSearch.isEmpty {
218 searchingViewController.searchRequestData = sitesFromSearch 217 searchingViewController.searchRequestData = sitesFromSearch
219 } 218 }
220 - addingSearchingViewController(searchingViewController) 219 + childViewControllerHandler(searchingViewController)
221 } 220 }
222 221
223 private func setupCollectionView() { 222 private func setupCollectionView() {
@@ -230,7 +229,8 @@ extension BrowserHomeViewController { @@ -230,7 +229,8 @@ extension BrowserHomeViewController {
230 mainView.settingButton.addTarget(self, action: #selector(settingButtonTapped(_ :)), for: .touchUpInside) 229 mainView.settingButton.addTarget(self, action: #selector(settingButtonTapped(_ :)), for: .touchUpInside)
231 mainView.removeAdvertSegmentControl.addTarget(self, action: #selector(advertSegmantControlStateHandler), for: .valueChanged) 230 mainView.removeAdvertSegmentControl.addTarget(self, action: #selector(advertSegmantControlStateHandler), for: .valueChanged)
232 mainView.searchBarContainer.searchBarView.searchTextFieldView.addTarget(self, action: #selector(searchBarTextChanged), for: .editingChanged) 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 addToolbarTargets() 234 addToolbarTargets()
235 } 235 }
236 236
@@ -238,6 +238,10 @@ extension BrowserHomeViewController { @@ -238,6 +238,10 @@ extension BrowserHomeViewController {
238 mainView.toolbarView.action = didTabButtonTapped 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 private func openAdditionViewController(_ viewController: UIViewController) { 245 private func openAdditionViewController(_ viewController: UIViewController) {
242 viewController.modalPresentationStyle = .fullScreen 246 viewController.modalPresentationStyle = .fullScreen
243 present(viewController, animated: true, completion: nil) 247 present(viewController, animated: true, completion: nil)
@@ -249,8 +253,8 @@ extension BrowserHomeViewController { @@ -249,8 +253,8 @@ extension BrowserHomeViewController {
249 return 253 return
250 } 254 }
251 searchRequestURL = "https://www.google.com/search?q=" + (cell.searchLabel.text ?? "") 255 searchRequestURL = "https://www.google.com/search?q=" + (cell.searchLabel.text ?? "")
252 - openSearchResult()  
253 mainView.searchBarContainer.searchBarView.searchTextFieldView.endEditing(true) 256 mainView.searchBarContainer.searchBarView.searchTextFieldView.endEditing(true)
  257 + openSearchResult()
254 } 258 }
255 } 259 }
256 260
@@ -261,7 +265,10 @@ extension BrowserHomeViewController { @@ -261,7 +265,10 @@ extension BrowserHomeViewController {
261 let request = URLRequest(url: localUrl) 265 let request = URLRequest(url: localUrl)
262 searchResultViewController.mainView.searchResultView.load(request) 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 private func tabsButtonHandler() { 274 private func tabsButtonHandler() {
@@ -283,18 +290,17 @@ extension BrowserHomeViewController { @@ -283,18 +290,17 @@ extension BrowserHomeViewController {
283 let finalUrl = siteUrl.absoluteString 290 let finalUrl = siteUrl.absoluteString
284 let lastVisit = DateManager.shared.currentDate 291 let lastVisit = DateManager.shared.currentDate
285 let homeViewSnapshot = SnapshotService.shared.makeSnapshot(mainView) 292 let homeViewSnapshot = SnapshotService.shared.makeSnapshot(mainView)
286 - navigationController?.popViewController(animated: true)  
287 TabManager.shared.saveTab(tabTitle: siteTitle, snapshotImage: homeViewSnapshot, tabUrl: finalUrl) 293 TabManager.shared.saveTab(tabTitle: siteTitle, snapshotImage: homeViewSnapshot, tabUrl: finalUrl)
  294 + HistoryDBManager.shared.saveToHistory(siteTitle: siteTitle, siteUrl: finalUrl, lastVisit: lastVisit)
288 self.currentTabId = tabsViewController?.getCellIndex().row 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 } else { 298 } else {
293 let homeViewSnapshot = SnapshotService.shared.makeSnapshot(mainView) 299 let homeViewSnapshot = SnapshotService.shared.makeSnapshot(mainView)
294 - navigationController?.popViewController(animated: true)  
295 TabManager.shared.saveTab(tabTitle: "Start Page", snapshotImage: homeViewSnapshot, tabUrl: "homeUrl") 300 TabManager.shared.saveTab(tabTitle: "Start Page", snapshotImage: homeViewSnapshot, tabUrl: "homeUrl")
296 -  
297 currentTabId = tabsViewController?.getCellIndex().row 301 currentTabId = tabsViewController?.getCellIndex().row
  302 +
  303 + navigationController?.popViewController(animated: true)
298 } 304 }
299 } 305 }
300 306
@@ -325,10 +331,9 @@ extension BrowserHomeViewController { @@ -325,10 +331,9 @@ extension BrowserHomeViewController {
325 } 331 }
326 } 332 }
327 333
328 -  
329 //MARK: - ChildVC actions 334 //MARK: - ChildVC actions
330 extension BrowserHomeViewController { 335 extension BrowserHomeViewController {
331 - private func addingSearchingViewController(_ childViewController: UIViewController) { 336 + private func childViewControllerHandler(_ childViewController: UIViewController) {
332 if self.children.isEmpty { 337 if self.children.isEmpty {
333 addNewChildViewController(childViewController) 338 addNewChildViewController(childViewController)
334 } else { 339 } else {
@@ -345,12 +350,7 @@ extension BrowserHomeViewController { @@ -345,12 +350,7 @@ extension BrowserHomeViewController {
345 } 350 }
346 351
347 private func removeChildViewController() { 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 childViewController.view.removeFromSuperview() 354 childViewController.view.removeFromSuperview()
355 childViewController.willMove(toParent: nil) 355 childViewController.willMove(toParent: nil)
356 childViewController.removeFromParent() 356 childViewController.removeFromParent()
@@ -358,7 +358,6 @@ extension BrowserHomeViewController { @@ -358,7 +358,6 @@ extension BrowserHomeViewController {
358 } 358 }
359 } 359 }
360 360
361 -  
362 //MARK: - SearchBar extention 361 //MARK: - SearchBar extention
363 extension BrowserHomeViewController: UITextFieldDelegate { 362 extension BrowserHomeViewController: UITextFieldDelegate {
364 func textFieldDidBeginEditing(_ textField: UITextField) { 363 func textFieldDidBeginEditing(_ textField: UITextField) {
@@ -368,7 +367,6 @@ extension BrowserHomeViewController: UITextFieldDelegate { @@ -368,7 +367,6 @@ extension BrowserHomeViewController: UITextFieldDelegate {
368 367
369 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 368 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
370 textField.resignFirstResponder() 369 textField.resignFirstResponder()
371 -  
372 searchRequestURL = "https://www.google.com/search?q=" + (textField.text ?? "") 370 searchRequestURL = "https://www.google.com/search?q=" + (textField.text ?? "")
373 openSearchResult() 371 openSearchResult()
374 372
@@ -379,11 +377,11 @@ extension BrowserHomeViewController: UITextFieldDelegate { @@ -379,11 +377,11 @@ extension BrowserHomeViewController: UITextFieldDelegate {
379 mainView.searchBarContainer.searchBarView.searchTextFieldView.autocorrectionType = .no 377 mainView.searchBarContainer.searchBarView.searchTextFieldView.autocorrectionType = .no
380 mainView.searchBarContainer.searchBarView.searchTextFieldView.delegate = self 378 mainView.searchBarContainer.searchBarView.searchTextFieldView.delegate = self
381 mainView.searchBarContainer.searchBarView.cleanTextFieldButton.addTarget(self, action: #selector(searchResultAction), for: .touchUpInside) 379 mainView.searchBarContainer.searchBarView.cleanTextFieldButton.addTarget(self, action: #selector(searchResultAction), for: .touchUpInside)
  380 +
382 buttonObserver() 381 buttonObserver()
383 } 382 }
384 } 383 }
385 384
386 -  
387 //MARK: - WebView extention 385 //MARK: - WebView extention
388 extension BrowserHomeViewController { 386 extension BrowserHomeViewController {
389 private func buttonObserver() { 387 private func buttonObserver() {
@@ -10,7 +10,8 @@ import SnapKit @@ -10,7 +10,8 @@ import SnapKit
10 10
11 final class BrowserHomeView: GradientView { 11 final class BrowserHomeView: GradientView {
12 let removeAdvertSegmentControl: UISegmentedControl = { 12 let removeAdvertSegmentControl: UISegmentedControl = {
13 - let items = ["AdBlock", "Browser"] 13 + let items = StringConstants.segmentedControlItems
  14 +
14 let obj = UISegmentedControl(items: items) 15 let obj = UISegmentedControl(items: items)
15 obj.selectedSegmentIndex = 1 16 obj.selectedSegmentIndex = 1
16 obj.backgroundColor = ColorConstants.segmentControlBackground 17 obj.backgroundColor = ColorConstants.segmentControlBackground
@@ -86,32 +87,37 @@ final class BrowserHomeView: GradientView { @@ -86,32 +87,37 @@ final class BrowserHomeView: GradientView {
86 } 87 }
87 88
88 private func setupConstraints() { 89 private func setupConstraints() {
89 - removeAdvertSegmentControl.snp.makeConstraints { make in 90 + removeAdvertSegmentControl.snp.makeConstraints { make in
90 make.top.equalTo(safeAreaLayoutGuide.snp.top).offset(16.sizeH) 91 make.top.equalTo(safeAreaLayoutGuide.snp.top).offset(16.sizeH)
91 make.leading.equalToSuperview().offset(54.sizeW) 92 make.leading.equalToSuperview().offset(54.sizeW)
92 make.trailing.equalTo(settingButton.snp.leading).offset(-15.sizeW) 93 make.trailing.equalTo(settingButton.snp.leading).offset(-15.sizeW)
93 make.height.equalTo(34.sizeH) 94 make.height.equalTo(34.sizeH)
94 } 95 }
  96 +
95 settingButton.snp.makeConstraints { make in 97 settingButton.snp.makeConstraints { make in
96 make.trailing.equalToSuperview().offset(-16.sizeW) 98 make.trailing.equalToSuperview().offset(-16.sizeW)
97 make.height.equalTo(24.sizeH) 99 make.height.equalTo(24.sizeH)
98 make.width.equalTo(24.sizeH) 100 make.width.equalTo(24.sizeH)
99 make.centerY.equalTo(removeAdvertSegmentControl) 101 make.centerY.equalTo(removeAdvertSegmentControl)
100 } 102 }
  103 +
101 titleLabel.snp.makeConstraints { make in 104 titleLabel.snp.makeConstraints { make in
102 make.top.equalTo(removeAdvertSegmentControl.snp.bottom).offset(64.sizeH) 105 make.top.equalTo(removeAdvertSegmentControl.snp.bottom).offset(64.sizeH)
103 make.leading.equalTo(safeAreaLayoutGuide.snp.leading).offset(16.sizeW) 106 make.leading.equalTo(safeAreaLayoutGuide.snp.leading).offset(16.sizeW)
104 } 107 }
  108 +
105 frequentlyVisitedCollectionView.snp.makeConstraints { make in 109 frequentlyVisitedCollectionView.snp.makeConstraints { make in
106 make.top.equalTo(titleLabel.snp.bottom).offset(8.sizeH) 110 make.top.equalTo(titleLabel.snp.bottom).offset(8.sizeH)
107 make.leading.trailing.equalToSuperview().inset(24.sizeW) 111 make.leading.trailing.equalToSuperview().inset(24.sizeW)
108 make.height.equalTo(120.sizeH) 112 make.height.equalTo(120.sizeH)
109 } 113 }
  114 +
110 toolbarView.snp.makeConstraints { make in 115 toolbarView.snp.makeConstraints { make in
111 make.leading.equalToSuperview() 116 make.leading.equalToSuperview()
112 make.bottom.equalToSuperview() 117 make.bottom.equalToSuperview()
113 make.trailing.equalToSuperview() 118 make.trailing.equalToSuperview()
114 } 119 }
  120 +
115 searchBarContainer.snp.makeConstraints { make in 121 searchBarContainer.snp.makeConstraints { make in
116 make.leading.equalToSuperview() 122 make.leading.equalToSuperview()
117 make.bottom.equalToSuperview().offset(-90.sizeH) 123 make.bottom.equalToSuperview().offset(-90.sizeH)
@@ -19,7 +19,7 @@ final class SearchBarView: UIView { @@ -19,7 +19,7 @@ final class SearchBarView: UIView {
19 let searchTextFieldView: UITextField = { 19 let searchTextFieldView: UITextField = {
20 let obj = UITextField() 20 let obj = UITextField()
21 obj.text = "Search" 21 obj.text = "Search"
22 - obj.textColor = ColorConstants.SearchbarTintBlue 22 + obj.textColor = ColorConstants.SearchbarTintBlue
23 23
24 return obj 24 return obj
25 }() 25 }()
@@ -9,9 +9,10 @@ import UIKit @@ -9,9 +9,10 @@ import UIKit
9 9
10 final class PayloadViewController: UIViewController { 10 final class PayloadViewController: UIViewController {
11 private let mainView = PayloadView() 11 private let mainView = PayloadView()
  12 +
12 private let payloadTableViewData: [String] 13 private let payloadTableViewData: [String]
13 14
14 - init(){ 15 + init() {
15 payloadTableViewData = StringConstants.payloadViewControllerData 16 payloadTableViewData = StringConstants.payloadViewControllerData
16 17
17 super.init(nibName: nil, bundle: nil) 18 super.init(nibName: nil, bundle: nil)
@@ -21,6 +22,10 @@ final class PayloadViewController: UIViewController { @@ -21,6 +22,10 @@ final class PayloadViewController: UIViewController {
21 fatalError("init(coder:) has not been implemented") 22 fatalError("init(coder:) has not been implemented")
22 } 23 }
23 24
  25 + override func loadView() {
  26 + view = mainView
  27 + }
  28 +
24 override func viewDidLoad() { 29 override func viewDidLoad() {
25 super.viewDidLoad() 30 super.viewDidLoad()
26 31
@@ -34,10 +39,6 @@ final class PayloadViewController: UIViewController { @@ -34,10 +39,6 @@ final class PayloadViewController: UIViewController {
34 addTargets() 39 addTargets()
35 } 40 }
36 41
37 - override func loadView() {  
38 - view = mainView  
39 - }  
40 -  
41 override func viewWillDisappear(_ animated: Bool) { 42 override func viewWillDisappear(_ animated: Bool) {
42 super.viewWillDisappear(animated) 43 super.viewWillDisappear(animated)
43 44
@@ -26,16 +26,16 @@ final class RemoveAdvertViewController: UIViewController { @@ -26,16 +26,16 @@ final class RemoveAdvertViewController: UIViewController {
26 fatalError("init(coder:) has not been implemented") 26 fatalError("init(coder:) has not been implemented")
27 } 27 }
28 28
  29 + override func loadView() {
  30 + view = mainView
  31 + }
  32 +
29 override func viewDidLoad() { 33 override func viewDidLoad() {
30 super.viewDidLoad() 34 super.viewDidLoad()
31 35
32 initViewController() 36 initViewController()
33 } 37 }
34 38
35 - override func loadView() {  
36 - view = mainView  
37 - }  
38 -  
39 private func initViewController() { 39 private func initViewController() {
40 addTargets() 40 addTargets()
41 setupTableView() 41 setupTableView()
@@ -51,7 +51,6 @@ extension RemoveAdvertViewController { @@ -51,7 +51,6 @@ extension RemoveAdvertViewController {
51 } else { 51 } else {
52 subscriptionHandler() 52 subscriptionHandler()
53 } 53 }
54 -  
55 } 54 }
56 55
57 @objc 56 @objc
@@ -128,6 +127,7 @@ extension RemoveAdvertViewController { @@ -128,6 +127,7 @@ extension RemoveAdvertViewController {
128 let okAction = UIAlertAction(title: "OK", style: .default) 127 let okAction = UIAlertAction(title: "OK", style: .default)
129 alert.addAction(okAction) 128 alert.addAction(okAction)
130 present(alert, animated: true) 129 present(alert, animated: true)
  130 +
131 turnOnAdBlocker() 131 turnOnAdBlocker()
132 } 132 }
133 133
@@ -138,7 +138,7 @@ extension RemoveAdvertViewController { @@ -138,7 +138,7 @@ extension RemoveAdvertViewController {
138 } 138 }
139 139
140 private func turnOnAdBlocker() { 140 private func turnOnAdBlocker() {
141 - mainView.adBlockButton.buttonImageView.image = .adBlockOnState 141 + mainView.adBlockButton.setImage(.adBlockOnState, for: .normal)
142 mainView.tapActionLabel.textColor = ColorConstants.SearchbarTintBlue 142 mainView.tapActionLabel.textColor = ColorConstants.SearchbarTintBlue
143 mainView.tapActionLabel.text = StringConstants.turnOff 143 mainView.tapActionLabel.text = StringConstants.turnOff
144 144
@@ -146,7 +146,7 @@ extension RemoveAdvertViewController { @@ -146,7 +146,7 @@ extension RemoveAdvertViewController {
146 } 146 }
147 147
148 private func turnOffAdBlocker() { 148 private func turnOffAdBlocker() {
149 - mainView.adBlockButton.buttonImageView.image = .adBlockOffState 149 + mainView.adBlockButton.setImage(.adBlockOffState, for: .normal)
150 mainView.tapActionLabel.textColor = ColorConstants.customPink 150 mainView.tapActionLabel.textColor = ColorConstants.customPink
151 mainView.tapActionLabel.text = StringConstants.turnOn 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,22 +18,33 @@ final class RemoveAdvertView: GradientView {
18 return obj 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 return obj 35 return obj
25 }() 36 }()
26 37
27 let removeAdvertSegmentControl: UISegmentedControl = { 38 let removeAdvertSegmentControl: UISegmentedControl = {
28 - let items = ["AdBlock", "Browser"] 39 + let items = StringConstants.segmentedControlItems
29 let obj = UISegmentedControl(items: items) 40 let obj = UISegmentedControl(items: items)
30 obj.selectedSegmentIndex = 0 41 obj.selectedSegmentIndex = 0
31 - obj.backgroundColor = ColorConstants.segmentControlBackground  
32 obj.layer.cornerRadius = 10 42 obj.layer.cornerRadius = 10
  43 + obj.backgroundColor = ColorConstants.segmentControlBackground
33 obj.selectedSegmentTintColor = UIColor(red: 0.349, green: 0.565, blue: 1, alpha: 1) 44 obj.selectedSegmentTintColor = UIColor(red: 0.349, green: 0.565, blue: 1, alpha: 1)
34 obj.setTitleTextAttributes([.foregroundColor: UIColor.black], for: .normal) 45 obj.setTitleTextAttributes([.foregroundColor: UIColor.black], for: .normal)
35 obj.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected) 46 obj.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
36 - 47 +
37 return obj 48 return obj
38 }() 49 }()
39 50
@@ -54,13 +65,13 @@ final class RemoveAdvertView: GradientView { @@ -54,13 +65,13 @@ final class RemoveAdvertView: GradientView {
54 let tapActionLabel: UILabel = { 65 let tapActionLabel: UILabel = {
55 let obj = UILabel() 66 let obj = UILabel()
56 let userDefaultsAdBlockerValue = CachingManager.shared.adBlockerState 67 let userDefaultsAdBlockerValue = CachingManager.shared.adBlockerState
57 -  
58 - obj.text = StringConstants.turnOn  
59 obj.font = FontConstants.semiboldFont_24 68 obj.font = FontConstants.semiboldFont_24
60 if userDefaultsAdBlockerValue { 69 if userDefaultsAdBlockerValue {
61 obj.textColor = ColorConstants.SearchbarTintBlue 70 obj.textColor = ColorConstants.SearchbarTintBlue
  71 + obj.text = StringConstants.turnOff
62 } else { 72 } else {
63 obj.textColor = ColorConstants.customPink 73 obj.textColor = ColorConstants.customPink
  74 + obj.text = StringConstants.turnOn
64 } 75 }
65 76
66 return obj 77 return obj
@@ -92,7 +103,7 @@ final class RemoveAdvertView: GradientView { @@ -92,7 +103,7 @@ final class RemoveAdvertView: GradientView {
92 required init?(coder: NSCoder) { 103 required init?(coder: NSCoder) {
93 fatalError("init(coder:) has not been implemented") 104 fatalError("init(coder:) has not been implemented")
94 } 105 }
95 - 106 +
96 private func setup() { 107 private func setup() {
97 addSubview(appLogoImageView) 108 addSubview(appLogoImageView)
98 addSubview(adBlockButton) 109 addSubview(adBlockButton)
@@ -102,7 +113,7 @@ final class RemoveAdvertView: GradientView { @@ -102,7 +113,7 @@ final class RemoveAdvertView: GradientView {
102 addSubview(rightDecorativeSquareImageView) 113 addSubview(rightDecorativeSquareImageView)
103 addSubview(protectFromLabel) 114 addSubview(protectFromLabel)
104 addSubview(adBlockTableView) 115 addSubview(adBlockTableView)
105 - 116 +
106 setupConstraints() 117 setupConstraints()
107 } 118 }
108 119
@@ -130,9 +141,10 @@ final class RemoveAdvertView: GradientView { @@ -130,9 +141,10 @@ final class RemoveAdvertView: GradientView {
130 } 141 }
131 142
132 adBlockButton.snp.makeConstraints { make in 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 make.height.equalTo(171.sizeH) 146 make.height.equalTo(171.sizeH)
  147 + make.width.equalTo(171.sizeH)
136 } 148 }
137 149
138 tapActionLabel.snp.makeConstraints { make in 150 tapActionLabel.snp.makeConstraints { make in
@@ -5,13 +5,14 @@ @@ -5,13 +5,14 @@
5 // Created by Artem Talko on 05.10.2023. 5 // Created by Artem Talko on 05.10.2023.
6 // 6 //
7 7
8 -  
9 import UIKit 8 import UIKit
10 import WebKit 9 import WebKit
11 10
12 final class SearchResultViewController: UIViewController { 11 final class SearchResultViewController: UIViewController {
13 let mainView = SearchResultView() 12 let mainView = SearchResultView()
  13 +
14 var searchLink: String 14 var searchLink: String
  15 + var onCloseButtonTapped: (() -> Void)?
15 16
16 init(searchLink: String) { 17 init(searchLink: String) {
17 self.searchLink = searchLink 18 self.searchLink = searchLink
@@ -34,10 +35,9 @@ final class SearchResultViewController: UIViewController { @@ -34,10 +35,9 @@ final class SearchResultViewController: UIViewController {
34 } 35 }
35 36
36 private func initViewController() { 37 private func initViewController() {
37 - view.backgroundColor = ColorConstants.lightGray  
38 -  
39 urlChecker(searchLink) 38 urlChecker(searchLink)
40 setupAdBlocker() 39 setupAdBlocker()
  40 + addTargets()
41 } 41 }
42 42
43 override func viewIsAppearing(_ animated: Bool) { 43 override func viewIsAppearing(_ animated: Bool) {
@@ -45,14 +45,26 @@ final class SearchResultViewController: UIViewController { @@ -45,14 +45,26 @@ final class SearchResultViewController: UIViewController {
45 } 45 }
46 } 46 }
47 47
48 -//MARK: URL handling 48 +//MARK: Helper
49 extension SearchResultViewController { 49 extension SearchResultViewController {
  50 + private func addTargets() {
  51 + mainView.closeWebViewButton.addTarget(self, action: #selector(closeWebViewTapped(_ :)), for: .touchUpInside)
  52 + }
  53 +
50 private func urlChecker(_ url: String) { 54 private func urlChecker(_ url: String) {
51 let request = URLRequest(url: URL(string: url) ?? URL(fileURLWithPath: "")) 55 let request = URLRequest(url: URL(string: url) ?? URL(fileURLWithPath: ""))
52 mainView.searchResultView.load(request) 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 //MARK: AdBlocker 69 //MARK: AdBlocker
58 extension SearchResultViewController { 70 extension SearchResultViewController {
@@ -9,6 +9,17 @@ import UIKit @@ -9,6 +9,17 @@ import UIKit
9 import WebKit 9 import WebKit
10 10
11 final class SearchResultView: UIView { 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 let searchResultView: WKWebView = { 23 let searchResultView: WKWebView = {
13 let obj = WKWebView() 24 let obj = WKWebView()
14 obj.allowsBackForwardNavigationGestures = true 25 obj.allowsBackForwardNavigationGestures = true
@@ -30,11 +41,18 @@ final class SearchResultView: UIView { @@ -30,11 +41,18 @@ final class SearchResultView: UIView {
30 private func setup() { 41 private func setup() {
31 backgroundColor = .white 42 backgroundColor = .white
32 addSubview(searchResultView) 43 addSubview(searchResultView)
  44 + addSubview(closeWebViewButton)
33 45
34 setupConstaraints() 46 setupConstaraints()
35 } 47 }
36 48
37 private func setupConstaraints() { 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 searchResultView.snp.makeConstraints { make in 56 searchResultView.snp.makeConstraints { make in
39 make.top.equalTo(safeAreaLayoutGuide.snp.top) 57 make.top.equalTo(safeAreaLayoutGuide.snp.top)
40 make.leading.trailing.equalToSuperview() 58 make.leading.trailing.equalToSuperview()
@@ -112,17 +112,9 @@ extension SettingViewController { @@ -112,17 +112,9 @@ extension SettingViewController {
112 break 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 private func shareButtonPressed() { 120 private func shareButtonPressed() {
@@ -139,6 +131,14 @@ extension SettingViewController { @@ -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 //MARK: Mail helper 142 //MARK: Mail helper
143 extension SettingViewController: MFMailComposeViewControllerDelegate { 143 extension SettingViewController: MFMailComposeViewControllerDelegate {
144 func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) { 144 func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
@@ -27,10 +27,9 @@ extension NavigationViewController { @@ -27,10 +27,9 @@ extension NavigationViewController {
27 private func setStartControllers() { 27 private func setStartControllers() {
28 let payloadViewController = PayloadViewController() 28 let payloadViewController = PayloadViewController()
29 let removeAdvertViewController = RemoveAdvertViewController() 29 let removeAdvertViewController = RemoveAdvertViewController()
30 -  
31 let cachingManager = CachingManager.shared 30 let cachingManager = CachingManager.shared
32 31
33 - if cachingManager.isFirstAppLoad == false { 32 + if !cachingManager.isFirstAppLoad {
34 setViewControllers([removeAdvertViewController, payloadViewController], animated: true) 33 setViewControllers([removeAdvertViewController, payloadViewController], animated: true)
35 cachingManager.isFirstAppLoad.toggle() 34 cachingManager.isFirstAppLoad.toggle()
36 } else { 35 } else {
Please register or login to post a comment