| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150 |
- //
- // APIS.swift
- // NexilisLite
- //
- // Created by Akhmad Al Qindi Irsyam on 05/05/23.
- //
- import Foundation
- import UIKit
- import FMDB
- import NotificationBannerSwift
- import Toast_Swift
- import nuSDKService
- import AVFoundation
- import AVKit
- import Intents
- public class APIS: NSObject {
- private static var isAlertPresented = false
- private static var transitioningDelegateRef: ZoomTransitioningDelegate?
- public static func connect(appName: String, apiKey: String, userName: String = "", delegate: ConnectDelegate, showButton: Bool = true, fromMAB: Bool = false) {
- APIS.appNm = appName.trimmingCharacters(in: .whitespacesAndNewlines)
- Nexilis.connect(apiKey: apiKey, userId: userName, delegate: delegate, showButton: showButton, fromMAB: fromMAB)
- }
-
- public static func getTotalCounter() -> Int32 {
- var counter: Int32?
- Database.shared.database?.inTransaction({ (fmdb, rollback) in
- do {
- let query = """
- select SUM(counter) as total_counter
- from (
- select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m, BUDDY b
- where ms.l_pin = b.f_pin and ms.message_id = m.message_id and m.is_call_center = 0
- union all
- select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m
- where ms.l_pin = '-999' and ms.message_id = m.message_id
- union all
- select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m
- where ms.l_pin = '-997' and ms.message_id = m.message_id
- union all
- select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m, GROUPZ b
- where ms.l_pin = b.group_id and ms.message_id = m.message_id and m.is_call_center = 0
- union all
- select ms.counter from MESSAGE_SUMMARY ms, MESSAGE m, DISCUSSION_FORUM b, GROUPZ c
- 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
- ) as subquery
- """
- if let cursor = Database.shared.getRecords(fmdb: fmdb, query: query), cursor.next() {
- counter = cursor.int(forColumnIndex: 0)
- cursor.close()
- }
- } catch {
- rollback.pointee = true
- print("Access database error: \(error.localizedDescription)")
- }
- })
- return counter ?? 0
- }
-
- private static func showChangeProfile() {
- guard !isAlertPresented else { return }
- isAlertPresented = true
- let alert = LibAlertController(title: "Set Profile".localized(), message: "You must set your profile to use this feature".localized(), preferredStyle: .alert)
- alert.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: {(_) in
- isAlertPresented = false
- guard let controller = APIS.getControllerSign() else { return }
- if let controller = controller as? SignUpSignIn {
- controller.forceLogin = true
- } else if let controller = controller as? SignInOption {
- controller.forceLogin = true
- }
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }))
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(alert, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(alert, animated: true, completion: nil)
- }
- }
-
- public static func openContactCenter(media: Int? = nil, category: Int? = nil) {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if !Nexilis.checkingAccess(key: "call_center") {
- if Nexilis.checkingAccessAlert(key: "call_center") != "|" && !Nexilis.checkingAccessAlert(key: "call_center").isEmpty {
- let title = Nexilis.checkingAccessAlert(key: "call_center").components(separatedBy: "|")[0]
- let message = Nexilis.checkingAccessAlert(key: "call_center").components(separatedBy: "|")[1]
- APIS.nexilisShowAlertWithHTMLMessage(on: UIApplication.shared.visibleViewController ?? UIViewController(), title: title, message: message)
- } else {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- }
- return
- }
- if User.isCallCenter(userType: (User.getData(pin: User.getMyPin())?.userType)!) {
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "myHistoryCC") as! HistoryCCViewController
- controller.isOfficer = true
- controller.fromAPI = true
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.setNavigationBarHidden(false, animated: false)
- navigationController.navigationBar.isTranslucent = false
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- } else {
- if media != nil || (media == nil && category != nil) {
- if media == nil || media! < 0 || media! > 2 {
- UIApplication.shared.visibleViewController?.view.makeToast("108:Invalid Contact Center media parameter (0:Chat, 1:Audio Call, 2:Video Call)".localized(), duration: 3)
- return
- }
- }
- if category != nil {
- if category != 0 {
- let service = CategoryCC.getDataFromServiceId(service_id: "\(category!)")
- if service == nil {
- UIApplication.shared.visibleViewController?.view.makeToast("109:Invalid Contact Center category parameter".localized(), duration: 3)
- return
- }
- let serviceChilds = CategoryCC.getDatafromParent(parent: service!.service_id)
- if serviceChilds.count > 0 {
- UIApplication.shared.visibleViewController?.view.makeToast("109:Invalid Contact Center category parameter".localized(), duration: 3)
- return
- }
- }
- }
- let isWaitingRequestCC: Bool = SecureUserDefaults.shared.value(forKey: "waitingRequestCC") ?? false
- if isWaitingRequestCC {
- let imageView = UIImageView(image: UIImage(systemName: "info.circle"))
- imageView.tintColor = .white
- 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)
- banner.show()
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
- controller.isContactCenter = true
- if media != nil {
- controller.isDirectCC = true
- controller.channelContactCenter = "\(media!)"
- controller.serviceIdCC = category == nil ? "" : "\(category!)"
- }
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
- }
-
- public static func openContactCenterWithContext(context: String) {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if !Nexilis.checkingAccess(key: "call_center") {
- if Nexilis.checkingAccessAlert(key: "call_center") != "|" && !Nexilis.checkingAccessAlert(key: "call_center").isEmpty {
- let title = Nexilis.checkingAccessAlert(key: "call_center").components(separatedBy: "|")[0]
- let message = Nexilis.checkingAccessAlert(key: "call_center").components(separatedBy: "|")[1]
- APIS.nexilisShowAlertWithHTMLMessage(on: UIApplication.shared.visibleViewController ?? UIViewController(), title: title, message: message)
- } else {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- }
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
- controller.isContactCenter = true
- controller.contextCC = context
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openUrl(url: String) {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let controller = BNIBookingWebView()
- controller.customUrl = url
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openNotificationCenter() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if !Nexilis.checkingAccess(key: "notification_center") {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- return
- }
- let controller = HistoryBroadcastViewController()
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openChat(withoutUCList: Bool = false) {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let navigationController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactChatNav") as! UINavigationController
- Utils.addBackground(view: navigationController.view)
- let vc = navigationController.topViewController as! ContactChatViewController
- vc.noUCList = withoutUCList
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openSmartChatbot() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let smartChatVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "chatGptVC") as! ChatGPTBotView
- smartChatVC.hidesBottomBarWhenPushed = true
- let navigationController = CustomNavigationController(rootViewController: smartChatVC)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func startChat(name: String) {
- if name.isEmpty {
- UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 2)
- return
- }
- let user = User.getDataFromNameCanNil(name: name)
- if user == nil {
- UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
- return
- }
- let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
- editorPersonalVC.hidesBottomBarWhenPushed = true
- editorPersonalVC.unique_l_pin = user!.pin
- editorPersonalVC.fromNotification = true
- let navigationController = CustomNavigationController(rootViewController: editorPersonalVC)
- navigationController.modalPresentationStyle = .fullScreen
- navigationController.navigationBar.tintColor = .white
- navigationController.navigationBar.barTintColor = UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
- navigationController.navigationBar.isTranslucent = false
- navigationController.navigationBar.overrideUserInterfaceStyle = .dark
- navigationController.navigationBar.barStyle = .black
- let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
- UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
- let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
- navigationController.navigationBar.titleTextAttributes = textAttributes
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openCall() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID")
- let navigationController = CustomNavigationController(rootViewController: callContact)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openStreaming() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if !Nexilis.checkingAccess(key: "live_streaming") {
- if Nexilis.checkingAccessAlert(key: "live_streaming") != "|" && !Nexilis.checkingAccessAlert(key: "live_streaming").isEmpty {
- let title = Nexilis.checkingAccessAlert(key: "live_streaming").components(separatedBy: "|")[0]
- let message = Nexilis.checkingAccessAlert(key: "live_streaming").components(separatedBy: "|")[1]
- APIS.nexilisShowAlertWithHTMLMessage(on: UIApplication.shared.visibleViewController ?? UIViewController(), title: title, message: message)
- } else {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- }
- return
- }
- let navigationController = CustomNavigationController(rootViewController: QmeraCreateStreamingViewController())
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openConference() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if !Nexilis.checkingAccess(key: "vconf_room") {
- if Nexilis.checkingAccessAlert(key: "vconf_room") != "|" && !Nexilis.checkingAccessAlert(key: "vconf_room").isEmpty {
- let title = Nexilis.checkingAccessAlert(key: "vconf_room").components(separatedBy: "|")[0]
- let message = Nexilis.checkingAccessAlert(key: "vconf_room").components(separatedBy: "|")[1]
- APIS.nexilisShowAlertWithHTMLMessage(on: UIApplication.shared.visibleViewController ?? UIViewController(), title: title, message: message)
- } else {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- }
- return
- }
- let navigationController = CustomNavigationController(rootViewController: CreateSeminarViewController())
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openAudioCall() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if !Nexilis.checkingAccess(key: "audio_call") {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- return
- }
- let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
- callContact.onlyAudioOrVideo = 1
- let navigationController = CustomNavigationController(rootViewController: callContact)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func startAudioCall(name: String) {
- if name.isEmpty {
- UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 3)
- return
- }
- if !Nexilis.checkingAccess(key: "audio_call") {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- return
- }
- let user = User.getDataFromNameCanNil(name: name)
- if user == nil {
- UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
- return
- }
- if !CheckConnection.isConnectedToNetwork() {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- return
- }
- let controller = QmeraAudioViewController()
- controller.user = user
- controller.isOutgoing = true
- controller.modalPresentationStyle = .overFullScreen
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
- }
- }
-
- public static func openVideoCall() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if !Nexilis.checkingAccess(key: "video_call") {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- return
- }
- let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
- callContact.onlyAudioOrVideo = 2
- let navigationController = CustomNavigationController(rootViewController: callContact)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func startVideoCall(name: String) {
- if name.isEmpty {
- UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 3)
- return
- }
- if !Nexilis.checkingAccess(key: "video_call") {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- return
- }
- let user = User.getDataFromNameCanNil(name: name)
- if user == nil {
- UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
- return
- }
- if !CheckConnection.isConnectedToNetwork() {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- return
- }
- let videoVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
- var data: [String: String?] = [:]
- data["f_pin"] = user!.pin
- data["name"] = user!.fullName
- data["picture"] = user!.thumb
- data["isOfficial"] = user!.official
- data["deviceId"] = user!.device_id
- data["isOffline"] = user!.offline_mode
- data["user_type"] = user!.userType
- videoVC.dataPerson.append(data)
- videoVC.isPresent = true
- videoVC.modalPresentationStyle = .overFullScreen
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(videoVC, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(videoVC, animated: true, completion: nil)
- }
- }
-
- public static func openBroadcastForm() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if !Nexilis.checkingAccess(key: "broadcast_message") {
- UIApplication.shared.visibleViewController?.view.makeToast("Feature disabled".localized(), duration: 5)
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "broadcastNav")
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
- }
- }
-
- public static func openConversation() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let navigationController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactChatNav") as! UINavigationController
- Utils.addBackground(view: navigationController.view)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openFavoriteMessage() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let editorStaredVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "staredVC") as! EditorStarMessages
- editorStaredVC.fromNotification = true
- let navigationController = CustomNavigationController(rootViewController: editorStaredVC)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openSecureFolder() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "secureFolderView") as! SecureFolderViewController
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- /*
- 0
- Success
- 1
- Invalid PIN/Password
- 2
- Auth Failure
- 3
- Device Key Signature Mismatch
- 4
- Policy Level Not Met
- 5
- PPKey Generated Failed
- 6
- Challenge-Response Failed
- 7
- TOTOP Mismatch
- 9
- Server Error Code
- 10
- Invalid Face ID or Face ID mismatch
- 11
- Invalid Fingerprint
- 12
- Invalid SIM Card does not match the one registered in our system
- 13
- Unable to access servers. Check your internet connection and try again later
- 99
- Back / Cancel
- */
- private static var mfaCallback: ((Int) -> Void)?
-
- private static var methodSetted = ""
- public static func setTxnAuthActivity(activity: String) {
- methodSetted = activity
- }
- static func getMFACallback() -> ((Int) -> Void)? {
- return mfaCallback
- }
-
- static func setMFACallback(mfaCallback: @escaping (Int) -> Void) {
- self.mfaCallback = mfaCallback
- }
-
- public static func signUp(userId: String, mfaCallback: @escaping (Int) -> Void) {
- self.mfaCallback = mfaCallback
- let method = "Sign Up"
- let policyLevel = Utils.getSignUpLevel()
- // print("signUp: \(policyLevel)")
- signUpSignInMFA(method: method, userId: userId, policyLevel: policyLevel)
- }
-
- public static func signIn(userId: String, mfaCallback: @escaping (Int) -> Void) {
- self.mfaCallback = mfaCallback
- let method = "Sign In"
- let policyLevel = Utils.getSignInLevel()
- // print("signIn: \(policyLevel)")
- signUpSignInMFA(method: method, userId: userId, policyLevel: policyLevel)
- }
-
- public static func txnAuth(userId: String, txnId: String, amount: Double, mfaCallback: @escaping (Int) -> Void) {
- self.mfaCallback = mfaCallback
- var method = "Transaction"
- if !methodSetted.isEmpty {
- method = methodSetted
- }
- var dataTxn = Utils.getTxnLevel()
- dataTxn = dataTxn.replacingOccurrences(of: "\\\"", with: "\"")
- .replacingOccurrences(of: "\"[", with: "[")
- .replacingOccurrences(of: "]\"", with: "]")
- var policyLevel = "1,2"
- // print("txnAuth: \(dataTxn)")
- if !dataTxn.isEmpty {
- if let data = dataTxn.data(using: .utf8) {
- do {
- // Parse to generic JSON array
- if let jsonArray = try JSONSerialization.jsonObject(with: data, options: []) as? [[String: Any]] {
- for json in jsonArray {
- let min = json["min"] as? Double ?? 0
- let max = json["max"] as? Double ?? 0
- let policy = json["policy"] as? String ?? ""
- if max == -1 {
- if amount >= min {
- policyLevel = policy
- break
- }
- } else {
- if amount >= min && amount <= max {
- policyLevel = policy
- break
- }
- }
- }
- openMFA(method: method, flag: policyLevel)
- }
- } catch {
- print("Error converting string to JSONArray:", error)
- }
- }
- }
- }
-
- private static func signUpSignInMFA(method: String, userId: String, policyLevel: String) {
- Nexilis.showLoader()
- DispatchQueue.global().async {
- var id = ""
- if Utils.isMiddleMode() || Utils.isHSAMode() {
- id = Nexilis.justInit()
- } else {
- id = User.getMyPin() ?? ""
- }
- if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignUpSignInAPI(p_name: userId, p_password: "", xPin: id), timeout: 15 * 1000) {
- if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- let errMessage = "Invalid user / Username and password does not match".localized()
- UIApplication.shared.visibleViewController?.view.makeToast(errMessage, duration: 3)
- APIS.getMFACallback()?(2)
- }
- }
- } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- let errMessage = "Failed, unknown user".localized()
- UIApplication.shared.visibleViewController?.view.makeToast(errMessage, duration: 3)
- APIS.getMFACallback()?(2)
- }
- }
- } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "4u" {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- let errMessage = "Failed, blocked user".localized()
- UIApplication.shared.visibleViewController?.view.makeToast(errMessage, duration: 3)
- APIS.getMFACallback()?(2)
- }
- }
- } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "13" {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- let errMessage = "Failed, This user is not registered on this device".localized()
- UIApplication.shared.visibleViewController?.view.makeToast(errMessage, duration: 3)
- APIS.getMFACallback()?(2)
- }
- }
- } else if !response.isOk() {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- let errMessage = "Failed".localized()
- UIApplication.shared.visibleViewController?.view.makeToast(errMessage, duration: 3)
- APIS.getMFACallback()?(2)
- }
- }
- } else {
- if Database.shared.openDatabase() == 0 {
- APIS.showRestartApp()
- KeyManagerNexilis.deleteKey()
- KeyManagerNexilis.deleteMarker()
- return
- }
- let sign = response.getBody(key: CoreMessage_TMessageKey.SIGN, default_value: "")
- if sign == "1" {
- let id = response.getBody(key: CoreMessage_TMessageKey.F_PIN, default_value: "")
- let f_pin = response.getBody(key: CoreMessage_TMessageKey.F_PIN_REAL, default_value: "")
- let device_id = response.getBody(key: CoreMessage_TMessageKey.IMEI, default_value: id)
- let last_sign = response.getBody(key: CoreMessage_TMessageKey.LAST_SIGN, default_value: "0")
- if last_sign != "0" {
- Utils.setLoginMultipleFPin(value: f_pin)
- DispatchQueue.main.async {
- let errMessage = "Multiple Login Detected...".localized()
- UIApplication.shared.visibleViewController?.view.makeToast(errMessage, duration: 3)
- if Nexilis.showFB {
- Nexilis.floatingButton.removeFromSuperview()
- FloatingButton.datePull = nil
- Nexilis.floatingButton = FloatingButton()
- Nexilis.addFB()
- }
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
- let dialog = DialogUnableAccess()
- dialog.modalTransitionStyle = .crossDissolve
- dialog.modalPresentationStyle = .overCurrentContext
- UIApplication.shared.visibleViewController?.present(dialog, animated: true)
- })
- }
- return
- }
- DispatchQueue.main.async {
- UIApplication.shared.visibleViewController?.deleteAllRecordDatabase()
- }
- if(!id.isEmpty) {
- SecureUserDefaults.shared.set(device_id, forKey: "device_id")
- Utils.setProfile(value: true)
- // pos registration
- _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
- DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
- Nexilis.hideLoader(completion: {
- if Nexilis.showFB {
- Nexilis.floatingButton.removeFromSuperview()
- FloatingButton.datePull = nil
- Nexilis.floatingButton = FloatingButton()
- Nexilis.addFB()
- }
- Nexilis.getFeatureAccess()
- openMFA(method: method, flag: policyLevel)
- })
- })
- }
- } else {
- let idMe = User.getMyPin()!
- _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: idMe))
- Utils.setProfile(value: true)
- DispatchQueue.main.async {
- Nexilis.hideLoader(completion: {
- openMFA(method: method, flag: policyLevel)
- })
- }
- }
- }
- } else {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- let errMessage = "Unable to access servers. Check your internet connection and try again later".localized()
- UIApplication.shared.visibleViewController?.view.makeToast(errMessage, duration: 3)
- APIS.getMFACallback()?(13)
- }
- }
- }
- }
- }
-
- private static func openMFA(method: String, flag: String) {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- if flag == MFAViewController.STEP_FIDO || flag == MFAViewController.STEP_FIDO_BIOFACE || flag == MFAViewController.STEP_FIDO_BIOFINGER {
- checkFidoWithOrBIO(method: method, flag: flag)
- } else {
- let controller = MFAViewController()
- controller.METHOD = method
- controller.STEP_NEEDED = flag
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
-
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
- }
-
- private static func checkFidoWithOrBIO(method: String, flag: String) {
- DispatchQueue.global().async {
- if let me = User.getMyPin() {
- do {
- let message = CoreMessage_TMessageBank.getMFAValidation(data: me)
- var hasKey = false
- if !KeyManagerNexilis.hasGeneratedKey() {
- KeyManagerNexilis.generateKey()
- KeyManagerNexilis.saveMarker()
- } else {
- hasKey = true
- }
- guard let privateKey = KeyManagerNexilis.getPrivateKey(useBiometric: false) else {
- KeyManagerNexilis.deleteKey()
- KeyManagerNexilis.deleteMarker()
- DispatchQueue.main.async {
- let errorMessage = "PPKey Generated Failed".localized()
- let dialog = DialogErrorMFA()
- dialog.modalTransitionStyle = .crossDissolve
- dialog.modalPresentationStyle = .overCurrentContext
- dialog.errorDesc = errorMessage
- dialog.method = method
- UIApplication.shared.visibleViewController?.present(dialog, animated: true)
- APIS.getMFACallback()?(5)
- }
- return
- }
- var id = ""
- if Utils.isMiddleMode() || Utils.isHSAMode() {
- id = Nexilis.justInit()
- } else {
- id = User.getMyPin() ?? ""
- }
- if let response = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getChalanger(xPin: id)) {
- if response.isOk() {
- let data = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "")
- if data.isEmpty {
- KeyManagerNexilis.deleteKey()
- KeyManagerNexilis.deleteMarker()
- DispatchQueue.main.async {
- let errorMessage = "Auth Failure".localized()
- let dialog = DialogErrorMFA()
- dialog.modalTransitionStyle = .crossDissolve
- dialog.modalPresentationStyle = .overCurrentContext
- dialog.errorDesc = errorMessage
- dialog.method = method
- UIApplication.shared.visibleViewController?.present(dialog, animated: true)
- APIS.getMFACallback()?(2)
- }
- return
- }
- let df = HMACDeviceFingerprintNexilis.generate()
- message.mBodies[CoreMessage_TMessageKey.FINGERPRINT] = df
- if hasKey {
- var sign = ""
- if let dataSign = "\(data)!\(df)".data(using: .utf8) {
- if let signature = KeyManagerNexilis.sign(data: dataSign, privateKey: privateKey) {
- sign = signature.base64EncodedString()
- }
- }
- message.mBodies[CoreMessage_TMessageKey.SIGNATURE] = sign
- } else {
- if let publicKey = KeyManagerNexilis.getRSAX509PublicKeyBase64(privateKey: privateKey) {
- message.mBodies[CoreMessage_TMessageKey.PUBLIC_KEY] = publicKey
- }
- }
- // let secret = "JBSWY3DPEHPK3PXP" // Google Authenticator example
- let otp = try TOTPGenerator.generateTOTP(base32Secret: TOTPGenerator.getTOTP(), digits: 6, timeStepSeconds: 300)
- message.mBodies[CoreMessage_TMessageKey.TOTP] = otp
- if let response = Nexilis.writeAndWait(message: message) {
- if response.isOk() {
- if flag == MFAViewController.STEP_FIDO_BIOFACE || flag == MFAViewController.STEP_FIDO_BIOFINGER {
- let semaphore = DispatchSemaphore(value: 0)
- var result = true
- var stateErr = 0
- let manager = BiometricStateManager()
- if method == "Sign Up" {
- manager.authenticateAndSaveState { res in
- result = res
- semaphore.signal()
- }
- } else {
- manager.hasBiometricStateChanged { (res, state) in
- result = res
- stateErr = state
- semaphore.signal()
- }
- }
-
- semaphore.wait()
- if result {
- DispatchQueue.main.async {
- UIApplication.shared.visibleViewController?.view.makeToast("Successfully Authenticated".localized(), duration: 3)
- }
- APIS.getMFACallback()?(0)
- } else {
- KeyManagerNexilis.deleteKey()
- KeyManagerNexilis.deleteMarker()
- DispatchQueue.main.async {
- var errorMessage = "Gagal mendeteksi Biometric (Touch/Face ID)"
- var errCode = 10
- if stateErr == 1 {
- errorMessage = "Terjadi Perubahan Biometric (Touch/Face ID)"
- errCode = 14
- }
- let dialog = DialogErrorMFA()
- dialog.modalTransitionStyle = .crossDissolve
- dialog.modalPresentationStyle = .overCurrentContext
- dialog.errorDesc = errorMessage
- dialog.method = method
- dialog.hideTryAgain = (stateErr == 1)
- dialog.isDismiss = { res in
- if res == 0 {
- APIS.logOut()
- APIS.getMFACallback()?(errCode)
- }
- }
- UIApplication.shared.visibleViewController?.present(dialog, animated: true)
- }
- }
- } else {
- DispatchQueue.main.async {
- UIApplication.shared.visibleViewController?.view.makeToast("Successfully Authenticated".localized(), duration: 3)
- }
- APIS.getMFACallback()?(0)
- }
- }
- else {
- KeyManagerNexilis.deleteKey()
- KeyManagerNexilis.deleteMarker()
- let errorMessage = response.getBody(key: CoreMessage_TMessageKey.MESSAGE_TEXT, default_value: "Auth Failure".localized())
- let errCode = response.getBodyAsInteger(key: CoreMessage_TMessageKey.ERRAPICOD, default_value: 2)
- DispatchQueue.main.async {
- let dialog = DialogErrorMFA()
- dialog.modalTransitionStyle = .crossDissolve
- dialog.modalPresentationStyle = .overCurrentContext
- dialog.errorDesc = errorMessage
- dialog.method = method
- UIApplication.shared.visibleViewController?.present(dialog, animated: true)
- APIS.getMFACallback()?(errCode)
- }
- }
- } else {
- KeyManagerNexilis.deleteKey()
- KeyManagerNexilis.deleteMarker()
- DispatchQueue.main.async {
- let errorMessage = "Unable to access servers. Check your internet connection and try again later".localized()
- let dialog = DialogErrorMFA()
- dialog.modalTransitionStyle = .crossDissolve
- dialog.modalPresentationStyle = .overCurrentContext
- dialog.errorDesc = errorMessage
- dialog.method = method
- UIApplication.shared.visibleViewController?.present(dialog, animated: true)
- APIS.getMFACallback()?(13)
- }
- }
- }
- } else {
- KeyManagerNexilis.deleteKey()
- KeyManagerNexilis.deleteMarker()
- DispatchQueue.main.async {
- let errorMessage = "Unable to access servers. Check your internet connection and try again later".localized()
- let dialog = DialogErrorMFA()
- dialog.modalTransitionStyle = .crossDissolve
- dialog.modalPresentationStyle = .overCurrentContext
- dialog.errorDesc = errorMessage
- dialog.method = method
- UIApplication.shared.visibleViewController?.present(dialog, animated: true)
- APIS.getMFACallback()?(13)
- }
- }
- } catch {
- }
- }
- }
- }
-
- public static func setFloatingButton(isShow: Bool) {
- DispatchQueue.main.async {
- Nexilis.floatingButton.removeFromSuperview()
- FloatingButton.datePull = nil
- if isShow {
- Nexilis.floatingButton = FloatingButton()
- Nexilis.addFB()
- }
- }
- }
-
- public static func openSecureBrowser() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let controller = BNIBookingWebView()
- controller.isSecureBrowser = true
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func createCommunity() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let startedNewCommunity = UIViewController()
- if let viewComm = startedNewCommunity.view {
- viewComm.backgroundColor = .black.withAlphaComponent(0.1)
-
- let containerView = UIView()
- viewComm.addSubview(containerView)
- containerView.anchor(left: viewComm.leftAnchor, bottom: viewComm.bottomAnchor, right: viewComm.rightAnchor, minHeight: 40)
- containerView.backgroundColor = .white
- containerView.layer.cornerRadius = 15
- containerView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
-
- let closeButton = UIButton(type: .close)
- containerView.addSubview(closeButton)
- closeButton.anchor(top: containerView.topAnchor, right: containerView.rightAnchor, paddingTop: 10, paddingRight: 10, width: 30, height: 30)
- closeButton.layer.cornerRadius = 15
- closeButton.clipsToBounds = true
- closeButton.backgroundColor = .lightGray.withAlphaComponent(0.1)
- let config = UIImage.SymbolConfiguration(pointSize: 18, weight: .semibold)
- closeButton.setImage(UIImage(systemName: "xmark", withConfiguration: config), for: .normal)
- closeButton.addAction(UIAction { _ in
- startedNewCommunity.dismiss(animated: true)
- }, for: .touchUpInside)
-
- let imageComm = UIImageView(image: UIImage(named: "pb_community_social", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
- containerView.addSubview(imageComm)
- imageComm.anchor(top: closeButton.bottomAnchor, paddingTop: -40, centerX: containerView.centerXAnchor, width: 350, height: 250)
-
- let titleComm = UILabel()
- containerView.addSubview(titleComm)
- titleComm.anchor(top: imageComm.bottomAnchor, left: containerView.leftAnchor, right: containerView.rightAnchor, paddingLeft: 20, paddingRight: 20)
- titleComm.font = .boldSystemFont(ofSize: 30)
- titleComm.textColor = .label
- titleComm.numberOfLines = 0
- titleComm.textAlignment = .center
- titleComm.text = "Create a new community".localized()
-
- let descComm = UILabel()
- containerView.addSubview(descComm)
- descComm.anchor(top: titleComm.bottomAnchor, left: containerView.leftAnchor, right: containerView.rightAnchor, paddingTop: 8, paddingLeft: 20, paddingRight: 20)
- descComm.font = .systemFont(ofSize: 16)
- descComm.textColor = .label
- descComm.numberOfLines = 0
- descComm.textAlignment = .center
- descComm.text = "Bring together a neighborhood, school or more. Create topic-based groups for members, and easily send them admin anouncements.".localized()
-
- let buttonComm = UIButton(type: .custom)
- containerView.addSubview(buttonComm)
- buttonComm.anchor(top: descComm.bottomAnchor, left: containerView.leftAnchor, bottom: containerView.bottomAnchor, right: containerView.rightAnchor, paddingTop: 20, paddingLeft: 20, paddingBottom: 20, paddingRight: 20, height: 45)
- buttonComm.backgroundColor = .whatsappGreenColor
- buttonComm.layer.cornerRadius = 15
- buttonComm.clipsToBounds = true
- buttonComm.setTitle("Get started".localized(), for: .normal)
- buttonComm.setTitleColor(.white, for: .normal)
- buttonComm.titleLabel?.font = .systemFont(ofSize: 16, weight: .medium)
- buttonComm.addAction(UIAction { _ in
- startedNewCommunity.dismiss(animated: true) {
- let navigationController = UINavigationController(rootViewController: CommunityNew())
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }, for: .touchUpInside)
- }
- startedNewCommunity.modalPresentationStyle = .overCurrentContext
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(startedNewCommunity, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(startedNewCommunity, animated: true, completion: nil)
- }
- }
-
- public static func openCreateGroup() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "createGroupNav") as! UINavigationController
- Utils.addBackground(view: controller.view)
- let vc = controller.topViewController as! GroupCreateViewController
- vc.isDismiss = { id in
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "groupDetailView") as! GroupDetailViewController
- controller.data = id
- controller.fromNotification = true
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- })
- }
- controller.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
- }
- }
-
- public static func openAddFriend() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "addFriendNav") as! UINavigationController
- Utils.addBackground(view: controller.view)
- controller.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
- }
- }
-
- public static func openSignUpOrSignIn() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- guard let controller = APIS.getControllerSign() else { return }
- if let controller = controller as? SignUpSignIn {
- controller.forceLogin = true
- } else if let controller = controller as? SignInOption {
- controller.forceLogin = true
- }
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openSetting() {
- let navigationController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "settingNav") as! UINavigationController
- let vc = navigationController.rootViewController as! SettingTableViewController
- vc.fromAPI = true
- Utils.addBackground(view: navigationController.view)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController is UINavigationController && (UIApplication.shared.visibleViewController as! UINavigationController).rootViewController is SettingTableViewController {
- return
- }
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openProfile() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
- controller.data = User.getMyPin()!
- controller.flag = .me
- controller.fromAPI = true
- controller.dismissImage = { image, imageName in
- var dataImage: [AnyHashable : Any] = [:]
- dataImage["name"] = imageName
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
- }
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openChatWallpaper(){
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "chatWallpaper") as! ChatWallpaperViewController
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func openWhiteboard() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
- callContact.startWhiteBoard = true
- let navigationController = CustomNavigationController(rootViewController: callContact)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func startWhiteboard(name: String) {
- if name.isEmpty {
- UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 3)
- return
- }
- let user = User.getDataFromNameCanNil(name: name)
- if user == nil {
- UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
- return
- }
- if !CheckConnection.isConnectedToNetwork() {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- return
- }
- let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "wbVC") as! WhiteboardViewController
- controller.modalPresentationStyle = .overFullScreen
- controller.fromContact = 0
- controller.user = user
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
- }
- }
-
- // public static func openScreenSharing() {
- // let isChangeProfile = Utils.getSetProfile()
- // if !isChangeProfile {
- // APIS.showChangeProfile()
- // return
- // }
- // let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
- // callContact.startSS = true
- // let navigationController = CustomNavigationController(rootViewController: callContact)
- // navigationController.defaultStyle()
- // if UIApplication.shared.visibleViewController?.navigationController != nil {
- // UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- // } else {
- // UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- // }
- // }
-
- public static func startScreenSharing(name: String) {
- if name.isEmpty {
- UIApplication.shared.visibleViewController?.view.makeToast("92:Username is empty".localized(), duration: 3)
- return
- }
- let user = User.getDataFromNameCanNil(name: name)
- if user == nil {
- UIApplication.shared.visibleViewController?.view.makeToast("91:Invalid name or you must add Username to your contact first".localized(), duration: 3)
- return
- }
- if !CheckConnection.isConnectedToNetwork() {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- return
- }
- let controller = ScreenSharingViewController()
- controller.modalPresentationStyle = .overFullScreen
- controller.fromContact = 0
- controller.user = user
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
- }
- }
-
- public static func openWhiteboardAndScreenSharing() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let callContact = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "contactSID") as! ContactCallViewController
- callContact.startSS = true
- callContact.startWhiteBoard = true
- let navigationController = CustomNavigationController(rootViewController: callContact)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func signInAdmin(password: String) {
- if password.isEmpty {
- UIApplication.shared.visibleViewController?.view.makeToast("113:Password is empty".localized(), duration: 3)
- return
- }
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let isAdmin = User.isAdmin()
- if isAdmin {
- UIApplication.shared.visibleViewController?.view.makeToast("112:You already login or registered as Admin".localized(), duration: 3)
- return
- }
- if !CheckConnection.isConnectedToNetwork() || API.nGetCLXConnState() == 0 {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- return
- }
- Nexilis.showLoader()
- self.signInAdmin(password: password, completion: { result in
- if result {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- }
- }
- } else {
- DispatchQueue.main.async {
- Nexilis.hideLoader {}
- }
- }
- })
- }
-
- private static func signInAdmin(password: String, completion: @escaping (Bool) -> ()) {
- DispatchQueue.global().async {
- let idMe = User.getMyPin() as String?
- let p_password = password
- let md5Hex = p_password
- var result: Bool = false
- if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignInApiAdmin(p_name: idMe!, p_password: md5Hex)) {
- if response.isOk() {
- result = true
- }
- DispatchQueue.main.async {
- if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "20" {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- }
- }
- } else {
- DispatchQueue.main.async {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- }
- }
- completion(result)
- }
- }
-
- public static func openSetAsOfficerForm() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let isAdmin = User.isAdmin()
- if !isAdmin {
- UIApplication.shared.visibleViewController?.view.makeToast("111:You must Sign In as Admin to use this feature".localized(), duration: 3)
- return
- }
- let controller = SetInternalCSAccount()
- controller.isSetCS = true
- controller.fromNotification = true
- let navigationController = CustomNavigationController(rootViewController: controller)
- navigationController.defaultStyle()
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
-
- public static func logOut() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- Nexilis.destroyAll()
- _ = Nexilis.write(message: CoreMessage_TMessageBank.getLogout())
- }
-
- public static func openPPOB() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let idx = Nexilis.IDX_PPOB
- let url = getURLFB(idx: idx)
- Nexilis.buttonClicked(index: idx, id: url)
- }
-
- public static func openWallet() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let idx = Nexilis.IDX_WALLET
- let url = getURLFB(idx: idx)
- Nexilis.buttonClicked(index: idx, id: url)
- }
-
- public static func openSocialCommerce() {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let idx = Nexilis.IDX_SOCIAL_COMMERCE
- let url = getURLFB(idx: idx)
- Nexilis.buttonClicked(index: idx, id: url)
- }
-
- private static func getURLFB(idx: Int) -> String {
- let data = Utils.getHistoryPullFB()
- if !data.isEmpty {
- if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
- let filteredData = jsonArray.filter({
- let package_id = ($0["package_id"] as! String)
- if package_id.contains("_fb") {
- let listSplit = package_id.split(separator: "_", maxSplits: 2, omittingEmptySubsequences: false).map { String($0) }
- let numIdx = listSplit[listSplit.firstIndex(where: { $0.contains("fb") }) ?? 0]
- let indexTap = Int(String(numIdx).substring(from: 2, to: numIdx.count)) ?? 0
- return indexTap == idx
- }
- return package_id.isEmpty
- })
- if filteredData.count != 0 {
- let data = filteredData[0] as? [String: Any]
- let package_id = data?["package_id"] as! String
- let listSplit = package_id.split(separator: "_", maxSplits: 2, omittingEmptySubsequences: false).map { String($0) }
- return String(listSplit[2])
- }
- }
- }
- return ""
- }
-
- public static func sendSMS(phoneNumber: String, message: String = ""){
- let formattedNumber = phoneNumber.replacingOccurrences(of: "-", with: "")
- let urlStringEncoded = message.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
- let paramMessage = message.isEmpty ? "" : "&body=\(urlStringEncoded!)"
- let url = URL(string: "sms:\(formattedNumber)\(paramMessage)")
- if UIApplication.shared.canOpenURL(url!) {
- UIApplication.shared.open(url!)
- }
- }
-
- public static func sendWhatsapp(phoneNumber: String, message: String = "") {
- let formattedNumber = phoneNumber.replacingOccurrences(of: "+", with: "").replacingOccurrences(of: "-", with: "")
- let urlStringEncoded = message.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)
- let paramMessage = message.isEmpty ? "" : "?text=\(urlStringEncoded!)"
- let url = URL(string: "https://wa.me/\(formattedNumber)\(paramMessage)")
- if UIApplication.shared.canOpenURL(url!) {
- UIApplication.shared.open(url!, options: [:]) { (success) in
- // if success {
- // //print("WhatsApp accessed successfully")
- // } else {
- // //print("Error accessing WhatsApp")
- // }
- }
- }
- }
-
- public static func changeUsername(uname: String) {
- let isChangeProfile = Utils.getSetProfile()
- if !isChangeProfile {
- APIS.showChangeProfile()
- return
- }
- let finalUname = uname.replacingOccurrences(of: "[\\n\\r\\t~%()\"]", with: "", options: .regularExpression)
- if finalUname == User.getData(pin: User.getMyPin())?.fullName {
- UIApplication.shared.visibleViewController?.view.makeToast("102:Duplicate username".localized(), duration: 3)
- return
- }
- if finalUname.count == 0 {
- UIApplication.shared.visibleViewController?.view.makeToast("103:Username is empty".localized(), duration: 3)
- return
- }
- if finalUname.count < 3 {
- UIApplication.shared.visibleViewController?.view.makeToast("104:Username length is too short".localized(), duration: 3)
- return
- }
- let a = finalUname.split(separator: " ", maxSplits: 1)
- let first = String(a[0])
- let last = a.count == 2 ? String(a[1]) : ""
- DispatchQueue.global().async {
- if let resp = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getChangePersonInfoName(firstname: first, lastname: last)) {
- if resp.isOk() {
- Database.shared.database?.inTransaction({ fmdb, rollback in
- do {
- _ = Database.shared.updateRecord(fmdb: fmdb, table: "BUDDY", cvalues: ["first_name": first , "last_name": last], _where: "f_pin = '\(User.getMyPin())'")
- } catch {
- rollback.pointee = true
- print("Access database error: \(error.localizedDescription)")
- }
- })
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- }
- }
- } else if resp.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "1a" {
- DispatchQueue.main.async {
- let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
- imageView.tintColor = .white
- 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)
- banner.show()
- }
- }
- }
- }
- }
-
- public static func openMail() {
- Nexilis.openmailAction()
- }
-
- public static func sendPushToken(_ token: String, isResend: Bool = false, isCall: Bool = false) {
- if !isCall {
- if Utils.getTokenAPN().isEmpty || token != Utils.getTokenAPN() {
- Utils.setTokenAPN(value: token)
- }
- DispatchQueue.global().async {
- while API.nGetCLXConnState() == 0 {
- Thread.sleep(forTimeInterval: 1)
- }
- _ = Nexilis.write(message: CoreMessage_TMessageBank.getToken(token: token, tokenCall: Utils.getTokenCall()))
- }
- }
- else {
- if Utils.getTokenCall().isEmpty || token != Utils.getTokenCall() {
- Utils.setTokenCall(value: token)
- }
- // DispatchQueue.global().async {
- // while API.nGetCLXConnState() == 0 {
- // Thread.sleep(forTimeInterval: 1)
- // }
- // print("SEND TOKEN CALL")
- // _ = Nexilis.write(message: CoreMessage_TMessageBank.getToken(token: token, isCall: true))
- // }
- }
- }
-
- public static var uuidCall: UUID?
- public static var fpinCall: String?
- public static func showNotificationNexilis(_ userInfo: [AnyHashable : Any]) {
- DispatchQueue.main.async {
- if checkAppStateisBackground() {
- DispatchQueue.global(qos: .background).async {
- if let payload = userInfo["payload"] as? [String: Any] {
- if let messagePayload = payload["message"] as? [String: Any] {
- if let data = messagePayload["data"] as? [String: Any] {
- let code = data["nx_code"] as? String ?? ""
- if code == "CL01" {
- if let message = data["bodies"] as? [String: String] {
- let idAck = data["message_id"] as? String ?? ""
- let messageToSave = TMessage()
- messageToSave.mBodies = message
- do {
- var messageExist = false
- Database.shared.database?.inTransaction({ (fmdb, rollback) in
- if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select message_id from MESSAGE where message_id = '\(message[CoreMessage_TMessageKey.MESSAGE_ID] ?? "")'"), cursor.next() {
- messageExist = true
- cursor.close()
- }
- })
- if messageExist {
- ackAPN(id: idAck)
- return
- }
- } catch {
- print("error saving message: \(error)")
- }
- APIS.addNotificationNexilis(messageToSave)
- ackAPN(id: idAck)
- Nexilis.saveMessage(message: messageToSave, withStatus: false, fromAPNS: true)
- }
- } else if code == "CL03" {
- let callFromName = data["call-from-name"] as? String ?? ""
- let callFrom = data["call-from"] as? String ?? ""
- let callType = data["call-type"] as? String ?? ""
- // uuidCall = UUID()
- fpinCall = callFrom
- Nexilis.callAPNActivated = true
- let center = UNUserNotificationCenter.current()
- let content = UNMutableNotificationContent()
- content.title = callFromName
- if callType == "1" {
- content.body = "Incoming Audio Call".localized()
- } else {
- content.body = "Incoming Video Call".localized()
- }
- content.userInfo = ["id" : callFrom, "type" : code, "callType": callType]
- content.sound = nil
- let request = UNNotificationRequest(identifier: callFrom, content: content, trigger: nil)
- center.add(request) { error in
- if let error = error {
- print("Error scheduling notification: \(error.localizedDescription)")
- }
- }
- let session = AVAudioSession.sharedInstance()
- do {
- try session.setCategory(.playback, options: [.duckOthers])
- try session.setActive(true)
- } catch {
- print("Audio session error: \(error)")
- }
- Nexilis.playRingtoneCall()
- } else if code == "CL02" {
- print("data \(data)")
- let callFromName = data["call-cancel-name"] as? String ?? ""
- let callFrom = data["call-cancel"] as? String ?? ""
- let callType = data["call-type"] as? String ?? ""
- // if let uuidCall = uuidCall {
- Nexilis.stopRingtoneCall()
- Nexilis.callAPNActivated = false
- let center = UNUserNotificationCenter.current()
- center.removeDeliveredNotifications(withIdentifiers: [callFrom])
- var textCall = ""
- if callType == "1" {
- textCall = "audio"
- } else {
- textCall = "video"
- }
- let content = UNMutableNotificationContent()
- content.title = callFromName
- content.body = "☎️ Missed \(textCall) call".localized()
- content.userInfo = ["id" : callFrom, "type" : code, "callType": callType]
- content.sound = nil
- let request = UNNotificationRequest(identifier: callFrom, content: content, trigger: nil)
- center.add(request) { error in
- if let error = error {
- print("Error scheduling notification: \(error.localizedDescription)")
- }
- }
- 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)
- }
- }
- }
- } else if let message_id = userInfo["message_id"] as? String {
- DispatchQueue.main.async {
- let lastBadgeNumber = UIApplication.shared.applicationIconBadgeNumber
- UIApplication.shared.applicationIconBadgeNumber = lastBadgeNumber + 1
- }
- getMessageById(id: message_id)
- }
- }
- }
- }
- }
-
- public static func showNotificationCallKitNexilis(payload: [AnyHashable : Any], completion: @escaping () -> ()) {
- if let messagePayload = payload["payload"] as? [String: Any] {
- if let message = messagePayload["message"] as? [String: Any] {
- if let data = message["data"] as? [String: Any] {
- let nxCode = data["nx_code"] as? String ?? ""
- let callFromName = data["call-from-name"] as? String ?? ""
- let callCancelName = data["call-cancel-name"] as? String ?? ""
- let callFrom = data["call-from"] as? String ?? ""
- let callCancel = data["call-cancel"] as? String ?? ""
- let callType = data["call-type"] as? String ?? ""
- if nxCode == "CL03" {
- Nexilis.callAPNActivated = true
- APIS.uuidCall = UUID()
- CallManager.shared.reportIncomingCall(uuid: APIS.uuidCall ?? UUID(), callerName: callFromName, callerId: callFrom, isVideo: callType != "1")
- } else {
- if APIS.uuidCall != nil {
- CallManager.shared.endCall(uuid: APIS.uuidCall!) {
- Nexilis.callAPNActivated = false
- APIS.uuidCall = nil
- let center = UNUserNotificationCenter.current()
- var textCall = ""
- if callType == "1" {
- textCall = "audio"
- } else {
- textCall = "video"
- }
- let content = UNMutableNotificationContent()
- content.title = callCancelName
- content.body = "☎️ Missed \(textCall) call".localized()
- content.userInfo = ["id" : callFrom, "type" : nxCode, "callType": callType]
- content.sound = nil
- let request = UNNotificationRequest(identifier: callCancel, content: content, trigger: nil)
- center.add(request) { error in
- if let error = error {
- print("Error scheduling notification: \(error.localizedDescription)")
- }
- }
- 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)
- }
- } else if UIApplication.shared.visibleViewController is QmeraAudioViewController || UIApplication.shared.visibleViewController is QmeraVideoViewController {
- var dataMessage: [AnyHashable : Any] = [:]
- dataMessage["call_cancel"] = true
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: Nexilis.callFCM), object: nil, userInfo: dataMessage)
- }
- }
- }
- }
- }
- }
-
- static func ackAPN(id: String) {
- DispatchQueue.global(qos: .background).async {
- // Nexilis.sendStateToServer(s: "send ack from apn")
- // if API.nGetCLXConnState() == 0 {
- // do {
- // let id = Utils.getConnectionID()
- // try API.initConnection(sAPIK: Nexilis.sAPIKey, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: id, sStartWH: "09:00")
- // } catch {}
- // }
- // while API.nGetCLXConnState() == 0 {
- // Thread.sleep(forTimeInterval: 0.5)
- // }
- // let _ = Nexilis.writeSync(message: CoreMessage_TMessageBank.getAckMessage(messageId: id), timeout: 30000)
-
- //HTTPS
- let parameter: [String : Any] = [
- "pin": User.getMyPin() ?? "",
- "message_id": id
- ]
- Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "ack_message")!, parameter: parameter, isFormData: true) { data, response, error in
- }
- }
- }
-
- private static func getMessageById(id: String, retry: Int = 0) {
- // if API.nGetCLXConnState() == 0 {
- // do {
- // let id = Utils.getConnectionID()
- // try API.initConnection(sAPIK: Nexilis.sAPIKey, cbiI: Callback(), sTCPAddr: Nexilis.ADDRESS, nTCPPort: Nexilis.PORT, sUserID: id, sStartWH: "09:00")
- // } catch {}
- // }
- // while API.nGetCLXConnState() == 0 {
- // Thread.sleep(forTimeInterval: 0.5)
- // }
- // if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getMessageById(messageId: id), timeout: 30000) {
- // if response.isOk() {
- // let data = response.getBody(key: CoreMessage_TMessageKey.DATA)
- // if let decodedData = Data(base64Encoded: data, options: .ignoreUnknownCharacters) {
- // if let respData = String(data: decodedData, encoding: .utf8) {
- // let message = TMessage(data: respData)
- // if Utils.getSecureFolderOffline() == "0" && IncomingThread.dispatch == nil {
- // if FileEncryption.shared.aesKey == nil {
- // IncomingThread.dispatch = DispatchGroup()
- // IncomingThread.dispatch?.enter()
- // Nexilis.getFeatureAccess()
- // IncomingThread.dispatch?.wait()
- // IncomingThread.dispatch = nil
- // }
- // }
- //// print("save from APIS")
- // Nexilis.saveMessage(message: message, withStatus: false, fromAPNS: true)
- // ackAPN(id: id)
- // DispatchQueue.main.async {
- // UIApplication.shared.applicationIconBadgeNumber = Int(APIS.getTotalCounter())
- // }
- // }
- // }
- // } else {
- // let ret = retry + 1
- // if ret <= 5 {
- // getMessageById(id: id, retry: ret)
- // }
- // }
- // } else {
- // let ret = retry + 1
- // if ret <= 5 {
- // getMessageById(id: id, retry: ret)
- // }
- // }
- //HTTPS
- let parameter: [String : Any] = [
- "pin": User.getMyPin() ?? "",
- "message_id": id
- ]
- Utils.postDataWithCookiesAndUserAgent(from: URL(string: Utils.getDomainOpr() + "pull_notification")!, parameter: parameter, isFormData: true) { data, response, error in
- if let error = error {
- print("Error: \(error.localizedDescription)")
- let ret = retry + 1
- if ret <= 5 {
- let delay = pow(2.0, Double(ret)) // 2, 4, 8, 16...
- DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + delay) {
- getMessageById(id: id, retry: ret)
- }
- }
- return
- }
-
- guard let data = data else {
- let ret = retry + 1
- if ret <= 5 {
- DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 1) {
- getMessageById(id: id, retry: ret)
- }
- }
- return
- }
- DispatchQueue.main.async {
- if !APIS.checkAppStateisBackground() {
- return
- }
- do {
- if let jsonObj = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
- let dataObj = jsonObj["data"] as? String ?? ""
- let message = TMessage(data: dataObj)
-
- // simpan message
- Nexilis.saveMessage(message: message, withStatus: false, fromAPNS: true)
- ackAPN(id: id)
-
- DispatchQueue.main.async {
- UIApplication.shared.applicationIconBadgeNumber = Int(APIS.getTotalCounter())
- }
- } else {
- throw NSError(domain: "Invalid JSON", code: -1)
- }
- } catch {
- print("Parsing error: \(error)")
- let ret = retry + 1
- if ret <= 5 {
- DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
- getMessageById(id: id, retry: ret)
- }
- }
- }
- }
- }
- }
-
- public static func addNotificationNexilis(_ message: TMessage) {
- var text = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_TEXT)
- text = text.toNormalString()
- let nameUser = message.getBody(key: CoreMessage_TMessageKey.F_DISPLAY_NAME)
- var threadIdentifier = message.getBody(key: CoreMessage_TMessageKey.OPPOSITE_PIN)
- let scope = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_SCOPE_ID)
- if threadIdentifier.isEmpty {
- if scope == "4" {
- threadIdentifier = message.getBody(key: CoreMessage_TMessageKey.CHAT_ID).isEmpty ? message.getBody(key: CoreMessage_TMessageKey.L_PIN) : message.getBody(key: CoreMessage_TMessageKey.CHAT_ID)
- } else {
- threadIdentifier = message.getBody(key: CoreMessage_TMessageKey.F_PIN)
- }
- }
- let messageId = message.getBody(key: CoreMessage_TMessageKey.MESSAGE_ID)
- var nameSubtitle = ""
- let imageId = CoreMessage_TMessageKey.IMAGE_ID
- let videoId = CoreMessage_TMessageKey.VIDEO_ID
- let fileId = CoreMessage_TMessageKey.FILE_ID
- let audioId = CoreMessage_TMessageKey.AUDIO_ID
- let attachmentFlag = CoreMessage_TMessageKey.ATTACHMENT_FLAG
- let messageScopeId = CoreMessage_TMessageKey.MESSAGE_SCOPE_ID
- let credential = CoreMessage_TMessageKey.CREDENTIAL
- let gif_id = CoreMessage_TMessageKey.GIF_ID
- let is_secret = CoreMessage_TMessageKey.IS_SECRET
- if message.getBody(key: is_secret) == "1" {
- text = "You got messages..."
- } else if message.getBody(key: gif_id) != "" {
- text = "Sent GIF 🎬"
- } else if !message.getBody(key: imageId).isEmpty {
- text = "Sent Image 📷"
- } else if message.getBody(key: attachmentFlag) == "11" {
- text = "Sent Sticker ❤️"
- } else if !message.getBody(key: videoId).isEmpty {
- text = "Sent Video 📹"
- } else if !message.getBody(key: fileId).isEmpty {
- if message.getBody(key: messageScopeId) == "18" {
- text = "Sent Form 📄"
- } else {
- text = "Sent File 📄"
- }
- } else if !message.getBody(key: audioId).isEmpty {
- text = "Sent Audio ♫"
- } else if text.contains("Share%20location%20") {
- text = "Sent Location 📌"
- } else if message.getBody(key: attachmentFlag) == "27" {
- text = "Sent Live Streaming"
- } else if message.getBody(key: attachmentFlag) == "26" {
- text = "Sent Seminar"
- } else if message.getBody(key: attachmentFlag) == "25" {
- text = "Sent Video Conference Room"
- } else if message.getBody(key: attachmentFlag) == "24" {
- text = "Sent Quiz"
- } else if message.getBody(key: credential) == "1" {
- text = "Sent Confidential Message"
- }
- var type = "1"
- var nameTopic = "Lounge".localized()
- var idGroup = ""
- if scope == "3" || scope == "18" || scope == "5"{
- type = "0"
- }
- var soundId: String = SecureUserDefaults.shared.value(forKey: "newNotifSoundPersonal") ?? "001:Nexilis Message (Default)"
- if type == "1" {
- Database.shared.database?.inTransaction({ (fmdb, rollback) in
- do {
- if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT title, group_id FROM DISCUSSION_FORUM WHERE chat_id='\(threadIdentifier)'"), cursor.next() {
- nameTopic = cursor.string(forColumnIndex: 0) ?? ""
- idGroup = cursor.string(forColumnIndex: 1) ?? ""
- cursor.close()
- }
- if idGroup.isEmpty {
- idGroup = threadIdentifier
- }
- if let cursorGroup = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_name, image_id FROM GROUPZ WHERE group_id='\(idGroup)'"), cursorGroup.next() {
- let nameGroup = cursorGroup.string(forColumnIndex: 0) ?? ""
- nameSubtitle = "\(nameGroup) (\(nameTopic))"
- cursorGroup.close()
- }
- } catch {
- rollback.pointee = true
- print("Access database error: \(error.localizedDescription)")
- }
- })
- soundId = SecureUserDefaults.shared.value(forKey: "newNotifSoundGroup") ?? "001:Nexilis Message (Default)"
- if idGroup.isEmpty {
- return
- }
- }
- var nameSound = soundId.components(separatedBy: ":")[1].replacingOccurrences(of: " ", with: "_")
- var fromPref = false
- if nameSound.contains("_(Default)") {
- if !Utils.getDefaultIncomingMsg().isEmpty {
- nameSound = Utils.getDefaultIncomingMsg()
- fromPref = true
- } else {
- nameSound = nameSound.replacingOccurrences(of: "_(Default)", with: "")
- }
- }
- copySoundToLocalPath(nameSound, fromPref)
- let center = UNUserNotificationCenter.current()
- let content = UNMutableNotificationContent()
- content.title = nameUser
- if type == "1" {
- content.body = text.richText(group_id: idGroup).string
- content.subtitle = nameSubtitle
- } else {
- content.body = text.richText().string
- }
- content.userInfo = ["id" : threadIdentifier, "type" : type]
- content.sound = UNNotificationSound(named: UNNotificationSoundName("\(nameSound).mp3"))
- let request = UNNotificationRequest(identifier: messageId, content: content, trigger: nil)
- center.add(request) { error in
- if let error = error {
- print("Error scheduling notification: \(error.localizedDescription)")
- }
- }
- DispatchQueue.main.async {
- UIApplication.shared.applicationIconBadgeNumber = Int(APIS.getTotalCounter())
- }
- }
-
- private static func copySoundToLocalPath(_ nameSound: String, _ fromPref: Bool) {
- var sourceURL: URL?
- if fromPref {
- let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
- let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
- let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
- if let dirPath = paths.first {
- let audioURL = URL(fileURLWithPath: dirPath).appendingPathComponent(nameSound)
- if FileManager.default.fileExists(atPath: audioURL.path) {
- sourceURL = audioURL
- } else if FileEncryption.shared.isSecureExists(filename: nameSound) {
- do {
- if var audioData = try FileEncryption.shared.readSecure(filename: nameSound) {
- let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: audioData)
- if dataDecrypt != nil {
- audioData = dataDecrypt!
- }
- let cachesDirectory = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first!
- let tempPath = cachesDirectory.appendingPathComponent(nameSound)
- try audioData.write(to: tempPath)
- sourceURL = tempPath
- }
- } catch {
-
- }
- } else {
- sourceURL = Bundle.resourceBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
- if sourceURL == nil {
- sourceURL = Bundle.resourcesMediaBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
- }
- }
- }
- } else {
- sourceURL = Bundle.resourceBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
- if sourceURL == nil {
- sourceURL = Bundle.resourcesMediaBundle(for: Nexilis.self).url(forResource: nameSound, withExtension: "mp3")
- }
- }
- if sourceURL == nil {
- return
- }
- let fileManager = FileManager.default
- let soundDirectory = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Sounds", isDirectory: true)
- if !fileManager.fileExists(atPath: soundDirectory.path) {
- do {
- try fileManager.createDirectory(at: soundDirectory, withIntermediateDirectories: true, attributes: nil)
- } catch {
- print("Error creating Sounds directory: \(error)")
- return
- }
- }
- let destinationURL = soundDirectory.appendingPathComponent("\(nameSound).mp3")
- if !fileManager.fileExists(atPath: destinationURL.path) {
- do {
- try fileManager.copyItem(at: sourceURL!, to: destinationURL)
- } catch {
-
- }
- }
- }
-
- public static func openNotificationNexilis(_ response: UNNotificationResponse) {
- DispatchQueue.main.async{
- if let userInfo = response.notification.request.content.userInfo as? [String: String] {
- let id = userInfo["id"] ?? ""
- let type = userInfo["type"] ?? ""
- let callType = userInfo["callType"] ?? ""
- if let navigationC = UIApplication.shared.visibleViewController as? UINavigationController {
- if navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorPersonal || navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorGroup {
- navigationC.popViewController(animated: true)
- }
- }
- showEditorOrCallFromAPN(id, type, callType)
- } else {
- let userInfo = response.notification.request.content.userInfo
- DispatchQueue.main.async {
- if let message_id = userInfo[CoreMessage_TMessageKey.MESSAGE_ID] as? String {
- var f_pin = ""
- var l_pin = ""
- var message_scope_id = ""
- var pin = ""
- var chat_id = ""
- Database.shared.database?.inTransaction({ (fmdb, rollback) in
- 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() {
- f_pin = cursor.string(forColumnIndex: 0) ?? ""
- l_pin = cursor.string(forColumnIndex: 1) ?? ""
- message_scope_id = cursor.string(forColumnIndex: 2) ?? ""
- chat_id = cursor.string(forColumnIndex: 3) ?? ""
- pin = f_pin == User.getMyPin() ? l_pin : f_pin
- if message_scope_id == "4" {
- pin = chat_id.isEmpty ? l_pin : chat_id
- }
- cursor.close()
- }
- })
- if let navigationC = UIApplication.shared.visibleViewController as? UINavigationController {
- if navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorPersonal || navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorGroup {
- navigationC.popViewController(animated: false)
- }
- }
- showEditorOrCallFromAPN(pin, message_scope_id == "4" ? "1" : !message_scope_id.isEmpty ? "0" : "", "CL01")
- }
- }
- }
- }
- // UNUserNotificationCenter.current().removeAllDeliveredNotifications()
- }
-
- private static func showEditorOrCallFromAPN(_ id: String, _ type: String, _ callType: String) {
- if type.isEmpty {
- return
- }
- if type == "0" {
- if User.getDataCanNil(pin: id) == nil && id != "-999" && id != "-997" {
- return
- }
- let editorPersonalVC = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "editorPersonalVC") as! EditorPersonal
- editorPersonalVC.hidesBottomBarWhenPushed = true
- editorPersonalVC.unique_l_pin = id
- editorPersonalVC.fromNotification = true
- let navigationController = CustomNavigationController(rootViewController: editorPersonalVC)
- navigationController.modalPresentationStyle = .fullScreen
- navigationController.navigationBar.tintColor = .white
- navigationController.navigationBar.barTintColor = UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
- navigationController.navigationBar.isTranslucent = false
- navigationController.navigationBar.overrideUserInterfaceStyle = .dark
- navigationController.navigationBar.barStyle = .black
- let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
- UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
- let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
- navigationController.navigationBar.titleTextAttributes = textAttributes
- if UIApplication.shared.visibleViewController is UINavigationController && Nexilis.fromMAB {
- editorPersonalVC.fromNotification = false
- UIApplication.shared.visibleViewController?.show(editorPersonalVC, sender: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- } else if type == "1" {
- var groupExist = false
- Database.shared.database?.inTransaction({ (fmdb, rollback) in
- var idGroup = ""
- if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT title, group_id FROM DISCUSSION_FORUM WHERE chat_id='\(id)'"), cursor.next() {
- groupExist = true
- cursor.close()
- } else {
- if idGroup.isEmpty {
- idGroup = id
- }
- if let cursorGroup = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_name, image_id FROM GROUPZ WHERE group_id='\(idGroup)'"), cursorGroup.next() {
- groupExist = true
- cursorGroup.close()
- }
- }
- })
- if !groupExist {
- return
- }
- let editorGroupVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "editorGroupVC") as! EditorGroup
- editorGroupVC.hidesBottomBarWhenPushed = true
- editorGroupVC.unique_l_pin = id
- editorGroupVC.fromNotification = true
- let navigationController = CustomNavigationController(rootViewController: editorGroupVC)
- navigationController.modalPresentationStyle = .fullScreen
- navigationController.navigationBar.tintColor = .white
- navigationController.navigationBar.barTintColor = UIApplication.shared.visibleViewController?.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
- navigationController.navigationBar.isTranslucent = false
- navigationController.navigationBar.overrideUserInterfaceStyle = .dark
- navigationController.navigationBar.barStyle = .black
- let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
- UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
- let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
- navigationController.navigationBar.titleTextAttributes = textAttributes
- if UIApplication.shared.visibleViewController is UINavigationController && Nexilis.fromMAB {
- editorGroupVC.fromNotification = false
- UIApplication.shared.visibleViewController?.show(editorGroupVC, sender: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- } else if type == "CL03" {
- Nexilis.stopRingtoneCall()
- if !Nexilis.callAPNActivated {
- return
- }
- if callType == "1" {
- if let user = User.getData(pin: id), user.firstName == "User".localized() {
- return
- }
- let controller = QmeraAudioViewController()
- controller.isOutgoing = false
- controller.user = User.getData(pin: id)
- controller.autoAcceptAPN = true
- controller.modalPresentationStyle = .overCurrentContext
- if UIApplication.shared.visibleViewController is UIAlertController {
- let vc = UIApplication.shared.visibleViewController as! UIAlertController
- vc.dismiss(animated: true, completion: {
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
- }
- })
- return
- }
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(controller, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(controller, animated: true, completion: nil)
- }
- } else {
- if let user = User.getData(pin: id), user.firstName == "User".localized() {
- return
- }
- let videoController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
- videoController.fPin = id
- videoController.isInisiator = false
- videoController.autoAcceptAPN = true
- let navigationController = CustomNavigationController(rootViewController: videoController)
- navigationController.modalPresentationStyle = .fullScreen
- if UIApplication.shared.visibleViewController is UIAlertController {
- let vc = UIApplication.shared.visibleViewController as! UIAlertController
- vc.dismiss(animated: true, completion: {
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- })
- return
- }
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
- }
- }
- }
- }
- // public static func checkClone(window: inout UIWindow?) {
- // CloneCheck.enforceAllChecks(window: &window)
- // }
-
- public static func checkAppStateisBackground() -> Bool {
- let state = UIApplication.shared.applicationState
-
- switch state {
- case .active:
- return false
- case .inactive:
- return false
- case .background:
- return true
- @unknown default:
- return false
- }
- }
-
- public static func enterBackground() {
- // if !API.bAVisOngoing() {
- // API.deinitConnection()
- // }
- notifTimer.invalidate()
- stopNotif = true
- if Utils.getSecureFolderOffline() == "0" {
- Database.shared.database = nil
- FileEncryption.shared.aesKey = nil
- FileEncryption.shared.aesIV = nil
- }
- FloatingButton.datePull = nil
- }
-
- public static var notifTimer = Timer()
- public static var stopNotif = false
- public static var afterEnterBackground = false
- public static func enterForeground() {
- APIS.checkNotificationPermission(completion: { isAllowed in
- if !isAllowed {
- showEnableNotificationsAlert()
- } else {
- UIApplication.shared.registerForRemoteNotifications()
- }
- })
- DispatchQueue.main.async {
- stopNotif = true
- self.notifTimer = Timer.scheduledTimer(withTimeInterval: 30, repeats: false) { _ in
- stopNotif = false
- }
- if !Utils.isHSAMode() && !Utils.isMiddleMode(){
- _ = Nexilis.justInit(isChecking: true)
- }
- }
- checkDataForShareExtension()
- UIApplication.shared.applicationIconBadgeNumber = 0
- UNUserNotificationCenter.current().removeAllDeliveredNotifications()
- if Utils.getSecureFolderOffline() == "0" && afterEnterBackground && Database.shared.database == nil && Utils.getSetProfile() && !Utils.isHSAMode() {
- Database.recreateInstance()
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: "disconnected_nexilis"), object: nil, userInfo: nil)
- if let navigationC = UIApplication.shared.visibleViewController as? UINavigationController {
- if navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorPersonal || navigationC.viewControllers[navigationC.viewControllers.count - 1] is EditorGroup {
- navigationC.popViewController(animated: true)
- }
- }
- // Nexilis.getFeatureAccessWithKey(key: ["secure_folder_encrypt_key", "secure_folder_encrypt_iv", "secure_folder_offline"])
- Nexilis.getFeatureAccess()
- }
- if (FloatingButton.datePull == nil || !afterEnterBackground) && Utils.getSetProfile() {
- DispatchQueue.global().async {
- while API.nGetCLXConnState() == 0 || User.getMyPin() == nil {
- Thread.sleep(forTimeInterval: 0.5)
- }
- if let vers = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.checkVersion()) {
- let dataVersion = vers.getBody(key: CoreMessage_TMessageKey.DATA)
- let type = vers.getBody(key: CoreMessage_TMessageKey.TYPE)
- if dataVersion != "1" {
- DispatchQueue.main.async {
- showExpiredVersion(mandatory: type == "1")
- }
- }
- }
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: "checkNewMessagesNexilis"), object: nil, userInfo: nil)
- }
-
- DispatchQueue.global(qos: .userInitiated).async {
- if Utils.shouldRequestAuthentication() && Utils.getSetProfile() && (Utils.isMiddleMode() || Utils.isHSAMode()) && Nexilis.hasInit {
- DispatchQueue.main.async {
- var viewController = UIApplication.shared.windows.first?.rootViewController
- var notNull = false
- while !notNull {
- viewController = UIApplication.shared.windows.first?.rootViewController
- if viewController != nil {
- notNull = true
- }
- }
- Nexilis.showPassSignIn()
- }
- }
- }
- }
- afterEnterBackground = true
- }
-
- public static func willEnterForeground() {
- // if APIS.uuidCall != nil {
- // CallManager.shared.endCall(uuid: APIS.uuidCall!) {
- // APIS.uuidCall = nil
- // }
- // }
- }
-
- private static func checkNotificationPermission(completion: @escaping (Bool) -> Void) {
- let center = UNUserNotificationCenter.current()
-
- center.getNotificationSettings { settings in
- DispatchQueue.main.async {
- switch settings.authorizationStatus {
- case .authorized, .provisional, .notDetermined:
- completion(true) // Notifications are allowed
- case .denied, .ephemeral:
- completion(false) // Notifications are disabled or not requested
- @unknown default:
- completion(false)
- }
- }
- }
- }
-
- public static func nexilisShowAlertWithHTMLMessage(on viewController: UIViewController, title: String, message: String = "<b>Bold</b> and <i>italic</i> text in an alert") {
- let alert = UIAlertController(title: title, message: "", preferredStyle: .alert)
-
- let titleFont = UIFont.boldSystemFont(ofSize: 16)
- let titleAttributes = [NSAttributedString.Key.font: titleFont]
- alert.setValue(NSAttributedString(string: title, attributes: titleAttributes), forKey: "attributedTitle")
-
- var message = message
- message = message.replacingOccurrences(of: "<b>", with: "*")
- message = message.replacingOccurrences(of: "</b>", with: "*")
- message = message.replacingOccurrences(of: "<i>", with: "_")
- message = message.replacingOccurrences(of: "</i>", with: "_")
-
- alert.setValue(message.richText(fontSize: 14), forKey: "attributedMessage")
-
- alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
- viewController.present(alert, animated: true, completion: nil)
- }
-
- static func showWarningFile(type: Int) {
- alertControllerExpired = LibAlertController(
- title: type == -1 ? "⚠️ Suspicious File Detected".localized() : "⚠️ Unrecognized File Type".localized(),
- message: type == -1 ? "The file appears to have a mismatched name and extension, which may indicate a malicious file. Please verify the file’s source and format before uploading it.".localized() : "The selected item is not listed in the system dashboard.".localized(),
- preferredStyle: .alert
- )
-
- alertControllerExpired.addAction(UIAlertAction(title: "OK".localized(), style: .default, handler: nil))
-
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(alertControllerExpired, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(alertControllerExpired, animated: true, completion: nil)
- }
- }
-
- static func showMessageGuardFile(mime: String) {
- alertControllerExpired = LibAlertController(
- title: "⚠️ Message Guard Announcement".localized(),
- message: mime == "image/jpeg" ? "Your image have been blocked by Message Guard. Please attach valid image.".localized() : "Your pdf file have been blocked by Message Guard. Please attach valid file.".localized() ,
- preferredStyle: .alert
- )
-
- alertControllerExpired.addAction(UIAlertAction(title: "OK".localized(), style: .default, handler: nil))
-
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(alertControllerExpired, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(alertControllerExpired, animated: true, completion: nil)
- }
- }
-
- private static func showEnableNotificationsAlert() {
- guard !isAlertPresented else { return }
- isAlertPresented = true
- let alertController = LibAlertController(
- title: "Enable Notification".localized(),
- message: "To stay updated, please enable notification in the Settings.".localized(),
- preferredStyle: .alert
- )
-
- alertController.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: { _ in
- isAlertPresented = false
- }))
-
- alertController.addAction(UIAlertAction(title: "Go to Settings".localized(), style: .default, handler: { _ in
- isAlertPresented = false
- openAppSettings()
- }))
-
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(alertController, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(alertController, animated: true, completion: nil)
- }
- }
-
- static func showRestartApp() {
- alertControllerExpired = LibAlertController(
- title: "Restart Required".localized(),
- message: "Oops! Something went wrong. Please restart the app to continue.".localized(),
- preferredStyle: .alert
- )
-
- alertControllerExpired.addAction(UIAlertAction(title: "OK".localized(), style: .default, handler: { _ in
- exit(0)
- }))
-
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(alertControllerExpired, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(alertControllerExpired, animated: true, completion: nil)
- }
- }
-
- private static var alertControllerExpired: LibAlertController!
- public static func showExpiredVersion(mandatory: Bool) {
- func showAl() {
- alertControllerExpired = LibAlertController(
- title: "Update Available".localized(),
- message: "A new version is now available. Please update to the latest version to enjoy new features and important improvements.".localized(),
- preferredStyle: .alert
- )
- if !mandatory {
- alertControllerExpired.addAction(UIAlertAction(title: "Later".localized(), style: .cancel, handler: nil))
- }
-
- alertControllerExpired.addAction(UIAlertAction(title: "Update Now".localized(), style: .default, handler: { _ in
- if APIS.appNm == "OneApp" {
- let appStoreURL = URL(string: "https://apps.apple.com/app/id6741251571")!
- UIApplication.shared.open(appStoreURL)
- } else {
- let appStoreURL = URL(string: "https://apps.apple.com/app/")!
- UIApplication.shared.open(appStoreURL)
- }
- }))
-
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(alertControllerExpired, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(alertControllerExpired, animated: true, completion: nil)
- }
- }
- if alertControllerExpired != nil {
- alertControllerExpired.dismiss(animated: true) {
- showAl()
- }
- } else {
- showAl()
- }
-
- }
-
- private static func openAppSettings() {
- if let settingsURL = URL(string: UIApplication.openSettingsURLString) {
- if UIApplication.shared.canOpenURL(settingsURL) {
- UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil)
- }
- }
- }
-
- public static func willTerminate() {
- Nexilis.destroyAll()
- }
-
- private static var isCheckingDataForShare = false
- public static func checkDataForShareExtension() {
- DispatchQueue.global().async {
- if let userDefaults = UserDefaults(suiteName: nameGroupShared) {
- if let value = userDefaults.string(forKey: "sharedItem") {
- if !value.isEmpty {
- if isCheckingDataForShare {
- return
- }
- isCheckingDataForShare = true
- if let jsonData = value.data(using: .utf8) {
- do {
- if let json = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String: Any] {
- let typeImage = 2
- let typeVideo = 3
- let typeFile = 4
- let typeAudio = 5
- let typeContact = json["typeContact"] as? String ?? "0"
- var data = json["data"] as? String ?? ""
- let idContact = json["idContact"] as? String ?? ""
- let typeShare = json["typeShare"] as? Int ?? 1
- var message = TMessage()
- var groupId = ""
- var chatId = ""
- let scopeId = typeContact == "1" ? "4" : "3"
- let thumb = json["thumb"] as? String ?? ""
- let imageId = json["image"] as? String ?? ""
- let videoId = json["video"] as? String ?? ""
- let fileId = json["file"] as? String ?? ""
- let audioId = json["audio"] as? String ?? ""
- var renamedFileId = ""
- var renamedAudioId = ""
- var attachmentFlag = ""
- if scopeId == "4" {
- Database.shared.database?.inTransaction({ (fmdb, rollback) in
- if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT group_id id FROM DISCUSSION_FORUM WHERE chat_id = '\(idContact)'"), cursor.next() {
- groupId = cursor.string(forColumnIndex: 0) ?? ""
- chatId = idContact
- cursor.close()
- } else {
- groupId = idContact
- }
- })
- }
- if typeShare == typeImage {
- attachmentFlag = "1"
- if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
- let sharedImageURL = appGroupURL.appendingPathComponent(imageId)
- let sharedThumbURL = appGroupURL.appendingPathComponent(thumb)
- if Nexilis.checkingAccess(key: "content_inspection") {
- DispatchQueue.main.async {
- Nexilis.showLoader(text: "Scanning File...".localized())
- }
- let result = sharedImageURL.validateFile()
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- if result == 1 {
- if copyData() {
- sendIt()
- }
- } else {
- APIS.showWarningFile(type: result)
- resetPrefs()
- }
- }
- }
- } else {
- if copyData() {
- sendIt()
- }
- }
- func copyData() -> Bool {
- var dataSanitized: Data!
- func sanitizeFile(sanitizeAction: (Data) -> MessageGuardLite.Result) -> Data? {
- DispatchQueue.main.async {
- Nexilis.showLoader(text: "Sanitizing your image (Message Guard)".localized())
- }
- let res = sanitizeAction(try! Data(contentsOf: sharedImageURL))
- defer {
- DispatchQueue.main.async { Nexilis.hideLoader {} }
- }
- if res.verdict == .block {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- APIS.showMessageGuardFile(mime: res.mime)
- }
- }
- return nil
- }
- return res.data ?? Data()
- }
- func processIt() {
- do {
- let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
- if FileManager.default.fileExists(atPath: sharedImageURL.path) {
- let file = documentDir.appendingPathComponent(imageId)
- if !FileManager().fileExists(atPath: file.path) {
- if dataSanitized != nil {
- let file = documentDir.appendingPathComponent(imageId)
- try? dataSanitized.write(to: file)
- } else {
- try? FileManager.default.copyItem(at: sharedImageURL, to: file)
- }
- }
- }
- if FileManager.default.fileExists(atPath: sharedThumbURL.path) {
- let file = documentDir.appendingPathComponent(thumb)
- if !FileManager().fileExists(atPath: file.path) {
- try? FileManager.default.copyItem(at: sharedThumbURL, to: file)
- }
- }
- } catch {
-
- }
- }
- if Nexilis.checkingAccess(key: "message_guard") {
- DispatchQueue.global().async {
- let guardLite = MessageGuardLite(limits: .defaults())
- if let sanitized = sanitizeFile(sanitizeAction: guardLite.sanitizeImage) {
- dataSanitized = sanitized
- } else { return }
- processIt()
- sendIt()
- }
- return false
- } else {
- processIt()
- return true
- }
- }
- }
- } else if typeShare == typeVideo {
- attachmentFlag = "2"
- if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
- let sharedVideoURL = appGroupURL.appendingPathComponent(videoId)
- let sharedThumbURL = appGroupURL.appendingPathComponent(thumb)
- if Nexilis.checkingAccess(key: "content_inspection") {
- DispatchQueue.main.async {
- Nexilis.showLoader(text: "Scanning File...".localized())
- }
- let result = sharedVideoURL.validateFile()
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- if result == 1 {
- copyData()
- sendIt()
- } else {
- APIS.showWarningFile(type: result)
- resetPrefs()
- }
- }
- }
- } else {
- copyData()
- sendIt()
- }
- func copyData() {
- do {
- let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
- if FileManager.default.fileExists(atPath: sharedVideoURL.path) {
- let file = documentDir.appendingPathComponent(videoId)
- if !FileManager().fileExists(atPath: file.path) {
- try? FileManager.default.copyItem(at: sharedVideoURL, to: file)
- }
- }
- if FileManager.default.fileExists(atPath: sharedThumbURL.path) {
- let file = documentDir.appendingPathComponent(thumb)
- if !FileManager().fileExists(atPath: file.path) {
- try? FileManager.default.copyItem(at: sharedThumbURL, to: file)
- }
- }
- } catch {
-
- }
- }
- }
- } else if typeShare == typeFile {
- attachmentFlag = "6"
- if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
- renamedFileId = "Nexilis_\(Date().currentTimeMillis())_" + fileId
- let sharedFileURL = appGroupURL.appendingPathComponent(fileId)
- if Nexilis.checkingAccess(key: "content_inspection") {
- DispatchQueue.main.async {
- Nexilis.showLoader(text: "Scanning File...".localized())
- }
- let result = sharedFileURL.validateFile()
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- if result == 1 {
- if copyData() {
- sendIt()
- }
- } else {
- APIS.showWarningFile(type: result)
- resetPrefs()
- }
- }
- }
- } else {
- if copyData() {
- sendIt()
- }
- }
- func copyData() -> Bool {
- var dataSanitized: Data!
- func sanitizeFile(sanitizeAction: (Data) -> MessageGuardLite.Result) -> Data? {
- DispatchQueue.main.async {
- Nexilis.showLoader(text: "Sanitizing your pdf file (Message Guard)".localized())
- }
- let res = sanitizeAction(try! Data(contentsOf: sharedFileURL))
- defer {
- DispatchQueue.main.async { Nexilis.hideLoader {} }
- }
- if res.verdict == .block {
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- APIS.showMessageGuardFile(mime: res.mime)
- }
- }
- return nil
- }
- return res.data ?? Data()
- }
-
- func processIt() {
- do {
- let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
- if FileManager.default.fileExists(atPath: sharedFileURL.path) {
- let file = documentDir.appendingPathComponent(renamedFileId)
- if !FileManager().fileExists(atPath: file.path) {
- if dataSanitized != nil {
- let file = documentDir.appendingPathComponent(renamedFileId)
- try? dataSanitized.write(to: file)
- } else {
- try? FileManager.default.copyItem(at: sharedFileURL, to: file)
- }
- }
- }
- data = "\(fileId)|\(data)"
- } catch {
-
- }
- }
-
- if Nexilis.checkingAccess(key: "message_guard") {
- DispatchQueue.global().async {
- let guardLite = MessageGuardLite(limits: .defaults())
- let mimeType = MessageGuardLite.sniffMime(try! Data(contentsOf: sharedFileURL))
- if mimeType == "application/pdf" {
- if let sanitized = sanitizeFile(sanitizeAction: guardLite.sanitizePdf) {
- dataSanitized = sanitized
- } else { return }
- }
- processIt()
- sendIt()
- }
- return false
- } else {
- processIt()
- return true
- }
- }
- }
- } else if typeShare == typeAudio {
- attachmentFlag = "5"
- if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
- renamedAudioId = "Nexilis_\(Date().currentTimeMillis())_" + audioId
- let sharedFileURL = appGroupURL.appendingPathComponent(audioId)
- if Nexilis.checkingAccess(key: "content_inspection") {
- DispatchQueue.main.async {
- Nexilis.showLoader(text: "Scanning File...".localized())
- }
- let result = sharedFileURL.validateFile()
- DispatchQueue.main.async {
- Nexilis.hideLoader {
- if result == 1 {
- copyData()
- sendIt()
- } else {
- APIS.showWarningFile(type: result)
- resetPrefs()
- }
- }
- }
- } else {
- copyData()
- sendIt()
- }
- func copyData() {
- do {
- let documentDir = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
- if FileManager.default.fileExists(atPath: sharedFileURL.path) {
- let file = documentDir.appendingPathComponent(renamedAudioId)
- if !FileManager().fileExists(atPath: file.path) {
- try? FileManager.default.copyItem(at: sharedFileURL, to: file)
- }
- }
- data = "\(audioId)|\(data)"
- } catch {
-
- }
- }
- }
- } else {
- sendIt()
- }
- func sendIt() {
- 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", specFile: "")
- Nexilis.addQueueMessage(message: message)
- resetPrefs()
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
- }
- func resetPrefs() {
- userDefaults.set("", forKey: "sharedItem")
- userDefaults.synchronize()
- isCheckingDataForShare = false
- }
- }
- } catch {
- print("Error parsing JSON: \(error)")
- }
- }
- }
- }
- }
- NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
- }
- }
-
- public static func setDataForShareExtension() {
- DispatchQueue.global().async {
- if let userDefaults = UserDefaults(suiteName: nameGroupShared) {
- Database.shared.database?.inTransaction({ (fmdb, rollback) in
- var dataShared: [[String: Any]] = []
- 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'") {
- while cursor.next() {
- var dataTemp: [String: Any] = [:]
- for columnIndex in 0..<cursor.columnCount {
- if let columnName = cursor.columnName(for: columnIndex) {
- if let value = cursor.object(forColumn: columnName) {
- if columnName == "image" {
- dataTemp[columnName] = value
- if let imageString = dataTemp[columnName] as? String, !imageString.isEmpty {
- do {
- if FileEncryption.shared.isSecureExists(filename: imageString) {
- if var data = try FileEncryption.shared.readSecure(filename: imageString) {
- let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: data)
- if dataDecrypt != nil {
- data = dataDecrypt!
- }
- if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
- let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
- if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
- try? data.write(to: sharedFileURL)
- }
- }
- }
- }
- } catch {
-
- }
- }
- } else {
- dataTemp[columnName] = value
- }
- dataTemp["type"] = 0
- }
- }
- }
- dataShared.append(dataTemp)
- }
- cursor.close()
- }
- if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT group_id id, image_id image, f_name name FROM GROUPZ WHERE official != 1") {
- while cursor.next() {
- var dataTemp: [String: Any] = [:]
- for columnIndex in 0..<cursor.columnCount {
- if let columnName = cursor.columnName(for: columnIndex) {
- if let value = cursor.object(forColumn: columnName) {
- if columnName == "name" {
- dataTemp[columnName] = "\(value) (Lounge)"
- } else if columnName == "image" {
- dataTemp[columnName] = value
- if let imageString = dataTemp[columnName] as? String, !imageString.isEmpty {
- do {
- if FileEncryption.shared.isSecureExists(filename: imageString) {
- if var data = try FileEncryption.shared.readSecure(filename: imageString) {
- let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: data)
- if dataDecrypt != nil {
- data = dataDecrypt!
- }
- if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
- let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
- if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
- try? data.write(to: sharedFileURL)
- }
- }
- }
- }
- } catch {
-
- }
- }
- } else {
- dataTemp[columnName] = value
- }
- dataTemp["type"] = 1
- }
- }
- }
- dataShared.append(dataTemp)
- let group_id = cursor.string(forColumnIndex: 0) ?? ""
- let image_group = cursor.string(forColumnIndex: 1) ?? ""
- let name_group = cursor.string(forColumnIndex: 2) ?? ""
- 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)'") {
- while cursorTopic.next() {
- var dataTempTopic: [String: Any] = [:]
- for columnIndex in 0..<cursorTopic.columnCount {
- if let columnName = cursorTopic.columnName(for: columnIndex) {
- if let value = cursorTopic.object(forColumn: columnName) {
- if columnName == "name" {
- dataTempTopic[columnName] = "\(name_group) (\(value))"
- } else if columnName == "image" {
- dataTempTopic[columnName] = "\(value)".isEmpty ? image_group : "\(value)"
- if let imageString = dataTempTopic[columnName] as? String, !imageString.isEmpty {
- do {
- if FileEncryption.shared.isSecureExists(filename: imageString) {
- if var data = try FileEncryption.shared.readSecure(filename: imageString) {
- let dataDecrypt = FileEncryption.shared.decryptFileFromServer(data: data)
- if dataDecrypt != nil {
- data = dataDecrypt!
- }
- if let appGroupURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: nameGroupShared) {
- let sharedFileURL = appGroupURL.appendingPathComponent(imageString)
- if !FileManager.default.fileExists(atPath: sharedFileURL.path) {
- try? data.write(to: sharedFileURL)
- }
- }
- }
- }
- } catch {
-
- }
- }
- } else {
- dataTempTopic[columnName] = value
- }
- dataTempTopic["type"] = 1
- }
- }
- }
- dataShared.append(dataTempTopic)
- }
- cursorTopic.close()
- }
- }
- cursor.close()
- }
- do {
- let jsonData = try JSONSerialization.data(withJSONObject: dataShared, options: .prettyPrinted)
- if let jsonString = String(data: jsonData, encoding: .utf8) {
- userDefaults.set(jsonString, forKey: "shareContacts")
- userDefaults.synchronize()
- }
- } catch {
- print("Error converting to JSON: \(error)")
- }
- })
- }
- }
- }
-
- public static func setCheckEmulator(isActive: Bool) {
- // Utils.bCheckEmulator = isActive
- }
-
- public static func setCheckRootedDevice(isActive: Bool) {
- // Utils.bCheckRooted = isActive
- }
-
- public static func setPreventScreenCapture(isActive: Bool) {
- // Utils.bPreventScreenCapture = isActive
- }
-
- public static func setNameGroupShare(_ name: String) {
- nameGroupShared = name
- }
-
- public static func openImageNexilis(imageView: UIImageView, data: Data? = nil, isGIF: Bool = false) {
- let image = UIImage(data: data ?? Data())
- let imageViewer = MediaViewerViewController()
- if !isGIF {
- imageViewer.media = .image(image ?? UIImage())
- } else {
- imageViewer.media = .gif(UIImage.gifImageWithData(data ?? Data()) ?? UIImage())
- }
-
- let navigationController = UINavigationController(rootViewController: imageViewer)
- navigationController.defaultStyle()
- navigationController.view.backgroundColor = .clear
- navigationController.modalPresentationCapturesStatusBarAppearance = true
- navigationController.modalPresentationStyle = .overFullScreen
-
- let backAction = UIAction { _ in
- navigationController.dismiss(animated: true)
- }
- let backButton = UIBarButtonItem(title: nil, image: UIImage(systemName: "chevron.backward"), primaryAction: backAction, menu: nil)
- imageViewer.navigationItem.leftBarButtonItem = backButton
-
- let name = ""
- imageViewer.title = name
-
- let transitionDelegate = ZoomTransitioningDelegate()
- transitionDelegate.originImageView = imageView
- navigationController.transitioningDelegate = transitionDelegate
- self.transitioningDelegateRef = transitionDelegate
-
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(navigationController, animated: true) {
- imageViewer.animateBackgroundIn()
- }
- } else {
- UIApplication.shared.visibleViewController?.present(navigationController, animated: true) {
- imageViewer.animateBackgroundIn()
- }
- }
- }
-
- public static func openVideoNexilis(videoURL: URL) {
- let player = AVPlayer(url: videoURL)
- let playerVC = AVPlayerViewController()
- playerVC.modalPresentationStyle = .custom
- playerVC.player = player
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(playerVC, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(playerVC, animated: true, completion: nil)
- }
- }
-
- public static func setAppMode(mode: Int) {
- Utils.selectedAppMode = mode
- }
-
- public static func checkSignMethod() -> (Int, Int) {
- var countMethod = 0
- var typeMethod = 0
- if Nexilis.checkingAccess(key: "sign_in_up_msisdn") {
- countMethod+=1
- typeMethod = 0
- }
- if Nexilis.checkingAccess(key: "sign_in_up_email") {
- countMethod+=1
- typeMethod = 1
- }
- if Nexilis.checkingAccess(key: "sign_in_up_username") {
- countMethod+=1
- typeMethod = 2
- }
- return (countMethod,typeMethod)
- }
-
- public static func getControllerSign(forceSignIn: Bool = false) -> UIViewController? {
- let data = APIS.checkSignMethod()
- let count = data.0
- let type = data.1
- if count > 0 {
- var controller: UIViewController!
- if count == 1 {
- if forceSignIn {
- let vc = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "changeDevice") as! ChangeDeviceViewController
- if type == 0 {
- vc.isMSISDN = true
- controller = vc
- } else if type == 1 {
- vc.isEmail = true
- }
- controller = vc
- } else {
- let vc = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "signupsignin") as! SignUpSignIn
- if type == 0 {
- vc.isMSISDN = true
- controller = vc
- } else if type == 1 {
- vc.isEmail = true
- }
- controller = vc
- }
- } else {
- let vc = SignInOption()
- vc.forceSignIn = forceSignIn
- controller = vc
- }
- return controller
- }
- return nil
- }
-
- public static func monitoredActivity() {
- UIViewController.swizzleViewDidAppearImplementation
- UINavigationController.swizzlePushViewControllerImplementation
- UINavigationController.swizzlePopViewControllerImplementation
- _ = DataCaptured()
- UIApplication.swizzleSendAction
- }
-
- private static var appNm = "";
- public static func getAppNm() -> String {
- return appNm
- }
-
- private static var nameGroupShared = "group.nexilis.share";
- public static func getnameGroupShared() -> String {
- return nameGroupShared
- }
-
- public static func openQris() {
- let scannerVC = QRScannerViewController()
- scannerVC.modalPresentationStyle = .fullScreen
- if UIApplication.shared.visibleViewController?.navigationController != nil {
- UIApplication.shared.visibleViewController?.navigationController?.present(scannerVC, animated: true, completion: nil)
- } else {
- UIApplication.shared.visibleViewController?.present(scannerVC, animated: true, completion: nil)
- }
- }
- }
- extension UINavigationController {
- func defaultStyle() {
- self.view.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .black : .white
- self.modalPresentationStyle = .fullScreen
- self.navigationBar.tintColor = .white
- self.navigationBar.barTintColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
- self.navigationBar.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : .mainColor
- self.navigationBar.isTranslucent = false
- self.navigationBar.overrideUserInterfaceStyle = .dark
- self.navigationBar.barStyle = .black
- let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font : UIFont.systemFont(ofSize: 16)]
- UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
- let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
- self.navigationBar.titleTextAttributes = textAttributes
- }
- }
|