Skip to content

Commit

Permalink
feat(config, lib, core, user): add social network conf ✨
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreBrisorgueil committed Oct 10, 2020
1 parent 53d93ca commit 4f5e071
Show file tree
Hide file tree
Showing 13 changed files with 315 additions and 15 deletions.
4 changes: 4 additions & 0 deletions waosSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
BF794D3A22671CD8000B19F3 /* TasksModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF794D3922671CD8000B19F3 /* TasksModel.swift */; };
BF794D51226880FB000B19F3 /* TasksService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF794D50226880FB000B19F3 /* TasksService.swift */; };
BF794D532269C4FB000B19F3 /* TasksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF794D522269C4FB000B19F3 /* TasksViewController.swift */; };
BF7975042531E8B700B92B0D /* UITextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7975032531E8B700B92B0D /* UITextField.swift */; };
BF7F894D2383F0BB00F98D98 /* UITricks.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF7F894C2383F0BB00F98D98 /* UITricks.swift */; };
BF8BD5F7235F30660083B912 /* KeyboardConstraints.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8BD5F6235F30660083B912 /* KeyboardConstraints.swift */; };
BF8C6723227C3E1E0012B5A8 /* TasksCellReactor.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8C6722227C3E1E0012B5A8 /* TasksCellReactor.swift */; };
Expand Down Expand Up @@ -288,6 +289,7 @@
BF794D40226856E6000B19F3 /* Differentiator.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Differentiator.framework; path = Carthage/Build/iOS/Differentiator.framework; sourceTree = "<group>"; };
BF794D50226880FB000B19F3 /* TasksService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TasksService.swift; sourceTree = "<group>"; };
BF794D522269C4FB000B19F3 /* TasksViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TasksViewController.swift; sourceTree = "<group>"; };
BF7975032531E8B700B92B0D /* UITextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextField.swift; sourceTree = "<group>"; };
BF7F894C2383F0BB00F98D98 /* UITricks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITricks.swift; sourceTree = "<group>"; };
BF8BD5F6235F30660083B912 /* KeyboardConstraints.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyboardConstraints.swift; sourceTree = "<group>"; };
BF8C6722227C3E1E0012B5A8 /* TasksCellReactor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TasksCellReactor.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -782,6 +784,7 @@
BFD9CB20238435B20034837F /* UIImage.swift */,
BFD9CB22238435CB0034837F /* UILabel.swift */,
BF4A2F86225C8F160001B4CE /* UILocalizations.swift */,
BF7975032531E8B700B92B0D /* UITextField.swift */,
BF4A2FD32265F4020001B4CE /* UserDefaults.swift */,
BF1D704C245F561100F8EA36 /* Data.swift */,
);
Expand Down Expand Up @@ -1338,6 +1341,7 @@
BF4A2F82225BBA3F0001B4CE /* TasksFlow.swift in Sources */,
BF0BB9FB236B495F00454BDD /* Eureka+Valid+Rx.swift in Sources */,
BF4A2F84225BBA4D0001B4CE /* SecondFlow.swift in Sources */,
BF7975042531E8B700B92B0D /* UITextField.swift in Sources */,
BF8C672C2280177E0012B5A8 /* UICollectionView+ReusableKit.swift in Sources */,
BF42E09D246595E900DA7B1E /* UserPreferenceController.swift in Sources */,
BFA92D2F237C050C006A3B8D /* CoreFormController.swift in Sources */,
Expand Down
8 changes: 8 additions & 0 deletions waosSwift/config/localizations/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ internal enum L10n {
internal static let userEditSectionImage = L10n.tr("Localizable", "user_edit_section_image")
/// Profile
internal static let userEditSectionProfile = L10n.tr("Localizable", "user_edit_section_profile")
/// Social networks
internal static let userEditSectionSocialnetworks = L10n.tr("Localizable", "user_edit_section_socialnetworks")
/// Facebook account name
internal static let userEditSocialnetworksFacebook = L10n.tr("Localizable", "user_edit_socialnetworks_facebook")
/// Instagram account name
internal static let userEditSocialnetworksInstagram = L10n.tr("Localizable", "user_edit_socialnetworks_instagram")
/// Twitter account name
internal static let userEditSocialnetworksTwitter = L10n.tr("Localizable", "user_edit_socialnetworks_twitter")
/// You must configure mail on your phone for this.
internal static let userErrorMail = L10n.tr("Localizable", "user_error_mail")
/// Waos legal
Expand Down
4 changes: 4 additions & 0 deletions waosSwift/config/localizations/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
"user_edit_section_image"= "Profile picture";
"user_edit_image"= "iPhone Gallery";
"user_edit_image_gravatar"= "Gravatar";
"user_edit_section_socialnetworks"= "Social networks";
"user_edit_socialnetworks_instagram"= "Instagram account name";
"user_edit_socialnetworks_twitter"= "Twitter account name";
"user_edit_socialnetworks_facebook"= "Facebook account name";

"user_preferences"= "Preferences";
"user_preferences_section"= "Style";
Expand Down
4 changes: 4 additions & 0 deletions waosSwift/config/localizations/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@
"user_edit_section_image"= "Photo de profil";
"user_edit_image"= "Galerie de l'iPhone";
"user_edit_image_gravatar"= "Gravatar";
"user_edit_section_socialnetworks"= "Réseaux sociaux";
"user_edit_socialnetworks_instagram"= "Nom de compte Instagram";
"user_edit_socialnetworks_twitter"= "Nom de compte Twitter";
"user_edit_socialnetworks_facebook"= "Nom de compte Facebook";

"user_preferences"= "Préférences";
"user_preferences_section"= "Style";
Expand Down
48 changes: 47 additions & 1 deletion waosSwift/lib/helpers/Extensions/Eureka.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import Eureka
*/

extension Form {

/**
* @desc merge error of sections to footer of it
*/
public func mergeErrorToFooter() {
for section in allSections {
section.footer?.title = ""
Expand All @@ -23,3 +25,47 @@ extension Form {
}

}

extension TextRow {
/**
* @desc set left font awesome icon on
* @param {String} icon code,
* @param {FontAwesomeStyle} icon style,
* @param {UIColor} icon color,
* @param {Int} icon padding,
* @param {Int} icon size,
* @param {CGFloat} icon opacity,
*/
public func setFontAwesomeIcon(_ code: String = "", style: FontAwesomeStyle = .solid, color: UIColor = .gray, padding: Int = 5, size: Int = 22, opacity: CGFloat = 0.5) {
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: size+padding*2, height: size) )
let iconView = UIImageView(frame: CGRect(x: 0, y: 0, width: size, height: size))
iconView.image = UIImage.fontAwesomeIcon(code: code, style: style, textColor: color, size: CGSize(width: 22, height: 22))
iconView.alpha = opacity
outerView.addSubview(iconView)
cell.textField.leftView = outerView
cell.textField.leftViewMode = .always
}

}

extension EmailRow {
/**
* @desc set left font awesome icon on
* @param {String} icon code,
* @param {FontAwesomeStyle} icon style,
* @param {UIColor} icon color,
* @param {Int} icon padding,
* @param {Int} icon size,
* @param {CGFloat} icon opacity,
*/
public func setFontAwesomeIcon(_ code: String = "", style: FontAwesomeStyle = .solid, color: UIColor = .gray, padding: Int = 5, size: Int = 22, opacity: CGFloat = 0.5) {
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: size+padding*2, height: size) )
let iconView = UIImageView(frame: CGRect(x: 0, y: 0, width: size, height: size))
iconView.image = UIImage.fontAwesomeIcon(code: code, style: style, textColor: color, size: CGSize(width: 22, height: 22))
iconView.alpha = opacity
outerView.addSubview(iconView)
cell.textField.leftView = outerView
cell.textField.leftViewMode = .always
}

}
21 changes: 21 additions & 0 deletions waosSwift/lib/helpers/Extensions/UITextField.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
extension UITextField {
/**
* @desc set left font awesome icon on
* @param {String} icon code,
* @param {FontAwesomeStyle} icon style,
* @param {UIColor} icon color,
* @param {Int} icon padding,
* @param {Int} icon size,
* @param {CGFloat} icon opacity,
*/
public func setFontAwesomeIcon(_ code: String = "", style: FontAwesomeStyle = .solid, _ color: UIColor = .gray, padding: Int = 10, size: Int = 22, opacity: CGFloat = 0.5) {
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: size+padding*2, height: size) )
let iconView = UIImageView(frame: CGRect(x: padding, y: 0, width: size, height: size))
iconView.image = UIImage.fontAwesomeIcon(code: code, style: style, textColor: color, size: CGSize(width: 22, height: 22))
iconView.alpha = opacity
outerView.addSubview(iconView)
leftView = outerView
leftViewMode = .always
}

}
6 changes: 6 additions & 0 deletions waosSwift/lib/helpers/Validations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,9 @@ public struct PasswordValidationPattern: ValidationPattern {
return "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[@$!%*#?&])[A-Za-z\\d@$!%*#?&]{8,}$"
}
}

