Bläddra i källkod

update fix bugs

alqindiirsyam 2 år sedan
förälder
incheckning
3ce3bbd1d2

+ 18 - 15
appbuilder-ios/AppBuilder/AppBuilder/FirstTabViewController.swift

@@ -364,8 +364,10 @@ class FirstTabViewController: UIViewController, UIScrollViewDelegate, UIGestureR
                 ViewController.alwaysHideButton = false
                 ViewController.alwaysHideButton = false
                 showTabBar()
                 showTabBar()
             } else {
             } else {
-                ViewController.alwaysHideButton = true
-                hideTabBar()
+                if self.viewIfLoaded?.window != nil {
+                    ViewController.alwaysHideButton = true
+                    hideTabBar()
+                }
             }
             }
         }
         }
     }
     }
@@ -509,20 +511,21 @@ extension FirstTabViewController: SFSpeechRecognizerDelegate {
 
 
 extension FirstTabViewController: WKUIDelegate, WKNavigationDelegate {
 extension FirstTabViewController: WKUIDelegate, WKNavigationDelegate {
       func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
       func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
-            if let urlStr = navigationAction.request.url?.absoluteString {
-                print("url: \(urlStr)")
-                collapseDocked()
-                if urlStr.contains("nexilis/pages/tab1-main-only") || urlStr.contains("nexilis/pages/tab3-main-only") || urlStr.contains("nexilis/pages/tab1-main") || urlStr.contains("nexilis/pages/tab3-commerce") || urlStr.contains("nexilis/pages/tab1-video") || urlStr.contains("nexilis/pages/tab3-main") {
-                    ViewController.alwaysHideButton = false
-                    showTabBar()
-                    FirstTabViewController.atFirstPage = true
-                } else if isUsingMyWebview() {
-                    ViewController.alwaysHideButton = true
-                    hideTabBar()
-                    FirstTabViewController.atFirstPage = false
-                }
+            if self.viewIfLoaded?.window != nil {
+              if let urlStr = navigationAction.request.url?.absoluteString {
+                  print("url: \(urlStr)")
+                  collapseDocked()
+                  if urlStr.contains("nexilis/pages/tab1-main-only") || urlStr.contains("nexilis/pages/tab3-main-only") || urlStr.contains("nexilis/pages/tab1-main") || urlStr.contains("nexilis/pages/tab3-commerce") || urlStr.contains("nexilis/pages/tab1-video") || urlStr.contains("nexilis/pages/tab3-main") {
+                      ViewController.alwaysHideButton = false
+                      showTabBar()
+                      FirstTabViewController.atFirstPage = true
+                  } else if isUsingMyWebview() {
+                      ViewController.alwaysHideButton = true
+                      hideTabBar()
+                      FirstTabViewController.atFirstPage = false
+                  }
+              }
             }
             }
-
             decisionHandler(.allow)
             decisionHandler(.allow)
       }
       }
 }
 }

+ 23 - 20
appbuilder-ios/AppBuilder/AppBuilder/FourthTabViewController.swift

@@ -481,16 +481,17 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                                 _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                                 _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                             }
                             }
                             DispatchQueue.main.async {
                             DispatchQueue.main.async {
-                                Nexilis.hideLoader()
-                                let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
-                                imageView.tintColor = .white
-                                let banner = FloatingNotificationBanner(title: "Successfully Logout".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()
-                                var dataImage: [AnyHashable : Any] = [:]
-                                dataImage["name"] = ""
-                                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
-                                self.makeMenu()
-                                self.tableView.reloadData()
+                                Nexilis.hideLoader(completion: {
+                                    let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
+                                    imageView.tintColor = .white
+                                    let banner = FloatingNotificationBanner(title: "Successfully Logout".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()
+                                    var dataImage: [AnyHashable : Any] = [:]
+                                    dataImage["name"] = ""
+                                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil, userInfo: dataImage)
+                                    self.makeMenu()
+                                    self.tableView.reloadData()
+                                })
                             }
                             }
                             if !Utils.getForceAnonymous() {
                             if !Utils.getForceAnonymous() {
                                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
@@ -504,19 +505,21 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                                 })
                                 })
                             }
                             }
                         } else {
                         } else {
-                            Nexilis.hideLoader()
-                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                            imageView.tintColor = .white
-                            let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                            banner.show()
+                            Nexilis.hideLoader(completion: {
+                                let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                                imageView.tintColor = .white
+                                let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                                banner.show()
+                            })
                         }
                         }
                     } else {
                     } else {
                         DispatchQueue.main.async {
                         DispatchQueue.main.async {
-                            Nexilis.hideLoader()
-                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                            imageView.tintColor = .white
-                            let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                            banner.show()
+                            Nexilis.hideLoader(completion: {
+                                let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                                imageView.tintColor = .white
+                                let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                                banner.show()
+                            })
                         }
                         }
                     }
                     }
                 }
                 }

+ 17 - 15
appbuilder-ios/AppBuilder/AppBuilder/ThirdTabViewController.swift

@@ -376,8 +376,10 @@ class ThirdTabViewController: UIViewController, UIScrollViewDelegate, UIGestureR
                 ViewController.alwaysHideButton = false
                 ViewController.alwaysHideButton = false
                 showTabBar()
                 showTabBar()
             } else {
             } else {
-                ViewController.alwaysHideButton = true
-                hideTabBar()
+                if self.viewIfLoaded?.window != nil {
+                    ViewController.alwaysHideButton = true
+                    hideTabBar()
+                }
             }
             }
         }
         }
     }
     }
