FourthTabViewController.swift 49 KB

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