SettingTableViewController.swift 71 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129
  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 Photos
  11. public class SettingTableViewController: UITableViewController, UIGestureRecognizerDelegate {
  12. var language: [[String: String]] = [["Indonesia": "id"],["English": "en"]]
  13. var alert: UIAlertController?
  14. var textFields = [UITextField]()
  15. var switchVibrateMode = UISwitch()
  16. var switchSaveToGallery = UISwitch()
  17. var switchAutoDownload = UISwitch()
  18. var notInTab = false
  19. var fromAPI = false
  20. public override func viewDidLoad() {
  21. super.viewDidLoad()
  22. // self.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
  23. self.navigationController?.navigationBar.topItem?.backButtonTitle = ""
  24. tableView.delegate = self
  25. tableView.dataSource = self
  26. tableView.layoutMargins = .init(top: 0, left: 0, bottom: 0, right: 0)
  27. // tableView.separatorColor = .gray
  28. tableView.separatorStyle = .none
  29. if fromAPI {
  30. let backButton = UIBarButtonItem(image: UIImage(systemName: "chevron.backward"), style: .plain, target: self, action: #selector(self.didTapExit))
  31. self.navigationItem.leftBarButtonItem = backButton
  32. }
  33. switchVibrateMode.tintColor = .gray
  34. switchSaveToGallery.tintColor = .gray
  35. switchAutoDownload.tintColor = .gray
  36. switchVibrateMode.onTintColor = .mainColor
  37. switchSaveToGallery.onTintColor = .mainColor
  38. switchAutoDownload.onTintColor = .mainColor
  39. let vibrateMode: Bool = SecureUserDefaults.shared.value(forKey: "vibrateMode") ?? false
  40. let saveGallery: Bool = SecureUserDefaults.shared.value(forKey: "saveToGallery") ?? false
  41. let autoDownload: Bool = SecureUserDefaults.shared.value(forKey: "autoDownload") ?? false
  42. if vibrateMode {
  43. switchVibrateMode.setOn(true, animated: false)
  44. }
  45. if saveGallery {
  46. switchSaveToGallery.setOn(true, animated: false)
  47. }
  48. if autoDownload {
  49. switchAutoDownload.setOn(true, animated: false)
  50. }
  51. switchVibrateMode.addTarget(self, action: #selector(vibrateModeSwitch), for: .valueChanged)
  52. switchSaveToGallery.addTarget(self, action: #selector(saveToGallerySwitch), for: .valueChanged)
  53. switchAutoDownload.addTarget(self, action: #selector(autoDownloadSwitch), for: .valueChanged)
  54. }
  55. @objc func didTapExit() {
  56. self.dismiss(animated: true)
  57. }
  58. public override func viewDidAppear(_ animated: Bool) {
  59. self.navigationController?.navigationBar.topItem?.title = "Settings".localized()
  60. self.navigationController?.navigationBar.setNeedsLayout()
  61. }
  62. @objc func vibrateModeSwitch() {
  63. SecureUserDefaults.shared.set(switchVibrateMode.isOn, forKey: "vibrateMode")
  64. }
  65. @objc func saveToGallerySwitch() {
  66. if switchSaveToGallery.isOn {
  67. PHPhotoLibrary.requestAuthorization({status in
  68. DispatchQueue.main.async {
  69. if status == .authorized {
  70. SecureUserDefaults.shared.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
  71. } else {
  72. self.switchSaveToGallery.setOn(false, animated: true)
  73. }
  74. }
  75. })
  76. } else {
  77. SecureUserDefaults.shared.set(self.switchSaveToGallery.isOn, forKey: "saveToGallery")
  78. }
  79. }
  80. @objc func autoDownloadSwitch() {
  81. SecureUserDefaults.shared.set(switchAutoDownload.isOn, forKey: "autoDownload")
  82. }
  83. func makeMenu(imageSignIn: String = ""){
  84. let isChangeProfile = Utils.getSetProfile()
  85. if Database.shared.database == nil {
  86. Item.menus["Personal"] = [
  87. Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
  88. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  89. Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Sign-Up/Sign-In".localized()),
  90. ]
  91. if Nexilis.showButtonFB {
  92. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "gearshape.circle"), title: "Configure Floating Button".localized()))
  93. }
  94. } else {
  95. Database.shared.database?.inTransaction({ fmdb, rollback in
  96. do {
  97. let idMe = User.getMyPin() as String?
  98. if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT user_type, image_id, official_account FROM BUDDY where f_pin='\(idMe!)'"), cursorUser.next() {
  99. if (User.isInternal(userType: cursorUser.string(forColumnIndex: 0) ?? "") && User.isAdmin(fmdb: fmdb)) || User.isOfficial(official_account: cursorUser.string(forColumnIndex: 2) ?? "") || User.isOfficial(official_account: cursorUser.string(forColumnIndex: 2) ?? "") {
  100. Item.menus["Personal"] = [
  101. Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
  102. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  103. Item(icon: UIImage(systemName: "lock"), title: "Secure Folder"),
  104. Item(icon: UIImage(systemName: "person.crop.rectangle"), title: "Change Admin / Internal Password".localized()),
  105. Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Sign-In to Web".localized()),
  106. Item(icon: UIImage(named: "ic_internal", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, title: "Set Internal Account".localized()),
  107. Item(icon: UIImage(named: "pb_call_center", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, title: "Set CS Account".localized()),
  108. ]
  109. } else if User.isInternal(userType: cursorUser.string(forColumnIndex: 0) ?? "") || User.isCallCenter(userType: cursorUser.string(forColumnIndex: 0) ?? "") || User.isVerified(official_account: cursorUser.string(forColumnIndex: 2) ?? "") {
  110. Item.menus["Personal"] = [
  111. Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
  112. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  113. Item(icon: UIImage(systemName: "lock"), title: "Secure Folder"),
  114. Item(icon: UIImage(systemName: "laptopcomputer.and.iphone"), title: "Sign-In to Web".localized()),
  115. ]
  116. } else {
  117. Item.menus["Personal"] = [
  118. Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
  119. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  120. Item(icon: UIImage(systemName: "lock"), title: "Secure Folder"),
  121. Item(icon: UIImage(systemName: "person.badge.key"), title: "Access Admin / Internal Features".localized()),
  122. ]
  123. }
  124. if !isChangeProfile {
  125. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Sign-Up/Sign-In".localized()))
  126. } else if isChangeProfile {
  127. if Nexilis.checkingAccess(key: "backup_restore") {
  128. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "arrow.clockwise.icloud"), title: "Backup & Restore".localized()))
  129. }
  130. if Utils.getLimitValidTrans() == "1" {
  131. Item.menus["Personal"]?.insert(Item(icon: UIImage(systemName: "lessthan.circle"), title: "Validation Transaction Limit".localized()), at: 1)
  132. }
  133. }
  134. let image = cursorUser.string(forColumnIndex: 1)
  135. if image != nil {
  136. if !image!.isEmpty {
  137. do {
  138. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  139. let file = documentDir.appendingPathComponent(image!)
  140. if FileManager().fileExists(atPath: file.path) {
  141. let image = UIImage(contentsOfFile: file.path)
  142. Item.menus["Personal"]?[0].icon = image?.circleMasked
  143. if !imageSignIn.isEmpty {
  144. var dataImage: [AnyHashable : Any] = [:]
  145. dataImage["name"] = imageSignIn
  146. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  147. }
  148. } else {
  149. Download().start(forKey: image!) { (name, progress) in
  150. guard progress == 100 else {
  151. return
  152. }
  153. DispatchQueue.main.async {
  154. let image = UIImage(contentsOfFile: file.path)
  155. Item.menus["Personal"]?[0].icon = image?.circleMasked
  156. self.tableView.reloadData()
  157. if !imageSignIn.isEmpty {
  158. var dataImage: [AnyHashable : Any] = [:]
  159. dataImage["name"] = imageSignIn
  160. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  161. }
  162. }
  163. }
  164. }
  165. } catch {}
  166. }
  167. }
  168. cursorUser.close()
  169. } else {
  170. Item.menus["Personal"] = [
  171. Item(icon: UIImage(systemName: "person"), title: "Personal Information".localized()),
  172. Item(icon: UIImage(systemName: "textformat.abc"), title: "Change Language".localized()),
  173. Item(icon: UIImage(systemName: "lock"), title: "Secure Folder"),
  174. Item(icon: UIImage(systemName: "person.badge.key"), title: "Access Admin / Internal Features".localized()),
  175. ]
  176. if Nexilis.showButtonFB {
  177. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "gearshape.circle"), title: "Configure Floating Button".localized()))
  178. }
  179. Item.menus["Personal"]?.append(Item(icon: UIImage(systemName: "arrow.up.and.person.rectangle.portrait"), title: "Sign-Up/Sign-In".localized()))
  180. if !imageSignIn.isEmpty {
  181. do {
  182. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  183. let file = documentDir.appendingPathComponent(imageSignIn)
  184. if FileManager().fileExists(atPath: file.path) {
  185. let image = UIImage(contentsOfFile: file.path)
  186. Item.menus["Personal"]?[0].icon = image?.circleMasked
  187. var dataImage: [AnyHashable : Any] = [:]
  188. dataImage["name"] = imageSignIn
  189. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  190. } else {
  191. Download().start(forKey: imageSignIn) { (name, progress) in
  192. guard progress == 100 else {
  193. return
  194. }
  195. DispatchQueue.main.async {
  196. let image = UIImage(contentsOfFile: file.path)
  197. Item.menus["Personal"]?[0].icon = image?.circleMasked
  198. self.tableView.reloadData()
  199. var dataImage: [AnyHashable : Any] = [:]
  200. dataImage["name"] = imageSignIn
  201. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  202. }
  203. }
  204. }
  205. } catch {}
  206. }
  207. }
  208. } catch {
  209. rollback.pointee = true
  210. print("Access database error: \(error.localizedDescription)")
  211. }
  212. })
  213. }
  214. Item.menus["Config"] = [
  215. Item(icon: UIImage(systemName: "iphone"), title: "Create Your Own App".localized()),
  216. Item(icon: UIImage(systemName: "gearshape.circle"), title: "Configure Floating Button".localized())
  217. ]
  218. if !isChangeProfile || Utils.getEnableMobileBuilder() != "1" {
  219. if Item.menus["Config"]!.count > 1 {
  220. Item.menus["Config"]!.remove(at: 0)
  221. } else {
  222. Item.menus["Config"]!.removeAll()
  223. }
  224. }
  225. if !Nexilis.showButtonFB {
  226. if Item.menus["Config"]!.count > 1 {
  227. Item.menus["Config"]!.remove(at: 1)
  228. } else {
  229. Item.menus["Config"]!.removeAll()
  230. }
  231. }
  232. if Utils.getIsLoadThemeFromOther() {
  233. Item.menus["Config"]?.insert(Item(icon: UIImage(systemName: "iphone"), title: "Back to Company App".localized()), at: 1)
  234. }
  235. Item.menus["Call"] = [
  236. Item(icon: UIImage(systemName: "message"), title: "Notification Message(s)".localized()),
  237. Item(icon: UIImage(systemName: "message"), title: "Notification Message(s) Group".localized()),
  238. Item(icon: UIImage(systemName: "iphone.homebutton.radiowaves.left.and.right"), title: "Vibrate Mode".localized()),
  239. Item(icon: UIImage(systemName: "photo.on.rectangle.angled"), title: "Save to Gallery".localized()),
  240. Item(icon: UIImage(systemName: "arrow.down.square"), title: "Auto Download".localized()),
  241. ]
  242. Item.menus["Version"] = [
  243. Item(icon: UIImage(systemName: "gear"), title: "Version".localized()),
  244. Item(icon: UIImage(named: "pb_powered_button", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), title: "Powered by Nexilis".localized()),
  245. ]
  246. if isChangeProfile {
  247. if Nexilis.checkingAccess(key: "logout"){
  248. Item.menus["Version"]?.insert(Item(icon: UIImage(systemName: "rectangle.portrait.and.arrow.right"), title: "Sign-Out".localized()), at: 0)
  249. }
  250. }
  251. }
  252. override public func viewWillAppear(_ animated: Bool) {
  253. // self.navigationController?.navigationBar.topItem?.title = ""
  254. self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: self.traitCollection.userInterfaceStyle == .dark ? .white : UIColor.black]
  255. let attributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: self.traitCollection.userInterfaceStyle == .dark ? .white : UIColor.black, NSAttributedString.Key.font : UIFont.boldSystemFont(ofSize: 16)]
  256. let navBarAppearance = UINavigationBarAppearance()
  257. navBarAppearance.configureWithTransparentBackground()
  258. navBarAppearance.titleTextAttributes = attributes
  259. navigationController?.navigationBar.standardAppearance = navBarAppearance
  260. navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
  261. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: self.traitCollection.userInterfaceStyle == .dark ? .white : UIColor.black, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  262. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  263. navigationController?.navigationBar.backgroundColor = .clear
  264. navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
  265. navigationController?.navigationBar.shadowImage = UIImage()
  266. navigationController?.navigationBar.isTranslucent = true
  267. navigationController?.setNavigationBarHidden(false, animated: false)
  268. navigationController?.navigationBar.overrideUserInterfaceStyle = self.traitCollection.userInterfaceStyle == .dark ? .dark : .light
  269. navigationController?.navigationBar.barStyle = .default
  270. navigationController?.navigationBar.tintColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .black
  271. tabBarController?.navigationItem.leftBarButtonItem = nil
  272. tabBarController?.navigationItem.searchController = nil
  273. tabBarController?.navigationItem.rightBarButtonItem = nil
  274. makeMenu()
  275. tableView.reloadData()
  276. }
  277. // MARK: - Table view data source
  278. public override func numberOfSections(in tableView: UITableView) -> Int {
  279. return Item.sections.count
  280. }
  281. public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  282. return Item.menuFor(section: section).count
  283. }
  284. public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  285. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  286. let isChangeProfile = Utils.getSetProfile()
  287. cell.accessoryType = .none
  288. cell.indentationLevel = 0
  289. var content = cell.defaultContentConfiguration()
  290. content.textProperties.font = UIFont.systemFont(ofSize: 14)
  291. content.secondaryTextProperties.font = UIFont.systemFont(ofSize: 14)
  292. content.secondaryTextProperties.color = .gray
  293. content.prefersSideBySideTextAndSecondaryText = true
  294. let section = Item.sections[indexPath.section]
  295. if let arr = Item.menus[section] {
  296. let menu = arr[indexPath.row]
  297. content.image = menu.icon
  298. content.imageProperties.tintColor = self.traitCollection.userInterfaceStyle == .dark ? .white : .black
  299. content.imageProperties.maximumSize = CGSize(width: 24, height: 24)
  300. content.text = menu.title
  301. cell.accessoryView = nil
  302. switch menu.title {
  303. case "Personal Information".localized():
  304. cell.accessoryType = .disclosureIndicator
  305. case "Secure Folder".localized():
  306. cell.accessoryType = .disclosureIndicator
  307. case "Access Admin / Internal Features".localized():
  308. cell.accessoryType = .disclosureIndicator
  309. case "Sign-In to Web".localized():
  310. cell.accessoryType = .disclosureIndicator
  311. case "Sign-Up/Sign-In".localized():
  312. cell.accessoryType = .disclosureIndicator
  313. case "Configure Floating Button".localized():
  314. cell.accessoryType = .disclosureIndicator
  315. case "Notification Message(s)".localized():
  316. cell.accessoryType = .disclosureIndicator
  317. case "Backup & Restore".localized():
  318. cell.accessoryType = .disclosureIndicator
  319. case "Validation Transaction Limit".localized():
  320. cell.accessoryType = .disclosureIndicator
  321. case "Create Your Own App".localized():
  322. cell.accessoryType = .disclosureIndicator
  323. case "Notification Message(s) Group".localized():
  324. cell.accessoryType = .disclosureIndicator
  325. case "Change Admin / Internal Password".localized():
  326. cell.accessoryType = .disclosureIndicator
  327. case "Change Language".localized():
  328. cell.accessoryType = .disclosureIndicator
  329. case "Set Internal Account".localized():
  330. cell.accessoryType = .disclosureIndicator
  331. case "Set CS Account".localized():
  332. cell.accessoryType = .disclosureIndicator
  333. case "Version".localized():
  334. let accessoryButton = UIButton(type: .custom)
  335. accessoryButton.setTitle(UIApplication.appVersion, for: .normal)
  336. accessoryButton.setTitleColor(self.traitCollection.userInterfaceStyle == .dark ? .white : .black, for: .normal)
  337. accessoryButton.titleLabel?.font = .systemFont(ofSize: 18)
  338. accessoryButton.contentHorizontalAlignment = .right
  339. accessoryButton.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
  340. accessoryButton.contentMode = .scaleAspectFit
  341. cell.accessoryView = accessoryButton as UIView
  342. case "Vibrate Mode".localized():
  343. cell.accessoryView = switchVibrateMode
  344. case "Save to Gallery".localized():
  345. cell.accessoryView = switchSaveToGallery
  346. case "Auto Download".localized():
  347. cell.accessoryView = switchAutoDownload
  348. default:
  349. content.secondaryText = nil
  350. }
  351. }
  352. cell.contentConfiguration = content
  353. return cell
  354. }
  355. public override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
  356. let footerView = UIView()
  357. if section != 3 {
  358. footerView.backgroundColor = .clear
  359. let lineView = UIView()
  360. lineView.backgroundColor = .gray
  361. lineView.translatesAutoresizingMaskIntoConstraints = false
  362. footerView.addSubview(lineView)
  363. NSLayoutConstraint.activate([
  364. lineView.leadingAnchor.constraint(equalTo: footerView.leadingAnchor),
  365. lineView.trailingAnchor.constraint(equalTo: footerView.trailingAnchor),
  366. lineView.heightAnchor.constraint(equalToConstant: 1),
  367. lineView.bottomAnchor.constraint(equalTo: footerView.bottomAnchor)
  368. ])
  369. }
  370. return footerView
  371. }
  372. public override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  373. let headerView = UIView()
  374. if (section == 2 && Item.menus["Config"]!.count > 0) || section == 3 || (section == 1 && Item.menus["Config"]!.count > 0) {
  375. headerView.backgroundColor = .clear
  376. let lineView = UIView()
  377. lineView.backgroundColor = .gray
  378. lineView.translatesAutoresizingMaskIntoConstraints = false
  379. headerView.addSubview(lineView)
  380. NSLayoutConstraint.activate([
  381. lineView.leadingAnchor.constraint(equalTo: headerView.leadingAnchor),
  382. lineView.trailingAnchor.constraint(equalTo: headerView.trailingAnchor),
  383. lineView.heightAnchor.constraint(equalToConstant: 1),
  384. lineView.bottomAnchor.constraint(equalTo: headerView.bottomAnchor)
  385. ])
  386. }
  387. return headerView
  388. }
  389. public override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  390. if section == 2 || section == 3 || section == 1 {
  391. return 6
  392. }
  393. return 1
  394. }
  395. public override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  396. let item = Item.menuFor(section: indexPath.section)[indexPath.row]
  397. if item.title == "Personal Information".localized() {
  398. if(Nexilis.checkIsChangePerson()){
  399. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
  400. controller.data = User.getMyPin()!
  401. controller.flag = .me
  402. controller.dismissImage = { image, imageName in
  403. var dataImage: [AnyHashable : Any] = [:]
  404. dataImage["name"] = imageName
  405. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  406. self.makeMenu()
  407. self.tableView.reloadData()
  408. }
  409. navigationController?.show(controller, sender: nil)
  410. }
  411. } else if item.title == "Secure Folder" {
  412. if(Nexilis.checkIsChangePerson()){
  413. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "secureFolderView") as! SecureFolderViewController
  414. navigationController?.show(controller, sender: nil)
  415. }
  416. } else if item.title == "Access Admin / Internal Features".localized() || item.title == "Change Admin / Internal Password".localized() {
  417. if(Nexilis.checkIsChangePerson()){
  418. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  419. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  420. imageView.tintColor = .white
  421. 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)
  422. banner.show()
  423. return
  424. }
  425. let alertController = LibAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
  426. if(item.title.contains("Change")){
  427. if let action = self.actionChangePassword(for: "admin", title: "Change Admin Password".localized()) {
  428. alertController.addAction(action)
  429. }
  430. if let action = self.actionChangePassword(for: "internal", title: "Change Internal Password".localized()) {
  431. alertController.addAction(action)
  432. }
  433. }
  434. else {
  435. if let action = self.actionLogin(for: "admin", title: "Access Admin Features".localized()) {
  436. alertController.addAction(action)
  437. }
  438. if let action = self.actionLogin(for: "internal", title: "Access Internal Features".localized()) {
  439. alertController.addAction(action)
  440. }
  441. }
  442. alertController.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  443. self.present(alertController, animated: true)
  444. }
  445. } else if item.title == "Change Language".localized() {
  446. let vc = UIViewController()
  447. vc.preferredContentSize = CGSize(width: UIScreen.main.bounds.width - 10, height: 150)
  448. let pickerView = UIPickerView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 10, height: 150))
  449. pickerView.dataSource = self
  450. pickerView.delegate = self
  451. let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
  452. var index = 1
  453. if lang == "id" {
  454. index = 0
  455. }
  456. pickerView.selectRow(index, inComponent: 0, animated: false)
  457. vc.view.addSubview(pickerView)
  458. pickerView.translatesAutoresizingMaskIntoConstraints = false
  459. pickerView.centerXAnchor.constraint(equalTo: vc.view.centerXAnchor).isActive = true
  460. pickerView.centerYAnchor.constraint(equalTo: vc.view.centerYAnchor).isActive = true
  461. let alert = LibAlertController(title: "Select Language".localized(), message: "", preferredStyle: .actionSheet)
  462. alert.setValue(vc, forKey: "contentViewController")
  463. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { (UIAlertAction) in
  464. }))
  465. alert.addAction(UIAlertAction(title: "Select".localized(), style: .default, handler: { (UIAlertAction) in
  466. let selectedIndex = pickerView.selectedRow(inComponent: 0)
  467. let lang = self.language[selectedIndex].values.first
  468. SecureUserDefaults.shared.set(lang, forKey: "i18n_language")
  469. self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
  470. self.navigationController?.navigationBar.setNeedsLayout()
  471. self.makeMenu()
  472. self.tableView.reloadData()
  473. }))
  474. self.present(alert, animated: true, completion: nil)
  475. } else if item.title == "Sign-In".localized() {
  476. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "changeDevice") as! ChangeDeviceViewController
  477. controller.isDismiss = { newThumb in
  478. self.makeMenu(imageSignIn: newThumb)
  479. self.tableView.reloadData()
  480. }
  481. navigationController?.show(controller, sender: nil)
  482. } else if item.title == "Sign-Up/Sign-In".localized() {
  483. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "signupsignin") as! SignUpSignIn
  484. controller.isDismiss = { newThumb in
  485. self.makeMenu(imageSignIn: newThumb)
  486. self.tableView.reloadData()
  487. }
  488. navigationController?.show(controller, sender: nil)
  489. } else if item.title == "Sign-Out".localized() {
  490. let alert = LibAlertController(title: "Sign-Out".localized(), message: "Are you sure want to logout?".localized(), preferredStyle: .alert)
  491. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
  492. alert.addAction(UIAlertAction(title: "Yes".localized(), style: .destructive, handler: {(_) in
  493. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  494. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  495. imageView.tintColor = .white
  496. 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)
  497. banner.show()
  498. return
  499. }
  500. Nexilis.showLoader()
  501. DispatchQueue.global().async {
  502. let apiKey = Nexilis.sAPIKey
  503. var id = Utils.getConnectionID()
  504. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpApi(api: apiKey, p_pin: id), timeout: 30 * 1000) {
  505. id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
  506. if(!id.isEmpty){
  507. // Nexilis.changeUser(f_pin: id)
  508. SecureUserDefaults.shared.set(id, forKey: "me")
  509. Utils.setProfile(value: false)
  510. if Utils.getForceAnonymous() {
  511. self.deleteAllRecordDatabase()
  512. SecureUserDefaults.shared.removeValue(forKey: "device_id")
  513. FileEncryption.shared.wipeFolder()
  514. Nexilis.destroyAll()
  515. _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
  516. }
  517. DispatchQueue.main.async {
  518. Nexilis.hideLoader(completion: {
  519. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  520. imageView.tintColor = .white
  521. let banner = FloatingNotificationBanner(title: "Successfully Sign-Out".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)
  522. banner.show()
  523. if Nexilis.showFB {
  524. Nexilis.floatingButton.removeFromSuperview()
  525. Nexilis.floatingButton = FloatingButton()
  526. let viewController = (UIApplication.shared.windows.first?.rootViewController)!
  527. Nexilis.addFB(viewController: viewController, fromMAB: true)
  528. }
  529. var dataImage: [AnyHashable : Any] = [:]
  530. dataImage["name"] = ""
  531. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  532. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
  533. self.makeMenu()
  534. self.tableView.reloadData()
  535. if !Utils.getForceAnonymous() {
  536. Nexilis.showForceSignIn()
  537. }
  538. })
  539. }
  540. } else {
  541. DispatchQueue.main.async {
  542. Nexilis.hideLoader(completion: {
  543. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  544. imageView.tintColor = .white
  545. 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)
  546. banner.show()
  547. })
  548. }
  549. }
  550. } else {
  551. DispatchQueue.main.async {
  552. Nexilis.hideLoader(completion: {
  553. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  554. imageView.tintColor = .white
  555. 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)
  556. banner.show()
  557. })
  558. }
  559. }
  560. }
  561. }))
  562. self.present(alert, animated: true, completion: nil)
  563. } else if item.title == "Sign-In to Web".localized() {
  564. var permissionCheck = -1
  565. if AVCaptureDevice.authorizationStatus(for: .video) == .authorized {
  566. permissionCheck = 1
  567. } else if AVCaptureDevice.authorizationStatus(for: .video) == .denied {
  568. permissionCheck = 0
  569. } else {
  570. AVCaptureDevice.requestAccess(for: .video, completionHandler: { (granted: Bool) -> Void in
  571. if granted == true {
  572. permissionCheck = 1
  573. } else {
  574. permissionCheck = 0
  575. }
  576. })
  577. }
  578. while permissionCheck == -1 {
  579. sleep(1)
  580. }
  581. if permissionCheck == 0 {
  582. let alert = LibAlertController(title: "Attention!".localized(), message: "Please allow camera permission in your settings".localized(), preferredStyle: .alert)
  583. alert.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: { _ in
  584. if let url = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(url) {
  585. UIApplication.shared.open(url, options: [:], completionHandler: nil)
  586. }
  587. }))
  588. if UIApplication.shared.visibleViewController?.navigationController != nil {
  589. UIApplication.shared.visibleViewController?.navigationController?.present(alert, animated: true, completion: nil)
  590. } else {
  591. UIApplication.shared.visibleViewController?.present(alert, animated: true, completion: nil)
  592. }
  593. return
  594. }
  595. let controller = ScannerViewController()
  596. let navigationController = CustomNavigationController(rootViewController: controller)
  597. navigationController.navigationBar.tintColor = .white
  598. navigationController.navigationBar.barTintColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
  599. navigationController.navigationBar.isTranslucent = false
  600. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  601. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  602. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  603. navigationController.navigationBar.titleTextAttributes = textAttributes
  604. navigationController.navigationBar.overrideUserInterfaceStyle = .dark
  605. navigationController.navigationBar.barStyle = .black
  606. navigationController.modalPresentationStyle = .custom
  607. self.present(navigationController, animated: true)
  608. } else if item.title == "Notification Message(s)".localized() || item.title == "Notification Message(s) Group".localized() {
  609. let controller = NotificationSound()
  610. if item.title != "Notification Message(s)".localized() {
  611. controller.isPersonal = false
  612. }
  613. let navigationController = CustomNavigationController(rootViewController: controller)
  614. navigationController.navigationBar.tintColor = .white
  615. navigationController.navigationBar.barTintColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
  616. navigationController.navigationBar.isTranslucent = false
  617. navigationController.navigationBar.overrideUserInterfaceStyle = .dark
  618. navigationController.navigationBar.barStyle = .black
  619. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  620. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  621. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  622. navigationController.navigationBar.titleTextAttributes = textAttributes
  623. self.present(navigationController, animated: true)
  624. } else if item.title == "Backup & Restore".localized() {
  625. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "backupRestore") as! BackupRestoreView
  626. navigationController?.show(controller, sender: nil)
  627. } else if item.title == "Set Internal Account".localized() {
  628. let controller = SetInternalCSAccount()
  629. navigationController?.show(controller, sender: nil)
  630. } else if item.title == "Set CS Account".localized() {
  631. let controller = SetInternalCSAccount()
  632. controller.isSetCS = true
  633. navigationController?.show(controller, sender: nil)
  634. } else if item.title == "Configure Floating Button".localized() {
  635. let viewConfigureFB = ConfigureFloatingButton()
  636. viewConfigureFB.modalTransitionStyle = .crossDissolve
  637. viewConfigureFB.modalPresentationStyle = .custom
  638. self.present(viewConfigureFB, animated: true)
  639. } else if item.title == "Validation Transaction Limit".localized() {
  640. let controller = ValidationTransactionLimit()
  641. navigationController?.show(controller, sender: nil)
  642. } else if item.title == "Create Your Own App".localized() {
  643. let controller = BNIBookingWebView()
  644. controller.customUrl = Utils.getURLBase() + "mobile_MAB?f_pin="
  645. self.present(controller, animated: true)
  646. } else if item.title == "Back to Company App".localized() {
  647. let alert = LibAlertController(title: "", message: "Are you sure want to back to company app?".localized(), preferredStyle: .alert)
  648. alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
  649. alert.addAction(UIAlertAction(title: "Yes".localized(), style: .destructive, handler: {(_) in
  650. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  651. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  652. imageView.tintColor = .white
  653. 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)
  654. banner.show()
  655. return
  656. }
  657. Nexilis.showLoader()
  658. DispatchQueue.global().async {
  659. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.backToSuperApp(), timeout: 30 * 1000) {
  660. DispatchQueue.main.async {
  661. if response.isOk() {
  662. Utils.setMyTheme(value: "")
  663. Utils.setIsLoadThemeFromOther(value: false)
  664. Utils.resetValueSuperApp()
  665. Utils.setValueInitialApp(data: Utils.getPrefTheme())
  666. Database.shared.database?.inTransaction({ fmdb, rollback in
  667. do {
  668. _ = Database.shared.deleteRecord(fmdb: fmdb, table: "GROUPZ", _where: "")
  669. _ = Database.shared.deleteRecord(fmdb: fmdb, table: "GROUPZ_MEMBER", _where: "")
  670. _ = Database.shared.deleteRecord(fmdb: fmdb, table: "DISCUSSION_FORUM", _where: "")
  671. _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: User.getMyPin() ?? ""))
  672. } catch {
  673. rollback.pointee = true
  674. print("Access database error: \(error.localizedDescription)")
  675. }
  676. })
  677. Nexilis.hideLoader {
  678. let alert = LibAlertController(title: "Successfully changed".localized(), message: "Please open the app again to see the changes".localized(), preferredStyle: .alert)
  679. alert.addAction(UIAlertAction(title: "OK".localized(), style: .default, handler: {(_) in
  680. exit(0)
  681. }))
  682. self.present(alert, animated: true, completion: nil)
  683. }
  684. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "10" {
  685. Nexilis.hideLoader(completion: {
  686. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  687. imageView.tintColor = .white
  688. let banner = FloatingNotificationBanner(title: "Failed to back to Company App".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)
  689. banner.show()
  690. })
  691. } else {
  692. Nexilis.hideLoader(completion: {
  693. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  694. imageView.tintColor = .white
  695. 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)
  696. banner.show()
  697. })
  698. }
  699. }
  700. } else {
  701. DispatchQueue.main.async {
  702. Nexilis.hideLoader(completion: {
  703. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  704. imageView.tintColor = .white
  705. 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)
  706. banner.show()
  707. })
  708. }
  709. }
  710. }
  711. }))
  712. self.present(alert, animated: true, completion: nil)
  713. }
  714. }
  715. private func actionLogin(for type: String, title: String) -> UIAlertAction? {
  716. return UIAlertAction(title: title, style: .default) { _ in
  717. self.alert = LibAlertController(title:"Access Admin Features".localized(), message: nil, preferredStyle: .alert)
  718. if type == "internal" {
  719. self.alert = LibAlertController(title: "Access Internal Features".localized(), message: nil, preferredStyle: .alert)
  720. }
  721. self.textFields.removeAll()
  722. self.alert?.addTextField{ (texfield) in
  723. texfield.placeholder = "Password".localized()
  724. texfield.isSecureTextEntry = true
  725. texfield.addPadding(.right(40))
  726. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  727. let buttonHideUnhide = UIButton()
  728. buttonHideUnhide.tag = 0
  729. texfield.addSubview(buttonHideUnhide)
  730. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  731. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  732. buttonHideUnhide.tintColor = .black
  733. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  734. }
  735. let submitAction = UIAlertAction(title: "Sign-In".localized(), style: .default, handler: { (action) -> Void in
  736. let textField = self.alert?.textFields![0]
  737. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  738. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  739. imageView.tintColor = .white
  740. 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)
  741. banner.show()
  742. return
  743. }
  744. Nexilis.showLoader()
  745. if type == "admin" {
  746. self.signInAdmin(password: textField!.text!, completion: { result in
  747. if result {
  748. DispatchQueue.main.async {
  749. Nexilis.hideLoader {
  750. self.makeMenu()
  751. self.tableView.reloadData()
  752. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  753. imageView.tintColor = .white
  754. let banner = FloatingNotificationBanner(title: "Successfully Sign-In 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)
  755. banner.show()
  756. }
  757. }
  758. } else {
  759. DispatchQueue.main.async {
  760. Nexilis.hideLoader {}
  761. }
  762. }
  763. })
  764. } else {
  765. self.signInInternal(password: textField!.text!, completion: { result in
  766. if result {
  767. DispatchQueue.main.async {
  768. Nexilis.hideLoader {
  769. self.makeMenu()
  770. self.tableView.reloadData()
  771. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  772. imageView.tintColor = .white
  773. let banner = FloatingNotificationBanner(title: "Successfully Sign-In 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)
  774. banner.show()
  775. }
  776. }
  777. } else {
  778. DispatchQueue.main.async {
  779. Nexilis.hideLoader {}
  780. }
  781. }
  782. })
  783. }
  784. })
  785. submitAction.isEnabled = false
  786. self.alert?.addAction(submitAction)
  787. self.alert?.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  788. self.present(self.alert!, animated: true, completion: nil)
  789. }
  790. }
  791. private func actionChangePassword(for type: String, title: String) -> UIAlertAction? {
  792. return UIAlertAction(title: title, style: .default) { _ in
  793. self.alert = LibAlertController(title: "Change Admin Password".localized(), message: nil, preferredStyle: .alert)
  794. if type == "internal" {
  795. self.alert = LibAlertController(title: "Change Internal Password".localized(), message: nil, preferredStyle: .alert)
  796. }
  797. self.textFields.removeAll()
  798. self.alert?.addTextField{ (texfield) in
  799. texfield.placeholder = "Old Password"
  800. texfield.isSecureTextEntry = true
  801. texfield.addPadding(.right(40))
  802. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  803. self.textFields.append(texfield)
  804. let buttonHideUnhide = UIButton()
  805. buttonHideUnhide.tag = 0
  806. texfield.addSubview(buttonHideUnhide)
  807. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  808. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  809. buttonHideUnhide.tintColor = .black
  810. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  811. }
  812. self.alert?.addTextField{ (texfield) in
  813. texfield.placeholder = "New Password"
  814. texfield.isSecureTextEntry = true
  815. texfield.addPadding(.right(40))
  816. texfield.addTarget(self, action: #selector(self.alertTextFieldDidChange(_:)), for: UIControl.Event.editingChanged)
  817. self.textFields.append(texfield)
  818. let buttonHideUnhide = UIButton()
  819. buttonHideUnhide.tag = 1
  820. texfield.addSubview(buttonHideUnhide)
  821. buttonHideUnhide.anchor(top: texfield.topAnchor, right: texfield.rightAnchor, paddingTop: -7, width: 30, height: 30)
  822. buttonHideUnhide.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  823. buttonHideUnhide.tintColor = .black
  824. buttonHideUnhide.addTarget(self, action: #selector(self.showPassword), for: .touchUpInside)
  825. }
  826. let submitAction = UIAlertAction(title: "Change Password".localized(), style: .default, handler: { (action) -> Void in
  827. let textFieldOld = self.alert?.textFields![0]
  828. let textFieldNew = self.alert?.textFields![1]
  829. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  830. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  831. imageView.tintColor = .white
  832. 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)
  833. banner.show()
  834. return
  835. }
  836. if type == "admin" {
  837. self.changePasswordAdmin(oldPassword: textFieldOld!.text!, newPassword: textFieldNew!.text!, completion: { result in
  838. if result {
  839. DispatchQueue.main.async {
  840. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  841. imageView.tintColor = .white
  842. 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)
  843. banner.show()
  844. }
  845. }
  846. })
  847. } else {
  848. self.changePasswordInternal(oldPassword: textFieldOld!.text!, newPassword: textFieldNew!.text!, completion: { result in
  849. if result {
  850. DispatchQueue.main.async {
  851. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  852. imageView.tintColor = .white
  853. 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)
  854. banner.show()
  855. }
  856. }
  857. })
  858. }
  859. })
  860. submitAction.isEnabled = false
  861. self.alert?.addAction(submitAction)
  862. self.alert?.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  863. self.present(self.alert!, animated: true, completion: nil)
  864. }
  865. }
  866. @objc func showPassword(_ sender:UIButton) {
  867. if alert!.textFields![sender.tag].isSecureTextEntry {
  868. alert!.textFields![sender.tag].isSecureTextEntry = false
  869. let buttonImage = alert!.textFields![sender.tag].subviews[0] as! UIButton
  870. buttonImage.setImage(UIImage(systemName: "eye.fill"), for: .normal)
  871. } else {
  872. alert!.textFields![sender.tag].isSecureTextEntry = true
  873. let buttonImage = alert!.textFields![sender.tag].subviews[0] as! UIButton
  874. buttonImage.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
  875. }
  876. }
  877. @objc func alertTextFieldDidChange(_ sender: UITextField) {
  878. if(!textFields.isEmpty){
  879. //print("text count 0: \(textFields[0].text!.count)")
  880. //print("text count 1: \(textFields[1].text!.count)")
  881. alert?.actions[0].isEnabled = textFields[0].text!.count > 0 && textFields[1].text!.count > 0
  882. }
  883. else {
  884. alert?.actions[0].isEnabled = sender.text!.count > 0
  885. }
  886. }
  887. private func signInAdmin(password: String, completion: @escaping (Bool) -> ()) {
  888. DispatchQueue.global().async {
  889. let idMe = User.getMyPin() as String?
  890. let p_password = password
  891. let md5Hex = p_password
  892. var result: Bool = false
  893. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignInApiAdmin(p_name: idMe!, p_password: md5Hex)) {
  894. if response.isOk() {
  895. result = true
  896. }
  897. DispatchQueue.main.async {
  898. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  899. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  900. imageView.tintColor = .white
  901. 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)
  902. banner.show()
  903. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  904. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  905. imageView.tintColor = .white
  906. 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)
  907. banner.show()
  908. }
  909. }
  910. } else {
  911. DispatchQueue.main.async {
  912. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  913. imageView.tintColor = .white
  914. 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)
  915. banner.show()
  916. }
  917. }
  918. completion(result)
  919. }
  920. }
  921. private func signInInternal(password: String, completion: @escaping (Bool) -> ()) {
  922. DispatchQueue.global().async {
  923. let idMe = User.getMyPin() as String?
  924. let p_password = password
  925. let md5Hex = p_password
  926. var result: Bool = false
  927. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignInApiInternal(p_name: idMe!, p_password: md5Hex)) {
  928. if response.isOk() {
  929. result = true
  930. }
  931. DispatchQueue.main.async {
  932. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  933. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  934. imageView.tintColor = .white
  935. 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)
  936. banner.show()
  937. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  938. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  939. imageView.tintColor = .white
  940. 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)
  941. banner.show()
  942. }
  943. }
  944. } else {
  945. DispatchQueue.main.async {
  946. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  947. imageView.tintColor = .white
  948. 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)
  949. banner.show()
  950. }
  951. }
  952. completion(result)
  953. }
  954. }
  955. private func changePasswordAdmin(oldPassword: String, newPassword: String, completion: @escaping (Bool) -> ()) {
  956. DispatchQueue.global().async {
  957. let idMe = User.getMyPin() as String?
  958. let p_password = oldPassword
  959. let n_password = newPassword
  960. let md5Hex = p_password
  961. let md5HexNew = n_password
  962. var result: Bool = false
  963. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getChangePasswordAdmin(p_f_pin: idMe!, pwd_en: md5HexNew, pwd_old: md5Hex)) {
  964. if response.isOk() {
  965. result = true
  966. }
  967. DispatchQueue.main.async {
  968. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  969. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  970. imageView.tintColor = .white
  971. 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)
  972. banner.show()
  973. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  974. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  975. imageView.tintColor = .white
  976. 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)
  977. banner.show()
  978. }
  979. }
  980. } else {
  981. DispatchQueue.main.async {
  982. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  983. imageView.tintColor = .white
  984. 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)
  985. banner.show()
  986. }
  987. }
  988. completion(result)
  989. }
  990. }
  991. private func changePasswordInternal(oldPassword: String, newPassword: String, completion: @escaping (Bool) -> ()) {
  992. DispatchQueue.global().async {
  993. let idMe = User.getMyPin() as String?
  994. let p_password = oldPassword
  995. let n_password = newPassword
  996. let md5Hex = p_password
  997. let md5HexNew = n_password
  998. var result: Bool = false
  999. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getChangePasswordInternal(p_f_pin: idMe!, pwd_en: md5HexNew, pwd_old: md5Hex)) {
  1000. if response.isOk() {
  1001. result = true
  1002. }
  1003. DispatchQueue.main.async {
  1004. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  1005. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  1006. imageView.tintColor = .white
  1007. 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)
  1008. banner.show()
  1009. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  1010. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  1011. imageView.tintColor = .white
  1012. 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)
  1013. banner.show()
  1014. }
  1015. }
  1016. } else {
  1017. DispatchQueue.main.async {
  1018. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  1019. imageView.tintColor = .white
  1020. 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)
  1021. banner.show()
  1022. }
  1023. }
  1024. completion(result)
  1025. }
  1026. }
  1027. }
  1028. // MARK: - Item
  1029. struct Item: Hashable {
  1030. static func == (lhs: Item, rhs: Item) -> Bool {
  1031. return lhs.title == rhs.title
  1032. }
  1033. var icon: UIImage?
  1034. var title = ""
  1035. static var sections: [String] {
  1036. return ["Personal", "Config", "Call", "Version"]
  1037. }
  1038. static var menus: [String: [Item]] = [:]
  1039. static func menuFor(section: Int) -> [Item] {
  1040. let sec = sections[section]
  1041. if let arr = menus[sec] {
  1042. return arr
  1043. }
  1044. return []
  1045. }
  1046. }
  1047. extension SettingTableViewController: UIPickerViewDelegate, UIPickerViewDataSource {
  1048. public func numberOfComponents(in pickerView: UIPickerView) -> Int {
  1049. return 1
  1050. }
  1051. public func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
  1052. return language.count
  1053. }
  1054. public func pickerView(_ pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
  1055. return 60
  1056. }
  1057. public func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusing view: UIView?) -> UIView {
  1058. let label = UILabel(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width - 10, height: 30))
  1059. label.text = (language[row]).keys.first
  1060. label.sizeToFit()
  1061. return label
  1062. }
  1063. }