@@ -521,20 +523,20 @@ extension ThirdTabViewController: SFSpeechRecognizerDelegate {
 
 
 extension ThirdTabViewController: WKUIDelegate {
 extension ThirdTabViewController: WKUIDelegate {
       func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
       func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
-
-            if let urlStr = navigationAction.request.url?.absoluteString {
-                collapseDocked()
-                if urlStr.contains("nexilis/pages/tab1-main-only") || urlStr.contains("nexilis/pages/tab3-main-only") || urlStr.contains("nexilis/pages/tab1-main") || urlStr.contains("nexilis/pages/tab3-commerce") || urlStr.contains("nexilis/pages/tab1-video") || urlStr.contains("nexilis/pages/tab3-main") {
-                    ViewController.alwaysHideButton = false
-                    showTabBar()
-                    ThirdTabViewController.atFirstPage = true
-                } else if isUsingMyWebview() {
-                    ViewController.alwaysHideButton = true
-                    hideTabBar()
-                    ThirdTabViewController.atFirstPage = false
-                }
+            if self.viewIfLoaded?.window != nil {
+              if let urlStr = navigationAction.request.url?.absoluteString {
+                  collapseDocked()
+                  if urlStr.contains("nexilis/pages/tab1-main-only") || urlStr.contains("nexilis/pages/tab3-main-only") || urlStr.contains("nexilis/pages/tab1-main") || urlStr.contains("nexilis/pages/tab3-commerce") || urlStr.contains("nexilis/pages/tab1-video") || urlStr.contains("nexilis/pages/tab3-main") {
+                      ViewController.alwaysHideButton = false
+                      showTabBar()
+                      ThirdTabViewController.atFirstPage = true
+                  } else if isUsingMyWebview() {
+                      ViewController.alwaysHideButton = true
+                      hideTabBar()
+                      ThirdTabViewController.atFirstPage = false
+                  }
+              }
             }
             }
-
             decisionHandler(.allow)
             decisionHandler(.allow)
       }
       }
 }
 }

+ 1 - 0
appbuilder-ios/NexilisLite/NexilisLite/Resource/id.lproj/Localizable.strings

@@ -194,3 +194,4 @@
 "Search groups name" = "Cari nama grup";
 "Search groups name" = "Cari nama grup";
 "Title" = "Judul";
 "Title" = "Judul";
 "Start Call" = "Mulai Panggilan";
 "Start Call" = "Mulai Panggilan";
+"Sticker" = "Stiker";

+ 10 - 6
appbuilder-ios/NexilisLite/NexilisLite/Source/Model/Chat.swift