public struct AccountValidationPattern: ValidationPattern {
public var pattern: String {
return "[a-zA-ZàáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšžÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ∂ð,.'-_]*"
}
}
1 change: 0 additions & 1 deletion waosSwift/lib/services/Networking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ final class Networking<Target: TargetType>: MoyaProvider<Target> {
let message = "🌎 failure -> \(requestString) (\(response.statusCode)) (\(target))"
log.warning(message, file: file, function: function, line: line)
}
print("totot", response.statusCode)
} else {
let message = "🌎 failure -> \(requestString)\n\(error)"
log.warning(message, file: file, function: function, line: line)
Expand Down
10 changes: 0 additions & 10 deletions waosSwift/modules/core/ui/CoreUITextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@
shared()
}

func setFontAwesomeIcon(_ code: String = "", _ color: UIColor = .gray, padding: Int = 10, size: Int = 22, opacity: CGFloat = 0.5) {
let outerView = UIView(frame: CGRect(x: 0, y: 0, width: size+padding*2, height: size) )
let iconView = UIImageView(frame: CGRect(x: padding, y: 0, width: size, height: size))
iconView.image = UIImage.fontAwesomeIcon(code: code, style: .solid, textColor: color, size: CGSize(width: 22, height: 22))
iconView.alpha = opacity
outerView.addSubview(iconView)
leftView = outerView
leftViewMode = .always
}

