SettingTableViewController.swift 75 KB

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