@@ -25,6 +25,7 @@ public class Chat: Model {
     public let official: String
     public let official: String
     public let status: String
     public let status: String
     public let credential: String
     public let credential: String
+    public let lock: String
     
     
     public init(pin: String) {
     public init(pin: String) {
         self.fpin = ""
         self.fpin = ""
@@ -43,9 +44,10 @@ public class Chat: Model {
         self.official = ""
         self.official = ""
         self.status = ""
         self.status = ""
         self.credential = ""
         self.credential = ""
+        self.lock = ""
     }
     }
     
     
-    public init(fpin:String, pin: String, messageId: String, counter: String, messageText: String, serverDate: String, image: String, video: String, file: String, attachmentFlag: String, messageScope: String, name: String, profile: String, official: String, status: String, credential: String) {
+    public init(fpin:String, pin: String, messageId: String, counter: String, messageText: String, serverDate: String, image: String, video: String, file: String, attachmentFlag: String, messageScope: String, name: String, profile: String, official: String, status: String, credential: String, lock: String) {
         self.fpin = fpin
         self.fpin = fpin
         self.pin = pin
         self.pin = pin
         self.messageId = messageId
         self.messageId = messageId
@@ -62,6 +64,7 @@ public class Chat: Model {
         self.official = official
         self.official = official
         self.status = status
         self.status = status
         self.credential = credential
         self.credential = credential
+        self.lock = lock
     }
     }
     
     
     public static func == (lhs: Chat, rhs: Chat) -> Bool {
     public static func == (lhs: Chat, rhs: Chat) -> Bool {
@@ -91,13 +94,13 @@ public class Chat: Model {
         var chats: [Chat] = []
         var chats: [Chat] = []
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
         Database.shared.database?.inTransaction({ (fmdb, rollback) in
             let query = """
             let query = """
-                        select m.f_pin, ms.l_pin, ms.message_id, ms.counter, m.message_text, m.server_date, m.image_id, m.video_id, m.file_id, m.attachment_flag, m.message_scope_id, b.first_name || ' ' || ifnull(b.last_name, '') name, b.image_id profile, b.official_account, m.status, m.credential from MESSAGE_SUMMARY ms, MESSAGE m, BUDDY b where ms.message_id = m.message_id and ms.l_pin = b.f_pin \(messageId.isEmpty ? "" : " and m.message_id = '\(messageId)'")
+                        select m.f_pin, ms.l_pin, ms.message_id, ms.counter, m.message_text, m.server_date, m.image_id, m.video_id, m.file_id, m.attachment_flag, m.message_scope_id, b.first_name || ' ' || ifnull(b.last_name, '') name, b.image_id profile, b.official_account, m.status, m.credential, m.lock from MESSAGE_SUMMARY ms, MESSAGE m, BUDDY b where ms.message_id = m.message_id and ms.l_pin = b.f_pin \(messageId.isEmpty ? "" : " and m.message_id = '\(messageId)'")
                         union
                         union
-                        select m.f_pin, ms.l_pin, ms.message_id, ms.counter, m.message_text, m.server_date, m.image_id, m.video_id, m.file_id, m.attachment_flag, m.message_scope_id, 'Bot' name, '' profile, '', m.status, m.credential from MESSAGE_SUMMARY ms, MESSAGE m where ms.message_id = m.message_id and ms.l_pin = '-999' \(messageId.isEmpty ? "" : " and m.message_id = '\(messageId)'")
+                        select m.f_pin, ms.l_pin, ms.message_id, ms.counter, m.message_text, m.server_date, m.image_id, m.video_id, m.file_id, m.attachment_flag, m.message_scope_id, 'Bot' name, '' profile, '', m.status, m.credential, m.lock from MESSAGE_SUMMARY ms, MESSAGE m where ms.message_id = m.message_id and ms.l_pin = '-999' \(messageId.isEmpty ? "" : " and m.message_id = '\(messageId)'")
                         union
                         union
-                        select m.f_pin, ms.l_pin, ms.message_id, ms.counter, m.message_text, m.server_date, m.image_id, m.video_id, m.file_id, m.attachment_flag, m.message_scope_id, b.f_name || ' (\("Lounge".localized()))', b.image_id profile, b.official, m.status, m.credential from MESSAGE_SUMMARY ms, MESSAGE m, GROUPZ b where ms.message_id = m.message_id and ms.l_pin = b.group_id \(messageId.isEmpty ? "" : " and m.message_id = '\(messageId)'")
+                        select m.f_pin, ms.l_pin, ms.message_id, ms.counter, m.message_text, m.server_date, m.image_id, m.video_id, m.file_id, m.attachment_flag, m.message_scope_id, b.f_name || ' (\("Lounge".localized()))', b.image_id profile, b.official, m.status, m.credential, m.lock from MESSAGE_SUMMARY ms, MESSAGE m, GROUPZ b where ms.message_id = m.message_id and ms.l_pin = b.group_id \(messageId.isEmpty ? "" : " and m.message_id = '\(messageId)'")
                         union
                         union
-                        select m.f_pin, ms.l_pin, ms.message_id, ms.counter, m.message_text, m.server_date, m.image_id, m.video_id, m.file_id, m.attachment_flag, m.message_scope_id, c.f_name || ' (' || b.title || ')', b.thumb profile, '', m.status, m.credential from MESSAGE_SUMMARY ms, MESSAGE m, DISCUSSION_FORUM b, GROUPZ c where ms.message_id = m.message_id and ms.l_pin = b.chat_id and b.group_id = c.group_id \(messageId.isEmpty ? "" : " and m.message_id = '\(messageId)'")
+                        select m.f_pin, ms.l_pin, ms.message_id, ms.counter, m.message_text, m.server_date, m.image_id, m.video_id, m.file_id, m.attachment_flag, m.message_scope_id, c.f_name || ' (' || b.title || ')', b.thumb profile, '', m.status, m.credential, m.lock from MESSAGE_SUMMARY ms, MESSAGE m, DISCUSSION_FORUM b, GROUPZ c where ms.message_id = m.message_id and ms.l_pin = b.chat_id and b.group_id = c.group_id \(messageId.isEmpty ? "" : " and m.message_id = '\(messageId)'")
                         order by 6 desc
                         order by 6 desc
                         """
                         """
             if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: query) {
             if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: query) {
@@ -117,7 +120,8 @@ public class Chat: Model {
                                     profile: cursorData.string(forColumnIndex: 12) ?? "",
                                     profile: cursorData.string(forColumnIndex: 12) ?? "",
                                     official: cursorData.string(forColumnIndex: 13) ?? "",
                                     official: cursorData.string(forColumnIndex: 13) ?? "",
                                     status: cursorData.string(forColumnIndex: 14) ?? "",
                                     status: cursorData.string(forColumnIndex: 14) ?? "",
-                                    credential: cursorData.string(forColumnIndex: 15) ?? "")
+                                    credential: cursorData.string(forColumnIndex: 15) ?? "",
+                                    lock: cursorData.string(forColumnIndex: 16) ?? "")
                     chats.append(chat)
                     chats.append(chat)
                 }
                 }
                 cursorData.close()
                 cursorData.close()

+ 50 - 46
appbuilder-ios/NexilisLite/NexilisLite/Source/Nexilis.swift

@@ -274,6 +274,10 @@ public class Nexilis: NSObject {
         InquiryThread.default.addQueue(message: message)
         InquiryThread.default.addQueue(message: message)
     }
     }
     
     
+    public static func deleteQueueMessage(message: TMessage) {
+        OutgoingThread.default.addQueue(message: message)
+    }
+    
     private static var wbDelegate: WhiteboardDelegate?
     private static var wbDelegate: WhiteboardDelegate?
     private static var wbReceiver: WhiteboardReceiver?
     private static var wbReceiver: WhiteboardReceiver?
     
     
@@ -802,8 +806,8 @@ public class Nexilis: NSObject {
         UIApplication.shared.visibleViewController?.present(loadingAlert, animated: true, completion: nil)
         UIApplication.shared.visibleViewController?.present(loadingAlert, animated: true, completion: nil)
     }
     }
     
     
-    public static func hideLoader() {
-        loadingAlert.dismiss(animated: true)
+    public static func hideLoader(completion: @escaping () -> ()) {
+        loadingAlert.dismiss(animated: true, completion: completion)
     }
     }
     
     
     private static var groupWait = DispatchGroup()
     private static var groupWait = DispatchGroup()
@@ -1587,37 +1591,54 @@ extension Nexilis: CallDelegate {
                 let fpin = deviceId
                 let fpin = deviceId
                 var data: [String: String?] = [:]
                 var data: [String: String?] = [:]
                 Database.shared.database?.inTransaction({ (fmdb, rollback) in
                 Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                    if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, official_account, image_id, device_id, offline_mode, user_type FROM BUDDY where f_pin = '\(fpin)'") {
-                        while cursorData.next() {
-                            data["f_pin"] = cursorData.string(forColumnIndex: 0)
-                            var name = ""
-                            if let firstname = cursorData.string(forColumnIndex: 1) {
-                                name = firstname
-                            }
-                            if let lastname = cursorData.string(forColumnIndex: 2) {
-                                name = name + " " + lastname
-                            }
-                            data["name"] = name
-                            data["picture"] = cursorData.string(forColumnIndex: 4)
-                            data["isOfficial"] = cursorData.string(forColumnIndex: 3)
-                            data["deviceId"] = cursorData.string(forColumnIndex: 5)
-                            data["isOffline"] = cursorData.string(forColumnIndex: 6)
-                            data["user_type"] = cursorData.string(forColumnIndex: 7)
+                    if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, official_account, image_id, device_id, offline_mode, user_type FROM BUDDY where f_pin = '\(fpin)'"), cursorData.next() {
+                        data["f_pin"] = cursorData.string(forColumnIndex: 0)
+                        var name = ""
+                        if let firstname = cursorData.string(forColumnIndex: 1) {
+                            name = firstname
+                        }
+                        if let lastname = cursorData.string(forColumnIndex: 2) {
+                            name = name + " " + lastname
                         }
                         }
+                        data["name"] = name
+                        data["picture"] = cursorData.string(forColumnIndex: 4)
+                        data["isOfficial"] = cursorData.string(forColumnIndex: 3)
+                        data["deviceId"] = cursorData.string(forColumnIndex: 5)
+                        data["isOffline"] = cursorData.string(forColumnIndex: 6)
+                        data["user_type"] = cursorData.string(forColumnIndex: 7)
                         cursorData.close()
                         cursorData.close()
                     }
                     }
                 })
                 })
