FourthTabViewController.swift 79 KB

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