FourthTabViewController.swift 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798
  1. //
  2. // SettingTableViewController.swift
  3. // Qmera
  4. //
  5. // Created by Yayan Dwi on 16/09/21.
  6. //
  7. import UIKit
  8. import NotificationBannerSwift
  9. import nuSDKService
  10. import NexilisLite
  11. import Photos
  12. public class FourthTabViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {
  13. var language: [[String: String]] = [["Indonesia": "id"],["English": "en"]]
  14. var alert: UIAlertController?
  15. var textFields = [UITextField]()
  16. var switchVibrateMode = UISwitch()
  17. var switchSaveToGallery = UISwitch()
  18. var switchAutoDownload = UISwitch()
  19. @IBOutlet weak var tableView: UITableView!
  20. @IBOutlet weak var backgroundImage: UIImageView!
  21. public override func viewDidLoad() {
  22. super.viewDidLoad()
  23. tableView.delegate = self
  24. tableView.dataSource = self
  25. tableView.layoutMargins = .init(top: 0, left: 5, bottom: 0, right: 5)
  26. // tableView.separatorColor = .gray
  27. tableView.separatorStyle = .none
  28. self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
  29. makeMenu()
  30. tableView.reloadData()
  31. switchVibrateMode.tintColor = .gray
  32. switchSaveToGallery.tintColor = .gray
  33. switchAutoDownload.tintColor = .gray
  34. switchVibrateMode.onTintColor = .mainColor
  35. switchSaveToGallery.onTintColor = .mainColor
  36. switchAutoDownload.onTintColor = .mainColor
  37. let vibrateMode = UserDefaults.standard.bool(forKey: "vibrateMode")
  38. let saveGallery = UserDefaults.standard.bool(forKey: "saveToGallery")
  39. let autoDownload = UserDefaults.standard.bool(forKey: "autoDownload")
  40. if vibrateMode {
  41. switchVibrateMode.setOn(true, animated: false)
  42. }
  43. if saveGallery {
  44. switchSaveToGallery.setOn(true, animated: false)
  45. }
  46. if autoDownload {
  47. switchAutoDownload.setOn(true, animated: false)
  48. }
  49. switchVibrateMode.addTarget(self, action: #selector(vibrateModeSwitch), for: .valueChanged)
  50. switchSaveToGallery.addTarget(self, action: #selector(saveToGallerySwitch), for: .valueChanged)
  51. switchAutoDownload.addTarget(self, action: #selector(autoDownloadSwitch), for: .valueChanged)
  52. // navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(didTapCancel))
  53. }
  54. public override func viewWillDisappear(_ animated: Bool) {
  55. if ViewController.isExpandButton {
  56. ViewController.expandButton()
  57. }
  58. }
  59. @objc func vibrateModeSwitch() {
  60. UserDefaults.standard.set(switchVibrateMode.isOn, forKey: "vibrateMode")
  61. }
  62. @objc func saveToGallerySwitch() {
  63. if switchSaveToGallery.isOn {
  64. PHPhotoLibrary.requestAuthorization({status in
  65. DispatchQueue.main.async {
  66. if status == .authorized {
  67. UserDefaults.standard.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
  68. } else {
  69. self.switchSaveToGallery.setOn(false, animated: true)
  70. }
  71. }
  72. })
  73. } else {
  74. UserDefaults.standard.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
  75. }
  76. }
  77. @objc func autoDownloadSwitch() {
  78. UserDefaults.standard.set(switchAutoDownload.isOn, forKey: "autoDownload")
  79. }
  80. func makeMenu(imageSignIn: String = ""){
  81. let isChangeProfile = UserDefaults.standard.bool(forKey: "is_change_profile")
  82. Database.shared.database?.inTransaction({ fmdb, rollback in
  83. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  84. if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT user_type, image_id FROM BUDDY where f_pin='\(idMe!)'"), cursorUser.next() {
  85. var groupId = ""
  86. if let cursorGroup = Database.shared.getRecords(fmdb: fmdb, query: "SELECT group_id FROM GROUPZ where group_type = 1 AND official = 1"), cursorGroup.next() {
  87. groupId = cursorGroup.string(forColumnIndex: 0) ?? ""
  88. cursorGroup.close()
  89. }
  90. var position = ""
  91. if let cursorIsAdmin = Database.shared.getRecords(fmdb: fmdb, query: "SELECT position FROM GROUPZ_MEMBER where group_id = '\(groupId)' AND f_pin = '\(idMe!)'"), cursorIsAdmin.next() {
  92. position = cursorIsAdmin.string(forColumnIndex: 0) ?? ""
  93. cursorIsAdmin.close()
  94. }
  95. if cursorUser.string(forColumnIndex: 0) == "23" && position == "1" {
  96. Item.menus["Personal"] = [
  97. Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
  98. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  99. Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Change Admin / Internal Password".localized()),
  100. // Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Login to Nexilis Web".localized()),
  101. ]
  102. } else if cursorUser.string(forColumnIndex: 0) == "23" || cursorUser.string(forColumnIndex: 0) == "24" {
  103. Item.menus["Personal"] = [
  104. Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
  105. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  106. // Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Login to Nexilis Web".localized()),
  107. ]
  108. } else {
  109. Item.menus["Personal"] = [
  110. Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
  111. // Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Login to Nexilis Web".localized()),
  112. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  113. Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Login as Admin / Internal".localized()),
  114. ]
  115. }
  116. if !isChangeProfile {
  117. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Change Device".localized()))
  118. } else if isChangeProfile {
  119. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "rectangle.portrait.and.arrow.right"), title: "Logout".localized()))
  120. }
  121. let image = cursorUser.string(forColumnIndex: 1)
  122. if image != nil {
  123. if !image!.isEmpty {
  124. do {
  125. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  126. let file = documentDir.appendingPathComponent(image!)
  127. if FileManager().fileExists(atPath: file.path) {
  128. let image = UIImage(contentsOfFile: file.path)
  129. Item.menus["Personal"]?[0].icon = image?.circleMasked
  130. if !imageSignIn.isEmpty {
  131. var dataImage: [AnyHashable : Any] = [:]
  132. dataImage["name"] = imageSignIn
  133. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  134. }
  135. } else {
  136. Download().start(forKey: image!) { (name, progress) in
  137. guard progress == 100 else {
  138. return
  139. }
  140. DispatchQueue.main.async {
  141. let image = UIImage(contentsOfFile: file.path)
  142. Item.menus["Personal"]?[0].icon = image?.circleMasked
  143. self.tableView.reloadData()
  144. if !imageSignIn.isEmpty {
  145. var dataImage: [AnyHashable : Any] = [:]
  146. dataImage["name"] = imageSignIn
  147. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  148. }
  149. }
  150. }
  151. }
  152. } catch {}
  153. }
  154. }
  155. cursorUser.close()
  156. } else {
  157. Item.menus["Personal"] = [
  158. Item(icon: UIImage(systemName: "person.fill"), title: "Personal Information".localized()),
  159. // Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Login to Nexilis Web".localized()),
  160. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  161. Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Login as Admin / Internal".localized()),
  162. Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Change Device".localized())
  163. ]
  164. if !imageSignIn.isEmpty {
  165. do {
  166. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  167. let file = documentDir.appendingPathComponent(imageSignIn)
  168. if FileManager().fileExists(atPath: file.path) {
  169. let image = UIImage(contentsOfFile: file.path)
  170. Item.menus["Personal"]?[0].icon = image?.circleMasked
  171. var dataImage: [AnyHashable : Any] = [:]
  172. dataImage["name"] = imageSignIn
  173. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  174. } else {
  175. Download().start(forKey: imageSignIn) { (name, progress) in
  176. guard progress == 100 else {
  177. return
  178. }
  179. DispatchQueue.main.async {
  180. let image = UIImage(contentsOfFile: file.path)
  181. Item.menus["Personal"]?[0].icon = image?.circleMasked
  182. self.tableView.reloadData()
  183. var dataImage: [AnyHashable : Any] = [:]
  184. dataImage["name"] = imageSignIn
  185. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  186. }
  187. }
  188. }
  189. } catch {}
  190. }
  191. }
  192. })
  193. Item.menus["Call"] = [
  194. Item(icon: UIImage(systemName: "message"), title: "Incoming Message(s)".localized()),
  195. Item(icon: UIImage(systemName: "phone"), title: "Incoming Call(s)".localized()),
  196. Item(icon: UIImage(systemName: "iphone.homebutton.radiowaves.left.and.right"), title: "Vibrate Mode".localized()),
  197. Item(icon: UIImage(systemName: "photo.on.rectangle.angled"), title: "Save to Gallery".localized()),
  198. Item(icon: UIImage(systemName: "arrow.down.square"), title: "Auto Download".localized()),
  199. ]
  200. Item.menus["Version"] = [
  201. Item(icon: UIImage(systemName: "gear"), title: "Version".localized()),
  202. Item(icon: UIImage(named: "pb_powered_button", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), title: "Powered by Nexilis".localized()),
  203. ]
  204. }
  205. override public func viewWillAppear(_ animated: Bool) {
  206. let randomInt = Int.random(in: 1..<10)
  207. backgroundImage.image = UIImage(named: "pb_lbackground_\(randomInt)")
  208. self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
  209. navigationController?.setNavigationBarHidden(false, animated: false)
  210. navigationController?.navigationBar.backgroundColor = .clear
  211. navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
  212. navigationController?.navigationBar.shadowImage = UIImage()
  213. navigationController?.navigationBar.isTranslucent = true
  214. }
  215. // MARK: - Table view data source
  216. public func numberOfSections(in tableView: UITableView) -> Int {
  217. return Item.sections.count
  218. }
  219. public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  220. return 1
  221. }
  222. public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  223. return Item.menuFor(section: section).count
  224. }
  225. public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  226. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  227. cell.accessoryType = .none
  228. cell.indentationLevel = 0
  229. var content = cell.defaultContentConfiguration()
  230. content.textProperties.font = UIFont.systemFont(ofSize: 14)
  231. content.secondaryTextProperties.font = UIFont.systemFont(ofSize: 14)
  232. content.secondaryTextProperties.color = .gray
  233. content.prefersSideBySideTextAndSecondaryText = true
  234. let section = Item.sections[indexPath.section]
  235. if let arr = Item.menus[section] {
  236. let menu = arr[indexPath.row]
  237. content.image = menu.icon
  238. content.imageProperties.tintColor = .mainColor
  239. content.imageProperties.maximumSize = CGSize(width: 24, height: 24)
  240. content.text = menu.title
  241. cell.accessoryView = nil
  242. cell.separatorInset = UIEdgeInsets(top: .greatestFiniteMagnitude, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
  243. switch menu.title {
  244. case "Personal Information".localized():
  245. cell.accessoryType = .disclosureIndicator
  246. case "Login as Admin / Internal".localized():
  247. cell.accessoryType = .disclosureIndicator
  248. case "Login to Nexilis Web".localized():
  249. cell.accessoryType = .disclosureIndicator
  250. case "Change Device".localized():
  251. cell.accessoryType = .disclosureIndicator
  252. // case "Logout".localized():
  253. case "Change Admin / Internal Password".localized():
  254. cell.accessoryType = .disclosureIndicator
  255. case "Change Language".localized():
  256. cell.accessoryType = .disclosureIndicator
  257. case "Version".localized():
  258. let accessoryButton = UIButton(type: .custom)
  259. accessoryButton.setTitle(UIApplication.appVersion, for: .normal)
  260. accessoryButton.setTitleColor(.black, for: .normal)
  261. accessoryButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
  262. accessoryButton.contentMode = .scaleAspectFit
  263. cell.accessoryView = accessoryButton as UIView
  264. case "Vibrate Mode".localized():
  265. cell.accessoryView = switchVibrateMode
  266. case "Save to Gallery".localized():
  267. cell.accessoryView = switchSaveToGallery
  268. case "Auto Download".localized():
  269. cell.accessoryView = switchAutoDownload
  270. default:
  271. content.secondaryText = nil
  272. }
  273. }
  274. cell.contentConfiguration = content
  275. return cell
  276. }
  277. public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  278. let item = Item.menuFor(section: indexPath.section)[indexPath.row]
  279. if item.title == "Personal Information".localized() {
  280. if(ViewController.checkIsChangePerson()){
  281. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
  282. controller.data = UserDefaults.standard.string(forKey: "me")!
  283. controller.flag = .me
  284. controller.dismissImage = { image, imageName in
  285. var dataImage: [AnyHashable : Any] = [:]
  286. dataImage["name"] = imageName
  287. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  288. self.makeMenu()
  289. self.tableView.reloadData()
  290. }
  291. navigationController?.show(controller, sender: nil)
  292. }
  293. } else if item.title == "Login as Admin / Internal".localized() || item.title == "Change Admin / Internal Password".localized() {
  294. if(ViewController.checkIsChangePerson()){
  295. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  296. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  297. imageView.tintColor = .white
  298. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  299. banner.show()
  300. return
  301. }
  302. let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
  303. if(item.title.contains("Change")){
  304. if let action = self.actionChangePassword(for: "admin", title: "Change Admin Password".localized()) {
  305. alertController.addAction(action)
  306. }
  307. if let action = self.actionChangePassword(for: "internal", title: "Change Internal Password".localized()) {
  308. alertController.addAction(action)
  309. }
  310. }
  311. else {
  312. if let action = self.actionLogin(for: "admin", title: "Login as Admin".localized()) {
  313. alertController.addAction(action)
  314. }
  315. if let action = self.actionLogin(for: "internal", title: "Login as Internal Team".localized()) {
  316. alertController.addAction(action)
  317. }
  318. }
  319. alertController.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  320. self.present(alertController, animated: true)
  321. }
  322. } else if item.title == "Change Language".localized() {
  323. let vc = UIViewController()
  324. vc.preferredContentSize = CGSize(width: UIScreen.main.bounds.width - 10, height: 150)
  325. let pickerView = UIPickerView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 10, height: 150))
  326. pickerView.dataSource = self
  327. pickerView.delegate = self
  328. let lang = UserDefaults.standard.string(forKey: "i18n_language")
  329. var index = 1
  330. if lang == "id" {
  331. index = 0
  332. }
  333. pickerView.selectRow(index, inComponent: 0, animated: false)
  334. vc.view.addSubview(pickerView)
  335. pickerView.translatesAutoresizingMaskIntoConstraints = false
  336. pickerView.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor).isActive = true
  337. pickerView.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor).isActive = true
  338. let alert = UIAlertController(title: "Select Language".localized(), message: "", preferredStyle: .actionSheet)
  339. alert.setValue(vc, forKey: "contentViewController")
  340. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { (UIAlertAction) in
  341. }))
  342. alert.addAction(UIAlertAction(title: "Select".localized(), style: .default, handler: { (UIAlertAction) in
  343. let selectedIndex = pickerView.selectedRow(inComponent: 0)
  344. let lang = self.language[selectedIndex].values.first
  345. UserDefaults.standard.set(lang, forKey: "i18n_language")
  346. self.viewDidLoad()
  347. }))
  348. self.present(alert, animated: true, completion: nil)
  349. } else if item.title == "Change Device".localized() {
  350. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "changeDevice") as! ChangeDeviceViewController
  351. controller.isDismiss = { newThumb in
  352. self.makeMenu(imageSignIn: newThumb)
  353. self.tableView.reloadData()
  354. }
  355. navigationController?.show(controller, sender: nil)
  356. } else if item.title == "Logout".localized() {
  357. let alert = UIAlertController(title: "Logout".localized(), message: "Are you sure want to logout?".localized(), preferredStyle: .alert)
  358. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
  359. alert.addAction(UIAlertAction(title: "Yes".localized(), style: .destructive, handler: {(_) in
  360. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  361. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  362. imageView.tintColor = .white
  363. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  364. banner.show()
  365. return
  366. }
  367. DispatchQueue.global().async {
  368. self.deleteAllRecordDatabase()
  369. Nexilis.destroyAll()
  370. let apiKey = Nexilis.sAPIKey
  371. var id = UIDevice.current.identifierForVendor?.uuidString ?? "UNK-DEVICE"
  372. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpApi(api: apiKey, p_pin: id), timeout: 30 * 1000) {
  373. id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
  374. if(!id.isEmpty){
  375. Nexilis.changeUser(f_pin: id)
  376. UserDefaults.standard.setValue(id, forKey: "me")
  377. UserDefaults.standard.set("", forKey: "pwd")
  378. UserDefaults.standard.set(false, forKey: "is_change_profile")
  379. UserDefaults.standard.synchronize()
  380. // pos registration
  381. _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
  382. DispatchQueue.main.async {
  383. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  384. imageView.tintColor = .white
  385. let banner = FloatingNotificationBanner(title: "Successfully Logout".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  386. banner.show()
  387. var dataImage: [AnyHashable : Any] = [:]
  388. dataImage["name"] = ""
  389. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  390. self.makeMenu()
  391. self.tableView.reloadData()
  392. }
  393. }
  394. } else {
  395. DispatchQueue.main.async {
  396. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  397. imageView.tintColor = .white
  398. let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  399. banner.show()
  400. }
  401. }
  402. }
  403. }))
  404. self.present(alert, animated: true, completion: nil)
  405. }
  406. }
  407. private func actionLogin(for type: String, title: String) -> UIAlertAction? {
  408. return UIAlertAction(title: title, style: .default) { _ in
  409. self.alert = UIAlertController(title: "Login as Admin".localized(), message: nil, preferredStyle: .alert)
  410. if type == "internal" {
  411. self.alert = UIAlertController(title: "Login as Internal Team".localized(), message: nil, preferredStyle: .alert)
  412. }
  413. self.textFields.removeAll()
  414. self.alert?.addTextField{ (texfield) in
  415. texfield.placeholder = "Password"
  416. texfield.isSecureTextEntry = true
  417. texfield.addPadding(.right(40))
  418. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  419. let buttonHideUnhide = UIButton()
  420. buttonHideUnhide.tag = 0
  421. texfield.addSubview(buttonHideUnhide)
  422. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  423. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  424. buttonHideUnhide.tintColor = .black
  425. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  426. }
  427. let submitAction = UIAlertAction(title: "Sign In".localized(), style: .default, handler: { (action) -> Void in
  428. let textField = self.alert?.textFields![0]
  429. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  430. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  431. imageView.tintColor = .white
  432. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  433. banner.show()
  434. return
  435. }
  436. if type == "admin" {
  437. self.signInAdmin(password: textField!.text!, completion: { result in
  438. if result {
  439. DispatchQueue.main.async {
  440. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  441. imageView.tintColor = .white
  442. let banner = FloatingNotificationBanner(title: "Successfully login Admin".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  443. banner.show()
  444. let itemCP = Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Change Admin / Internal Password".localized())
  445. Item.menus["Personal"]?[1] = itemCP
  446. self.tableView.reloadData()
  447. }
  448. }
  449. })
  450. } else {
  451. self.signInInternal(password: textField!.text!, completion: { result in
  452. if result {
  453. DispatchQueue.main.async {
  454. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  455. imageView.tintColor = .white
  456. let banner = FloatingNotificationBanner(title: "Successfully login Internal Team".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  457. banner.show()
  458. Item.menus["Personal"]?.remove(at: 1)
  459. self.tableView.reloadData()
  460. }
  461. }
  462. })
  463. }
  464. })
  465. submitAction.isEnabled = false
  466. self.alert?.addAction(submitAction)
  467. self.alert?.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  468. self.present(self.alert!, animated: true, completion: nil)
  469. }
  470. }
  471. private func actionChangePassword(for type: String, title: String) -> UIAlertAction? {
  472. return UIAlertAction(title: title, style: .default) { _ in
  473. self.alert = UIAlertController(title: "Change Admin Password".localized(), message: nil, preferredStyle: .alert)
  474. if type == "internal" {
  475. self.alert = UIAlertController(title: "Change Internal Password".localized(), message: nil, preferredStyle: .alert)
  476. }
  477. self.textFields.removeAll()
  478. self.alert?.addTextField{ (texfield) in
  479. texfield.placeholder = "Old Password"
  480. texfield.isSecureTextEntry = true
  481. texfield.addPadding(.right(40))
  482. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  483. self.textFields.append(texfield)
  484. let buttonHideUnhide = UIButton()
  485. buttonHideUnhide.tag = 0
  486. texfield.addSubview(buttonHideUnhide)
  487. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  488. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  489. buttonHideUnhide.tintColor = .black
  490. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  491. }
  492. self.alert?.addTextField{ (texfield) in
  493. texfield.placeholder = "New Password"
  494. texfield.isSecureTextEntry = true
  495. texfield.addPadding(.right(40))
  496. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  497. self.textFields.append(texfield)
  498. let buttonHideUnhide = UIButton()
  499. buttonHideUnhide.tag = 1
  500. texfield.addSubview(buttonHideUnhide)
  501. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  502. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  503. buttonHideUnhide.tintColor = .black
  504. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  505. }
  506. let submitAction = UIAlertAction(title: "Change Password".localized(), style: .default, handler: { (action) -> Void in
  507. let textFieldOld = self.alert?.textFields![0]
  508. let textFieldNew = self.alert?.textFields![1]
  509. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  510. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  511. imageView.tintColor = .white
  512. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  513. banner.show()
  514. return
  515. }
  516. if type == "admin" {
  517. self.changePasswordAdmin(oldPassword: textFieldOld!.text!, newPassword: textFieldNew!.text!, completion: { result in
  518. if result {
  519. DispatchQueue.main.async {
  520. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  521. imageView.tintColor = .white
  522. let banner = FloatingNotificationBanner(title: "Admin password changed successfully".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  523. banner.show()
  524. }
  525. }
  526. })
  527. } else {
  528. self.changePasswordInternal(oldPassword: textFieldOld!.text!, newPassword: textFieldNew!.text!, completion: { result in
  529. if result {
  530. DispatchQueue.main.async {
  531. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  532. imageView.tintColor = .white
  533. let banner = FloatingNotificationBanner(title: "Internal password changed successfully".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  534. banner.show()
  535. }
  536. }
  537. })
  538. }
  539. })
  540. submitAction.isEnabled = false
  541. self.alert?.addAction(submitAction)
  542. self.alert?.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  543. self.present(self.alert!, animated: true, completion: nil)
  544. }
  545. }
  546. @objc func showPassword(_ sender:UIButton) {
  547. if alert!.textFields![sender.tag].isSecureTextEntry {
  548. alert!.textFields![sender.tag].isSecureTextEntry = false
  549. let buttonImage = alert!.textFields![sender.tag].subviews[0] as! UIButton
  550. buttonImage.setImage(UIImage(systemName: "eye.fill"), for: .normal)
  551. } else {
  552. alert!.textFields![sender.tag].isSecureTextEntry = true
  553. let buttonImage = alert!.textFields![sender.tag].subviews[0] as! UIButton
  554. buttonImage.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  555. }
  556. }
  557. @objc func alertTextFieldDidChange(_ sender: UITextField) {
  558. if(!textFields.isEmpty){
  559. print("text count 0: \(textFields[0].text!.count)")
  560. print("text count 1: \(textFields[1].text!.count)")
  561. alert?.actions[0].isEnabled = textFields[0].text!.count > 0 && textFields[1].text!.count > 0
  562. }
  563. else {
  564. alert?.actions[0].isEnabled = sender.text!.count > 0
  565. }
  566. }
  567. private func signInAdmin(password: String, completion: @escaping (Bool) -> ()) {
  568. DispatchQueue.global().async {
  569. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  570. let p_password = password
  571. let md5Hex = Utils.getMD5(string: p_password).map { String(format: "%02hhx", $0) }.joined()
  572. var result: Bool = false
  573. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignInApiAdmin(p_name: idMe!, p_password: md5Hex)) {
  574. if response.isOk() {
  575. result = true
  576. }
  577. DispatchQueue.main.async {
  578. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  579. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  580. imageView.tintColor = .white
  581. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  582. banner.show()
  583. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  584. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  585. imageView.tintColor = .white
  586. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  587. banner.show()
  588. }
  589. }
  590. } else {
  591. DispatchQueue.main.async {
  592. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  593. imageView.tintColor = .white
  594. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  595. banner.show()
  596. }
  597. }
  598. completion(result)
  599. }
  600. }
  601. private func signInInternal(password: String, completion: @escaping (Bool) -> ()) {
  602. DispatchQueue.global().async {
  603. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  604. let p_password = password
  605. let md5Hex = Utils.getMD5(string: p_password).map { String(format: "%02hhx", $0) }.joined()
  606. var result: Bool = false
  607. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignInApiInternal(p_name: idMe!, p_password: md5Hex)) {
  608. if response.isOk() {
  609. result = true
  610. }
  611. DispatchQueue.main.async {
  612. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  613. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  614. imageView.tintColor = .white
  615. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  616. banner.show()
  617. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  618. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  619. imageView.tintColor = .white
  620. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  621. banner.show()
  622. }
  623. }
  624. } else {
  625. DispatchQueue.main.async {
  626. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  627. imageView.tintColor = .white
  628. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  629. banner.show()
  630. }
  631. }
  632. completion(result)
  633. }
  634. }
  635. private func changePasswordAdmin(oldPassword: String, newPassword: String, completion: @escaping (Bool) -> ()) {
  636. DispatchQueue.global().async {
  637. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  638. let p_password = oldPassword
  639. let n_password = newPassword
  640. let md5Hex = Utils.getMD5(string: p_password).map { String(format: "%02hhx", $0) }.joined()
  641. let md5HexNew = Utils.getMD5(string: n_password).map { String(format: "%02hhx", $0) }.joined()
  642. var result: Bool = false
  643. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getChangePasswordAdmin(p_f_pin: idMe!, pwd_en: md5HexNew, pwd_old: md5Hex)) {
  644. if response.isOk() {
  645. result = true
  646. }
  647. DispatchQueue.main.async {
  648. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  649. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  650. imageView.tintColor = .white
  651. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  652. banner.show()
  653. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  654. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  655. imageView.tintColor = .white
  656. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  657. banner.show()
  658. }
  659. }
  660. } else {
  661. DispatchQueue.main.async {
  662. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  663. imageView.tintColor = .white
  664. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  665. banner.show()
  666. }
  667. }
  668. completion(result)
  669. }
  670. }
  671. private func changePasswordInternal(oldPassword: String, newPassword: String, completion: @escaping (Bool) -> ()) {
  672. DispatchQueue.global().async {
  673. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  674. let p_password = oldPassword
  675. let n_password = newPassword
  676. let md5Hex = Utils.getMD5(string: p_password).map { String(format: "%02hhx", $0) }.joined()
  677. let md5HexNew = Utils.getMD5(string: n_password).map { String(format: "%02hhx", $0) }.joined()
  678. var result: Bool = false
  679. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getChangePasswordInternal(p_f_pin: idMe!, pwd_en: md5HexNew, pwd_old: md5Hex)) {
  680. if response.isOk() {
  681. result = true
  682. }
  683. DispatchQueue.main.async {
  684. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  685. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  686. imageView.tintColor = .white
  687. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  688. banner.show()
  689. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  690. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  691. imageView.tintColor = .white
  692. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  693. banner.show()
  694. }
  695. }
  696. } else {
  697. DispatchQueue.main.async {
  698. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  699. imageView.tintColor = .white
  700. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  701. banner.show()
  702. }
  703. }
  704. completion(result)
  705. }
  706. }
  707. }
  708. // MARK: - Item
  709. struct Item: Hashable {
  710. static func == (lhs: Item, rhs: Item) -> Bool {
  711. return lhs.title == rhs.title
  712. }
  713. var icon: UIImage?
  714. var title = ""
  715. static var sections: [String] {
  716. return ["Personal", "Call", "Version"]
  717. }
  718. static var menus: [String: [Item]] = [:]
  719. static func menuFor(section: Int) -> [Item] {
  720. let sec = sections[section]
  721. if let arr = menus[sec] {
  722. return arr
  723. }
  724. return []
  725. }
  726. }
  727. extension FourthTabViewController: UIPickerViewDelegate, UIPickerViewDataSource {
  728. public func numberOfComponents(in pickerView: UIPickerView) -> Int {
  729. return 1
  730. }
  731. public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
  732. return language.count
  733. }
  734. public func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
  735. return 60
  736. }
  737. public func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
  738. let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 10, height: 30))
  739. label.text = (language[row]).keys.first
  740. label.sizeToFit()
  741. return label
  742. }
  743. }