-                let videoController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
-                videoController.dataPerson.append(data)
-                videoController.isInisiator = false
-                if !onGoingCC.isEmpty {
-                    videoController.users.append(User.getData(pin: data["f_pin"]!!)!)
-                }
-                let navigationController = UINavigationController(rootViewController: videoController)
-                navigationController.modalPresentationStyle = .fullScreen
-                if !onGoingCC.isEmpty {
-                    videoController.isAutoAccept = true
-                    DispatchQueue.main.asyncAfter(deadline: .now() + isShowAlert!, execute: {
+                if data["f_pin"] != nil {
+                    let videoController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
+                    videoController.dataPerson.append(data)
+                    videoController.isInisiator = false
+                    if !onGoingCC.isEmpty {
+                        videoController.users.append(User.getData(pin: data["f_pin"]!!)!)
+                    }
+                    let navigationController = UINavigationController(rootViewController: videoController)
+                    navigationController.modalPresentationStyle = .fullScreen
+                    if !onGoingCC.isEmpty {
+                        videoController.isAutoAccept = true
+                        DispatchQueue.main.asyncAfter(deadline: .now() + isShowAlert!, execute: {
+                            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)
+                            }
+                        })
+                    } else {
                         if UIApplication.shared.visibleViewController is UIAlertController {
                         if UIApplication.shared.visibleViewController is UIAlertController {
                             let vc = UIApplication.shared.visibleViewController as! UIAlertController
                             let vc = UIApplication.shared.visibleViewController as! UIAlertController
                             vc.dismiss(animated: true, completion: {
                             vc.dismiss(animated: true, completion: {
@@ -1634,23 +1655,6 @@ extension Nexilis: CallDelegate {
                         } else {
                         } else {
                             UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
                             UIApplication.shared.visibleViewController?.present(navigationController, animated: true, completion: nil)
                         }
                         }
-                    })
-                } else {
-                    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)
                     }
                     }
                 }
                 }
             }
             }

+ 3 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/Utils.swift

