ViewController.swift 89 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531
  1. //
  2. // ViewController.swift
  3. // TestQmeraLite
  4. //
  5. // Created by Qindi on 29/11/21.
  6. //
  7. import UIKit
  8. import NexilisLite
  9. import AVKit
  10. import AVFoundation
  11. import SwiftUI
  12. import Speech
  13. import Alamofire
  14. import WebKit
  15. class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMABDelegate, WKNavigationDelegate {
  16. let playerController = AVPlayerViewController()
  17. static var sURL = "https://www.google.com"
  18. static var tab3 = "0"
  19. public var isShow: Bool = false
  20. public static var chatButton = UIButton()
  21. public static var callButton = UIButton()
  22. public static var ccButton = UIButton()
  23. public static var streamingButton = UIButton()
  24. public static var postButton = UIButton()
  25. public static var middleButton = UIButton()
  26. var buttonChatGR : UITapGestureRecognizer?
  27. var buttonCallGR : UITapGestureRecognizer?
  28. var buttonCCGR : UITapGestureRecognizer?
  29. var buttonStreamGR : UITapGestureRecognizer?
  30. var floating : FloatingButton?
  31. var firstTab : UINavigationController?
  32. var secondTab : UINavigationController?
  33. var thirdTab : UINavigationController?
  34. var fourthTab : UINavigationController?
  35. var callTab : UINavigationController?
  36. var chatWATab : UINavigationController?
  37. var communityTab : UINavigationController?
  38. var secureFolderTab : UINavigationController?
  39. let emptyTab = EmptyTabViewController()
  40. public static var isTab1 = true
  41. public static var isTab2 = false
  42. public static var isTab3 = false
  43. public static var isTab4 = false
  44. public static var isTabCall = false
  45. public static var isExpandButton = false
  46. public static var alwaysHideButton = false
  47. static var listPullFB: [String] = []
  48. static var datePullFB: Date?
  49. let welcomeVC = UIViewController()
  50. let privacyPolicyVC = UIViewController()
  51. var termVC: UIViewController?
  52. let welcomeDesc = UILabel()
  53. let termText = "Read our Terms of Service. Tap \"Agree and Continue\" to accept Terms of Service.".localized()
  54. let notifDisclaim = "Enabling notifications ensures you receive important updates, alerts, and reminders from our app. By turning on notifications, you agree to receive push notifications related to app features, promotions, and relevant updates.".localized()
  55. let term = "Terms of Service.".localized()
  56. var firstLoad = true
  57. let privacyWV = WKWebView()
  58. let indicatorCounterFB = UIView()
  59. let labelCounterFB = UILabel()
  60. var indicatorView : UIView!
  61. var indicatorImage : UIImageView!
  62. var imageIndicator: UIImage!
  63. public static var def: ViewController?
  64. override func viewDidLoad() {
  65. super.viewDidLoad()
  66. DispatchQueue.main.async { [self] in
  67. while !Utils.getFinishInitPrefsr() || HTTPCookieStorage.shared.cookies(for: URL(string: Utils.getDomainOpr())!)!.count == 0 {
  68. Thread.sleep(forTimeInterval: 1)
  69. }
  70. startView()
  71. }
  72. }
  73. override func viewDidDisappear(_ animated: Bool) {
  74. Nexilis.floatingButton.hideButton()
  75. Utils.randomizeBackground(view: self.navigationController?.view)
  76. }
  77. func startView() {
  78. navigationController?.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
  79. Utils.addBackground(view: self.navigationController?.view)
  80. let topBorder = CALayer()
  81. topBorder.backgroundColor = UIColor.borderTabColor.cgColor
  82. topBorder.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: 1)
  83. tabBar.layer.addSublayer(topBorder)
  84. ViewController.def = self
  85. title = Bundle.main.displayName
  86. let customTab = PrefsUtil.getCustomTab().split(separator: ",")
  87. let cpaasMode = PrefsUtil.getCpaasMode()
  88. var tabs : [UIViewController] = []
  89. firstTab = UINavigationController(rootViewController: FirstTabViewController())
  90. secondTab = UINavigationController(rootViewController: SecondTabViewController())
  91. thirdTab = UINavigationController(rootViewController: ThirdTabViewController())
  92. fourthTab = UINavigationController(rootViewController: FourthTabViewController())
  93. callTab = UINavigationController(rootViewController: CallLogVC())
  94. chatWATab = UINavigationController(rootViewController: ChatWALikeVC())
  95. communityTab = UINavigationController(rootViewController: CommunityList())
  96. secureFolderTab = UINavigationController(rootViewController: SecureFolderViewController())
  97. self.delegate = self
  98. firstTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_1_icon")!.withTintColor(.white) : UIImage(named: "tab_1_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_1_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
  99. secondTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_2_icon")!.withTintColor(.white) : UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
  100. thirdTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_3_icon")!.withTintColor(.white) : UIImage(named: "tab_3_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_3_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
  101. fourthTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_4_icon")!.withTintColor(.white) : UIImage(named: "tab_4_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_4_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
  102. callTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_6_icon")!.withTintColor(.white) : UIImage(named: "tab_6_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_6_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
  103. chatWATab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_2_icon")!.withTintColor(.white) : UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
  104. communityTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_2_icon")!.withTintColor(.white) : UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
  105. secureFolderTab?.tabBarItem = UITabBarItem(title: "", image: resizeImage(image: self.traitCollection.userInterfaceStyle == .dark ? UIImage(named: "tab_2_icon")!.withTintColor(.white) : UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(named: "tab_2_icon")!, targetSize: CGSize(width: 25, height: 25)).withRenderingMode(.alwaysOriginal).withTintColor(self.traitCollection.userInterfaceStyle == .dark ? .lightGray : .mainColor))
  106. var i = 0
  107. var j = 0
  108. while j < customTab.count {
  109. if(((i == 1 && customTab.count == 3) || i == 2) &&
  110. (cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX)){
  111. tabs.append(emptyTab)
  112. }
  113. else {
  114. switch(customTab[j]){
  115. case "1":
  116. tabs.append(firstTab!)
  117. case "2":
  118. tabs.append(secondTab!)
  119. case "3":
  120. tabs.append(thirdTab!)
  121. case "4":
  122. tabs.append(fourthTab!)
  123. case "5":
  124. tabs.append(secureFolderTab!)
  125. case "6":
  126. tabs.append(callTab!)
  127. case "16":
  128. tabs.append(communityTab!)
  129. case "18":
  130. tabs.append(chatWATab!)
  131. default:
  132. break
  133. }
  134. j += 1
  135. }
  136. i += 1
  137. }
  138. DispatchQueue.global().async {
  139. if !Utils.getTab1Icon().isEmpty {
  140. let urlString = "\(PrefsUtil.getURLBase())get_file_from_path?img=\(Utils.getTab1Icon())"
  141. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  142. DispatchQueue.main.async() {
  143. tabs[0].tabBarItem = UITabBarItem(title: "", image: self.resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: self.resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  144. }
  145. } else {
  146. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  147. guard let data = data, error == nil else { return }
  148. // always update the UI from the main thread
  149. DispatchQueue.main.async() { [self] in
  150. if UIImage(data: data) != nil {
  151. tabs[0].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  152. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  153. }
  154. }
  155. }
  156. }
  157. }
  158. if !Utils.getTab2Icon().isEmpty && tabs.count > 1 {
  159. let urlString = "\(PrefsUtil.getURLBase())get_file_from_path?img=\(Utils.getTab2Icon())"
  160. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  161. DispatchQueue.main.async() { [self] in
  162. tabs[1].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  163. }
  164. } else {
  165. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  166. guard let data = data, error == nil else { return }
  167. // always update the UI from the main thread
  168. DispatchQueue.main.async() { [self] in
  169. if UIImage(data: data) != nil {
  170. tabs[1].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  171. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  172. }
  173. }
  174. }
  175. }
  176. }
  177. if !Utils.getTab3Icon().isEmpty && tabs.count > 2 {
  178. let urlString = "\(PrefsUtil.getURLBase())get_file_from_path?img=\(Utils.getTab3Icon())"
  179. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  180. DispatchQueue.main.async() { [self] in
  181. if cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX {
  182. tabs[3].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  183. } else {
  184. tabs[2].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  185. }
  186. }
  187. } else {
  188. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  189. guard let data = data, error == nil else { return }
  190. // always update the UI from the main thread
  191. DispatchQueue.main.async() { [self] in
  192. if UIImage(data: data) != nil {
  193. if cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX {
  194. tabs[3].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  195. } else {
  196. tabs[2].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  197. }
  198. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  199. }
  200. }
  201. }
  202. }
  203. }
  204. if !Utils.getTab4Icon().isEmpty && tabs.count > 3 {
  205. let urlString = "\(PrefsUtil.getURLBase())get_file_from_path?img=\(Utils.getTab4Icon())"
  206. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  207. DispatchQueue.main.async() { [self] in
  208. if cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX {
  209. tabs[4].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  210. } else {
  211. tabs[3].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: cachedImage, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  212. }
  213. }
  214. } else {
  215. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  216. guard let data = data, error == nil else { return }
  217. // always update the UI from the main thread
  218. DispatchQueue.main.async() { [self] in
  219. if UIImage(data: data) != nil {
  220. if cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX {
  221. tabs[4].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  222. } else {
  223. tabs[3].tabBarItem = UITabBarItem(title: "", image: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal), selectedImage: resizeImage(image: UIImage(data: data)!, targetSize: CGSize(width: 30, height: 30)).withRenderingMode(.alwaysOriginal))
  224. }
  225. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  226. }
  227. }
  228. }
  229. }
  230. }
  231. }
  232. if((cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX)){
  233. createMidFloatingButton()
  234. navigationController?.setNavigationBarHidden(true, animated: false)
  235. ViewController.pullActionButton()
  236. }
  237. // if((cpaasMode == PrefsUtil.CPAAS_MODE_FLOATING || cpaasMode == PrefsUtil.CPAAS_MODE_MIX)) {
  238. // let rect = CGRect(x: self.view.bounds.width - 100, y: self.view.bounds.height / 2, width: 50, height: 250)
  239. // floating = FloatingButton()
  240. // floating?.frame = rect
  241. // floating?.isShow = true
  242. //
  243. // view.addSubview(floating!)
  244. // navigationController?.setNavigationBarHidden(true, animated: false)
  245. // }
  246. self.setViewControllers(tabs, animated: false)
  247. self.selectedIndex = Utils.getLastTabSelected()
  248. if(cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX){
  249. if(customTab.count == 3){
  250. self.tabBar.items?[1].isEnabled = false
  251. }
  252. self.tabBar.items?[2].isEnabled = false
  253. }
  254. let center: NotificationCenter = NotificationCenter.default
  255. center.addObserver(self, selector: #selector(checkCounter), name: NSNotification.Name(rawValue: Nexilis.listenerReceiveChat), object: nil)
  256. center.addObserver(self, selector: #selector(checkCounter), name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil)
  257. if !Utils.getIndicatorTabImage().isEmpty {
  258. let indicatorImage = Utils.getIndicatorTabImage()
  259. let fullUrl = "\(PrefsUtil.getURLBase())get_file_from_path?img=\(indicatorImage)"
  260. if let cachedImage = ImageCache.shared.image(forKey: fullUrl) {
  261. DispatchQueue.main.async() { [self] in
  262. imageIndicator = cachedImage
  263. addCustomViewAboveTabBarItem(at: Utils.getLastTabSelected(), image: imageIndicator)
  264. }
  265. } else {
  266. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: fullUrl)!) { data, response, error in
  267. guard let data = data, error == nil else { return }
  268. // always update the UI from the main thread
  269. DispatchQueue.main.async() { [self] in
  270. if UIImage(data: data) != nil {
  271. imageIndicator = UIImage(data: data)!
  272. addCustomViewAboveTabBarItem(at: Utils.getLastTabSelected(), image: imageIndicator)
  273. ImageCache.shared.save(image: UIImage(data: data)!, forKey: fullUrl)
  274. }
  275. }
  276. }
  277. }
  278. }
  279. DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: { [self] in
  280. checkCounter()
  281. })
  282. willappear()
  283. let notificationName = "realtimeShareExtensionNexilis" as CFString
  284. CFNotificationCenterAddObserver(
  285. CFNotificationCenterGetDarwinNotifyCenter(),
  286. nil,
  287. { _, _, _, _, _ in
  288. APIS.checkDataForShareExtension()
  289. },
  290. notificationName,
  291. nil,
  292. .deliverImmediately
  293. )
  294. // Nexilis.debugBroadcast()
  295. }
  296. func addCustomViewAboveTabBarItem(at index: Int, image: UIImage?) {
  297. guard let tabBarItems = tabBar.items, index < tabBarItems.count else { return }
  298. let tabBarFrame = tabBar.frame
  299. let tabBarItemWidth = tabBarFrame.width / CGFloat(tabBarItems.count)
  300. let multiplierValue: CGFloat = CGFloat(index + index + 1)
  301. let xCenter = tabBarItemWidth * multiplierValue / 2 - 20
  302. if image != nil {
  303. indicatorImage = UIImageView(image: image)
  304. indicatorImage.contentMode = .scaleAspectFit
  305. indicatorImage.frame = CGRect(x: xCenter, y: 5, width: 40, height: 40)
  306. tabBar.addSubview(indicatorImage)
  307. tabBar.sendSubviewToBack(indicatorImage)
  308. }
  309. }
  310. static func getiPhoneModel() -> String {
  311. var systemInfo = utsname()
  312. uname(&systemInfo)
  313. let machineMirror = Mirror(reflecting: systemInfo.machine)
  314. let identifier = machineMirror.children.reduce("") { identifier, element in
  315. guard let value = element.value as? Int8, value != 0 else { return identifier }
  316. return identifier + String(UnicodeScalar(UInt8(value)))
  317. }
  318. var model = ""
  319. if let modelName = mapToDevice(identifier: identifier) {
  320. model = modelName
  321. } else {
  322. model = "Unknown"
  323. }
  324. return model
  325. }
  326. static func mapToDevice(identifier: String) -> String? {
  327. // Add mappings for iPhone models as needed
  328. switch identifier {
  329. case "iPhone1,1", "iPhone1,2", "iPhone2,1", "iPhone3,1", "iPhone3,2", "iPhone3,3", "iPhone4,1", "iPhone5,1", "iPhone5,2", "iPhone5,3", "iPhone5,4", "iPhone6,1", "iPhone6,2", "iPhone7,1", "iPhone7,2", "iPhone8,1", "iPhone8,2", "iPhone8,4", "iPhone9,1", "iPhone9,2", "iPhone9,3", "iPhone9,4", "iPhone10,1", "iPhone10,2", "iPhone10,4", "iPhone10,5": return "iPhone under X"
  330. default: return "iPhone X or newer"
  331. }
  332. }
  333. @objc func checkCounter() {
  334. DispatchQueue.global().async {
  335. DispatchQueue.main.async { [self] in
  336. if self.viewControllers?.firstIndex(of: secondTab!) != nil {
  337. let counter = APIS.getTotalCounter()
  338. let indexSecondTab = self.viewControllers?.firstIndex(of: secondTab!)
  339. if counter > 0 {
  340. if !indicatorCounterFB.isDescendant(of: tabBar) {
  341. guard let tabBarItems = tabBar.items, let index = indexSecondTab else { return }
  342. let tabBarFrame = tabBar.frame
  343. let tabBarItemWidth = tabBarFrame.width / CGFloat(tabBarItems.count)
  344. let multiplierValue: CGFloat = CGFloat(index + index + 1)
  345. let xCenter = tabBarItemWidth * multiplierValue / 2 + 10
  346. indicatorCounterFB.backgroundColor = .red
  347. indicatorCounterFB.layer.cornerRadius = 8
  348. indicatorCounterFB.clipsToBounds = true
  349. indicatorCounterFB.frame = CGRect(x: xCenter, y: 5, width: counter > 99 ? 30 : counter > 9 ? 23 : 16, height: 16)
  350. tabBar.addSubview(indicatorCounterFB)
  351. indicatorCounterFB.addSubview(labelCounterFB)
  352. labelCounterFB.anchor(centerX: indicatorCounterFB.centerXAnchor, centerY: indicatorCounterFB.centerYAnchor)
  353. labelCounterFB.font = .systemFont(ofSize: 10)
  354. labelCounterFB.textColor = .white
  355. }
  356. if counter > 99 {
  357. labelCounterFB.text = "99+"
  358. } else {
  359. labelCounterFB.text = "\(counter)"
  360. }
  361. } else {
  362. if indicatorCounterFB.isDescendant(of: tabBar) {
  363. indicatorCounterFB.removeFromSuperview()
  364. }
  365. }
  366. }
  367. }
  368. }
  369. }
  370. // override func viewDidLayoutSubviews() {
  371. // super.viewDidLayoutSubviews()
  372. // tabBar.frame.size.height = 65
  373. // tabBar.frame.origin.y = view.frame.height - 65
  374. // }
  375. override func viewDidAppear(_ animated: Bool) {
  376. Nexilis.floatingButton.isHidden = false
  377. }
  378. func settingDelegate() {
  379. if self.navigationController?.visibleViewController == fourthTab {
  380. return
  381. }
  382. if self.viewControllers?.firstIndex(of: fourthTab!) == nil {
  383. let vc = FourthTabViewController()
  384. vc.notInTab = true
  385. Nexilis.floatingButton.isHidden = true
  386. self.navigationController?.show(vc, sender: nil)
  387. } else {
  388. self.selectedIndex = (self.viewControllers?.firstIndex(of: fourthTab!))!
  389. }
  390. }
  391. static var alertChangeProfile = LibAlertController()
  392. public static func checkIsChangePerson() -> Bool {
  393. let isChangeProfile = Utils.getSetProfile()
  394. if !isChangeProfile {
  395. alertChangeProfile.dismiss(animated: false)
  396. alertChangeProfile = LibAlertController(title: "Set Profile".localized(), message: "You must set your profile to use this feature".localized(), preferredStyle: .alert)
  397. alertChangeProfile.addAction(UIAlertAction(title: "Cancel".localized(), style: .destructive, handler: {_ in
  398. if ViewController.def?.viewControllers?.firstIndex(of: (ViewController.def?.firstTab)!) == ViewController.def?.selectedIndex {
  399. if let wv = ViewController.def?.firstTab?.viewControllers.first as? FirstTabViewController {
  400. wv.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  401. }
  402. }
  403. if ViewController.def?.viewControllers?.firstIndex(of: (ViewController.def?.thirdTab)!) == ViewController.def?.selectedIndex {
  404. if let wv = ViewController.def?.thirdTab?.viewControllers.first as? ThirdTabViewController {
  405. wv.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  406. }
  407. }
  408. }))
  409. alertChangeProfile.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: {(_) in
  410. ViewController.resetTabSelected()
  411. guard let controller = APIS.getControllerSign() else { return }
  412. if let controller = controller as? SignUpSignIn {
  413. controller.forceLogin = true
  414. } else if let controller = controller as? SignInOption {
  415. controller.forceLogin = true
  416. }
  417. let navigationController = CustomNavigationController(rootViewController: controller)
  418. navigationController.modalPresentationStyle = .fullScreen
  419. navigationController.navigationBar.tintColor = .white
  420. navigationController.navigationBar.barTintColor = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.rootViewController?.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
  421. navigationController.navigationBar.isTranslucent = false
  422. navigationController.navigationBar.overrideUserInterfaceStyle = .dark
  423. navigationController.navigationBar.barStyle = .black
  424. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  425. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  426. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  427. navigationController.navigationBar.titleTextAttributes = textAttributes
  428. ViewController.def?.show(b: false)
  429. if let wv1 = ViewController.def?.firstTab?.viewControllers.first as? FirstTabViewController {
  430. wv1.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  431. }
  432. if let wv3 = ViewController.def?.thirdTab?.viewControllers.first as? ThirdTabViewController {
  433. wv3.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  434. }
  435. let rootVC = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.rootViewController
  436. if rootVC?.presentedViewController == nil {
  437. rootVC?.present(navigationController, animated: true, completion: nil)
  438. } else {
  439. rootVC?.presentedViewController?.present(navigationController, animated: true, completion: nil)
  440. }
  441. }))
  442. let rootVC = UIApplication.shared.windows.filter {$0.isKeyWindow}.first?.rootViewController
  443. if rootVC?.presentedViewController == nil {
  444. rootVC?.present(alertChangeProfile, animated: true, completion: nil)
  445. } else {
  446. rootVC?.presentedViewController?.present(alertChangeProfile, animated: true, completion: nil)
  447. }
  448. return false
  449. }
  450. return true
  451. }
  452. public static func resetTabSelected(){
  453. ViewController.isTab1 = true
  454. ViewController.isTab2 = false
  455. ViewController.isTab3 = false
  456. ViewController.isTab4 = false
  457. }
  458. override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
  459. let cpaasMode = PrefsUtil.getCpaasMode()
  460. let customTab = PrefsUtil.getCustomTab().split(separator: ",")
  461. if(cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX){
  462. if(customTab.count == 2){
  463. ViewController.isTab1 = item == tabBar.items?[0]
  464. ViewController.isTab2 = item == tabBar.items?[2]
  465. }
  466. else if(customTab.count == 3){
  467. ViewController.isTab1 = item == tabBar.items?[0]
  468. ViewController.isTab2 = item == tabBar.items?[2]
  469. ViewController.isTab3 = item == tabBar.items?[3]
  470. }
  471. else if(customTab.count == 4){
  472. ViewController.isTab1 = item == tabBar.items?[0]
  473. ViewController.isTab2 = item == tabBar.items?[1]
  474. ViewController.isTab3 = item == tabBar.items?[3]
  475. ViewController.isTab4 = item == tabBar.items?[4]
  476. }
  477. }
  478. else{
  479. ViewController.isTab1 = item == tabBar.items?[0]
  480. ViewController.isTab2 = item == tabBar.items?[1]
  481. if(customTab.count > 2){
  482. ViewController.isTab3 = item == tabBar.items?[2]
  483. }
  484. if(customTab.count > 3){
  485. ViewController.isTab4 = item == tabBar.items?[3]
  486. }
  487. }
  488. }
  489. func createMidFloatingButton(){
  490. var minYIpX: CGFloat = 0
  491. let iPhoneModel = ViewController.getiPhoneModel()
  492. if iPhoneModel == "iPhone X or newer" {
  493. minYIpX += 20
  494. }
  495. var widthHeightButton: CGFloat = 45
  496. if Utils.getIconDockSize() == "1" {
  497. widthHeightButton = 55
  498. }
  499. ViewController.chatButton = UIButton(frame: CGRect(x: self.view.bounds.width / 2 - 22.5 , y: self.view.bounds.height - 80 - minYIpX, width: widthHeightButton, height: widthHeightButton))
  500. ViewController.chatButton.setBackgroundImage(UIImage(named: "pb_button_chat", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  501. ViewController.chatButton.layer.shadowColor = UIColor.black.cgColor
  502. ViewController.chatButton.layer.shadowOpacity = 0.1
  503. ViewController.chatButton.layer.shadowOffset = CGSize(width: 4, height: 4)
  504. ViewController.chatButton.addTarget(self, action: #selector(chatTap), for: .touchUpInside)
  505. ViewController.callButton = UIButton(frame: CGRect(x: self.view.bounds.width / 2 - 22.5 , y: self.view.bounds.height - 80 - minYIpX, width: widthHeightButton, height: widthHeightButton))
  506. ViewController.callButton.setBackgroundImage(UIImage(named: "pb_button_call", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  507. ViewController.callButton.layer.shadowColor = UIColor.black.cgColor
  508. ViewController.callButton.layer.shadowOpacity = 0.1
  509. ViewController.callButton.layer.shadowOffset = CGSize(width: 4, height: 4)
  510. ViewController.callButton.addTarget(self, action: #selector(callTap), for: .touchUpInside)
  511. ViewController.ccButton = UIButton(frame: CGRect(x: self.view.bounds.width / 2 - 22.5 , y: self.view.bounds.height - 80 - minYIpX, width: widthHeightButton, height: widthHeightButton))
  512. ViewController.ccButton.setBackgroundImage(UIImage(named: "pb_button_cc", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  513. ViewController.ccButton.layer.shadowColor = UIColor.black.cgColor
  514. ViewController.ccButton.layer.shadowOpacity = 0.1
  515. ViewController.ccButton.layer.shadowOffset = CGSize(width: 4, height: 4)
  516. ViewController.ccButton.addTarget(self, action: #selector(ccTap), for: .touchUpInside)
  517. ViewController.streamingButton = UIButton(frame: CGRect(x: self.view.bounds.width / 2 - 22.5 , y: self.view.bounds.height - 80 - minYIpX, width: widthHeightButton, height: widthHeightButton))
  518. ViewController.streamingButton.setBackgroundImage(UIImage(named: "pb_button_stream", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  519. ViewController.streamingButton.layer.shadowColor = UIColor.black.cgColor
  520. ViewController.streamingButton.layer.shadowOpacity = 0.1
  521. ViewController.streamingButton.layer.shadowOffset = CGSize(width: 4, height: 4)
  522. ViewController.streamingButton.addTarget(self, action: #selector(streamTap), for: .touchUpInside)
  523. ViewController.postButton = UIButton(frame: CGRect(x: self.view.bounds.width / 2 - 22.5 , y: self.view.bounds.height - 80 - minYIpX, width: widthHeightButton, height: widthHeightButton))
  524. ViewController.postButton.setBackgroundImage(UIImage(named: "pb_button_post", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  525. ViewController.postButton.layer.shadowColor = UIColor.black.cgColor
  526. ViewController.postButton.layer.shadowOpacity = 0.1
  527. ViewController.postButton.layer.shadowOffset = CGSize(width: 4, height: 4)
  528. ViewController.postButton.addTarget(self, action: #selector(postTap), for: .touchUpInside)
  529. let buttonCenterX = self.view.bounds.width / 2
  530. let buttonCenterY = self.view.bounds.height - self.tabBar.bounds.height
  531. //print("buttonCenterX \(buttonCenterX)")
  532. //print("buttonCenterY \(buttonCenterY)")
  533. ViewController.middleButton = UIButton(frame: CGRect(x: buttonCenterX - 40 , y: buttonCenterY - 40, width: 80, height: 80))
  534. if !PrefsUtil.getIconDock().isEmpty {
  535. if PrefsUtil.getIconDock().contains(".gif") {
  536. ViewController.middleButton.sd_setBackgroundImage(with: URL(string: PrefsUtil.getIconCenterAnim()!), for: .normal, completed: nil)
  537. } else {
  538. DispatchQueue.global().async {
  539. let urlString = PrefsUtil.getUrlDock()!
  540. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  541. DispatchQueue.main.async() {
  542. ViewController.middleButton.setBackgroundImage(cachedImage, for: .normal)
  543. }
  544. return
  545. }
  546. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  547. guard let data = data, error == nil else { return }
  548. // always update the UI from the main thread
  549. DispatchQueue.main.async() {
  550. if UIImage(data: data) != nil {
  551. ViewController.middleButton.setBackgroundImage(UIImage(data: data), for: .normal)
  552. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  553. }
  554. }
  555. }
  556. }
  557. }
  558. } else {
  559. ViewController.middleButton.setBackgroundImage(UIImage(named: "pb_button", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), for: .normal)
  560. }
  561. ViewController.middleButton.layer.shadowColor = UIColor.black.cgColor
  562. ViewController.middleButton.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
  563. ViewController.middleButton.layer.shadowOpacity = 1.0
  564. ViewController.middleButton.layer.shadowRadius = 5.0
  565. ViewController.middleButton.layer.masksToBounds = false
  566. ViewController.middleButton.layer.cornerRadius = 4.0
  567. ViewController.middleButton.addTarget(self, action: #selector(middleBtnTapped), for: .touchUpInside)
  568. let longPressMidButton = UILongPressGestureRecognizer(target: self, action: #selector(longPressMidBtn(gestureRecognizer:)))
  569. ViewController.middleButton.addGestureRecognizer(longPressMidButton)
  570. self.view.addSubview(ViewController.chatButton)
  571. self.view.addSubview(ViewController.callButton)
  572. self.view.addSubview(ViewController.ccButton)
  573. self.view.addSubview(ViewController.postButton)
  574. self.view.addSubview(ViewController.streamingButton)
  575. self.view.addSubview(ViewController.middleButton)
  576. ViewController.hideDockedButton()
  577. }
  578. @objc func longPressMidBtn(gestureRecognizer: UILongPressGestureRecognizer) {
  579. if gestureRecognizer.state == .began {
  580. APIS.openSetting()
  581. // if self.viewControllers?.firstIndex(of: fourthTab!) == nil {
  582. // let vc = fourthTab!
  583. // vc.notInTab = true
  584. // self.navigationController?.show(vc, sender: nil)
  585. // } else {
  586. // self.selectedIndex = (self.viewControllers?.firstIndex(of: fourthTab!))!
  587. // }
  588. }
  589. }
  590. func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool {
  591. if(viewController == secondTab){
  592. if(!ViewController.checkIsChangePerson()){
  593. return false
  594. }
  595. }
  596. return true
  597. }
  598. func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
  599. if let selectedIndex = viewControllers?.firstIndex(of: viewController) {
  600. if indicatorImage != nil {
  601. indicatorImage.removeFromSuperview()
  602. addCustomViewAboveTabBarItem(at: selectedIndex, image: imageIndicator)
  603. }
  604. Utils.setLastTabSelected(value: selectedIndex)
  605. }
  606. if viewController != secondTab {
  607. let idxTabChat = self.viewControllers?.firstIndex(where: {$0 == secondTab})
  608. if idxTabChat != nil {
  609. let navTabs = self.viewControllers![idxTabChat!] as! UINavigationController
  610. let vcTabChats = navTabs.viewControllers.first as! SecondTabViewController
  611. if vcTabChats.searchController.isActive {
  612. vcTabChats.searchController.isActive = false
  613. }
  614. }
  615. }
  616. }
  617. override func viewWillAppear(_ animated: Bool) {
  618. navigationController?.setNavigationBarHidden(true, animated: false)
  619. if !firstLoad {
  620. willappear()
  621. } else {
  622. firstLoad = false
  623. }
  624. }
  625. func willappear() {
  626. let acceptTerm = PrefsUtil.getTerms()
  627. let enable_privacy_policy = PrefsUtil.getEnablePrivacyPolicy()
  628. if !acceptTerm {
  629. if !Utils.getForceAnonymous() && !Utils.getSetProfile() {
  630. Nexilis.showForceSignIn() {
  631. self.showWelocomeView()
  632. }
  633. } else {
  634. showWelocomeView()
  635. }
  636. return
  637. } else if enable_privacy_policy && !PrefsUtil.getAgreePrivacyPolicy() {
  638. showPrivacyPolicyView()
  639. return
  640. } else if acceptTerm {
  641. if !Utils.getForceAnonymous() && !Utils.getSetProfile() {
  642. Nexilis.showForceSignIn()
  643. return
  644. }
  645. }
  646. self.selectedViewController?.viewWillAppear(false)
  647. self.selectedViewController?.viewDidAppear(false)
  648. }
  649. func showPrivacyPolicyView() {
  650. if let privacyView = privacyPolicyVC.view {
  651. let bgImage = UIImageView()
  652. privacyView.addSubview(bgImage)
  653. bgImage.anchor(top: privacyView.topAnchor, left: privacyView.leftAnchor, bottom: privacyView.bottomAnchor, right: privacyView.rightAnchor)
  654. bgImage.backgroundColor = .white
  655. DispatchQueue.global().async {
  656. DispatchQueue.main.async {
  657. let listBg = PrefsUtil.getBackgroundLight().isEmpty && PrefsUtil.getBackgroundDark().isEmpty ? PrefsUtil.getBackground() :
  658. self.traitCollection.userInterfaceStyle == .dark ? PrefsUtil.getBackgroundDark() : PrefsUtil.getBackgroundLight()
  659. if listBg.isEmpty {
  660. return
  661. }
  662. var bgChoosen = ""
  663. let arrayBg = listBg.split(separator: ",")
  664. bgChoosen = String(arrayBg[Int.random(in: 0..<arrayBg.count)])
  665. let urlString = PrefsUtil.getURLBase() + "get_file_from_path?img=" + bgChoosen
  666. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  667. DispatchQueue.main.async() {
  668. bgImage.image = cachedImage
  669. }
  670. return
  671. }
  672. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  673. guard let data = data, error == nil else { return }
  674. // always update the UI from the main thread
  675. DispatchQueue.main.async() {
  676. if UIImage(data: data) != nil {
  677. bgImage.image = UIImage(data: data)!
  678. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  679. }
  680. }
  681. }
  682. }
  683. }
  684. let containerButton = UIView()
  685. privacyView.addSubview(containerButton)
  686. containerButton.anchor(left: privacyView.safeAreaLayoutGuide.leftAnchor, bottom: privacyView.safeAreaLayoutGuide.bottomAnchor, paddingLeft: 10, paddingBottom: 10, minHeight: 40)
  687. containerButton.rightAnchor.constraint(lessThanOrEqualTo: privacyView.safeAreaLayoutGuide.rightAnchor, constant: -10).isActive = true
  688. containerButton.isUserInteractionEnabled = true
  689. let tapgestureAgree = UITapGestureRecognizer(target: self, action: #selector(tappedOnAgreePrivacy(_ :)))
  690. tapgestureAgree.numberOfTapsRequired = 1
  691. containerButton.addGestureRecognizer(tapgestureAgree)
  692. let imageAgree = UIImageView()
  693. imageAgree.image = UIImage(systemName: "arrow.forward.circle")
  694. imageAgree.tintColor = .black
  695. containerButton.addSubview(imageAgree)
  696. imageAgree.anchor(left: containerButton.leftAnchor, centerY: containerButton.centerYAnchor, width: 40, height: 40)
  697. let titleAgree = UILabel()
  698. titleAgree.text = "Agree and Continue".localized()
  699. titleAgree.textColor = .black
  700. containerButton.addSubview(titleAgree)
  701. titleAgree.anchor(left: imageAgree.rightAnchor, right: containerButton.rightAnchor, paddingLeft: 5, centerY: containerButton.centerYAnchor)
  702. privacyWV.isOpaque = false
  703. privacyWV.backgroundColor = UIColor.clear
  704. privacyWV.scrollView.backgroundColor = UIColor.clear
  705. //print("URL: \(PrefsUtil.getURLPrivacyPolicy())")
  706. let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
  707. var urlPrivacyPolicy = PrefsUtil.getURLPrivacyPolicy()
  708. if lang == "id" {
  709. urlPrivacyPolicy = urlPrivacyPolicy.replacingOccurrences(of: "/en/", with: "/id/")
  710. }
  711. privacyWV.load(URLRequest(url: URL(string: urlPrivacyPolicy)!))
  712. privacyView.addSubview(privacyWV)
  713. privacyWV.navigationDelegate = self
  714. privacyWV.anchor(top: privacyView.safeAreaLayoutGuide.topAnchor, left: privacyView.leftAnchor, right: privacyView.rightAnchor, height: privacyView.bounds.height - 80)
  715. }
  716. privacyPolicyVC.modalPresentationStyle = .fullScreen
  717. privacyPolicyVC.modalTransitionStyle = .crossDissolve
  718. UIApplication.shared.visibleViewController?.present(privacyPolicyVC, animated: true)
  719. }
  720. func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
  721. let js = "(function() { document.body.style.background='transparent'; })();"
  722. privacyWV.evaluateJavaScript(js) { (_, error) in
  723. //print(error as Any)
  724. }
  725. }
  726. func showWelocomeView() {
  727. if let viewWelcome = welcomeVC.view {
  728. viewWelcome.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
  729. Utils.addBackground(view: viewWelcome)
  730. let bgImage = UIImageView()
  731. viewWelcome.addSubview(bgImage)
  732. bgImage.anchor(top: viewWelcome.topAnchor, left: viewWelcome.leftAnchor, bottom: viewWelcome.bottomAnchor, right: viewWelcome.rightAnchor)
  733. DispatchQueue.global().async {
  734. DispatchQueue.main.async {
  735. let listBg = PrefsUtil.getBackgroundLight().isEmpty && PrefsUtil.getBackgroundDark().isEmpty ? PrefsUtil.getBackground() :
  736. self.traitCollection.userInterfaceStyle == .dark ? PrefsUtil.getBackgroundDark() : PrefsUtil.getBackgroundLight()
  737. if listBg.isEmpty {
  738. return
  739. }
  740. var bgChoosen = ""
  741. let arrayBg = listBg.split(separator: ",")
  742. bgChoosen = String(arrayBg[Int.random(in: 0..<arrayBg.count)])
  743. let urlString = PrefsUtil.getURLBase() + "get_file_from_path?img=" + bgChoosen
  744. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  745. DispatchQueue.main.async() {
  746. bgImage.image = cachedImage
  747. }
  748. return
  749. }
  750. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  751. guard let data = data, error == nil else { return }
  752. // always update the UI from the main thread
  753. DispatchQueue.main.async() {
  754. if UIImage(data: data) != nil {
  755. bgImage.image = UIImage(data: data)!
  756. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  757. }
  758. }
  759. }
  760. }
  761. }
  762. let welcomeTitle = UILabel()
  763. welcomeTitle.text = "Welcome to".localized() + " " + (Bundle.main.displayName ?? "")
  764. welcomeTitle.font = .systemFont(ofSize: 25, weight: .bold)
  765. welcomeTitle.numberOfLines = 0
  766. viewWelcome.addSubview(welcomeTitle)
  767. welcomeTitle.anchor(top: viewWelcome.safeAreaLayoutGuide.topAnchor, left: viewWelcome.safeAreaLayoutGuide.leftAnchor, right: viewWelcome.safeAreaLayoutGuide.rightAnchor, paddingTop: 10, paddingLeft: 10, paddingRight: 10)
  768. let logoImage = UIImageView()
  769. logoImage.image = UIImage(named: getHighResolutionAppIconName() ?? "")
  770. viewWelcome.addSubview(logoImage)
  771. logoImage.anchor(centerX: viewWelcome.centerXAnchor, centerY: viewWelcome.centerYAnchor, width: 200, height: 200)
  772. let containerButton = UIView()
  773. viewWelcome.addSubview(containerButton)
  774. containerButton.anchor(left: viewWelcome.safeAreaLayoutGuide.leftAnchor, bottom: viewWelcome.safeAreaLayoutGuide.bottomAnchor, paddingLeft: 10, paddingBottom: 10, minHeight: 40)
  775. containerButton.rightAnchor.constraint(lessThanOrEqualTo: viewWelcome.safeAreaLayoutGuide.rightAnchor, constant: -10).isActive = true
  776. containerButton.isUserInteractionEnabled = true
  777. let tapgestureAgree = UITapGestureRecognizer(target: self, action: #selector(tappedOnAgree(_ :)))
  778. tapgestureAgree.numberOfTapsRequired = 1
  779. containerButton.addGestureRecognizer(tapgestureAgree)
  780. let imageAgree = UIImageView()
  781. imageAgree.image = UIImage(systemName: "arrow.forward.circle")
  782. imageAgree.tintColor = self.traitCollection.userInterfaceStyle == .dark ? UIColor.white: UIColor.black
  783. containerButton.addSubview(imageAgree)
  784. imageAgree.anchor(left: containerButton.leftAnchor, centerY: containerButton.centerYAnchor, width: 40, height: 40)
  785. let titleAgree = UILabel()
  786. titleAgree.text = "Agree and Continue".localized()
  787. titleAgree.textColor = self.traitCollection.userInterfaceStyle == .dark ? UIColor.white: UIColor.black
  788. containerButton.addSubview(titleAgree)
  789. titleAgree.anchor(left: imageAgree.rightAnchor, right: containerButton.rightAnchor, paddingLeft: 5, centerY: containerButton.centerYAnchor)
  790. let formattedText = String.format(strings: [term], inString: "\(termText)\n\n\(notifDisclaim)", color: self.traitCollection.userInterfaceStyle == .dark ? UIColor.white: UIColor.black)
  791. welcomeDesc.isUserInteractionEnabled = true
  792. welcomeDesc.attributedText = formattedText
  793. welcomeDesc.numberOfLines = 0
  794. viewWelcome.addSubview(welcomeDesc)
  795. welcomeDesc.anchor(left: viewWelcome.safeAreaLayoutGuide.leftAnchor, bottom: containerButton.topAnchor, right: viewWelcome.rightAnchor, paddingLeft: 10, paddingBottom: 10, paddingRight: 10)
  796. let tapgesture = UITapGestureRecognizer(target: self, action: #selector(tappedOnLabelTerms(_ :)))
  797. tapgesture.numberOfTapsRequired = 1
  798. welcomeDesc.addGestureRecognizer(tapgesture)
  799. }
  800. welcomeVC.modalPresentationStyle = .fullScreen
  801. welcomeVC.modalTransitionStyle = .crossDissolve
  802. UIApplication.shared.visibleViewController?.present(welcomeVC, animated: true)
  803. }
  804. func getHighResolutionAppIconName() -> String? {
  805. guard let infoPlist = Bundle.main.infoDictionary else { return nil }
  806. guard let bundleIcons = infoPlist["CFBundleIcons"] as? NSDictionary else { return nil }
  807. guard let bundlePrimaryIcon = bundleIcons["CFBundlePrimaryIcon"] as? NSDictionary else { return nil }
  808. guard let bundleIconFiles = bundlePrimaryIcon["CFBundleIconFiles"] as? NSArray else { return nil }
  809. guard let appIcon = bundleIconFiles.lastObject as? String else { return nil }
  810. return appIcon
  811. }
  812. func showWebviewTerm() {
  813. termVC = UIViewController()
  814. if let viewTerm = termVC!.view {
  815. let webView = WKWebView()
  816. let lang: String = SecureUserDefaults.shared.value(forKey: "i18n_language") ?? "en"
  817. var urlTerm = "https://nexilis.io/newuniverse-tos"
  818. if lang == "id" {
  819. urlTerm = "https://nexilis.io/newuniverse-tos-id"
  820. }
  821. let url = URL (string: urlTerm)
  822. let requestObj = URLRequest(url: url!)
  823. webView.load(requestObj)
  824. viewTerm.addSubview(webView)
  825. webView.anchor(top: viewTerm.safeAreaLayoutGuide.topAnchor, left: viewTerm.safeAreaLayoutGuide.leftAnchor, bottom: viewTerm.safeAreaLayoutGuide.bottomAnchor, right: viewTerm.safeAreaLayoutGuide.rightAnchor)
  826. }
  827. let navigationController = CustomNavigationController(rootViewController: termVC!)
  828. navigationController.navigationBar.tintColor = .mainColor
  829. navigationController.navigationBar.barTintColor = .white
  830. navigationController.navigationBar.isTranslucent = false
  831. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.mainColor]
  832. navigationController.navigationBar.titleTextAttributes = textAttributes
  833. termVC!.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Close".localized(), style: .plain, target: self, action: #selector(closeTerm))
  834. welcomeVC.present(navigationController, animated: true)
  835. }
  836. @objc func closeTerm() {
  837. termVC!.dismiss(animated: true)
  838. }
  839. @objc func tappedOnLabelTerms(_ gesture: UITapGestureRecognizer) {
  840. let termString = termText as NSString
  841. let termRange = termString.range(of: term)
  842. let tapLocation = gesture.location(in: welcomeDesc)
  843. let index = welcomeDesc.indexOfAttributedTextCharacterAtPoint(point: tapLocation)
  844. if checkRange(termRange, contain: index) == true {
  845. showWebviewTerm()
  846. return
  847. }
  848. }
  849. @objc func tappedOnAgree(_ gesture: UITapGestureRecognizer) {
  850. PrefsUtil.setTerms(value: true)
  851. welcomeVC.dismiss(animated: true)
  852. }
  853. @objc func tappedOnAgreePrivacy(_ gesture: UITapGestureRecognizer) {
  854. PrefsUtil.setAgreePrivacyPolicy(value: true)
  855. privacyPolicyVC.dismiss(animated: true)
  856. }
  857. func checkRange(_ range: NSRange, contain index: Int) -> Bool {
  858. return index > range.location && index < range.location + range.length
  859. }
  860. @objc func middleBtnTapped() {
  861. ViewController.expandButton()
  862. }
  863. public func show(b: Bool) {
  864. if(!b){
  865. if(ViewController.isExpandButton){
  866. ViewController.expandButton()
  867. }
  868. }
  869. }
  870. @objc func ccTap() {
  871. //print("ccTap")
  872. if(ViewController.checkIsChangePerson()){
  873. show(b: false)
  874. if let wv1 = ViewController.def?.firstTab?.viewControllers.first as? FirstTabViewController {
  875. wv1.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  876. }
  877. if let wv3 = ViewController.def?.thirdTab?.viewControllers.first as? ThirdTabViewController {
  878. wv3.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  879. }
  880. if ViewController.listPullFB.count != 0 && ViewController.listPullFB.count > 2 {
  881. let package_id = ViewController.listPullFB[2].split(separator: "|")[0]
  882. var app_id = ""
  883. if package_id.contains("_fb") {
  884. let listSplit = package_id.split(separator: "_", maxSplits: 1)
  885. let numIdx = listSplit[listSplit.firstIndex(where: { $0.contains("fb") }) ?? 0]
  886. let indexTap = Int(String(numIdx).substring(from: 2, to: numIdx.count))!
  887. if listSplit.count == 2 {
  888. app_id = String(listSplit[1])
  889. }
  890. if indexTap == 99 {
  891. openTabPost()
  892. } else {
  893. Nexilis.buttonClicked(index: indexTap, id: app_id)
  894. }
  895. } else {
  896. if !app_id.isEmpty {
  897. Nexilis.buttonClicked(index: 0, id: app_id)
  898. }
  899. }
  900. } else {
  901. Nexilis.buttonClicked(index: 9)
  902. }
  903. }
  904. }
  905. @objc func streamTap() {
  906. //print("streamTap")
  907. if(ViewController.checkIsChangePerson()){
  908. show(b: false)
  909. if let wv1 = ViewController.def?.firstTab?.viewControllers.first as? FirstTabViewController {
  910. wv1.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  911. }
  912. if let wv3 = ViewController.def?.thirdTab?.viewControllers.first as? ThirdTabViewController {
  913. wv3.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  914. }
  915. if ViewController.listPullFB.count != 0 && ViewController.listPullFB.count > 4 {
  916. let package_id = ViewController.listPullFB[4].split(separator: "|")[0]
  917. var app_id = ""
  918. if package_id.contains("_fb") {
  919. let listSplit = package_id.split(separator: "_", maxSplits: 1)
  920. let numIdx = listSplit[listSplit.firstIndex(where: { $0.contains("fb") }) ?? 0]
  921. let indexTap = Int(String(numIdx).substring(from: 2, to: numIdx.count))!
  922. if listSplit.count == 2 {
  923. app_id = String(listSplit[1])
  924. }
  925. if indexTap == 99 {
  926. openTabPost()
  927. } else {
  928. Nexilis.buttonClicked(index: indexTap, id: app_id)
  929. }
  930. } else {
  931. if !app_id.isEmpty {
  932. Nexilis.buttonClicked(index: 0, id: app_id)
  933. }
  934. }
  935. } else {
  936. Nexilis.buttonClicked(index: 8)
  937. }
  938. }
  939. }
  940. @objc func callTap() {
  941. //print("callTap")
  942. if(ViewController.checkIsChangePerson()){
  943. show(b: false)
  944. if let wv1 = ViewController.def?.firstTab?.viewControllers.first as? FirstTabViewController {
  945. wv1.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  946. }
  947. if let wv3 = ViewController.def?.thirdTab?.viewControllers.first as? ThirdTabViewController {
  948. wv3.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  949. }
  950. if ViewController.listPullFB.count != 0 && ViewController.listPullFB.count > 1 {
  951. let package_id = ViewController.listPullFB[1].split(separator: "|")[0]
  952. var app_id = ""
  953. if package_id.contains("_fb") {
  954. let listSplit = package_id.split(separator: "_", maxSplits: 1)
  955. let numIdx = listSplit[listSplit.firstIndex(where: { $0.contains("fb") }) ?? 0]
  956. let indexTap = Int(String(numIdx).substring(from: 2, to: numIdx.count))!
  957. if listSplit.count == 2 {
  958. app_id = String(listSplit[1])
  959. }
  960. if indexTap == 99 {
  961. openTabPost()
  962. } else {
  963. Nexilis.buttonClicked(index: indexTap, id: app_id)
  964. }
  965. } else {
  966. if !app_id.isEmpty {
  967. Nexilis.buttonClicked(index: 0, id: app_id)
  968. }
  969. }
  970. } else {
  971. Nexilis.buttonClicked(index: 7)
  972. }
  973. }
  974. }
  975. @objc func chatTap() {
  976. //print("chatTap")
  977. // APIS.openWhiteboard()
  978. // return
  979. if(ViewController.checkIsChangePerson()){
  980. show(b: false)
  981. if let wv1 = ViewController.def?.firstTab?.viewControllers.first as? FirstTabViewController {
  982. wv1.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  983. }
  984. if let wv3 = ViewController.def?.thirdTab?.viewControllers.first as? ThirdTabViewController {
  985. wv3.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  986. }
  987. if ViewController.listPullFB.count != 0 && ViewController.listPullFB.count > 0 {
  988. let package_id = ViewController.listPullFB[0].split(separator: "|")[0]
  989. var app_id = ""
  990. if package_id.contains("_fb") {
  991. let listSplit = package_id.split(separator: "_", maxSplits: 1)
  992. let numIdx = listSplit[listSplit.firstIndex(where: { $0.contains("fb") }) ?? 0]
  993. let indexTap = Int(String(numIdx).substring(from: 2, to: numIdx.count))!
  994. if listSplit.count == 2 {
  995. app_id = String(listSplit[1])
  996. }
  997. if indexTap == 99 {
  998. openTabPost()
  999. } else {
  1000. Nexilis.buttonClicked(index: indexTap, id: app_id)
  1001. }
  1002. } else {
  1003. if !app_id.isEmpty {
  1004. Nexilis.buttonClicked(index: 0, id: app_id)
  1005. }
  1006. }
  1007. } else {
  1008. Nexilis.buttonClicked(index: 6)
  1009. }
  1010. }
  1011. }
  1012. @objc func postTap() {
  1013. if(ViewController.checkIsChangePerson()){
  1014. show(b: false)
  1015. if let wv1 = ViewController.def?.firstTab?.viewControllers.first as? FirstTabViewController {
  1016. wv1.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  1017. }
  1018. if let wv3 = ViewController.def?.thirdTab?.viewControllers.first as? ThirdTabViewController {
  1019. wv3.webView?.evaluateJavaScript("if(resumeAll){resumeAll();}")
  1020. }
  1021. if ViewController.listPullFB.count != 0 && ViewController.listPullFB.count > 3 {
  1022. let package_id = ViewController.listPullFB[3].split(separator: "|")[0]
  1023. var app_id = ""
  1024. if package_id.contains("_fb") {
  1025. let listSplit = package_id.split(separator: "_", maxSplits: 1)
  1026. let numIdx = listSplit[listSplit.firstIndex(where: { $0.contains("fb") }) ?? 0]
  1027. let indexTap = Int(String(numIdx).substring(from: 2, to: numIdx.count))!
  1028. if listSplit.count == 2 {
  1029. app_id = String(listSplit[1])
  1030. }
  1031. if indexTap == 99 {
  1032. openTabPost()
  1033. } else {
  1034. Nexilis.buttonClicked(index: indexTap, id: app_id)
  1035. }
  1036. } else {
  1037. if !app_id.isEmpty {
  1038. Nexilis.buttonClicked(index: 0, id: app_id)
  1039. }
  1040. }
  1041. } else {
  1042. openTabPost()
  1043. }
  1044. }
  1045. }
  1046. func openTabPost() {
  1047. let customTab = PrefsUtil.getCustomTab().split(separator: ",")
  1048. let cpaasMode = PrefsUtil.getCpaasMode()
  1049. var i = 0
  1050. var j = 0
  1051. //print("custom tab post tap = \(customTab)")
  1052. while j < customTab.count {
  1053. if(((i == 1 && customTab.count == 3) || i == 2) &&
  1054. (cpaasMode == PrefsUtil.CPAAS_MODE_DOCKED || cpaasMode == PrefsUtil.CPAAS_MODE_MIX)){
  1055. }
  1056. else {
  1057. if customTab[j] == "3" {
  1058. break
  1059. }
  1060. j += 1
  1061. }
  1062. i += 1
  1063. }
  1064. if(j < customTab.count){
  1065. self.selectedIndex = i
  1066. DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(1), execute: {
  1067. let me = User.getMyPin()
  1068. let address = "\(PrefsUtil.getURLBase())nexilis/pages/tab5-new-post?f_pin=\(me ?? "")"
  1069. if let wv3 = ViewController.def?.thirdTab?.viewControllers.first as? ThirdTabViewController {
  1070. wv3.webView.evaluateJavaScript("{window.localStorage.setItem('currentTab','\(ViewController.tab3)')}")
  1071. wv3.webView.evaluateJavaScript("window.location = '\(address)'")
  1072. }
  1073. })
  1074. }
  1075. }
  1076. static func pullActionButton() {
  1077. if datePullFB == nil || Int(Date().timeIntervalSince(datePullFB!)) >= 60 {
  1078. datePullFB = Date()
  1079. DispatchQueue.global().async {
  1080. if !PrefsUtil.getCustomButtons().isEmpty {
  1081. DispatchQueue.main.async { [self] in
  1082. let customButtons = PrefsUtil.getCustomButtons().components(separatedBy: ",")
  1083. var customIcons = PrefsUtil.getCustomFBIcon().components(separatedBy: ",")
  1084. if Utils.getIsLoadThemeFromOther() {
  1085. customIcons = Utils.getButtonIcon().components(separatedBy: ",")
  1086. }
  1087. for i in 0..<customButtons.count {
  1088. let package_id = customButtons[i]
  1089. let app_id = ""
  1090. let icon = customIcons[i]
  1091. listPullFB.append("\(package_id)|\(app_id)")
  1092. DispatchQueue.global().async {
  1093. let urlString = PrefsUtil.getURLBase() + "get_file_from_path?img=\(icon)"
  1094. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  1095. if i == 0 {
  1096. DispatchQueue.main.async {
  1097. ViewController.chatButton.setBackgroundImage(cachedImage, for: .normal)
  1098. }
  1099. } else if i == 1 {
  1100. DispatchQueue.main.async {
  1101. ViewController.callButton.setBackgroundImage(cachedImage, for: .normal)
  1102. }
  1103. } else if i == 2 {
  1104. DispatchQueue.main.async {
  1105. ViewController.ccButton.setBackgroundImage(cachedImage, for: .normal)
  1106. }
  1107. } else if i == 3 {
  1108. DispatchQueue.main.async {
  1109. ViewController.postButton.setBackgroundImage(cachedImage, for: .normal)
  1110. }
  1111. } else if i == 4 {
  1112. DispatchQueue.main.async {
  1113. ViewController.streamingButton.setBackgroundImage(cachedImage, for: .normal)
  1114. }
  1115. }
  1116. return
  1117. }
  1118. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  1119. guard let data = data, error == nil else { return }
  1120. // always update the UI from the main thread
  1121. DispatchQueue.main.async() {
  1122. if UIImage(data: data) != nil {
  1123. if i == 0 {
  1124. ViewController.chatButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1125. } else if i == 1 {
  1126. ViewController.callButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1127. } else if i == 2 {
  1128. ViewController.ccButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1129. } else if i == 3 {
  1130. ViewController.postButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1131. } else if i == 4 {
  1132. ViewController.streamingButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1133. }
  1134. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  1135. }
  1136. }
  1137. }
  1138. }
  1139. }
  1140. }
  1141. return
  1142. }
  1143. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.pullFloatingButton(), timeout: 30 * 1000) {
  1144. if response.isOk() {
  1145. let data = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "")
  1146. if !data.isEmpty {
  1147. if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
  1148. DispatchQueue.main.async { [self] in
  1149. listPullFB.removeAll()
  1150. if jsonArray.count != 0 {
  1151. var count = 0
  1152. for json in jsonArray {
  1153. let package_id = json["package_act"] as! String
  1154. let app_id = (json["app_id"] as? String) ?? ""
  1155. let icon = (json["icon"] as? String) ?? ""
  1156. listPullFB.append("\(package_id)|\(app_id)")
  1157. let urlString = "https://nexilis.io/get_file?account=\(Nexilis.sAPIKey)&image=\(icon)"
  1158. if count == 0 {
  1159. if !icon.isEmpty {
  1160. DispatchQueue.global().async {
  1161. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  1162. DispatchQueue.main.async() {
  1163. ViewController.chatButton.setBackgroundImage(cachedImage, for: .normal)
  1164. }
  1165. return
  1166. }
  1167. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  1168. guard let data = data, error == nil else { return }
  1169. // always update the UI from the main thread
  1170. DispatchQueue.main.async() {
  1171. if UIImage(data: data) != nil {
  1172. ViewController.chatButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1173. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  1174. }
  1175. }
  1176. }
  1177. }
  1178. } else {
  1179. ViewController.chatButton.setBackgroundImage(UIImage(named: "pb_button_chat", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  1180. }
  1181. } else if count == 1 {
  1182. if !icon.isEmpty {
  1183. DispatchQueue.global().async {
  1184. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  1185. DispatchQueue.main.async() {
  1186. ViewController.callButton.setBackgroundImage(cachedImage, for: .normal)
  1187. }
  1188. return
  1189. }
  1190. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  1191. guard let data = data, error == nil else { return }
  1192. // always update the UI from the main thread
  1193. DispatchQueue.main.async() {
  1194. if UIImage(data: data) != nil {
  1195. ViewController.callButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1196. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  1197. }
  1198. }
  1199. }
  1200. }
  1201. } else {
  1202. ViewController.callButton.setBackgroundImage(UIImage(named: "pb_button_call", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  1203. }
  1204. } else if count == 2 {
  1205. if !icon.isEmpty {
  1206. DispatchQueue.global().async {
  1207. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  1208. DispatchQueue.main.async() {
  1209. ViewController.ccButton.setBackgroundImage(cachedImage, for: .normal)
  1210. }
  1211. return
  1212. }
  1213. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  1214. guard let data = data, error == nil else { return }
  1215. // always update the UI from the main thread
  1216. DispatchQueue.main.async() {
  1217. if UIImage(data: data) != nil {
  1218. ViewController.ccButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1219. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  1220. }
  1221. }
  1222. }
  1223. }
  1224. } else {
  1225. ViewController.ccButton.setBackgroundImage(UIImage(named: "pb_button_cc", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  1226. }
  1227. } else if count == 3 {
  1228. if !icon.isEmpty {
  1229. DispatchQueue.global().async {
  1230. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  1231. DispatchQueue.main.async() {
  1232. ViewController.postButton.setBackgroundImage(cachedImage, for: .normal)
  1233. }
  1234. return
  1235. }
  1236. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  1237. guard let data = data, error == nil else { return }
  1238. // always update the UI from the main thread
  1239. DispatchQueue.main.async() {
  1240. if UIImage(data: data) != nil {
  1241. ViewController.postButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1242. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  1243. }
  1244. }
  1245. }
  1246. }
  1247. } else {
  1248. ViewController.postButton.setBackgroundImage(UIImage(named: "pb_button_post", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  1249. }
  1250. } else if count == 4 {
  1251. if !icon.isEmpty {
  1252. DispatchQueue.global().async {
  1253. if let cachedImage = ImageCache.shared.image(forKey: urlString) {
  1254. DispatchQueue.main.async() {
  1255. ViewController.streamingButton.setBackgroundImage(cachedImage, for: .normal)
  1256. }
  1257. return
  1258. }
  1259. Utils.fetchDataWithCookiesAndUserAgent(from: URL(string: urlString)!) { data, response, error in
  1260. guard let data = data, error == nil else { return }
  1261. // always update the UI from the main thread
  1262. DispatchQueue.main.async() {
  1263. if UIImage(data: data) != nil {
  1264. ViewController.streamingButton.setBackgroundImage(UIImage(data: data), for: .normal)
  1265. ImageCache.shared.save(image: UIImage(data: data)!, forKey: urlString)
  1266. }
  1267. }
  1268. }
  1269. }
  1270. } else {
  1271. ViewController.streamingButton.setBackgroundImage(UIImage(named: "pb_button_stream", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withRenderingMode(.alwaysOriginal), for: .normal)
  1272. }
  1273. }
  1274. count += 1
  1275. }
  1276. }
  1277. }
  1278. }
  1279. }
  1280. }
  1281. }
  1282. }
  1283. }
  1284. }
  1285. public static func showDockedButton() {
  1286. ViewController.chatButton.isHidden = false
  1287. ViewController.callButton.isHidden = false
  1288. ViewController.ccButton.isHidden = false
  1289. ViewController.streamingButton.isHidden = false
  1290. ViewController.postButton.isHidden = false
  1291. }
  1292. public static func hideDockedButton() {
  1293. ViewController.chatButton.isHidden = true
  1294. ViewController.callButton.isHidden = true
  1295. ViewController.ccButton.isHidden = true
  1296. ViewController.streamingButton.isHidden = true
  1297. ViewController.postButton.isHidden = true
  1298. }
  1299. public static func expandButton() {
  1300. let cpaasMode = PrefsUtil.getCpaasMode()
  1301. if cpaasMode != PrefsUtil.CPAAS_MODE_DOCKED && cpaasMode != PrefsUtil.CPAAS_MODE_MIX {
  1302. return
  1303. }
  1304. if ViewController.alwaysHideButton && !ViewController.isExpandButton {
  1305. return
  1306. }
  1307. var minYIpX: CGFloat = 0
  1308. let iPhoneModel = getiPhoneModel()
  1309. if iPhoneModel == "iPhone X or newer" {
  1310. minYIpX += 20
  1311. }
  1312. if ViewController.isExpandButton {
  1313. ViewController.isExpandButton = false
  1314. let xChatPosition = ViewController.chatButton.frame.origin.x + 90
  1315. let yChatPosition = ViewController.chatButton.frame.origin.y + 20
  1316. let xCallPosition = ViewController.callButton.frame.origin.x + 55
  1317. let yCallPosition = ViewController.callButton.frame.origin.y + 70
  1318. let xCCPosition = ViewController.ccButton.frame.origin.x
  1319. let yCCPosition = ViewController.ccButton.frame.origin.y + 90
  1320. let xPostPosition = ViewController.postButton.frame.origin.x - 55
  1321. let yPostPosition = ViewController.postButton.frame.origin.y + 70
  1322. let xStreamingPosition = ViewController.streamingButton.frame.origin.x - 90
  1323. let yStreamingPosition = ViewController.streamingButton.frame.origin.y + 20
  1324. UIView.animate(withDuration: 0.5, animations: {
  1325. // if !ViewController.isBlue {
  1326. // ViewController.middleButton.transform = CGAffineTransform(rotationAngle: 0)
  1327. // }
  1328. ViewController.chatButton.frame.origin = CGPoint(x: xChatPosition, y: yChatPosition + minYIpX)
  1329. ViewController.callButton.frame.origin = CGPoint(x: xCallPosition, y: yCallPosition + minYIpX)
  1330. ViewController.ccButton.frame.origin = CGPoint(x: xCCPosition, y: yCCPosition + minYIpX)
  1331. ViewController.streamingButton.frame.origin = CGPoint(x: xStreamingPosition, y: yStreamingPosition + minYIpX)
  1332. ViewController.postButton.frame.origin = CGPoint(x: xPostPosition, y: yPostPosition + minYIpX)
  1333. })
  1334. DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
  1335. if !ViewController.isExpandButton {
  1336. ViewController.hideDockedButton()
  1337. }
  1338. })
  1339. } else {
  1340. ViewController.isExpandButton = true
  1341. ViewController.showDockedButton()
  1342. let xChatPosition = ViewController.chatButton.frame.origin.x - 90
  1343. let yChatPosition = ViewController.chatButton.frame.origin.y - 20
  1344. let xCallPosition = ViewController.callButton.frame.origin.x - 55
  1345. let yCallPosition = ViewController.callButton.frame.origin.y - 70
  1346. let xCCPosition = ViewController.ccButton.frame.origin.x
  1347. let yCCPosition = ViewController.ccButton.frame.origin.y - 90
  1348. let xPostPosition = ViewController.postButton.frame.origin.x + 55
  1349. let yPostPosition = ViewController.postButton.frame.origin.y - 70
  1350. let xStreamingPosition = ViewController.streamingButton.frame.origin.x + 90
  1351. let yStreamingPosition = ViewController.streamingButton.frame.origin.y - 20
  1352. UIView.animate(withDuration: 0.5, animations: {
  1353. // if !ViewController.isBlue{
  1354. // ViewController.middleButton.transform = CGAffineTransform(rotationAngle: .pi / 2)
  1355. // }
  1356. ViewController.chatButton.frame.origin = CGPoint(x: xChatPosition, y: yChatPosition - minYIpX)
  1357. ViewController.callButton.frame.origin = CGPoint(x: xCallPosition, y: yCallPosition - minYIpX)
  1358. ViewController.ccButton.frame.origin = CGPoint(x: xCCPosition, y: yCCPosition - minYIpX)
  1359. ViewController.streamingButton.frame.origin = CGPoint(x: xStreamingPosition, y: yStreamingPosition - minYIpX)
  1360. ViewController.postButton.frame.origin = CGPoint(x: xPostPosition, y: yPostPosition - minYIpX)
  1361. })
  1362. }
  1363. }
  1364. public static func removeMiddleButton() {
  1365. // ViewController.chatButton.removeFromSuperview()
  1366. // ViewController.callButton.removeFromSuperview()
  1367. // ViewController.ccButton.removeFromSuperview()
  1368. // ViewController.streamingButton.removeFromSuperview()
  1369. // ViewController.postButton.removeFromSuperview()
  1370. ViewController.middleButton.isHidden = true
  1371. }
  1372. }
  1373. class EmptyTabViewController: UIViewController {
  1374. override func viewDidLoad() {
  1375. }
  1376. }
  1377. extension Bundle {
  1378. // Name of the app - title under the icon.
  1379. var displayName: String? {
  1380. return object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ??
  1381. object(forInfoDictionaryKey: "CFBundleName") as? String
  1382. }
  1383. }
  1384. extension BinaryInteger {
  1385. var degreesToRadians: CGFloat { CGFloat(self) * .pi / 180 }
  1386. }
  1387. extension FloatingPoint {
  1388. var degreesToRadians: Self { self * .pi / 180 }
  1389. var radiansToDegrees: Self { self * 180 / .pi }
  1390. }
  1391. extension UIImage {
  1392. class func imageWithColor(color: UIColor, size: CGSize) -> UIImage {
  1393. let rect: CGRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
  1394. UIGraphicsBeginImageContextWithOptions(size, false, 0)
  1395. color.setFill()
  1396. UIRectFill(rect)
  1397. let image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
  1398. UIGraphicsEndImageContext()
  1399. return image
  1400. }
  1401. }
  1402. extension String {
  1403. static func format(strings: [String],
  1404. italicFont: UIFont = UIFont.italicSystemFont(ofSize: 12),
  1405. italicColor: UIColor = UIColor.systemGreen,
  1406. inString string: String,
  1407. font: UIFont = UIFont.systemFont(ofSize: 12),
  1408. color: UIColor = UIColor.black) -> NSAttributedString {
  1409. let attributedString =
  1410. NSMutableAttributedString(string: string,
  1411. attributes: [
  1412. NSAttributedString.Key.font: font,
  1413. NSAttributedString.Key.foregroundColor: color])
  1414. let italicFontAttribute = [NSAttributedString.Key.font: italicFont, NSAttributedString.Key.foregroundColor: italicColor]
  1415. for italic in strings {
  1416. attributedString.addAttributes(italicFontAttribute, range: (string as NSString).range(of: italic))
  1417. }
  1418. return attributedString
  1419. }
  1420. }
  1421. extension UILabel {
  1422. func indexOfAttributedTextCharacterAtPoint(point: CGPoint) -> Int {
  1423. assert(self.attributedText != nil, "This method is developed for attributed string")
  1424. let textStorage = NSTextStorage(attributedString: self.attributedText!)
  1425. let layoutManager = NSLayoutManager()
  1426. textStorage.addLayoutManager(layoutManager)
  1427. let textContainer = NSTextContainer(size: self.frame.size)
  1428. textContainer.lineFragmentPadding = 0
  1429. textContainer.maximumNumberOfLines = self.numberOfLines
  1430. textContainer.lineBreakMode = self.lineBreakMode
  1431. layoutManager.addTextContainer(textContainer)
  1432. let index = layoutManager.characterIndex(for: point, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
  1433. return index
  1434. }
  1435. }