func shared() {
self.backgroundColor = Metric.surface
self.borderStyle = .none
Expand Down
105 changes: 103 additions & 2 deletions waosSwift/modules/user/controllers/UserViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,31 @@ class UserViewController: CoreFormController, View, NVActivityIndicatorViewable
$0.title = L10n.userEditImageGravatar
}

// social networks
let inputInstagram = TextRow {
$0.placeholder = L10n.userEditSocialnetworksInstagram
$0.setFontAwesomeIcon("fa-instagram", style: .brands)
}.cellSetup { (cell, _) in
cell.textField.autocapitalizationType = .none
}
let inputTwitter = TextRow {
$0.placeholder = L10n.userEditSocialnetworksTwitter
$0.setFontAwesomeIcon("fa-twitter", style: .brands)
}.cellSetup { (cell, _) in
cell.textField.autocapitalizationType = .none
}
let inputFacebook = TextRow {
$0.placeholder = L10n.userEditSocialnetworksFacebook
$0.setFontAwesomeIcon("fa-facebook", style: .brands)
}.cellSetup { (cell, _) in
cell.textField.autocapitalizationType = .none
}
let labelErrorsSocialNetworks = CoreUILabel().then {
$0.textAlignment = .left
$0.textColor = Metric.error
$0.font = UIFont.systemFont(ofSize: 13)
}

// MARK: Initializing