@@ -89,7 +89,9 @@ public final class Utils {
     }()
     }()
     
     
     public static func previewMessageText(chat: Chat) -> Any {
     public static func previewMessageText(chat: Chat) -> Any {
-        if chat.credential == "1" {
+        if chat.credential == "1" && chat.lock == "2" {
+            return ("🚫 _"+"Message has expired".localized()+"_").richText()
+        } else if chat.credential == "1" {
             return "Confidential Message".localized().richText()
             return "Confidential Message".localized().richText()
         } else if chat.attachmentFlag == "27" {
         } else if chat.attachmentFlag == "27" {
             return ("📄 " + "Live Streaming".localized()).richText()
             return ("📄 " + "Live Streaming".localized()).richText()

+ 2 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraAudioViewController.swift

@@ -640,6 +640,8 @@ class QmeraAudioViewController: UIViewController {
                             self.timer = nil
                             self.timer = nil
                             self.status.text = "Audio Call Ended"
                             self.status.text = "Audio Call Ended"
                             self.end.isEnabled = false
                             self.end.isEnabled = false
+                            self.invite.isEnabled = false
+                            self.speaker.isEnabled = false
                         }
                         }
                         DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                         DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                             self.didEnd(sender: true)
                             self.didEnd(sender: true)

+ 12 - 7
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraVideoViewController.swift

@@ -1071,13 +1071,18 @@ class QmeraVideoViewController: UIViewController {
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
                             if indexPerson! + 1 <= self.listRemoteViewFix.count {
                             if indexPerson! + 1 <= self.listRemoteViewFix.count {
-                                let viewAfterRemote = self.listRemoteViewFix[indexPerson! + 1]
-                                let viewAfterName = self.containerLabelName[indexPerson! + 1]
-                                viewAfterRemote.frame.origin.y = viewAfterRemote.frame.origin.y - 170
-                                viewAfterName.frame.origin.y = viewAfterName.frame.origin.y - 170
-                                UIView.animate(withDuration: 0.35, animations: {
-                                    self.scrollRemoteView.layoutIfNeeded()
-                                })
+                                let iLoop = (self.listRemoteViewFix.count - 1) - (indexPerson! + 1)
+                                if iLoop >= 0 {
+                                    for i in 0...iLoop {
+                                        let viewAfterRemote = self.listRemoteViewFix[(indexPerson! + i) + 1]
+                                        let viewAfterName = self.containerLabelName[(indexPerson! + i) + 1]
+                                        viewAfterRemote.frame.origin.y = viewAfterRemote.frame.origin.y - 170
+                                        viewAfterName.frame.origin.y = viewAfterName.frame.origin.y - 170
+                                        UIView.animate(withDuration: 0.35, animations: {
+                                            self.scrollRemoteView.layoutIfNeeded()
+                                        })
+                                    }
+                                }
                             }
                             }
                         }
                         }
                         self.dataPerson.remove(at: indexPerson!)
                         self.dataPerson.remove(at: indexPerson!)

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift

@@ -2030,7 +2030,7 @@ extension EditorGroup: UIContextMenuInteractionDelegate {
             if self.viewAttachment.isHidden {
             if self.viewAttachment.isHidden {
                 self.viewAttachment.isHidden = false
                 self.viewAttachment.isHidden = false
             }
             }
-            if !self.isSearching {
+            if self.constraintBottomTableViewWithTextfield.constant == -60.0 {
                 self.constraintBottomTableViewWithTextfield.constant = self.constraintBottomTableViewWithTextfield.constant + 70
                 self.constraintBottomTableViewWithTextfield.constant = self.constraintBottomTableViewWithTextfield.constant + 70
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
                     if (self.currentIndexpath != nil) {
                     if (self.currentIndexpath != nil) {

+ 2 - 2
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift

@@ -3128,7 +3128,7 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
             if self.containerAction.isHidden {
             if self.containerAction.isHidden {
                 self.containerAction.isHidden = false
                 self.containerAction.isHidden = false
             }
             }
-            if !self.isSearching && (self.copySession || self.forwardSession || self.deleteSession){
+            if self.constraintBottomTableViewWithTextfield.constant == -60.0 {
                 self.constraintBottomTableViewWithTextfield.constant = self.constraintBottomTableViewWithTextfield.constant + 70
                 self.constraintBottomTableViewWithTextfield.constant = self.constraintBottomTableViewWithTextfield.constant + 70
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
                 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
                     if (self.currentIndexpath != nil) {
                     if (self.currentIndexpath != nil) {
@@ -3390,7 +3390,7 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
     
     
     private func deleteMessage(l_pin: String, message_id: String, scope: String, type: String, chat: String) {
     private func deleteMessage(l_pin: String, message_id: String, scope: String, type: String, chat: String) {
         let tmessage = CoreMessage_TMessageBank.deleteMessage(l_pin: l_pin, messageId: message_id, scope: scope, type: type, chat: chat)
         let tmessage = CoreMessage_TMessageBank.deleteMessage(l_pin: l_pin, messageId: message_id, scope: scope, type: type, chat: chat)
-        Nexilis.addQueueMessage(message: tmessage)
+        Nexilis.deleteQueueMessage(message: tmessage)
     }
     }
     
     
     private func queryMessageReply(message_id: String) -> [String: Any?] {
     private func queryMessageReply(message_id: String) -> [String: Any?] {

+ 10 - 5
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/AddFriendTableViewController.swift

@@ -143,12 +143,17 @@ class AddFriendTableViewController: UITableViewController {
         controller.name = user.fullName
         controller.name = user.fullName
         controller.picture = user.thumb
         controller.picture = user.thumb
         controller.isDismiss = {
         controller.isDismiss = {
-            self.getData { d in
-                self.data = d
-                DispatchQueue.main.async {
-                    self.tableView.reloadData()
-                }
+            self.data.removeAll(where: {$0.pin == user.pin})
+            if self.isFilltering {
+                self.fillteredData.removeAll(where: {$0.pin == user.pin})
             }
             }
+            self.tableView.reloadData()
+//            self.getData { d in
+//                self.data = d
+//                DispatchQueue.main.async {
+//                    self.tableView.reloadData()
+//                }
+//            }
         }
         }
         navigationController?.show(controller, sender: nil)
         navigationController?.show(controller, sender: nil)
     }
     }

+ 78 - 68
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangeDeviceViewController.swift

@@ -86,25 +86,28 @@ public class ChangeDeviceViewController: UIViewController {
             if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendOTPLogin(p_email: email), timeout: 30 * 1000) {
             if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendOTPLogin(p_email: email), timeout: 30 * 1000) {
                 if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") != "00" {
                 if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") != "00" {
                     DispatchQueue.main.async {
                     DispatchQueue.main.async {
-                        Nexilis.hideLoader()
-                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                        imageView.tintColor = .white
-                        let banner = FloatingNotificationBanner(title: "Unregistered email account".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()
+                        Nexilis.hideLoader(completion: {
+                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Unregistered email account".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()
+                        })
                     }
                     }
                 } else {
                 } else {
                     DispatchQueue.main.async {
                     DispatchQueue.main.async {
-                        Nexilis.hideLoader()
-                        self.showPageOTP(email: email)
+                        Nexilis.hideLoader(completion: {
+                            self.showPageOTP(email: email)
+                        })
                     }
                     }
                 }
                 }
             } else {
             } else {
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {
-                    Nexilis.hideLoader()
-                    let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                    imageView.tintColor = .white
-                    let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                    banner.show()
+                    Nexilis.hideLoader(completion: {
+                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                        imageView.tintColor = .white
+                        let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                        banner.show()
+                    })
                 }
                 }
             }
             }
         }
         }
@@ -120,8 +123,9 @@ public class ChangeDeviceViewController: UIViewController {
                 if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendVerifyChangeDevice(p_email: email, p_vercode: code), timeout: 30 * 1000) {
                 if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendVerifyChangeDevice(p_email: email, p_vercode: code), timeout: 30 * 1000) {
                     if !response.isOk() {
                     if !response.isOk() {
                         DispatchQueue.main.async {
                         DispatchQueue.main.async {
-                            Nexilis.hideLoader()
-                            self.showPageOTP(email: email, errCode: response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99"))
+                            Nexilis.hideLoader(completion: {
+                                self.showPageOTP(email: email, errCode: response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99"))
+                            })
                         }
                         }
                     } else {
                     } else {
                         self.deleteAllRecordDatabase()
                         self.deleteAllRecordDatabase()
@@ -135,34 +139,36 @@ public class ChangeDeviceViewController: UIViewController {
                             // pos registration
                             // pos registration
                             _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                             _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                             DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
-                                Nexilis.hideLoader()
-                                let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
-                                imageView.tintColor = .white
-                                let banner = FloatingNotificationBanner(title: "Successfully changed device".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()
-                                if self.fromChangeNamePass{
-                                    var vc = self.navigationController?.presentingViewController
-                                    while vc?.presentingViewController != nil {
-                                        vc = vc?.presentingViewController
+                                Nexilis.hideLoader(completion: {
+                                    let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
+                                    imageView.tintColor = .white
+                                    let banner = FloatingNotificationBanner(title: "Successfully changed device".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()
+                                    if self.fromChangeNamePass{
+                                        var vc = self.navigationController?.presentingViewController
+                                        while vc?.presentingViewController != nil {
+                                            vc = vc?.presentingViewController
+                                        }
+                                        vc?.dismiss(animated: true, completion: nil)
                                     }
                                     }
-                                    vc?.dismiss(animated: true, completion: nil)
-                                }
-                                else if !self.forceLogin {
-                                    self.navigationController?.popViewController(animated: true)
-                                } else {
-                                    self.navigationController?.dismiss(animated: true)
-                                }
-                                self.isDismiss?(thumb)
+                                    else if !self.forceLogin {
+                                        self.navigationController?.popViewController(animated: true)
+                                    } else {
+                                        self.navigationController?.dismiss(animated: true)
+                                    }
+                                    self.isDismiss?(thumb)
+                                })
                             })
                             })
                         }
                         }
                     }
                     }
                 } else {
                 } else {
                     DispatchQueue.main.async {
                     DispatchQueue.main.async {
-                        Nexilis.hideLoader()
-                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                        imageView.tintColor = .white
-                        let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                        banner.show()
+                        Nexilis.hideLoader(completion: {
+                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                            banner.show()
+                        })
                     }
                     }
                 }
                 }
             }
             }
@@ -218,19 +224,21 @@ public class ChangeDeviceViewController: UIViewController {
             if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignIn(p_name: name, p_password: md5Hex), timeout: 30 * 1000) {
             if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSignIn(p_name: name, p_password: md5Hex), timeout: 30 * 1000) {
                 if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
                 if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "11" {
                     DispatchQueue.main.async {
                     DispatchQueue.main.async {
-                        Nexilis.hideLoader()
-                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                        imageView.tintColor = .white
-                        let banner = FloatingNotificationBanner(title: "Invalid user / Username and 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: .center)
-                        banner.show()
+                        Nexilis.hideLoader(completion: {
+                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Invalid user / Username and 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: .center)
+                            banner.show()
+                        })
                     }
                     }
                 } else if !response.isOk() {
                 } else if !response.isOk() {
                     DispatchQueue.main.async {
                     DispatchQueue.main.async {
-                        Nexilis.hideLoader()
-                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                        imageView.tintColor = .white
-                        let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                        banner.show()
+                        Nexilis.hideLoader(completion: {
+                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                            banner.show()
+                        })
                     }
                     }
                 } else {
                 } else {
                     self.deleteAllRecordDatabase()
                     self.deleteAllRecordDatabase()
@@ -244,34 +252,36 @@ public class ChangeDeviceViewController: UIViewController {
                         // pos registration
                         // pos registration
                         _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                         _ = Nexilis.write(message: CoreMessage_TMessageBank.getPostRegistration(p_pin: id))
                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
-                            Nexilis.hideLoader()
-                            let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
-                            imageView.tintColor = .white
-                            let banner = FloatingNotificationBanner(title: "Successfully changed device".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()
-                            if self.fromChangeNamePass{
-                                var vc = self.navigationController?.presentingViewController
-                                while vc?.presentingViewController != nil {
-                                    vc = vc?.presentingViewController
+                            Nexilis.hideLoader(completion: {
+                                let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
+                                imageView.tintColor = .white
+                                let banner = FloatingNotificationBanner(title: "Successfully changed device".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()
+                                if self.fromChangeNamePass{
+                                    var vc = self.navigationController?.presentingViewController
+                                    while vc?.presentingViewController != nil {
+                                        vc = vc?.presentingViewController
+                                    }
+                                    vc?.dismiss(animated: true, completion: nil)
+                                }
+                                else if !self.forceLogin {
+                                    self.navigationController?.popViewController(animated: true)
+                                } else {
+                                    self.navigationController?.dismiss(animated: true)
                                 }
                                 }
-                                vc?.dismiss(animated: true, completion: nil)
-                            }
-                            else if !self.forceLogin {
-                                self.navigationController?.popViewController(animated: true)
-                            } else {
-                                self.navigationController?.dismiss(animated: true)
-                            }
-                            self.isDismiss?(thumb)
+                                self.isDismiss?(thumb)
+                            })
                         })
                         })
                     }
                     }
                 }
                 }
             } else {
             } else {
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {
-                    Nexilis.hideLoader()
-                    let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                    imageView.tintColor = .white
-                    let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                    banner.show()
+                    Nexilis.hideLoader(completion: {
+                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                        imageView.tintColor = .white
+                        let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                        banner.show()
+                    })
                 }
                 }
             }
             }
         }
         }

