Rev 20 | AutorÃa | Comparar con el anterior | Ultima modificación | Ver Log |
//// LoginView.swift// twogetskills//// Created by Efrain Yanez Recanatini on 1/27/22.//import SwiftUIimport AudioToolboximport Networkimport Alamofireimport SwiftyJSONimport SafariServicesimport RNCryptorstruct SigninView: View {@EnvironmentObject var networkMonitor : NetworkMonitor@EnvironmentObject var appNavigation : AppNavigation@State private var keyboardHeight : CGFloat = 0private var appData = Environment(\.appData).wrappedValue@State private var email: String = "" {didSet {if email.count > 250 {email = String(email.prefix(250))AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) { return }}}}@State private var isProcessing : Bool = false@State private var isValidEmail : Bool = true@State private var isEditingEmail : Bool = false@State private var password: String = "" {didSet {if password.count > 25 {password = String(password.prefix(25))AudioServicesPlayAlertSoundWithCompletion(SystemSoundID(kSystemSoundID_Vibrate)) { return }}}}@State private var isValidPassword : Bool = true@State private var isEditingPassword : Bool = false@State private var isPasswordShow: Bool = false@State private var showProgressView : Bool = false@State private var presentAlert : Bool = false@State private var titleAlert : String = ""@State private var messageAlert : String = ""@State private var openForgotPassword : Bool = false@State private var openSignup : Bool = falsevar body: some View {ZStack {Color("color_window_background").edgesIgnoringSafeArea(.all)if self.showProgressView {ProgressView().progressViewStyle(CircularProgressViewStyle(tint: Color("color_progress_view_foreground"))).scaleEffect(3, anchor: .center).zIndex(100000)}VStack(spacing: 0) {if networkMonitor.status == .disconnected {HStack {Text(Config.LANG_ERROR_NETWORK_MESSAGE_SHORT).font(Font.custom(Config.FONT_NAME_REGULAR, size: Config.FONT_SIZE_APP_BAR_HEAD1 )).foregroundColor(Color("color_network_disconnected_foreground")).padding(.leading, 16)Spacer()}.edgesIgnoringSafeArea(.top).frame(height: 50).background(Color("color_network_disconnected_background"))Divider().background(Color("color_network_disconnected_background"))}HeaderGroupView()EmailTextFieldGroup(email: self.$email, isEditingEmail: self.$isEditingEmail, isValidEmail: self.$isValidEmail, password: self.$password, isEditingPassword: self.$isEditingPassword, isValidPassword: self.$isValidPassword)PasswordTextFieldGroup(password: self.$password,isEditingPassword: self.$isEditingPassword,isValidPassword: self.$isValidPassword,isPasswordShow: self.$isPasswordShow).padding(.top, isValidEmail ? 10 : 2)Button(action: {if(validate()) {signin()}}, label: {Text(Config.LANG_SIGNIN_BUTTON_SIGNIN).font(Font.custom(Config.FONT_NAME_REGULAR, size: 13)).frame(width: UIScreen.main.bounds.width - 32, height: 35).foregroundColor(Color("color_button_foreground")).background(Color("color_button_background")).border(Color("color_button_border"), width: Config.BUTTON_BORDER_SIZE).cornerRadius(Config.BUTTON_BORDER_RADIUS)}).padding(.top, 16).padding(.leading, 16).padding(.trailing, 16)ButtonSignUpGroup(openSignup: self.$openSignup)Spacer()ButtonForgotPasswordGroup(openForgotPassword: self.$openForgotPassword)}}//}.offset(y : CGFloat(-(self.keyboardHeight / 2))).onAppear {/*NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: .main) { (notification) inlet keyboardHeight: CGFloat = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height ?? 0self.keyboardHeight = keyboardHeight//print("keyboardHeightShow = \(keyboardHeight)")}*/NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: .main) { (notification) in// print("keyboardHeightHide ")}}.popover(isPresented: self.$openSignup, content: {SafariView(sURL: Config.URL_SIGNUP_ENDPOINT)}).popover(isPresented: self.$openForgotPassword, content: {SafariView(sURL: Config.URL_FORGOT_PASSWORD_ENDPOINT)}).alert(isPresented: $presentAlert) {Alert(title: Text(self.titleAlert),message: Text(self.messageAlert),dismissButton: .default(Text(Config.LANG_COMMON_OK)))}}private func signin() -> Void{if isProcessing {self.titleAlert = Config.LANG_ERROR_SIGNIN_IN_PROGRESS_TITLEself.messageAlert = Config.LANG_ERROR_SIGNIN_IN_PROGRESS_MESSAGEself.presentAlert = truereturn}self.isEditingEmail = falseself.isValidEmail = Validator.checkEmail(email: self.email)self.isEditingPassword = falseself.isValidPassword = Validator.checkPassword(password: self.password)if !self.isValidEmail || !self.isValidPassword {return}let device_uuid = appData.deviceUuidlet emailTrimming = email.trimmingCharacters(in: .whitespaces)let passwordTrimming = password.trimmingCharacters(in: .whitespaces)//print("signin")//print(" aes = \(appData.deviceAes) " )//print(" email = \(self.email) " )//print(" password = \(self.password) " )let syncDao = SyncDao()if appData.deviceAes.isEmpty {Device.sharedInstance.generateUUID()self.titleAlert = Config.LANG_ERROR_DEVICE_NOT_REGISTER_TITLEself.messageAlert = Config.LANG_ERROR_DEVICE_NOT_REGISTER_MESSAGEself.presentAlert = truereturn}if networkMonitor.status == .disconnected {self.titleAlert = Config.LANG_ERROR_NETWORK_TITLEself.messageAlert = Config.LANG_ERROR_NETWORK_MESSAGE_SHORTself.presentAlert = truereturn}self.showProgressView = true;let emailData = emailTrimming.data(using: .utf8)!let emailCipherData = RNCryptor.encrypt(data: emailData, withPassword: appData.deviceAes)let emailEncrypted = emailCipherData.base64EncodedString()let passwordData = passwordTrimming.data(using: .utf8)!let passwordCipherData = RNCryptor.encrypt(data: passwordData, withPassword: appData.deviceAes)let passwordEncrypted = passwordCipherData.base64EncodedString()//print(" email encrypted = \(emailEncrypted) " )//print(" password encrypted = \(passwordEncrypted) " )let parameters = [Constants.POST_SIGNIN_FIELD_APPLICATION_ID: "\(Config.APPLICATION_ID)",Constants.POST_SIGNIN_FIELD_VARIANT_ID: "\(Config.VARIANT_ID)",Constants.POST_SYNC_FIELD_DEVICE_UUID: device_uuid,Constants.POST_SIGNIN_FIELD_EMAIL: emailEncrypted,Constants.POST_SIGNIN_FIELD_PASSWORD: passwordEncrypted,Constants.POST_SIGNIN_FIELD_ENCRYPTER: Constants.GLOBAL_ENCRYPTER]let headers: HTTPHeaders = [.accept(Constants.HTTP_HEADER_ACCEPT)]//print("URL signin : \(Config.URL_SIGNIN)")self.showProgressView = trueAF.request(Config.URL_SIGNIN, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers).responseJSON{(response) inself.showProgressView = falseswitch response.result {case .success:let json = try? JSON(data: response.data!)//print("json : \(json)")if json?["success"] ?? "" != false {let dataService = DataService()if dataService.syncFromServer(json : json) {let userinfo = ["title" : Config.LANG_TITLE_NOTIFICATION_SIGNIN_PUSH,"body" : Config.LANG_BODY_NOTIFICATION_SIGNIN_PUSH,"url" : ""]NotificationCenter.default.post(name: Constants.NOTIFICATION_NAME_PUSH , object: self, userInfo: userinfo)let now = Date()let dateFormatter = DateFormatter()dateFormatter.dateFormat = Constants.FORMAT_DATETIME_SERVICElet dateOn = dateFormatter.string(from: now)var userLog = UserLogModel()userLog.userUuid = appData.userUuiduserLog.activity = Constants.USER_LOG_ACTIVITY_SIGNINuserLog.addedOn = dateOnlet userLogDao = UserLogDao()userLogDao.insert(record: userLog)var sync = SyncModel()var json = userLog.toJson()json[Constants.SYNC_ADAPTER_DATA_TYPE_FIELD_NAME] = Constants.SYNC_ADAPTER_DATA_TYPE_USER_LOGsync = SyncModel();sync.type = Constants.SYNC_ADAPTER_TYPE_SYNCif let theJSONData = try? JSONSerialization.data(withJSONObject: json, options: .prettyPrinted),let data = String(data: theJSONData, encoding: String.Encoding.ascii) {sync.data = data}syncDao.insert(record : sync);appNavigation.subpageActive = AppMainSubPage.mycapsulesappNavigation.pageActive = AppMainPage.home//self.goToMain = true}} else {let message = json?["data"].string ?? ""if !message.isEmpty {self.titleAlert = Config.LANG_ERROR_GENERIC_TITLEself.messageAlert = messageself.presentAlert = true}}returncase .failure :self.titleAlert = Config.LANG_ERROR_COMMUNICATION_TITLEself.messageAlert = Config.LANG_ERROR_COMMUNICATION_MESSAGEself.presentAlert = truereturn}}}private func validate() -> Bool{//print("validate - email : \(email)")//print("validate - password : \(password)")if email.isEmpty {self.isValidEmail = false} else if !Validator.checkEmail(email: email) {self.isValidEmail = false} else {self.isValidEmail = true}if password.isEmpty {self.isValidPassword = false} else if(!Validator.checkPassword(password: password)) {self.isValidPassword = false} else {self.isValidPassword = true}return self.isValidEmail && self.isValidPassword}}struct SigninView_Previews: PreviewProvider {static var previews: some View {SigninView()}}struct HeaderGroupView: View {var body: some View {//Inicio LogoHStack {Image("logo").resizable().frame(width: 50, height: 50)Text(Config.LANG_SIGNIN_APP_NAME).font(Font.custom(Config.FONT_NAME_BOLD, size: 24)).foregroundColor(Color("color_textview_foreground"))Spacer()}.padding(.leading, 16).padding(.top, 66)//Fin logo//Inicio SaludoHStack {Text(Config.LANG_SIGNIN_GREATING).font(Font.custom(Config.FONT_NAME_BOLD, size: 32)).foregroundColor(Color("color_textview_foreground"))Spacer()}.padding(.leading, 16).padding(.top, 10)//Fin Saludo//Inicio EncabezadoHStack {Text(Config.LANG_SIGNIN_HEAD_LINE1).font(Font.custom(Config.FONT_NAME_REGULAR, size: 16)).foregroundColor(Color("color_textview_foreground"))Spacer()}.padding(.leading, 16).padding(.top, 10)//Fin Encabezado}}struct EmailTextFieldGroup : View {@Binding var email: String@Binding var isEditingEmail : Bool@Binding var isValidEmail : Bool@Binding var password: String@Binding var isEditingPassword: Bool@Binding var isValidPassword: Boolvar body : some View {//Inicio Label EmailHStack {Text(Config.LANG_SIGNIN_TITLE_EMAIL_FIELD).font(Font.custom(Config .FONT_NAME_REGULAR, size: Config.FONT_SIZE_TEXTFIELD_LABEL)).foregroundColor(Color("color_textview_foreground"))Spacer()}.padding(.leading, 16).padding(.top, 10)//Fin Label Email//Inicio TextField EmailGroup {HStack {/*Image("ui_mail").resizable().frame(width: 24, height: 24).padding(.horizontal, 4)*/TextField("",text: self.$email,onEditingChanged: { (changed) inif changed {if self.isEditingPassword {self.isValidPassword = Validator.checkPassword(password: self.password)self.isEditingPassword = false}self.isEditingEmail = true} else {self.isEditingEmail = falseself.isValidEmail = Validator.checkEmail(email: self.email)}}, onCommit: {self.isEditingEmail = falseself.isValidEmail = Validator.checkEmail(email: self.email)}).font(Font.custom(Config.FONT_NAME_REGULAR, size: Config.FONT_SIZE_TEXTFIELD)).textFieldStyle(PlainTextFieldStyle()).frame(height: 32).keyboardType(.emailAddress).autocapitalization(.none)//.foregroundColor(Color("color_textfield_foreground"))//.background(Color("color_textfield_background")).padding(.leading, 4)Spacer()}}.foregroundColor(Color("color_textfield_foreground")).background(Color("color_textfield_background")).overlay(RoundedRectangle(cornerRadius: 5).stroke(Color(self.isEditingEmail ? "color_textfield_border_active" : self.isValidEmail ? "color_textfield_border" : "color_textfield_border_error" ))).padding(.leading, 16).padding(.trailing, 16).padding(.top, self.isValidEmail ? 10 : 2)if !self.isValidEmail {HStack {Spacer()Text(Config.LANG_SIGNIN_ERROR_EMAIL_FIELD).foregroundColor(.red).font(Font.custom(Config.FONT_NAME_REGULAR, size: Config.FONT_SIZE_TEXTFIELD_ERROR))}.padding(.top, 5).padding(.trailing, 16)}//Fin TextField Email}}struct PasswordTextFieldGroup : View {@Binding var password: String@Binding var isEditingPassword: Bool@Binding var isValidPassword: Bool@Binding var isPasswordShow: Boolvar body : some View {//Inicio Label PasswordHStack {Text(Config.LANG_SIGNIN_TITLE_PASSWORD_FIELD).font(Font.custom(Config .FONT_NAME_REGULAR, size: Config.FONT_SIZE_TEXTFIELD_LABEL)).foregroundColor(Color("color_textview_foreground"))Spacer()}.padding(.leading, 16)//Fin Label Password//Inicio TextField PasswordGroup {HStack {/*Image("ui_key").resizable().frame(width: 24, height: 24).padding(.horizontal, 4)*/if isPasswordShow {TextField("",text: self.$password,onEditingChanged: { (changed) inif changed {self.isEditingPassword = true} else {self.isEditingPassword = falseself.isValidPassword = Validator.checkPassword(password: self.password)}}, onCommit: {self.isEditingPassword = falseself.isValidPassword = Validator.checkPassword(password: self.password)}).font(Font.custom(Config.FONT_NAME_REGULAR, size: Config.FONT_SIZE_TEXTFIELD)).textFieldStyle(PlainTextFieldStyle()).frame(height: 32).keyboardType(.default).autocapitalization(.none)/*.foregroundColor(Color("color_textfield_foreground")).background(Color("color_textfield_background"))*/.padding(.leading, 4)Spacer()Button(action: {self.isPasswordShow.toggle()}, label: {Image("ui_visibility_off").resizable().frame(width: 24, height: 24).padding(.horizontal, 4)})} else {SecureField("", text: self.$password, onCommit: {self.isEditingPassword = falseself.isValidPassword = Validator.checkPassword(password: self.password)}).onTapGesture {self.isEditingPassword = true}.font(Font.custom(Config.FONT_NAME_REGULAR, size: Config.FONT_SIZE_TEXTFIELD)).textFieldStyle(PlainTextFieldStyle()).frame(height: 32).keyboardType(.default).autocapitalization(.none)/*.foregroundColor(Color("color_textfield_foreground")).background(Color("color_textfield_background"))*/.padding(.leading, 4)Spacer()Button(action: {self.isPasswordShow.toggle()}, label: {Image("ui_visibility").resizable().frame(width: 24, height: 24).padding(.horizontal, 4)})}////ui_visibility}}.foregroundColor(Color("color_textfield_foreground")).background(Color("color_textfield_background")).overlay(RoundedRectangle(cornerRadius: 5).stroke(Color(self.isEditingPassword ? "color_textfield_border_active" : self.isValidPassword ? "color_textfield_border" : "color_textfield_border_error" ))).padding(.leading, 16).padding(.trailing, 16).padding(.top, 2)if !self.isValidPassword {HStack {Spacer()Text(Config.LANG_SIGNIN_ERROR_PASSWORD_FIELD).foregroundColor(.red).font(Font.custom(Config.FONT_NAME_REGULAR, size: Config.FONT_SIZE_TEXTFIELD_ERROR))}.padding(.top, 5).padding(.trailing, 16)}//Fin TextField Password}}struct ButtonSignUpGroup : View {@Binding var openSignup : Boolvar body : some View {Button(action: {openSignup = true}, label: {Text(Config.LANG_SIGNIN_BUTTON_SIGNUP).font(Font.custom(Config.FONT_NAME_REGULAR, size: 13)).frame(width: UIScreen.main.bounds.width - 32, height: 35).foregroundColor(Color("color_button_foreground")).background(Color("color_button_background")).border(Color("color_button_border"), width: Config.BUTTON_BORDER_SIZE).cornerRadius(Config.BUTTON_BORDER_RADIUS)}).padding(.top, 16).padding(.leading, 16).padding(.trailing, 16)}}struct ButtonForgotPasswordGroup : View {@Binding var openForgotPassword : Boolvar body : some View {Button(action: {openForgotPassword = true}, label: {Text(Config.LANG_SIGNIN_BUTTON_FORGOT_PASSWORD).font(Font.custom(Config.FONT_NAME_REGULAR, size: 13)).foregroundColor(Color("color_button_foreground"))}).padding(.vertical, 16)}}