SettingTableViewController.swift 74 KB

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