+ 25 - 23
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ChangeNamePassswordViewController.swift

@@ -139,11 +139,12 @@ public class ChangeNamePassswordViewController: UIViewController {
             if let resp = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendOTPChangeProfile(name: first + " " + last, type: "2")) {
             if let resp = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSendOTPChangeProfile(name: first + " " + last, type: "2")) {
                 if resp.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "1a" {
                 if resp.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "1a" {
                     DispatchQueue.main.async {
                     DispatchQueue.main.async {
-                        Nexilis.hideLoader()
-                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                        imageView.tintColor = .white
-                        let banner = FloatingNotificationBanner(title: "Username has already been registered. Please use another username".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()
+                        Nexilis.hideLoader(completion: {
+                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                            imageView.tintColor = .white
+                            let banner = FloatingNotificationBanner(title: "Username has already been registered. Please use another username".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()
+                        })
                     }
                     }
                 } else if resp.isOk() {
                 } else if resp.isOk() {
                     let md5Hex = Utils.getMD5(string: password).map { String(format: "%02hhx", $0) }.joined()
                     let md5Hex = Utils.getMD5(string: password).map { String(format: "%02hhx", $0) }.joined()
@@ -161,33 +162,34 @@ public class ChangeNamePassswordViewController: UIViewController {
                             UserDefaults.standard.synchronize()
                             UserDefaults.standard.synchronize()
         //                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
         //                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
                             DispatchQueue.main.async {
                             DispatchQueue.main.async {
-                                Nexilis.hideLoader()
+                                Nexilis.hideLoader(completion: {
+                                    let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
+                                    imageView.tintColor = .white
+                                    let banner = FloatingNotificationBanner(title: "Successfully changed".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()
+                                    self.didTapExit(sender: "exit")
+                                })
                             }
                             }
-                            DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: {
-                                let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
-                                imageView.tintColor = .white
-                                let banner = FloatingNotificationBanner(title: "Successfully changed".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()
-                                self.didTapExit(sender: "exit")
-                            })
                         }
                         }
                     } else {
                     } else {
                         DispatchQueue.main.async {
                         DispatchQueue.main.async {
-                            Nexilis.hideLoader()
-                            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                            imageView.tintColor = .white
-                            let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                            banner.show()
+                            Nexilis.hideLoader(completion: {
+                                let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                                imageView.tintColor = .white
+                                let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                                banner.show()
+                            })
                         }
                         }
                     }
                     }
                 }
                 }
             } else {
             } else {
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {
-                    Nexilis.hideLoader()
-                    let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
-                    imageView.tintColor = .white
-                    let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
-                    banner.show()
+                    Nexilis.hideLoader(completion: {
+                        let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                        imageView.tintColor = .white
+                        let banner = FloatingNotificationBanner(title: "Unable to access servers. Try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                        banner.show()
+                    })
                 }
                 }
             }
             }
         }
         }

