FourthTabViewController.swift 79 KB

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