APIS.swift 110 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939
  1. //
  2. // APIS.swift
  3. // NexilisLite
  4. //
  5. // Created by Akhmad Al Qindi Irsyam on 05/05/23.
  6. //
  7. import Foundation
  8. import UIKit
  9. import FMDB
  10. import NotificationBannerSwift
  11. import Toast_Swift
  12. import nuSDKService
  13. import AVFoundation
  14. import AVKit
  15. import Intents
  16. public class APIS: NSObject {
  17. private static var isAlertPresented = false
  18. public static func connect(appName: String, apiKey: String, delegate: ConnectDelegate, showButton: Bool = true, fromMAB: Bool = false) {
  19. APIS.appNm = appName.trimmingCharacters(in: .whitespacesAndNewlines)
  20. Nexilis.connect(apiKey: apiKey, delegate: delegate, showButton: showButton, fromMAB: fromMAB)
  21. }
  22. public static func getTotalCounter() -> Int32 {
  23. var counter: Int32?
  24. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  25. do {
  26. let query = """
  27. select SUM(counter) as total_counter
  28. from (
  29. select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m, BUDDY b
  30. where ms.l_pin = b.f_pin and ms.message_id = m.message_id and m.is_call_center = 0
  31. union all
  32. select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m
  33. where ms.l_pin = '-999' and ms.message_id = m.message_id
  34. union all
  35. select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m
  36. where ms.l_pin = '-997' and ms.message_id = m.message_id
  37. union all
  38. select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m, GROUPZ b
  39. where ms.l_pin = b.group_id and ms.message_id = m.message_id and m.is_call_center = 0
  40. union all
  41. select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m, DISCUSSION_FORUM b, GROUPZ c
  42. where b.group_id = c.group_id and ms.l_pin = b.chat_id and ms.message_id = m.message_id and m.is_call_center = 0
  43. ) as subquery
  44. """
  45. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: query), cursor.next() {
  46. counter = cursor.int(forColumnIndex: 0)
  47. cursor.close()
  48. }
  49. } catch {
  50. rollback.pointee = true
  51. print("Access database error: \(error.localizedDescription)")
  52. }
  53. })
  54. return counter ?? 0
  55. }
  56. private static func showChangeProfile() {
  57. guard !isAlertPresented else { return }
  58. isAlertPresented = true
  59. let alert = LibAlertController(title: "Set Profile".localized(), message: "You must set your profile to use this feature".localized(), preferredStyle: .alert)
  60. alert.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: {(_) in
  61. isAlertPresented = false
  62. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "signupsignin") as! SignUpSignIn
  63. controller.forceLogin = true
  64. let navigationController = CustomNavigationController(rootViewController: controller)
  65. navigationController.defaultStyle()
  66. if UIApplication.shared.visibleViewController?.navigationController != nil {
  67. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  68. } else {
  69. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  70. }
  71. }))
  72. if UIApplication.shared.visibleViewController?.navigationController != nil {
  73. UIApplication.shared.visibleViewController?.navigationController?.present(alert, animated: true, completion: nil)
  74. } else {
  75. UIApplication.shared.visibleViewController?.present(alert, animated: true, completion: nil)
  76. }
  77. }
  78. public static func openContactCenter(media: Int? = nil, category: Int? = nil) {
  79. let isChangeProfile = Utils.getSetProfile()
  80. if !isChangeProfile {
  81. APIS.showChangeProfile()
  82. return
  83. }
  84. if User.isCallCenter(userType: (User.getData(pin: User.getMyPin())?.userType)!) {
  85. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "myHistoryCC") as! HistoryCCViewController
  86. controller.isOfficer = true
  87. controller.fromAPI = true
  88. let navigationController = CustomNavigationController(rootViewController: controller)
  89. navigationController.setNavigationBarHidden(false, animated: false)
  90. navigationController.navigationBar.isTranslucent = false
  91. navigationController.defaultStyle()
  92. if UIApplication.shared.visibleViewController?.navigationController != nil {
  93. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  94. } else {
  95. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  96. }
  97. } else {
  98. if media != nil || (media == nil && category != nil) {
  99. if media == nil || media! < 0 || media! > 2 {
  100. UIApplication.shared.visibleViewController?.view.makeToast("108:Invalid Contact Center media parameter (0:Chat, 1:Audio Call, 2:Video Call)".localized(), duration: 3)
  101. return
  102. }
  103. }
  104. if category != nil {
  105. if category != 0 {
  106. let service = CategoryCC.getDataFromServiceId(service_id: "\(category!)")
  107. if service == nil {
  108. UIApplication.shared.visibleViewController?.view.makeToast("109:Invalid Contact Center category parameter".localized(), duration: 3)
  109. return
  110. }
  111. let serviceChilds = CategoryCC.getDatafromParent(parent: service!.service_id)
  112. if serviceChilds.count > 0 {
  113. UIApplication.shared.visibleViewController?.view.makeToast("109:Invalid Contact Center category parameter".localized(), duration: 3)
  114. return
  115. }
  116. }
  117. }
  118. let isWaitingRequestCC: Bool = SecureUserDefaults.shared.value(forKey: "waitingRequestCC") ?? false
  119. if isWaitingRequestCC {
  120. let imageView = UIImageView(image: UIImage(systemName: "info.circle"))
  121. imageView.tintColor = .white
  122. let banner = FloatingNotificationBanner(title: "You have requested Call Center, please wait for response.".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .info, colors: nil, iconPosition: .center)
  123. banner.show()
  124. return
  125. }
  126. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
  127. controller.isContactCenter = true
  128. if media != nil {
  129. controller.isDirectCC = true
  130. controller.channelContactCenter = "\(media!)"
  131. controller.serviceIdCC = category == nil ? "" : "\(category!)"
  132. }
  133. let navigationController = CustomNavigationController(rootViewController: controller)
  134. navigationController.defaultStyle()
  135. if UIApplication.shared.visibleViewController?.navigationController != nil {
  136. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  137. } else {
  138. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  139. }
  140. }
  141. }
  142. public static func openUrl(url: String) {
  143. let isChangeProfile = Utils.getSetProfile()
  144. if !isChangeProfile {
  145. APIS.showChangeProfile()
  146. return
  147. }
  148. let controller = BNIBookingWebView()
  149. controller.customUrl = url
  150. let navigationController = CustomNavigationController(rootViewController: controller)
  151. navigationController.defaultStyle()
  152. if UIApplication.shared.visibleViewController?.navigationController != nil {
  153. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  154. } else {
  155. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  156. }
  157. }
  158. public static func openNotificationCenter() {
  159. let isChangeProfile = Utils.getSetProfile()
  160. if !isChangeProfile {
  161. APIS.showChangeProfile()
  162. return
  163. }
  164. let controller = HistoryBroadcastViewController()
  165. let navigationController = CustomNavigationController(rootViewController: controller)
  166. navigationController.defaultStyle()
  167. if UIApplication.shared.visibleViewController?.navigationController != nil {
  168. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  169. } else {
  170. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  171. }
  172. }
  173. public static func openChat() {
  174. let isChangeProfile = Utils.getSetProfile()
  175. if !isChangeProfile {
  176. APIS.showChangeProfile()
  177. return
  178. }
  179. let navigationController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactChatNav") as! UINavigationController
  180. Utils.addBackground(view: navigationController.view)
  181. let vc = navigationController.topViewController as! ContactChatViewController
  182. vc.noUCList = true
  183. navigationController.defaultStyle()
  184. if UIApplication.shared.visibleViewController?.navigationController != nil {
  185. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  186. } else {
  187. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  188. }
  189. }
  190. public static func openSmartChatbot() {
  191. let isChangeProfile = Utils.getSetProfile()
  192. if !isChangeProfile {
  193. APIS.showChangeProfile()
  194. return
  195. }
  196. let smartChatVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "chatGptVC") as! ChatGPTBotView
  197. smartChatVC.hidesBottomBarWhenPushed = true
  198. let navigationController = CustomNavigationController(rootViewController: smartChatVC)
  199. navigationController.defaultStyle()
  200. if UIApplication.shared.visibleViewController?.navigationController != nil {
  201. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  202. } else {
  203. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  204. }
  205. }
  206. public static func startChat(name: String) {
  207. if name.isEmpty {
  208. UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 2)
  209. return
  210. }
  211. let user = User.getDataFromNameCanNil(name: name)
  212. if user == nil {
  213. UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
  214. return
  215. }
  216. let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
  217. editorPersonalVC.hidesBottomBarWhenPushed = true
  218. editorPersonalVC.unique_l_pin = user!.pin
  219. editorPersonalVC.fromNotification = true
  220. let navigationController = CustomNavigationController(rootViewController: editorPersonalVC)
  221. navigationController.modalPresentationStyle = .fullScreen
  222. navigationController.navigationBar.tintColor = .white
  223. navigationController.navigationBar.barTintColor = UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
  224. navigationController.navigationBar.isTranslucent = false
  225. navigationController.navigationBar.overrideUserInterfaceStyle = .dark
  226. navigationController.navigationBar.barStyle = .black
  227. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  228. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  229. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  230. navigationController.navigationBar.titleTextAttributes = textAttributes
  231. if UIApplication.shared.visibleViewController?.navigationController != nil {
  232. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  233. } else {
  234. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  235. }
  236. }
  237. public static func openCall() {
  238. let isChangeProfile = Utils.getSetProfile()
  239. if !isChangeProfile {
  240. APIS.showChangeProfile()
  241. return
  242. }
  243. let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID")
  244. let navigationController = CustomNavigationController(rootViewController: callContact)
  245. navigationController.defaultStyle()
  246. if UIApplication.shared.visibleViewController?.navigationController != nil {
  247. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  248. } else {
  249. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  250. }
  251. }
  252. public static func openStreaming() {
  253. let isChangeProfile = Utils.getSetProfile()
  254. if !isChangeProfile {
  255. APIS.showChangeProfile()
  256. return
  257. }
  258. let navigationController = CustomNavigationController(rootViewController: QmeraCreateStreamingViewController())
  259. navigationController.defaultStyle()
  260. if UIApplication.shared.visibleViewController?.navigationController != nil {
  261. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  262. } else {
  263. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  264. }
  265. }
  266. public static func openConference() {
  267. let isChangeProfile = Utils.getSetProfile()
  268. if !isChangeProfile {
  269. APIS.showChangeProfile()
  270. return
  271. }
  272. let navigationController = CustomNavigationController(rootViewController: CreateSeminarViewController())
  273. navigationController.defaultStyle()
  274. if UIApplication.shared.visibleViewController?.navigationController != nil {
  275. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  276. } else {
  277. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  278. }
  279. }
  280. public static func openAudioCall() {
  281. let isChangeProfile = Utils.getSetProfile()
  282. if !isChangeProfile {
  283. APIS.showChangeProfile()
  284. return
  285. }
  286. let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
  287. callContact.onlyAudioOrVideo = 1
  288. let navigationController = CustomNavigationController(rootViewController: callContact)
  289. navigationController.defaultStyle()
  290. if UIApplication.shared.visibleViewController?.navigationController != nil {
  291. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  292. } else {
  293. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  294. }
  295. }
  296. public static func startAudioCall(name: String) {
  297. if name.isEmpty {
  298. UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 3)
  299. return
  300. }
  301. let user = User.getDataFromNameCanNil(name: name)
  302. if user == nil {
  303. UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
  304. return
  305. }
  306. if !CheckConnection.isConnectedToNetwork() {
  307. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  308. imageView.tintColor = .white
  309. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  310. banner.show()
  311. return
  312. }
  313. let controller = QmeraAudioViewController()
  314. controller.user = user
  315. controller.isOutgoing = true
  316. controller.modalPresentationStyle = .overFullScreen
  317. if UIApplication.shared.visibleViewController?.navigationController != nil {
  318. UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
  319. } else {
  320. UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
  321. }
  322. }
  323. public static func openVideoCall() {
  324. let isChangeProfile = Utils.getSetProfile()
  325. if !isChangeProfile {
  326. APIS.showChangeProfile()
  327. return
  328. }
  329. let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
  330. callContact.onlyAudioOrVideo = 2
  331. let navigationController = CustomNavigationController(rootViewController: callContact)
  332. navigationController.defaultStyle()
  333. if UIApplication.shared.visibleViewController?.navigationController != nil {
  334. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  335. } else {
  336. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  337. }
  338. }
  339. public static func startVideoCall(name: String) {
  340. if name.isEmpty {
  341. UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 3)
  342. return
  343. }
  344. let user = User.getDataFromNameCanNil(name: name)
  345. if user == nil {
  346. UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
  347. return
  348. }
  349. if !CheckConnection.isConnectedToNetwork() {
  350. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  351. imageView.tintColor = .white
  352. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  353. banner.show()
  354. return
  355. }
  356. let videoVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
  357. var data: [String: String?] = [:]
  358. data["f_pin"] = user!.pin
  359. data["name"] = user!.fullName
  360. data["picture"] = user!.thumb
  361. data["isOfficial"] = user!.official
  362. data["deviceId"] = user!.device_id
  363. data["isOffline"] = user!.offline_mode
  364. data["user_type"] = user!.userType
  365. videoVC.dataPerson.append(data)
  366. videoVC.isPresent = true
  367. videoVC.modalPresentationStyle = .overFullScreen
  368. if UIApplication.shared.visibleViewController?.navigationController != nil {
  369. UIApplication.shared.visibleViewController?.navigationController?.present(videoVC, animated: true, completion: nil)
  370. } else {
  371. UIApplication.shared.visibleViewController?.present(videoVC, animated: true, completion: nil)
  372. }
  373. }
  374. public static func openBroadcastForm() {
  375. let isChangeProfile = Utils.getSetProfile()
  376. if !isChangeProfile {
  377. APIS.showChangeProfile()
  378. return
  379. }
  380. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "broadcastNav")
  381. if UIApplication.shared.visibleViewController?.navigationController != nil {
  382. UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
  383. } else {
  384. UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
  385. }
  386. }
  387. public static func openConversation() {
  388. let isChangeProfile = Utils.getSetProfile()
  389. if !isChangeProfile {
  390. APIS.showChangeProfile()
  391. return
  392. }
  393. let navigationController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactChatNav") as! UINavigationController
  394. Utils.addBackground(view: navigationController.view)
  395. navigationController.defaultStyle()
  396. if UIApplication.shared.visibleViewController?.navigationController != nil {
  397. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  398. } else {
  399. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  400. }
  401. }
  402. public static func openFavoriteMessage() {
  403. let isChangeProfile = Utils.getSetProfile()
  404. if !isChangeProfile {
  405. APIS.showChangeProfile()
  406. return
  407. }
  408. let editorStaredVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "staredVC") as! EditorStarMessages
  409. editorStaredVC.fromNotification = true
  410. let navigationController = CustomNavigationController(rootViewController: editorStaredVC)
  411. navigationController.defaultStyle()
  412. if UIApplication.shared.visibleViewController?.navigationController != nil {
  413. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  414. } else {
  415. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  416. }
  417. }
  418. public static func openSecureFolder() {
  419. let isChangeProfile = Utils.getSetProfile()
  420. if !isChangeProfile {
  421. APIS.showChangeProfile()
  422. return
  423. }
  424. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "secureFolderView") as! SecureFolderViewController
  425. let navigationController = CustomNavigationController(rootViewController: controller)
  426. navigationController.defaultStyle()
  427. if UIApplication.shared.visibleViewController?.navigationController != nil {
  428. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  429. } else {
  430. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  431. }
  432. }
  433. public static func openSecureBrowser() {
  434. let isChangeProfile = Utils.getSetProfile()
  435. if !isChangeProfile {
  436. APIS.showChangeProfile()
  437. return
  438. }
  439. let controller = BNIBookingWebView()
  440. controller.isSecureBrowser = true
  441. let navigationController = CustomNavigationController(rootViewController: controller)
  442. navigationController.defaultStyle()
  443. if UIApplication.shared.visibleViewController?.navigationController != nil {
  444. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  445. } else {
  446. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  447. }
  448. }
  449. public static func openCreateGroup() {
  450. let isChangeProfile = Utils.getSetProfile()
  451. if !isChangeProfile {
  452. APIS.showChangeProfile()
  453. return
  454. }
  455. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "createGroupNav") as! UINavigationController
  456. Utils.addBackground(view: controller.view)
  457. let vc = controller.topViewController as! GroupCreateViewController
  458. vc.isDismiss = { id in
  459. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "groupDetailView") as! GroupDetailViewController
  460. controller.data = id
  461. controller.fromNotification = true
  462. let navigationController = CustomNavigationController(rootViewController: controller)
  463. navigationController.defaultStyle()
  464. DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
  465. if UIApplication.shared.visibleViewController?.navigationController != nil {
  466. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  467. } else {
  468. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  469. }
  470. })
  471. }
  472. controller.defaultStyle()
  473. if UIApplication.shared.visibleViewController?.navigationController != nil {
  474. UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
  475. } else {
  476. UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
  477. }
  478. }
  479. public static func openAddFriend() {
  480. let isChangeProfile = Utils.getSetProfile()
  481. if !isChangeProfile {
  482. APIS.showChangeProfile()
  483. return
  484. }
  485. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "addFriendNav") as! UINavigationController
  486. Utils.addBackground(view: controller.view)
  487. controller.defaultStyle()
  488. if UIApplication.shared.visibleViewController?.navigationController != nil {
  489. UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
  490. } else {
  491. UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
  492. }
  493. }
  494. public static func openSignUpOrSignIn() {
  495. let isChangeProfile = Utils.getSetProfile()
  496. if !isChangeProfile {
  497. APIS.showChangeProfile()
  498. return
  499. }
  500. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "signupsignin") as! SignUpSignIn
  501. controller.forceLogin = true
  502. let navigationController = CustomNavigationController(rootViewController: controller)
  503. navigationController.defaultStyle()
  504. if UIApplication.shared.visibleViewController?.navigationController != nil {
  505. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  506. } else {
  507. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  508. }
  509. }
  510. public static func openSetting() {
  511. let navigationController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "settingNav") as! UINavigationController
  512. let vc = navigationController.rootViewController as! SettingTableViewController
  513. vc.fromAPI = true
  514. Utils.addBackground(view: navigationController.view)
  515. navigationController.defaultStyle()
  516. if UIApplication.shared.visibleViewController is UINavigationController && (UIApplication.shared.visibleViewController as! UINavigationController).rootViewController is SettingTableViewController {
  517. return
  518. }
  519. if UIApplication.shared.visibleViewController?.navigationController != nil {
  520. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  521. } else {
  522. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  523. }
  524. }
  525. public static func openProfile() {
  526. let isChangeProfile = Utils.getSetProfile()
  527. if !isChangeProfile {
  528. APIS.showChangeProfile()
  529. return
  530. }
  531. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
  532. controller.data = User.getMyPin()!
  533. controller.flag = .me
  534. controller.fromAPI = true
  535. controller.dismissImage = { image, imageName in
  536. var dataImage: [AnyHashable : Any] = [:]
  537. dataImage["name"] = imageName
  538. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
  539. }
  540. let navigationController = CustomNavigationController(rootViewController: controller)
  541. navigationController.defaultStyle()
  542. if UIApplication.shared.visibleViewController?.navigationController != nil {
  543. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  544. } else {
  545. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  546. }
  547. }
  548. public static func openChatWallpaper(){
  549. let isChangeProfile = Utils.getSetProfile()
  550. if !isChangeProfile {
  551. APIS.showChangeProfile()
  552. return
  553. }
  554. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "chatWallpaper") as! ChatWallpaperViewController
  555. let navigationController = CustomNavigationController(rootViewController: controller)
  556. navigationController.defaultStyle()
  557. if UIApplication.shared.visibleViewController?.navigationController != nil {
  558. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  559. } else {
  560. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  561. }
  562. }
  563. public static func openWhiteboard() {
  564. let isChangeProfile = Utils.getSetProfile()
  565. if !isChangeProfile {
  566. APIS.showChangeProfile()
  567. return
  568. }
  569. let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
  570. callContact.startWhiteBoard = true
  571. let navigationController = CustomNavigationController(rootViewController: callContact)
  572. navigationController.defaultStyle()
  573. if UIApplication.shared.visibleViewController?.navigationController != nil {
  574. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  575. } else {
  576. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  577. }
  578. }
  579. public static func startWhiteboard(name: String) {
  580. if name.isEmpty {
  581. UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 3)
  582. return
  583. }
  584. let user = User.getDataFromNameCanNil(name: name)
  585. if user == nil {
  586. UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
  587. return
  588. }
  589. if !CheckConnection.isConnectedToNetwork() {
  590. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  591. imageView.tintColor = .white
  592. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  593. banner.show()
  594. return
  595. }
  596. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "wbVC") as! WhiteboardViewController
  597. controller.modalPresentationStyle = .overFullScreen
  598. controller.fromContact = 0
  599. controller.user = user
  600. if UIApplication.shared.visibleViewController?.navigationController != nil {
  601. UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
  602. } else {
  603. UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
  604. }
  605. }
  606. // public static func openScreenSharing() {
  607. // let isChangeProfile = Utils.getSetProfile()
  608. // if !isChangeProfile {
  609. // APIS.showChangeProfile()
  610. // return
  611. // }
  612. // let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
  613. // callContact.startSS = true
  614. // let navigationController = CustomNavigationController(rootViewController: callContact)
  615. // navigationController.defaultStyle()
  616. // if UIApplication.shared.visibleViewController?.navigationController != nil {
  617. // UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  618. // } else {
  619. // UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  620. // }
  621. // }
  622. public static func startScreenSharing(name: String) {
  623. if name.isEmpty {
  624. UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 3)
  625. return
  626. }
  627. let user = User.getDataFromNameCanNil(name: name)
  628. if user == nil {
  629. UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
  630. return
  631. }
  632. if !CheckConnection.isConnectedToNetwork() {
  633. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  634. imageView.tintColor = .white
  635. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  636. banner.show()
  637. return
  638. }
  639. let controller = ScreenSharingViewController()
  640. controller.modalPresentationStyle = .overFullScreen
  641. controller.fromContact = 0
  642. controller.user = user
  643. if UIApplication.shared.visibleViewController?.navigationController != nil {
  644. UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
  645. } else {
  646. UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
  647. }
  648. }
  649. public static func openWhiteboardAndScreenSharing() {
  650. let isChangeProfile = Utils.getSetProfile()
  651. if !isChangeProfile {
  652. APIS.showChangeProfile()
  653. return
  654. }
  655. let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
  656. callContact.startSS = true
  657. callContact.startWhiteBoard = true
  658. let navigationController = CustomNavigationController(rootViewController: callContact)
  659. navigationController.defaultStyle()
  660. if UIApplication.shared.visibleViewController?.navigationController != nil {
  661. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  662. } else {
  663. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  664. }
  665. }
  666. public static func signInAdmin(password: String) {
  667. if password.isEmpty {
  668. UIApplication.shared.visibleViewController?.view.makeToast("113:Password is empty".localized(), duration: 3)
  669. return
  670. }
  671. let isChangeProfile = Utils.getSetProfile()
  672. if !isChangeProfile {
  673. APIS.showChangeProfile()
  674. return
  675. }
  676. let isAdmin = User.isAdmin()
  677. if isAdmin {
  678. UIApplication.shared.visibleViewController?.view.makeToast("112:You already login or registered as Admin".localized(), duration: 3)
  679. return
  680. }
  681. if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
  682. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  683. imageView.tintColor = .white
  684. let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  685. banner.show()
  686. return
  687. }
  688. Nexilis.showLoader()
  689. self.signInAdmin(password: password, completion: { result in
  690. if result {
  691. DispatchQueue.main.async {
  692. Nexilis.hideLoader {
  693. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  694. imageView.tintColor = .white
  695. let banner = FloatingNotificationBanner(title: "Successfully Sign-In Admin".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  696. banner.show()
  697. }
  698. }
  699. } else {
  700. DispatchQueue.main.async {
  701. Nexilis.hideLoader {}
  702. }
  703. }
  704. })
  705. }
  706. private static func signInAdmin(password: String, completion: @escaping (Bool) -> ()) {
  707. DispatchQueue.global().async {
  708. let idMe = User.getMyPin() as String?
  709. let p_password = password
  710. let md5Hex = p_password
  711. var result: Bool = false
  712. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignInApiAdmin(p_name: idMe!, p_password: md5Hex)) {
  713. if response.isOk() {
  714. result = true
  715. }
  716. DispatchQueue.main.async {
  717. if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
  718. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  719. imageView.tintColor = .white
  720. let banner = FloatingNotificationBanner(title: "Username or password does not match".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  721. banner.show()
  722. } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
  723. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  724. imageView.tintColor = .white
  725. let banner = FloatingNotificationBanner(title: "Invalid password".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  726. banner.show()
  727. }
  728. }
  729. } else {
  730. DispatchQueue.main.async {
  731. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  732. imageView.tintColor = .white
  733. let banner = FloatingNotificationBanner(title: "Unable to access servers".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .top)
  734. banner.show()
  735. }
  736. }
  737. completion(result)
  738. }
  739. }
  740. public static func openSetAsOfficerForm() {
  741. let isChangeProfile = Utils.getSetProfile()
  742. if !isChangeProfile {
  743. APIS.showChangeProfile()
  744. return
  745. }
  746. let isAdmin = User.isAdmin()
  747. if !isAdmin {
  748. UIApplication.shared.visibleViewController?.view.makeToast("111:You must Sign In as Admin to use this feature".localized(), duration: 3)
  749. return
  750. }
  751. let controller = SetInternalCSAccount()
  752. controller.isSetCS = true
  753. controller.fromNotification = true
  754. let navigationController = CustomNavigationController(rootViewController: controller)
  755. navigationController.defaultStyle()
  756. if UIApplication.shared.visibleViewController?.navigationController != nil {
  757. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  758. } else {
  759. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  760. }
  761. }
  762. public static func sendSMS(phoneNumber: String, message: String = ""){
  763. let formattedNumber = phoneNumber.replacingOccurrences(of: "-", with: "")
  764. let urlStringEncoded = message.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
  765. let paramMessage = message.isEmpty ? "" : "&body=\(urlStringEncoded!)"
  766. let url = URL(string: "sms:\(formattedNumber)\(paramMessage)")
  767. if UIApplication.shared.canOpenURL(url!) {
  768. UIApplication.shared.open(url!)
  769. }
  770. }
  771. public static func sendWhatsapp(phoneNumber: String, message: String = "") {
  772. let formattedNumber = phoneNumber.replacingOccurrences(of: "+", with: "").replacingOccurrences(of: "-", with: "")
  773. let urlStringEncoded = message.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
  774. let paramMessage = message.isEmpty ? "" : "?text=\(urlStringEncoded!)"
  775. let url = URL(string: "https://wa.me/\(formattedNumber)\(paramMessage)")
  776. if UIApplication.shared.canOpenURL(url!) {
  777. UIApplication.shared.open(url!, options: [:]) { (success) in
  778. // if success {
  779. // //print("WhatsApp accessed successfully")
  780. // } else {
  781. // //print("Error accessing WhatsApp")
  782. // }
  783. }
  784. }
  785. }
  786. public static func changeUsername(uname: String) {
  787. let isChangeProfile = Utils.getSetProfile()
  788. if !isChangeProfile {
  789. APIS.showChangeProfile()
  790. return
  791. }
  792. let finalUname = uname.replacingOccurrences(of: "[\\n\\r\\t~%()\"]", with: "", options: .regularExpression)
  793. if finalUname == User.getData(pin: User.getMyPin())?.fullName {
  794. UIApplication.shared.visibleViewController?.view.makeToast("102:Duplicate username".localized(), duration: 3)
  795. return
  796. }
  797. if finalUname.count == 0 {
  798. UIApplication.shared.visibleViewController?.view.makeToast("103:Username is empty".localized(), duration: 3)
  799. return
  800. }
  801. if finalUname.count < 3 {
  802. UIApplication.shared.visibleViewController?.view.makeToast("104:Username length is too short".localized(), duration: 3)
  803. return
  804. }
  805. let a = finalUname.split(separator: " ", maxSplits: 1)
  806. let first = String(a[0])
  807. let last = a.count == 2 ? String(a[1]) : ""
  808. DispatchQueue.global().async {
  809. if let resp = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getChangePersonInfoName(firstname: first, lastname: last)) {
  810. if resp.isOk() {
  811. Database.shared.database?.inTransaction({ fmdb, rollback in
  812. do {
  813. _ = Database.shared.updateRecord(fmdb: fmdb, table: "BUDDY", cvalues: ["first_name": first , "last_name": last], _where: "f_pin = '\(User.getMyPin())'")
  814. } catch {
  815. rollback.pointee = true
  816. print("Access database error: \(error.localizedDescription)")
  817. }
  818. })
  819. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
  820. DispatchQueue.main.async {
  821. Nexilis.hideLoader {
  822. let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
  823. imageView.tintColor = .white
  824. let banner = FloatingNotificationBanner(title: "Successfully changed name".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .success, colors: nil, iconPosition: .center)
  825. banner.show()
  826. }
  827. }
  828. } else if resp.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "1a" {
  829. DispatchQueue.main.async {
  830. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  831. imageView.tintColor = .white
  832. let banner = FloatingNotificationBanner(title: "Username has been registered, please use another name".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
  833. banner.show()
  834. }
  835. }
  836. }
  837. }
  838. }
  839. public static func openMail() {
  840. Nexilis.openmailAction()
  841. }
  842. public static func sendPushToken(_ token: String, isResend: Bool = false, isCall: Bool = false) {
  843. DispatchQueue.global().async{
  844. if !isCall {
  845. if Utils.getTokenAPN().isEmpty || token != Utils.getTokenAPN() {
  846. Utils.setTokenAPN(value: token)
  847. }
  848. DispatchQueue.global().async {
  849. while API.nGetCLXConnState() == 0 {
  850. Thread.sleep(forTimeInterval: 1)
  851. }
  852. _ = Nexilis.write(message: CoreMessage_TMessageBank.getToken(token: token, tokenCall: Utils.getTokenCall()))
  853. }
  854. }
  855. else {
  856. if Utils.getTokenCall().isEmpty || token != Utils.getTokenCall() {
  857. Utils.setTokenCall(value: token)
  858. }
  859. // DispatchQueue.global().async {
  860. // while API.nGetCLXConnState() == 0 {
  861. // Thread.sleep(forTimeInterval: 1)
  862. // }
  863. // print("SEND TOKEN CALL")
  864. // _ = Nexilis.write(message: CoreMessage_TMessageBank.getToken(token: token, isCall: true))
  865. // }
  866. }
  867. }
  868. }
  869. public static var uuidCall: UUID?
  870. public static var fpinCall: String?
  871. public static func showNotificationNexilis(_ userInfo: [AnyHashable : Any]) {
  872. if checkAppStateisBackground() {
  873. // Nexilis.sendStateToServer(s: "MASUK SHOW NOTIFICATION NEXILIS")
  874. // print("MASUK SHOW NOTIFICATION NEXILIS: \(userInfo)")
  875. DispatchQueue.main.async {
  876. if let payload = userInfo["payload"] as? [String: Any] {
  877. if let messagePayload = payload["message"] as? [String: Any] {
  878. if let data = messagePayload["data"] as? [String: Any] {
  879. let code = data["nx_code"] as? String ?? ""
  880. if code == "CL01" {
  881. if let message = data["bodies"] as? [String: String] {
  882. let idAck = data["message_id"] as? String ?? ""
  883. let messageToSave = TMessage()
  884. messageToSave.mBodies = message
  885. do {
  886. var messageExist = false
  887. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  888. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select message_id from MESSAGE where message_id = '\(message[CoreMessage_TMessageKey.MESSAGE_ID] ?? "")'"), cursor.next() {
  889. messageExist = true
  890. cursor.close()
  891. }
  892. })
  893. if messageExist {
  894. ackAPN(id: idAck)
  895. return
  896. }
  897. } catch {
  898. print("error saving message: \(error)")
  899. }
  900. APIS.addNotificationNexilis(messageToSave)
  901. ackAPN(id: idAck)
  902. Nexilis.saveMessage(message: messageToSave, withStatus: false, fromAPNS: true)
  903. }
  904. } else if code == "CL03" {
  905. let callFromName = data["call-from-name"] as? String ?? ""
  906. let callFrom = data["call-from"] as? String ?? ""
  907. let callType = data["call-type"] as? String ?? ""
  908. // uuidCall = UUID()
  909. fpinCall = callFrom
  910. Nexilis.callAPNActivated = true
  911. let center = UNUserNotificationCenter.current()
  912. let content = UNMutableNotificationContent()
  913. content.title = callFromName
  914. if callType == "1" {
  915. content.body = "Incoming Audio Call".localized()
  916. } else {
  917. content.body = "Incoming Video Call".localized()
  918. }
  919. content.userInfo = ["id" : callFrom, "type" : code, "callType": callType]
  920. content.sound = nil
  921. let request = UNNotificationRequest(identifier: callFrom, content: content, trigger: nil)
  922. center.add(request) { error in
  923. if let error = error {
  924. print("Error scheduling notification: \(error.localizedDescription)")
  925. }
  926. }
  927. let session = AVAudioSession.sharedInstance()
  928. do {
  929. try session.setCategory(.playback, options: [.duckOthers])
  930. try session.setActive(true)
  931. } catch {
  932. print("Audio session error: \(error)")
  933. }
  934. Nexilis.playRingtoneCall()
  935. } else if code == "CL02" {
  936. print("data \(data)")
  937. let callFromName = data["call-cancel-name"] as? String ?? ""
  938. let callFrom = data["call-cancel"] as? String ?? ""
  939. let callType = data["call-type"] as? String ?? ""
  940. // if let uuidCall = uuidCall {
  941. Nexilis.stopRingtoneCall()
  942. Nexilis.callAPNActivated = false
  943. let center = UNUserNotificationCenter.current()
  944. center.removeDeliveredNotifications(withIdentifiers: [callFrom])
  945. var textCall = ""
  946. if callType == "1" {
  947. textCall = "audio"
  948. } else {
  949. textCall = "video"
  950. }
  951. let content = UNMutableNotificationContent()
  952. content.title = callFromName
  953. content.body = "☎️ Missed \(textCall) call".localized()
  954. content.userInfo = ["id" : callFrom, "type" : code, "callType": callType]
  955. content.sound = nil
  956. let request = UNNotificationRequest(identifier: callFrom, content: content, trigger: nil)
  957. center.add(request) { error in
  958. if let error = error {
  959. print("Error scheduling notification: \(error.localizedDescription)")
  960. }
  961. }
  962. Nexilis.saveMessageCall(idCall: (User.getMyPin() ?? "") + CoreMessage_TMessageUtil.getTID(), textMessage: "Missed \(textCall) call".localized() + " at 0", fPin: callFrom, lPin: (User.getMyPin() ?? ""), timeCall: String(Date().currentTimeMillis()), attachment_type: MessageScope.MISSED_CALL)
  963. }
  964. }
  965. }
  966. } else if let message_id = userInfo["message_id"] as? String {
  967. getMessageById(id: message_id)
  968. }
  969. }
  970. }
  971. }
  972. public static func showNotificationCallKitNexilis(payload: [AnyHashable : Any], completion: @escaping () -> ()) {
  973. if let messagePayload = payload["payload"] as? [String: Any] {
  974. if let message = messagePayload["message"] as? [String: Any] {
  975. if let data = message["data"] as? [String: Any] {
  976. let nxCode = data["nx_code"] as? String ?? ""
  977. let callFromName = data["call-from-name"] as? String ?? ""
  978. let callCancelName = data["call-cancel-name"] as? String ?? ""
  979. let callFrom = data["call-from"] as? String ?? ""
  980. let callCancel = data["call-cancel"] as? String ?? ""
  981. let callType = data["call-type"] as? String ?? ""
  982. if nxCode == "CL03" {
  983. Nexilis.callAPNActivated = true
  984. APIS.uuidCall = UUID()
  985. CallManager.shared.reportIncomingCall(uuid: APIS.uuidCall ?? UUID(), callerName: callFromName, callerId: callFrom, isVideo: callType != "1")
  986. } else {
  987. if APIS.uuidCall != nil {
  988. CallManager.shared.endCall(uuid: APIS.uuidCall!) {
  989. Nexilis.callAPNActivated = false
  990. APIS.uuidCall = nil
  991. let center = UNUserNotificationCenter.current()
  992. var textCall = ""
  993. if callType == "1" {
  994. textCall = "audio"
  995. } else {
  996. textCall = "video"
  997. }
  998. let content = UNMutableNotificationContent()
  999. content.title = callCancelName
  1000. content.body = "☎️ Missed \(textCall) call".localized()
  1001. content.userInfo = ["id" : callFrom, "type" : nxCode, "callType": callType]
  1002. content.sound = nil
  1003. let request = UNNotificationRequest(identifier: callCancel, content: content, trigger: nil)
  1004. center.add(request) { error in
  1005. if let error = error {
  1006. print("Error scheduling notification: \(error.localizedDescription)")
  1007. }
  1008. }
  1009. Nexilis.saveMessageCall(idCall: (User.getMyPin() ?? "") + CoreMessage_TMessageUtil.getTID(), textMessage: "Missed \(textCall) call".localized() + " at 0", fPin: callCancel, lPin: (User.getMyPin() ?? ""), timeCall: String(Date().currentTimeMillis()), attachment_type: MessageScope.MISSED_CALL)
  1010. }
  1011. } else if UIApplication.shared.visibleViewController is QmeraAudioViewController || UIApplication.shared.visibleViewController is QmeraVideoViewController {
  1012. var dataMessage: [AnyHashable : Any] = [:]
  1013. dataMessage["call_cancel"] = true
  1014. NotificationCenter.default.post(name: NSNotification.Name(rawValue: Nexilis.callFCM), object: nil, userInfo: dataMessage)
  1015. }
  1016. }
  1017. }
  1018. }
  1019. }
  1020. }
  1021. private static func ackAPN(id: String) {
  1022. DispatchQueue.global().async {
  1023. // Nexilis.sendStateToServer(s: "send ack from apn")
  1024. DispatchQueue.global().async {
  1025. let parameter: [String : Any] = [
  1026. "pin": User.getMyPin() ?? "",
  1027. "message_id": id
  1028. ]
  1029. Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "ack_message")!, parameter: parameter, isFormData: true) { data, response, error in
  1030. }
  1031. }
  1032. }
  1033. }
  1034. private static func getMessageById(id: String) {
  1035. DispatchQueue.global().async {
  1036. // Nexilis.sendStateToServer(s: "send ack from apn")
  1037. DispatchQueue.global().async {
  1038. let parameter: [String : Any] = [
  1039. "pin": User.getMyPin() ?? "",
  1040. "message_id": id
  1041. ]
  1042. Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "pull_notification")!, parameter: parameter, isFormData: true) { data, response, error in
  1043. if let data = data {
  1044. do {
  1045. if let dataString = String(data: data, encoding: .utf8) {
  1046. if let jsonObj = try JSONSerialization.jsonObject(with: dataString.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [String: Any] {
  1047. let dataObj = jsonObj["data"] as? String ?? ""
  1048. let message = TMessage(data: dataObj)
  1049. Nexilis.saveMessage(message: message, withStatus: false, fromAPNS: true)
  1050. ackAPN(id: id)
  1051. }
  1052. }
  1053. } catch {
  1054. }
  1055. }
  1056. DispatchQueue.main.async {
  1057. UIApplication.shared.applicationIconBadgeNumber = Int(APIS.getTotalCounter())
  1058. }
  1059. }
  1060. DispatchQueue.main.async {
  1061. UIApplication.shared.applicationIconBadgeNumber = Int(APIS.getTotalCounter())
  1062. }
  1063. }
  1064. // do {
  1065. // if API.nGetCLXConnState() == 0 {
  1066. // let id = Utils.getConnectionID()
  1067. // try API.initConnection(sAPIK: Nexilis.sAPIKey, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: id, sStartWH: "09:00")
  1068. // while API.nGetCLXConnState() == 0 {
  1069. // print("nGetCLXConnState: 0")
  1070. // Thread.sleep(forTimeInterval: 1)
  1071. // }
  1072. // print("nGetCLXConnState: lewat")
  1073. // getMessage()
  1074. // } else {
  1075. // getMessage()
  1076. // }
  1077. // func getMessage() {
  1078. // if let result = Nexilis.writeSync(message: CoreMessage_TMessageBank.getMessageById(messageId: id), timeout: 30 * 1000) {
  1079. // print("result: \(result.toLogString())")
  1080. // if result.isOk() {
  1081. // let respData = result.getBody(key: CoreMessage_TMessageKey.DATA)
  1082. // if let data = Data(base64Encoded: respData, options: .ignoreUnknownCharacters),
  1083. // let decodedString = String(data: data, encoding: .utf8) {
  1084. // let message = TMessage(data: decodedString)
  1085. // print("message: \(message.toLogString())")
  1086. // }
  1087. // } else {
  1088. //
  1089. // }
  1090. // } else {
  1091. // }
  1092. // }
  1093. // } catch {
  1094. //
  1095. // }
  1096. }
  1097. }
  1098. public static func addNotificationNexilis(_ message: TMessage) {
  1099. var text = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_TEXT)
  1100. text = text.toNormalString()
  1101. let nameUser = message.getBody(key: CoreMessage_TMessageKey.F_DISPLAY_NAME)
  1102. var threadIdentifier = message.getBody(key: CoreMessage_TMessageKey.OPPOSITE_PIN)
  1103. let scope = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_SCOPE_ID)
  1104. if threadIdentifier.isEmpty {
  1105. if scope == "4" {
  1106. threadIdentifier = message.getBody(key: CoreMessage_TMessageKey.CHAT_ID).isEmpty ? message.getBody(key: CoreMessage_TMessageKey.L_PIN) : message.getBody(key: CoreMessage_TMessageKey.CHAT_ID)
  1107. } else {
  1108. threadIdentifier = message.getBody(key: CoreMessage_TMessageKey.F_PIN)
  1109. }
  1110. }
  1111. let messageId = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_ID)
  1112. var nameSubtitle = ""
  1113. let imageId = CoreMessage_TMessageKey.IMAGE_ID
  1114. let videoId = CoreMessage_TMessageKey.VIDEO_ID
  1115. let fileId = CoreMessage_TMessageKey.FILE_ID
  1116. let audioId = CoreMessage_TMessageKey.AUDIO_ID
  1117. let attachmentFlag = CoreMessage_TMessageKey.ATTACHMENT_FLAG
  1118. let messageScopeId = CoreMessage_TMessageKey.MESSAGE_SCOPE_ID
  1119. let credential = CoreMessage_TMessageKey.CREDENTIAL
  1120. let gif_id = CoreMessage_TMessageKey.GIF_ID
  1121. let is_secret = CoreMessage_TMessageKey.IS_SECRET
  1122. if message.getBody(key: is_secret) == "1" {
  1123. text = "You got messages..."
  1124. } else if message.getBody(key: gif_id) != "" {
  1125. text = "Sent GIF 🎬"
  1126. } else if !message.getBody(key: imageId).isEmpty {
  1127. text = "Sent Image 📷"
  1128. } else if message.getBody(key: attachmentFlag) == "11" {
  1129. text = "Sent Sticker ❤️"
  1130. } else if !message.getBody(key: videoId).isEmpty {
  1131. text = "Sent Video 📹"
  1132. } else if !message.getBody(key: fileId).isEmpty {
  1133. if message.getBody(key: messageScopeId) == "18" {
  1134. text = "Sent Form 📄"
  1135. } else {
  1136. text = "Sent File 📄"
  1137. }
  1138. } else if !message.getBody(key: audioId).isEmpty {
  1139. text = "Sent Audio ♫"
  1140. } else if text.contains("Share%20location%20") {
  1141. text = "Sent Location 📌"
  1142. } else if message.getBody(key: attachmentFlag) == "27" {
  1143. text = "Sent Live Streaming"
  1144. } else if message.getBody(key: attachmentFlag) == "26" {
  1145. text = "Sent Seminar"
  1146. } else if message.getBody(key: attachmentFlag) == "25" {
  1147. text = "Sent Video Conference Room"
  1148. } else if message.getBody(key: attachmentFlag) == "24" {
  1149. text = "Sent Quiz"
  1150. } else if message.getBody(key: credential) == "1" {
  1151. text = "Sent Confidential Message"
  1152. }
  1153. var type = "1"
  1154. var nameTopic = "Lounge".localized()
  1155. var idGroup = ""
  1156. if scope == "3" || scope == "18" || scope == "5"{
  1157. type = "0"
  1158. }
  1159. var soundId: String = SecureUserDefaults.shared.value(forKey: "newNotifSoundPersonal") ?? "001:Nexilis Message (Default)"
  1160. if type == "1" {
  1161. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  1162. do {
  1163. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT title, group_id FROM DISCUSSION_FORUM WHERE chat_id='\(threadIdentifier)'"), cursor.next() {
  1164. nameTopic = cursor.string(forColumnIndex: 0) ?? ""
  1165. idGroup = cursor.string(forColumnIndex: 1) ?? ""
  1166. cursor.close()
  1167. }
  1168. if idGroup.isEmpty {
  1169. idGroup = threadIdentifier
  1170. }
  1171. if let cursorGroup = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_name, image_id FROM GROUPZ WHERE group_id='\(idGroup)'"), cursorGroup.next() {
  1172. let nameGroup = cursorGroup.string(forColumnIndex: 0) ?? ""
  1173. nameSubtitle = "\(nameGroup) (\(nameTopic))"
  1174. cursorGroup.close()
  1175. }
  1176. } catch {
  1177. rollback.pointee = true
  1178. print("Access database error: \(error.localizedDescription)")
  1179. }
  1180. })
  1181. soundId = SecureUserDefaults.shared.value(forKey: "newNotifSoundGroup") ?? "001:Nexilis Message (Default)"
  1182. if idGroup.isEmpty {
  1183. return
  1184. }
  1185. }
  1186. var nameSound = soundId.components(separatedBy: ":")[1].replacingOccurrences(of: " ", with: "_")
  1187. var fromPref = false
  1188. if nameSound.contains("_(Default)") {
  1189. if !Utils.getDefaultIncomingMsg().isEmpty {
  1190. nameSound = Utils.getDefaultIncomingMsg()
  1191. fromPref = true
  1192. } else {
  1193. nameSound = nameSound.replacingOccurrences(of: "_(Default)", with: "")
  1194. }
  1195. }
  1196. copySoundToLocalPath(nameSound, fromPref)
  1197. let center = UNUserNotificationCenter.current()
  1198. let content = UNMutableNotificationContent()
  1199. content.title = nameUser
  1200. if type == "1" {
  1201. content.body = text.richText(group_id: idGroup).string
  1202. content.subtitle = nameSubtitle
  1203. } else {
  1204. content.body = text.richText().string
  1205. }
  1206. content.userInfo = ["id" : threadIdentifier, "type" : type]
  1207. content.sound = UNNotificationSound(named: UNNotificationSoundName("\(nameSound).mp3"))
  1208. let request = UNNotificationRequest(identifier: messageId, content: content, trigger: nil)
  1209. center.add(request) { error in
  1210. if let error = error {
  1211. print("Error scheduling notification: \(error.localizedDescription)")
  1212. }
  1213. }
  1214. DispatchQueue.main.async {
  1215. UIApplication.shared.applicationIconBadgeNumber = Int(APIS.getTotalCounter())
  1216. }
  1217. }
  1218. private static func copySoundToLocalPath(_ nameSound: String, _ fromPref: Bool) {
  1219. var sourceURL: URL?
  1220. if fromPref {
  1221. let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
  1222. let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
  1223. let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
  1224. if let dirPath = paths.first {
  1225. let audioURL = URL(fileURLWithPath: dirPath).appendingPathComponent(nameSound)
  1226. if FileManager.default.fileExists(atPath: audioURL.path) {
  1227. sourceURL = audioURL
  1228. } else if FileEncryption.shared.isSecureExists(filename: nameSound) {
  1229. do {
  1230. if var audioData = try FileEncryption.shared.readSecure(filename: nameSound) {
  1231. let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: audioData)
  1232. if dataDecrypt != nil {
  1233. audioData = dataDecrypt!
  1234. }
  1235. let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
  1236. let tempPath = cachesDirectory.appendingPathComponent(nameSound)
  1237. try audioData.write(to: tempPath)
  1238. sourceURL = tempPath
  1239. }
  1240. } catch {
  1241. }
  1242. } else {
  1243. sourceURL = Bundle.resourceBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
  1244. if sourceURL == nil {
  1245. sourceURL = Bundle.resourcesMediaBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
  1246. }
  1247. }
  1248. }
  1249. } else {
  1250. sourceURL = Bundle.resourceBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
  1251. if sourceURL == nil {
  1252. sourceURL = Bundle.resourcesMediaBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
  1253. }
  1254. }
  1255. if sourceURL == nil {
  1256. return
  1257. }
  1258. let fileManager = FileManager.default
  1259. let soundDirectory = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Sounds", isDirectory: true)
  1260. if !fileManager.fileExists(atPath: soundDirectory.path) {
  1261. do {
  1262. try fileManager.createDirectory(at: soundDirectory, withIntermediateDirectories: true, attributes: nil)
  1263. } catch {
  1264. print("Error creating Sounds directory: \(error)")
  1265. return
  1266. }
  1267. }
  1268. let destinationURL = soundDirectory.appendingPathComponent("\(nameSound).mp3")
  1269. if !fileManager.fileExists(atPath: destinationURL.path) {
  1270. do {
  1271. try fileManager.copyItem(at: sourceURL!, to: destinationURL)
  1272. } catch {
  1273. }
  1274. }
  1275. }
  1276. public static func openNotificationNexilis(_ response: UNNotificationResponse) {
  1277. DispatchQueue.main.async{
  1278. if let userInfo = response.notification.request.content.userInfo as? [String: String] {
  1279. let id = userInfo["id"] ?? ""
  1280. let type = userInfo["type"] ?? ""
  1281. let callType = userInfo["callType"] ?? ""
  1282. if let navigationC = UIApplication.shared.visibleViewController as? UINavigationController {
  1283. if navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorPersonal || navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorGroup {
  1284. navigationC.popViewController(animated: true)
  1285. }
  1286. }
  1287. showEditorOrCallFromAPN(id, type, callType)
  1288. } else {
  1289. let userInfo = response.notification.request.content.userInfo
  1290. DispatchQueue.main.async {
  1291. if let message_id = userInfo[CoreMessage_TMessageKey.MESSAGE_ID] as? String {
  1292. var f_pin = ""
  1293. var l_pin = ""
  1294. var message_scope_id = ""
  1295. var pin = ""
  1296. var chat_id = ""
  1297. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  1298. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select f_pin, l_pin, message_scope_id, chat_id from MESSAGE where message_id = '\(message_id)'"), cursor.next() {
  1299. f_pin = cursor.string(forColumnIndex: 0) ?? ""
  1300. l_pin = cursor.string(forColumnIndex: 1) ?? ""
  1301. message_scope_id = cursor.string(forColumnIndex: 2) ?? ""
  1302. chat_id = cursor.string(forColumnIndex: 3) ?? ""
  1303. pin = f_pin == User.getMyPin() ? l_pin : f_pin
  1304. if message_scope_id == "4" {
  1305. pin = chat_id.isEmpty ? l_pin : chat_id
  1306. }
  1307. cursor.close()
  1308. }
  1309. })
  1310. if let navigationC = UIApplication.shared.visibleViewController as? UINavigationController {
  1311. if navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorPersonal || navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorGroup {
  1312. navigationC.popViewController(animated: false)
  1313. }
  1314. }
  1315. print("HUHU \(f_pin) \(l_pin) \(message_scope_id)")
  1316. showEditorOrCallFromAPN(pin, message_scope_id == "4" ? "1" : "0", "CL01")
  1317. }
  1318. }
  1319. }
  1320. }
  1321. // UNUserNotificationCenter.current().removeAllDeliveredNotifications()
  1322. }
  1323. private static func showEditorOrCallFromAPN(_ id: String, _ type: String, _ callType: String) {
  1324. if type == "0" {
  1325. if User.getDataCanNil(pin: id) == nil && id != "-999" && id != "-997" {
  1326. return
  1327. }
  1328. let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
  1329. editorPersonalVC.hidesBottomBarWhenPushed = true
  1330. editorPersonalVC.unique_l_pin = id
  1331. editorPersonalVC.fromNotification = true
  1332. let navigationController = CustomNavigationController(rootViewController: editorPersonalVC)
  1333. navigationController.modalPresentationStyle = .fullScreen
  1334. navigationController.navigationBar.tintColor = .white
  1335. navigationController.navigationBar.barTintColor = UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
  1336. navigationController.navigationBar.isTranslucent = false
  1337. navigationController.navigationBar.overrideUserInterfaceStyle = .dark
  1338. navigationController.navigationBar.barStyle = .black
  1339. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  1340. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  1341. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  1342. navigationController.navigationBar.titleTextAttributes = textAttributes
  1343. if UIApplication.shared.visibleViewController is UINavigationController && Nexilis.fromMAB {
  1344. editorPersonalVC.fromNotification = false
  1345. UIApplication.shared.visibleViewController?.show(editorPersonalVC, sender: nil)
  1346. } else {
  1347. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  1348. }
  1349. } else if type == "1" {
  1350. var groupExist = false
  1351. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  1352. var idGroup = ""
  1353. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT title, group_id FROM DISCUSSION_FORUM WHERE chat_id='\(id)'"), cursor.next() {
  1354. groupExist = true
  1355. cursor.close()
  1356. } else {
  1357. if idGroup.isEmpty {
  1358. idGroup = id
  1359. }
  1360. if let cursorGroup = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_name, image_id FROM GROUPZ WHERE group_id='\(idGroup)'"), cursorGroup.next() {
  1361. groupExist = true
  1362. cursorGroup.close()
  1363. }
  1364. }
  1365. })
  1366. if !groupExist {
  1367. return
  1368. }
  1369. let editorGroupVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "editorGroupVC") as! EditorGroup
  1370. editorGroupVC.hidesBottomBarWhenPushed = true
  1371. editorGroupVC.unique_l_pin = id
  1372. editorGroupVC.fromNotification = true
  1373. let navigationController = CustomNavigationController(rootViewController: editorGroupVC)
  1374. navigationController.modalPresentationStyle = .fullScreen
  1375. navigationController.navigationBar.tintColor = .white
  1376. navigationController.navigationBar.barTintColor = UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
  1377. navigationController.navigationBar.isTranslucent = false
  1378. navigationController.navigationBar.overrideUserInterfaceStyle = .dark
  1379. navigationController.navigationBar.barStyle = .black
  1380. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  1381. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  1382. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  1383. navigationController.navigationBar.titleTextAttributes = textAttributes
  1384. if UIApplication.shared.visibleViewController is UINavigationController && Nexilis.fromMAB {
  1385. editorGroupVC.fromNotification = false
  1386. UIApplication.shared.visibleViewController?.show(editorGroupVC, sender: nil)
  1387. } else {
  1388. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  1389. }
  1390. } else if type == "CL03" {
  1391. Nexilis.stopRingtoneCall()
  1392. if !Nexilis.callAPNActivated {
  1393. return
  1394. }
  1395. if callType == "1" {
  1396. if let user = User.getData(pin: id), user.firstName == "User".localized() {
  1397. return
  1398. }
  1399. let controller = QmeraAudioViewController()
  1400. controller.isOutgoing = false
  1401. controller.user = User.getData(pin: id)
  1402. controller.autoAcceptAPN = true
  1403. controller.modalPresentationStyle = .overCurrentContext
  1404. if UIApplication.shared.visibleViewController is UIAlertController {
  1405. let vc = UIApplication.shared.visibleViewController as! UIAlertController
  1406. vc.dismiss(animated: true, completion: {
  1407. if UIApplication.shared.visibleViewController?.navigationController != nil {
  1408. UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
  1409. } else {
  1410. UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
  1411. }
  1412. })
  1413. return
  1414. }
  1415. if UIApplication.shared.visibleViewController?.navigationController != nil {
  1416. UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
  1417. } else {
  1418. UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
  1419. }
  1420. } else {
  1421. if let user = User.getData(pin: id), user.firstName == "User".localized() {
  1422. return
  1423. }
  1424. let videoController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
  1425. videoController.fPin = id
  1426. videoController.isInisiator = false
  1427. videoController.autoAcceptAPN = true
  1428. let navigationController = CustomNavigationController(rootViewController: videoController)
  1429. navigationController.modalPresentationStyle = .fullScreen
  1430. if UIApplication.shared.visibleViewController is UIAlertController {
  1431. let vc = UIApplication.shared.visibleViewController as! UIAlertController
  1432. vc.dismiss(animated: true, completion: {
  1433. if UIApplication.shared.visibleViewController?.navigationController != nil {
  1434. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  1435. } else {
  1436. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  1437. }
  1438. })
  1439. return
  1440. }
  1441. if UIApplication.shared.visibleViewController?.navigationController != nil {
  1442. UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
  1443. } else {
  1444. UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
  1445. }
  1446. }
  1447. }
  1448. }
  1449. public static func checkAppStateisBackground() -> Bool {
  1450. let state = UIApplication.shared.applicationState
  1451. switch state {
  1452. case .active:
  1453. return false
  1454. case .inactive:
  1455. return false
  1456. case .background:
  1457. return true
  1458. @unknown default:
  1459. return false
  1460. }
  1461. }
  1462. public static func enterBackground() {
  1463. // if !API.bAVisOngoing() {
  1464. // API.deinitConnection()
  1465. // }
  1466. notifTimer.invalidate()
  1467. }
  1468. public static var notifTimer = Timer()
  1469. public static var stopNotif = false
  1470. public static var afterEnterForeground = false
  1471. public static func enterForeground() {
  1472. APIS.checkNotificationPermission(completion: { isAllowed in
  1473. if !isAllowed {
  1474. showEnableNotificationsAlert()
  1475. } else {
  1476. UIApplication.shared.registerForRemoteNotifications()
  1477. }
  1478. })
  1479. DispatchQueue.main.async {
  1480. stopNotif = true
  1481. self.notifTimer = Timer.scheduledTimer(withTimeInterval: 30, repeats: false) { _ in
  1482. stopNotif = false
  1483. }
  1484. do {
  1485. if !Nexilis.afterConnect && API.nGetCLXConnState() == 0 {
  1486. let id = Utils.getConnectionID()
  1487. try API.initConnection(sAPIK: Nexilis.sAPIKey, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: id, sStartWH: "09:00")
  1488. }
  1489. // listIdentifierNotif.removeAll()
  1490. Nexilis.afterConnect = false
  1491. } catch {
  1492. }
  1493. }
  1494. checkDataForShareExtension()
  1495. UIApplication.shared.applicationIconBadgeNumber = 0
  1496. UNUserNotificationCenter.current().removeAllDeliveredNotifications()
  1497. afterEnterForeground = true
  1498. }
  1499. public static func willEnterForeground() {
  1500. if APIS.uuidCall != nil {
  1501. CallManager.shared.endCall(uuid: APIS.uuidCall!) {
  1502. APIS.uuidCall = nil
  1503. }
  1504. }
  1505. }
  1506. private static func checkNotificationPermission(completion: @escaping (Bool) -> Void) {
  1507. let center = UNUserNotificationCenter.current()
  1508. center.getNotificationSettings { settings in
  1509. DispatchQueue.main.async {
  1510. switch settings.authorizationStatus {
  1511. case .authorized, .provisional, .notDetermined:
  1512. completion(true) // Notifications are allowed
  1513. case .denied, .ephemeral:
  1514. completion(false) // Notifications are disabled or not requested
  1515. @unknown default:
  1516. completion(false)
  1517. }
  1518. }
  1519. }
  1520. }
  1521. private static func showEnableNotificationsAlert() {
  1522. guard !isAlertPresented else { return }
  1523. isAlertPresented = true
  1524. let alertController = LibAlertController(
  1525. title: "Enable Notification".localized(),
  1526. message: "To stay updated, please enable notification in the Settings.".localized(),
  1527. preferredStyle: .alert
  1528. )
  1529. alertController.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
  1530. alertController.addAction(UIAlertAction(title: "Go to Settings".localized(), style: .default, handler: { _ in
  1531. isAlertPresented = false
  1532. openAppSettings()
  1533. }))
  1534. if UIApplication.shared.visibleViewController?.navigationController != nil {
  1535. UIApplication.shared.visibleViewController?.navigationController?.present(alertController, animated: true, completion: nil)
  1536. } else {
  1537. UIApplication.shared.visibleViewController?.present(alertController, animated: true, completion: nil)
  1538. }
  1539. }
  1540. private static func openAppSettings() {
  1541. if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
  1542. if UIApplication.shared.canOpenURL(settingsURL) {
  1543. UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil)
  1544. }
  1545. }
  1546. }
  1547. public static func willTerminate() {
  1548. Nexilis.destroyAll()
  1549. }
  1550. public static func checkDataForShareExtension() {
  1551. DispatchQueue.global().async {
  1552. if let userDefaults = UserDefaults(suiteName: nameGroupShared) {
  1553. if let value = userDefaults.string(forKey: "sharedItem") {
  1554. if !value.isEmpty {
  1555. if let jsonData = value.data(using: .utf8) {
  1556. do {
  1557. if let json = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
  1558. let typeImage = 2
  1559. let typeVideo = 3
  1560. let typeFile = 4
  1561. let typeAudio = 5
  1562. let typeContact = json["typeContact"] as? String ?? "0"
  1563. var data = json["data"] as? String ?? ""
  1564. let idContact = json["idContact"] as? String ?? ""
  1565. let typeShare = json["typeShare"] as? Int ?? 1
  1566. var message = TMessage()
  1567. var groupId = ""
  1568. var chatId = ""
  1569. let scopeId = typeContact == "1" ? "4" : "3"
  1570. let thumb = json["thumb"] as? String ?? ""
  1571. let imageId = json["image"] as? String ?? ""
  1572. let videoId = json["video"] as? String ?? ""
  1573. let fileId = json["file"] as? String ?? ""
  1574. let audioId = json["audio"] as? String ?? ""
  1575. var renamedFileId = ""
  1576. var renamedAudioId = ""
  1577. var attachmentFlag = ""
  1578. if scopeId == "4" {
  1579. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  1580. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT group_id id FROM DISCUSSION_FORUM WHERE chat_id = '\(idContact)'"), cursor.next() {
  1581. groupId = cursor.string(forColumnIndex: 0) ?? ""
  1582. chatId = idContact
  1583. cursor.close()
  1584. } else {
  1585. groupId = idContact
  1586. }
  1587. })
  1588. }
  1589. if typeShare == typeImage {
  1590. if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
  1591. let sharedImageURL = appGroupURL.appendingPathComponent(imageId)
  1592. let sharedThumbURL = appGroupURL.appendingPathComponent(thumb)
  1593. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  1594. if FileManager.default.fileExists(atPath: sharedImageURL.path) {
  1595. let file = documentDir.appendingPathComponent(imageId)
  1596. if !FileManager().fileExists(atPath: file.path) {
  1597. try? FileManager.default.copyItem(at: sharedImageURL, to: file)
  1598. }
  1599. }
  1600. if FileManager.default.fileExists(atPath: sharedThumbURL.path) {
  1601. let file = documentDir.appendingPathComponent(thumb)
  1602. if !FileManager().fileExists(atPath: file.path) {
  1603. try? FileManager.default.copyItem(at: sharedThumbURL, to: file)
  1604. }
  1605. }
  1606. }
  1607. attachmentFlag = "1"
  1608. } else if typeShare == typeVideo {
  1609. if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
  1610. let sharedVideoURL = appGroupURL.appendingPathComponent(videoId)
  1611. let sharedThumbURL = appGroupURL.appendingPathComponent(thumb)
  1612. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  1613. if FileManager.default.fileExists(atPath: sharedVideoURL.path) {
  1614. let file = documentDir.appendingPathComponent(videoId)
  1615. if !FileManager().fileExists(atPath: file.path) {
  1616. try? FileManager.default.copyItem(at: sharedVideoURL, to: file)
  1617. }
  1618. }
  1619. if FileManager.default.fileExists(atPath: sharedThumbURL.path) {
  1620. let file = documentDir.appendingPathComponent(thumb)
  1621. if !FileManager().fileExists(atPath: file.path) {
  1622. try? FileManager.default.copyItem(at: sharedThumbURL, to: file)
  1623. }
  1624. }
  1625. }
  1626. attachmentFlag = "2"
  1627. } else if typeShare == typeFile {
  1628. if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
  1629. renamedFileId = "Nexilis_\(Date().currentTimeMillis())_" + fileId
  1630. let sharedFileURL = appGroupURL.appendingPathComponent(fileId)
  1631. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  1632. if FileManager.default.fileExists(atPath: sharedFileURL.path) {
  1633. let file = documentDir.appendingPathComponent(renamedFileId)
  1634. if !FileManager().fileExists(atPath: file.path) {
  1635. try? FileManager.default.copyItem(at: sharedFileURL, to: file)
  1636. }
  1637. }
  1638. data = "\(fileId)|\(data)"
  1639. }
  1640. attachmentFlag = "6"
  1641. } else if typeShare == typeAudio {
  1642. if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
  1643. renamedAudioId = "Nexilis_\(Date().currentTimeMillis())_" + audioId
  1644. let sharedFileURL = appGroupURL.appendingPathComponent(audioId)
  1645. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  1646. if FileManager.default.fileExists(atPath: sharedFileURL.path) {
  1647. let file = documentDir.appendingPathComponent(renamedAudioId)
  1648. if !FileManager().fileExists(atPath: file.path) {
  1649. try? FileManager.default.copyItem(at: sharedFileURL, to: file)
  1650. }
  1651. }
  1652. data = "\(audioId)|\(data)"
  1653. }
  1654. attachmentFlag = "5"
  1655. }
  1656. message = CoreMessage_TMessageBank.sendMessage(l_pin: groupId.isEmpty ? idContact : groupId, message_scope_id: scopeId, status: scopeId == "3" ? "1" : "2", message_text: data, credential: "0", attachment_flag: attachmentFlag, ex_blog_id: "", message_large_text: "", ex_format: "", image_id: imageId, audio_id: renamedAudioId, video_id: videoId, file_id: renamedFileId, thumb_id: thumb, reff_id: "", read_receipts: "4", chat_id: chatId, is_call_center: "0", call_center_id: "", opposite_pin: scopeId == "3" ? (User.getMyPin() ?? "") : idContact, gif_id: "", isForwarded: "0", isSecret: "0")
  1657. Nexilis.addQueueMessage(message: message)
  1658. userDefaults.set("", forKey: "sharedItem")
  1659. userDefaults.synchronize()
  1660. }
  1661. } catch {
  1662. print("Error parsing JSON: \(error)")
  1663. }
  1664. }
  1665. }
  1666. }
  1667. }
  1668. DispatchQueue.global().asyncAfter(deadline: .now() + 0.5, execute: {
  1669. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
  1670. })
  1671. }
  1672. }
  1673. public static func setDataForShareExtension() {
  1674. DispatchQueue.global().async {
  1675. if let userDefaults = UserDefaults(suiteName: nameGroupShared) {
  1676. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  1677. var dataShared: [[String: Any]] = []
  1678. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin id, image_id image, first_name || ' ' || ifnull(last_name, '') name FROM BUDDY WHERE f_pin != '\(User.getMyPin() ?? "")' AND f_pin != '-997' AND official_account != '1'") {
  1679. while cursor.next() {
  1680. var dataTemp: [String: Any] = [:]
  1681. for columnIndex in 0..<cursor.columnCount {
  1682. if let columnName = cursor.columnName(for: columnIndex) {
  1683. if let value = cursor.object(forColumn: columnName) {
  1684. if columnName == "image" {
  1685. dataTemp[columnName] = value
  1686. if let imageString = dataTemp[columnName] as? String, !imageString.isEmpty {
  1687. do {
  1688. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  1689. let file = documentDir.appendingPathComponent(imageString)
  1690. if FileManager().fileExists(atPath: file.path) {
  1691. if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
  1692. let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
  1693. if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
  1694. try? FileManager.default.copyItem(at: file, to: sharedFileURL)
  1695. }
  1696. }
  1697. }
  1698. } catch {
  1699. }
  1700. }
  1701. } else {
  1702. dataTemp[columnName] = value
  1703. }
  1704. dataTemp["type"] = 0
  1705. }
  1706. }
  1707. }
  1708. dataShared.append(dataTemp)
  1709. }
  1710. cursor.close()
  1711. }
  1712. if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT group_id id, image_id image, f_name name FROM GROUPZ WHERE official != 1") {
  1713. while cursor.next() {
  1714. var dataTemp: [String: Any] = [:]
  1715. for columnIndex in 0..<cursor.columnCount {
  1716. if let columnName = cursor.columnName(for: columnIndex) {
  1717. if let value = cursor.object(forColumn: columnName) {
  1718. if columnName == "name" {
  1719. dataTemp[columnName] = "\(value) (Lounge)"
  1720. } else if columnName == "image" {
  1721. dataTemp[columnName] = value
  1722. if let imageString = dataTemp[columnName] as? String, !imageString.isEmpty {
  1723. do {
  1724. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  1725. let file = documentDir.appendingPathComponent(imageString)
  1726. if FileManager().fileExists(atPath: file.path) {
  1727. if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
  1728. let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
  1729. if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
  1730. try? FileManager.default.copyItem(at: file, to: sharedFileURL)
  1731. }
  1732. }
  1733. }
  1734. } catch {
  1735. }
  1736. }
  1737. } else {
  1738. dataTemp[columnName] = value
  1739. }
  1740. dataTemp["type"] = 1
  1741. }
  1742. }
  1743. }
  1744. dataShared.append(dataTemp)
  1745. let group_id = cursor.string(forColumnIndex: 0) ?? ""
  1746. let image_group = cursor.string(forColumnIndex: 1) ?? ""
  1747. let name_group = cursor.string(forColumnIndex: 2) ?? ""
  1748. if let cursorTopic = Database.shared.getRecords(fmdb: fmdb, query: "SELECT chat_id id, thumb image, title name FROM DISCUSSION_FORUM WHERE group_id = '\(group_id)'") {
  1749. while cursorTopic.next() {
  1750. var dataTempTopic: [String: Any] = [:]
  1751. for columnIndex in 0..<cursorTopic.columnCount {
  1752. if let columnName = cursorTopic.columnName(for: columnIndex) {
  1753. if let value = cursorTopic.object(forColumn: columnName) {
  1754. if columnName == "name" {
  1755. dataTempTopic[columnName] = "\(name_group) (\(value))"
  1756. } else if columnName == "image" {
  1757. dataTempTopic[columnName] = "\(value)".isEmpty ? image_group : "\(value)"
  1758. if let imageString = dataTempTopic[columnName] as? String, !imageString.isEmpty {
  1759. do {
  1760. let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
  1761. let file = documentDir.appendingPathComponent(imageString)
  1762. if FileManager().fileExists(atPath: file.path) {
  1763. if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
  1764. let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
  1765. if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
  1766. try? FileManager.default.copyItem(at: file, to: sharedFileURL)
  1767. }
  1768. }
  1769. }
  1770. } catch {
  1771. }
  1772. }
  1773. } else {
  1774. dataTempTopic[columnName] = value
  1775. }
  1776. dataTempTopic["type"] = 1
  1777. }
  1778. }
  1779. }
  1780. dataShared.append(dataTempTopic)
  1781. }
  1782. cursorTopic.close()
  1783. }
  1784. }
  1785. cursor.close()
  1786. }
  1787. do {
  1788. let jsonData = try JSONSerialization.data(withJSONObject: dataShared, options: .prettyPrinted)
  1789. if let jsonString = String(data: jsonData, encoding: .utf8) {
  1790. userDefaults.set(jsonString, forKey: "shareContacts")
  1791. userDefaults.synchronize()
  1792. }
  1793. } catch {
  1794. print("Error converting to JSON: \(error)")
  1795. }
  1796. })
  1797. }
  1798. }
  1799. }
  1800. public static func setCheckEmulator(isActive: Bool) {
  1801. // Utils.bCheckEmulator = isActive
  1802. }
  1803. public static func setCheckRootedDevice(isActive: Bool) {
  1804. // Utils.bCheckRooted = isActive
  1805. }
  1806. public static func setPreventScreenCapture(isActive: Bool) {
  1807. // Utils.bPreventScreenCapture = isActive
  1808. }
  1809. public static func setNameGroupShare(_ name: String) {
  1810. nameGroupShared = name
  1811. }
  1812. public static func openImageNexilis(image: UIImage, data: Data? = nil, isGIF: Bool = false) {
  1813. let previewImageVC = PreviewAttachmentImageVideo(nibName: "PreviewAttachmentImageVideo", bundle: Bundle.resourceBundle(for: Nexilis.self))
  1814. previewImageVC.image = image
  1815. previewImageVC.isHiddenTextField = true
  1816. previewImageVC.isGIF = isGIF
  1817. previewImageVC.dataGIF = data
  1818. previewImageVC.modalPresentationStyle = .custom
  1819. previewImageVC.modalTransitionStyle = .crossDissolve
  1820. if UIApplication.shared.visibleViewController?.navigationController != nil {
  1821. UIApplication.shared.visibleViewController?.navigationController?.present(previewImageVC, animated: true, completion: nil)
  1822. } else {
  1823. UIApplication.shared.visibleViewController?.present(previewImageVC, animated: true, completion: nil)
  1824. }
  1825. }
  1826. public static func openVideoNexilis(videoURL: URL) {
  1827. let player = AVPlayer(url: videoURL)
  1828. let playerVC = AVPlayerViewController()
  1829. playerVC.modalPresentationStyle = .custom
  1830. playerVC.player = player
  1831. if UIApplication.shared.visibleViewController?.navigationController != nil {
  1832. UIApplication.shared.visibleViewController?.navigationController?.present(playerVC, animated: true, completion: nil)
  1833. } else {
  1834. UIApplication.shared.visibleViewController?.present(playerVC, animated: true, completion: nil)
  1835. }
  1836. }
  1837. private static var appNm = "";
  1838. public static func getAppNm() -> String {
  1839. return appNm
  1840. }
  1841. private static var nameGroupShared = "group.nexilis.share";
  1842. public static func getnameGroupShared() -> String {
  1843. return nameGroupShared
  1844. }
  1845. }
  1846. extension UINavigationController {
  1847. func defaultStyle() {
  1848. self.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
  1849. self.modalPresentationStyle = .fullScreen
  1850. self.navigationBar.tintColor = .white
  1851. self.navigationBar.barTintColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
  1852. self.navigationBar.isTranslucent = false
  1853. self.navigationBar.overrideUserInterfaceStyle = .dark
  1854. self.navigationBar.barStyle = .black
  1855. let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
  1856. UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
  1857. let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
  1858. self.navigationBar.titleTextAttributes = textAttributes
  1859. }
  1860. }