ViewController.swift 91 KB

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