+ 14 - 11
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/GroupDetailViewController.swift

@@ -294,17 +294,19 @@ class GroupDetailViewController: UITableViewController {
                 self.changeOpenGroup(open: currentAccess) { result in
                 self.changeOpenGroup(open: currentAccess) { result in
                     if result {
                     if result {
                         DispatchQueue.main.async {
                         DispatchQueue.main.async {
-                            g.isOpen = currentAccess
-                            tableView.reloadRows(at: [indexPath], with: .none)
-                            Nexilis.hideLoader()
+                            Nexilis.hideLoader(completion: {
+                                g.isOpen = currentAccess
+                                tableView.reloadRows(at: [indexPath], with: .none)
+                            })
                         }
                         }
                     } else {
                     } else {
                         DispatchQueue.main.async {
                         DispatchQueue.main.async {
-                            Nexilis.hideLoader()
-                            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()
+                            Nexilis.hideLoader(completion: {
+                                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()
+                            })
                         }
                         }
                     }
                     }
                 }
                 }
@@ -938,9 +940,10 @@ extension GroupDetailViewController: ImageVideoPickerDelegate {
                             Database.shared.database?.inTransaction({ fmdb, rollback in
                             Database.shared.database?.inTransaction({ fmdb, rollback in
                                 _ = Database.shared.updateRecord(fmdb: fmdb, table: "GROUPZ", cvalues: ["image_id": fileDir.lastPathComponent], _where: "group_id = '\(g.id)'")
                                 _ = Database.shared.updateRecord(fmdb: fmdb, table: "GROUPZ", cvalues: ["image_id": fileDir.lastPathComponent], _where: "group_id = '\(g.id)'")
                                 DispatchQueue.main.async {
                                 DispatchQueue.main.async {
-                                    Nexilis.hideLoader()
-                                    self.tempImage = image
-                                    cell.profile.image = self.tempImage
+                                    Nexilis.hideLoader(completion: {
+                                        self.tempImage = image
+                                        cell.profile.image = self.tempImage
+                                    })
                                 }
                                 }
                             })
                             })
                         } else {
                         } else {

+ 38 - 21
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ProfileViewController.swift

@@ -470,9 +470,17 @@ public class ProfileViewController: UITableViewController {
     }
     }
     
     
     @objc func didTapUnfriend(sender: Any) {
     @objc func didTapUnfriend(sender: Any) {
+        call.isEnabled = false
+        video.isEnabled = false
+        message.isEnabled = false
         let alert = UIAlertController(title: "", message: "Are you sure to unfriend".localized() + " \(self.user!.fullName)", preferredStyle: .alert)
         let alert = UIAlertController(title: "", message: "Are you sure to unfriend".localized() + " \(self.user!.fullName)", preferredStyle: .alert)
-        alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
+        alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: {(_) in
+            self.call.isEnabled = true
+            self.video.isEnabled = true
+            self.message.isEnabled = true
+        } ))
         alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
         alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
+            Nexilis.showLoader()
             self.unFriend { result in
             self.unFriend { result in
                 DispatchQueue.main.async {
                 DispatchQueue.main.async {
                     if result {
                     if result {
@@ -482,20 +490,28 @@ public class ProfileViewController: UITableViewController {
                                 _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.data)'")
                                 _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.data)'")
                                 _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.data)' or l_pin='\(self.data)') and message_scope_id='3'")
                                 _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.data)' or l_pin='\(self.data)') and message_scope_id='3'")
                                 cursor.close()
                                 cursor.close()
-                                var data: [AnyHashable : Any] = [:]
-                                data["state"] = 99
-                                data["message"] = "delete_buddy,\(self.data)"
-                                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onUpdatePersonInfo"), object: nil, userInfo: data)
+                                Nexilis.hideLoader(completion: {
+                                    var data: [AnyHashable : Any] = [:]
+                                    data["state"] = 99
+                                    data["message"] = "delete_buddy,\(self.data)"
+                                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "onUpdatePersonInfo"), object: nil, userInfo: data)
+                                })
                                 return
                                 return
                             }
                             }
                         })
                         })