init(reactor: UserViewReactor) {
Expand All @@ -86,6 +111,7 @@ class UserViewController: CoreFormController, View, NVActivityIndicatorViewable
super.viewDidLoad()

form
// Account
+++ Section(header: L10n.userEditSectionAccount, footer: "") { section in
var footer = HeaderFooterView<UILabel>(.class)
footer.height = { 30 }
Expand All @@ -101,7 +127,7 @@ class UserViewController: CoreFormController, View, NVActivityIndicatorViewable
<<< self.inputFirstName
<<< self.inputLastName
<<< self.inputEmail

// Profile
+++ Section(header: L10n.userEditSectionProfile, footer: "") { section in
var footer = HeaderFooterView<UILabel>(.class)
footer.height = { 30 }
Expand All @@ -115,7 +141,7 @@ class UserViewController: CoreFormController, View, NVActivityIndicatorViewable
section.footer = footer
}
<<< self.inputBio

// Avatar
+++ Section(header: L10n.userEditSectionImage, footer: "")
<<< self.inputAvatar.cellUpdate { cell, _ in
cell.accessoryView?.layer.cornerRadius = (cell.accessoryView?.frame.height ?? 20)/2
Expand All @@ -129,6 +155,22 @@ class UserViewController: CoreFormController, View, NVActivityIndicatorViewable
<<< self.buttonImageGravatar.cellUpdate { cell, _ in
cell.accessoryView = self.imageGravatar
}
// Social Networks
+++ Section(header: L10n.userEditSectionSocialnetworks, footer: "") { section in
var footer = HeaderFooterView<UILabel>(.class)
footer.height = { 30 }
footer.onSetupView = {view, _ in
view.addSubview(self.labelErrorsSocialNetworks)
self.labelErrorsSocialNetworks.snp.makeConstraints { (make) -> Void in
make.right.left.equalTo(view).offset(Metric.margin/2)
make.top.equalTo(view).offset(Metric.margin)
}
}
section.footer = footer
}
<<< self.inputInstagram
<<< self.inputTwitter
<<< self.inputFacebook

self.navigationItem.leftBarButtonItem = self.barButtonCancel
self.navigationItem.rightBarButtonItem = self.barButtonDone
Expand Down Expand Up @@ -243,6 +285,40 @@ private extension UserViewController {
.map { _ in Reactor.Action.deleteAvatar }
.bind(to: reactor.action)
.disposed(by: self.disposeBag)
// social networks
let observableInstagram = self.inputInstagram.rx.text.share()
observableInstagram
.skip(1)
.map {Reactor.Action.updateInstagram($0)}
.bind(to: reactor.action)
.disposed(by: self.disposeBag)
observableInstagram
.debounce(.milliseconds(Metric.timesErrorsDebounce), scheduler: MainScheduler.instance)
.map {_ in Reactor.Action.validateInstagram("socialnetworks")}
.bind(to: reactor.action)
.disposed(by: self.disposeBag)
let observableTwitter = self.inputTwitter.rx.text.share()
observableTwitter
.skip(1)
.map {Reactor.Action.updateTwitter($0)}
.bind(to: reactor.action)
.disposed(by: self.disposeBag)
observableTwitter
.debounce(.milliseconds(Metric.timesErrorsDebounce), scheduler: MainScheduler.instance)
.map {_ in Reactor.Action.validateTwitter("socialnetworks")}
.bind(to: reactor.action)
.disposed(by: self.disposeBag)
let observableFacebook = self.inputFacebook.rx.text.share()
observableFacebook
.skip(1)
.map {Reactor.Action.updateFacebook($0)}
.bind(to: reactor.action)
.disposed(by: self.disposeBag)
observableFacebook
.debounce(.milliseconds(Metric.timesErrorsDebounce), scheduler: MainScheduler.instance)
.map {_ in Reactor.Action.validateFacebook("socialnetworks")}
.bind(to: reactor.action)
.disposed(by: self.disposeBag)
}

// MARK: states (Reactor -> View)
Expand Down Expand Up @@ -310,6 +386,31 @@ private extension UserViewController {
}
})
.disposed(by: self.disposeBag)
// social networks
reactor.state
.map { $0.user.complementary?.socialNetworks?.instagram }
.distinctUntilChanged()
.subscribe(onNext: { instagram in
self.inputInstagram.value = instagram
self.inputInstagram.updateCell()
})
.disposed(by: self.disposeBag)
reactor.state
.map { $0.user.complementary?.socialNetworks?.twitter }
.distinctUntilChanged()
.subscribe(onNext: { twitter in
self.inputTwitter.value = twitter
self.inputTwitter.updateCell()
})
.disposed(by: self.disposeBag)
reactor.state
.map { $0.user.complementary?.socialNetworks?.facebook }
.distinctUntilChanged()
.subscribe(onNext: { facebook in
self.inputFacebook.value = facebook
self.inputFacebook.updateCell()
})
.disposed(by: self.disposeBag)
// refreshing
reactor.state
.map { $0.isRefreshing }
Expand Down
Loading

0 comments on commit 4f5e071

Please sign in to comment.