Skip to content

Commit

Permalink
Add CompliancePopoverCoordinator CompliancePopoverViewModel & `Co…
Browse files Browse the repository at this point in the history
…mpliancePopoverViewController`
  • Loading branch information
alpavanoglu committed Jul 5, 2023
1 parent b4b45b4 commit cec1679
Show file tree
Hide file tree
Showing 11 changed files with 321 additions and 23 deletions.
4 changes: 2 additions & 2 deletions Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ def wordpress_ui
end

def wordpress_kit
pod 'WordPressKit', '~> 8.4-beta'
# pod 'WordPressKit', git: 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', branch: ''
pod 'WordPressKit', '~> 8.4-beta.3'
# pod 'WordPressKit', git: 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', tag: ''
# pod 'WordPressKit', git: 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', branch: ''
# pod 'WordPressKit', git: 'https://github.com/wordpress-mobile/WordPressKit-iOS.git', commit: ''
# pod 'WordPressKit', path: '../WordPressKit-iOS'
end
Expand Down
8 changes: 4 additions & 4 deletions Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -612,7 +612,7 @@ DEPENDENCIES:
- SwiftLint (~> 0.50)
- WordPress-Editor-iOS (~> 1.19.8)
- WordPressAuthenticator (~> 6.1-beta)
- WordPressKit (~> 8.4-beta)
- WordPressKit (~> 8.4-beta.3)
- WordPressShared (~> 2.2-beta)
- WordPressUI (~> 1.12.5)
- WPMediaPicker (~> 1.8-beta)
Expand All @@ -623,7 +623,6 @@ DEPENDENCIES:
SPEC REPOS:
https://github.com/wordpress-mobile/cocoapods-specs.git:
- WordPressAuthenticator
- WordPressKit
trunk:
- Alamofire
- AlamofireImage
Expand Down Expand Up @@ -662,6 +661,7 @@ SPEC REPOS:
- UIDeviceIdentifier
- WordPress-Aztec-iOS
- WordPress-Editor-iOS
- WordPressKit
- WordPressShared
- WordPressUI
- WPMediaPicker
Expand Down Expand Up @@ -880,7 +880,7 @@ SPEC CHECKSUMS:
WordPress-Aztec-iOS: 7d11d598f14c82c727c08b56bd35fbeb7dafb504
WordPress-Editor-iOS: 9eb9f12f21a5209cb837908d81ffe1e31cb27345
WordPressAuthenticator: b0b900696de5129a215adcd1e9ae6eb89da36ac8
WordPressKit: f445e6fc3c63ddf611513a435408f86fdf3808b3
WordPressKit: 66e1411f48503b3ff3ab2c7db82590e436097882
WordPressShared: 87f3ee89b0a3e83106106f13a8b71605fb8eb6d2
WordPressUI: c5be816f6c7b3392224ac21de9e521e89fa108ac
WPMediaPicker: 0d40b8d66b6dfdaa2d6a41e3be51249ff5898775
Expand All @@ -895,6 +895,6 @@ SPEC CHECKSUMS:
ZendeskSupportSDK: 3a8e508ab1d9dd22dc038df6c694466414e037ba
ZIPFoundation: ae5b4b813d216d3bf0a148773267fff14bd51d37

PODFILE CHECKSUM: 623e3fe64f67d2c0352e26d1ac2bcd58c06b3494
PODFILE CHECKSUM: df7dcee5d41f8627da2633111de057f07ee5bf55