-                        if self.previousViewController is GroupDetailViewController || self.isBNI {
-                            self.isDismiss?()
-                            self.navigationController?.popViewController(animated: true)
-                        } else {
-                            self.navigationController?.popToRootViewController(animated: true)
-                        }
+                        Nexilis.hideLoader(completion: {
+                            if self.previousViewController is GroupDetailViewController || self.isBNI {
+                                self.isDismiss?()
+                                self.navigationController?.popViewController(animated: true)
+                            } else {
+                                self.navigationController?.popToRootViewController(animated: true)
+                            }
+                        })
                     } else {
                     } else {
+                        self.call.isEnabled = true
+                        self.video.isEnabled = true
+                        self.message.isEnabled = true
+                        Nexilis.hideLoader(completion: {})
                         let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
                         let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
                         imageView.tintColor = .white
                         imageView.tintColor = .white
                         let banner = FloatingNotificationBanner(title: "Server busy, please try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
                         let banner = FloatingNotificationBanner(title: "Server busy, please try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
@@ -591,21 +607,22 @@ extension ProfileViewController: ImageVideoPickerDelegate {
                             NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
                             NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
                             
                             
                             DispatchQueue.main.async {
                             DispatchQueue.main.async {
-                                self.profile.image = image
-                                let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
-                                self.user?.thumb = fileDir.lastPathComponent
-                                imageView.tintColor = .white
-                                let banner = FloatingNotificationBanner(title: "Successfully changed image".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()
-                                self.dismissImage?(image, fileDir.lastPathComponent)
-                                Nexilis.hideLoader()
+                                Nexilis.hideLoader(completion: {
+                                    self.profile.image = image
+                                    let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
+                                    self.user?.thumb = fileDir.lastPathComponent
+                                    imageView.tintColor = .white
+                                    let banner = FloatingNotificationBanner(title: "Successfully changed image".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()
+                                    self.dismissImage?(image, fileDir.lastPathComponent)
+                                })
                             }
                             }
                         } else {
                         } else {
-                            Nexilis.hideLoader()
+                            Nexilis.hideLoader(completion: {})
                         }
                         }
                     }
                     }
                 } else {
                 } else {
-                    Nexilis.hideLoader()
+                    Nexilis.hideLoader(completion: {})
                 }
                 }
             }
             }
         }
         }