COCOAPODS: 1.12.1
5 changes: 5 additions & 0 deletions WordPress/Classes/Utility/BuildInformation/FeatureFlag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum FeatureFlag: Int, CaseIterable {
case personalizeHomeTab
case commentModerationUpdate
case jetpackSocial
case compliancePopover

/// Returns a boolean indicating if the feature is enabled
var enabled: Bool {
Expand Down Expand Up @@ -131,6 +132,8 @@ enum FeatureFlag: Int, CaseIterable {
return false
case .jetpackSocial:
return AppConfiguration.isJetpack && BuildConfiguration.current == .localDeveloper
case .compliancePopover:
return true
}
}

Expand Down Expand Up @@ -231,6 +234,8 @@ extension FeatureFlag {
return "Comments Moderation Update"
case .jetpackSocial:
return "Jetpack Social"
case .compliancePopover:
return "Compliance Popover"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ class GravatarButtonView: CircularImageView {
}
}


/// Touch animation
extension GravatarButtonView {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ final class BlogDashboardViewController: UIViewController {
BlogDashboardViewModel(viewController: self, blog: blog)
}()

private var complianceCoordinator: CompliancePopoverCoordinator?

lazy var collectionView: DynamicHeightCollectionView = {
let collectionView = DynamicHeightCollectionView(frame: .zero, collectionViewLayout: createLayout())
collectionView.translatesAutoresizingMaskIntoConstraints = false
Expand Down Expand Up @@ -79,6 +81,9 @@ final class BlogDashboardViewController: UIViewController {
startAlertTimer()

WPAnalytics.track(.mySiteDashboardShown)

complianceCoordinator = CompliancePopoverCoordinator(viewController: self)
complianceCoordinator?.presentIfNeeded()
}

override func viewWillDisappear(_ animated: Bool) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import WordPressKit

final class ComplianceLocationService {
func getIPCountryCode(completion: @escaping (Result<String, Error>) -> Void) {
IPLocationRemote().fetchIPCountryCode { result in
switch result {
case .success(let countryCode):
completion(.success(countryCode))
case .failure(let error):
completion(.failure(error))
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import SwiftUI

struct CompliancePopover: View {
var goToSettingsAction: (() -> ())?
var saveAction: (() -> ())?
var shouldScroll: Bool = false

@State
private var isAnalyticsOn = true

var body: some View {
if shouldScroll {
ScrollView(showsIndicators: false) {
contentVStack
}
} else {
contentVStack
}
}

private var contentVStack: some View {
VStack(alignment: .leading, spacing: Length.Padding.double) {
titleText
subtitleText
Expand All @@ -13,6 +27,7 @@ struct CompliancePopover: View {
buttonsHStack
}
.padding(Length.Padding.small)
.fixedSize(horizontal: false, vertical: true)
}

private var titleText: some View {
Expand All @@ -34,7 +49,8 @@ struct CompliancePopover: View {
}

private var footnote: some View {
Text("")
Text(Strings.footnote)
.font(.body)
.foregroundColor(.secondary)
}

Expand All @@ -46,30 +62,32 @@ struct CompliancePopover: View {
}

private var settingsButton: some View {
ZStack {
RoundedRectangle(cornerRadius: Length.Padding.single)
.stroke(Color.DS.Border.divider, lineWidth: Length.Border.thin)
Button(action: {
print("Settings tapped")
}) {
Button(action: {
goToSettingsAction?()
}) {
ZStack {
RoundedRectangle(cornerRadius: Length.Padding.single)
.stroke(Color.DS.Border.divider, lineWidth: Length.Border.thin)
Text(Strings.settingsButtonTitle)
.font(.body)
}
.foregroundColor(Color.DS.Background.brand)
}
.foregroundColor(Color.DS.Background.brand)
.frame(height: Length.Hitbox.minTapDimension)
}

private var saveButton: some View {
ZStack {
RoundedRectangle(cornerRadius: Length.Radius.minHeightButton)
.fill(Color.DS.Background.brand)
Button(action: {
print("Save tapped")
}) {
Button(action: {
saveAction?()
}) {
ZStack {
RoundedRectangle(cornerRadius: Length.Radius.minHeightButton)
.fill(Color.DS.Background.brand)
Text(Strings.saveButtonTitle)
.font(.body)
}
.foregroundColor(.white)
}
.foregroundColor(.white)
.frame(height: Length.Hitbox.minTapDimension)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import UIKit

final class CompliancePopoverCoordinator {
fileprivate enum Constants {
static let hasSavedPrivacyBannerSettingsKey = "hasSavedPrivacyBannerSettings"
}

private let viewController: UIViewController
private let complianceService = ComplianceLocationService()
private let defaults: UserDefaults

init(viewController: UIViewController, defaults: UserDefaults = UserDefaults.standard) {
self.viewController = viewController
self.defaults = defaults
}

func presentIfNeeded() {
guard FeatureFlag.compliancePopover.enabled else {
return
}
complianceService.getIPCountryCode { [weak self] result in
switch result {
case .success(let countryCode):
DispatchQueue.main.async {
guard let self, self.shouldShowPrivacyBanner(countryCode: countryCode) else {
return
}
let complianceViewModel = CompliancePopoverViewModel()
let complianceViewController = CompliancePopoverViewController(viewModel: complianceViewModel)
let bottomSheetViewController = BottomSheetViewController(childViewController: complianceViewController, customHeaderSpacing: 0)
bottomSheetViewController.show(from: self.viewController)
}
case .failure(let error):
()
}
}
}

func shouldShowPrivacyBanner(countryCode: String) -> Bool {
let isCountryInEU = Self.gdprCountryCodes.contains(countryCode)
let hasSavedPrivacySettings = defaults.hasSavedPrivacyBannerSettings
return isCountryInEU && !hasSavedPrivacySettings
}
}

private extension CompliancePopoverCoordinator {
static let gdprCountryCodes: Set<String> = [
"AT", "AUT", // Austria
"BE", "BEL", // Belgium
"BG", "BGR", // Bulgaria
"HR", "HRV", // Croatia
"CY", "CYP", // Cyprus
"CZ", "CZE", // Czech Republic
"DK", "DNK", // Denmark
"EE", "EST", // Estonia
"FI", "FIN", // Finland
"FR", "FRA", // France
"DE", "DEU", // Germany
"GR", "GRC", // Greece
"HU", "HUN", // Hungary
"IE", "IRL", // Ireland
"IT", "ITA", // Italy
"LV", "LVA", // Latvia
"LT", "LTU", // Lithuania
"LU", "LUX", // Luxembourg
"MT", "MLT", // Malta
"NL", "NLD", // Netherlands
"NO", "NOR", // Norway
"PL", "POL", // Poland
"PT", "PRT", // Portugal
"RO", "ROU", // Romania
"SK", "SVK", // Slovakia
"SI", "SVN", // Slovenia
"ES", "ESP", // Spain
"SE", "SWE", // Sweden
"CH", "CHE", // Switzerland
"IS",
"LI",
"GB",
// *Although the UK has departed from the EU as of January 2021,
// the GDPR was enacted before its withdrawal and is therefore considered a valid UK law.*
]
}

private extension UserDefaults {
@objc dynamic var hasSavedPrivacyBannerSettings: Bool {
bool(forKey: CompliancePopoverCoordinator.Constants.hasSavedPrivacyBannerSettingsKey)
}
}
Loading

0 comments on commit cec1679

Please sign in to comment.