alqindiirsyam 2 лет назад
Родитель
Сommit
f5e88965ae

+ 3 - 0
appbuilder-ios/AppBuilder/AppBuilder/FirstTabViewController.swift

@@ -166,6 +166,9 @@ class FirstTabViewController: UIViewController, UIScrollViewDelegate, UIGestureR
     }
     
     override func viewWillDisappear(_ animated: Bool) {
+        if self.webView.scrollView.contentOffset.y < 0 { // Move tableView to top
+            self.webView.scrollView.setContentOffset(CGPoint.zero, animated: true)
+        }
         self.webView.evaluateJavaScript("{if(pauseAll){pauseAll();}}")
     }
     

+ 4 - 2
appbuilder-ios/AppBuilder/AppBuilder/FourthTabViewController.swift

@@ -478,8 +478,10 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
                 if !(viewController is ViewController) {
                     viewController = self.parent
                 }
-                if !(viewController?.tabBarController?.selectedViewController is FourthTabViewController) {
-                    return
+                if let viewController = viewController as? ViewController {
+                    if !(viewController.selectedViewController is FourthTabViewController) {
+                        viewController.selectedIndex = (viewController.viewControllers?.firstIndex(of: viewController.fourthTab!))!
+                    }
                 }
                 if !CheckConnection.isConnectedToNetwork()  || API.nGetCLXConnState() == 0 {
                     let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))

+ 2 - 1
appbuilder-ios/AppBuilder/AppBuilder/SecondTabViewController.swift

@@ -884,8 +884,10 @@ extension SecondTabViewController: UITableViewDelegate, UITableViewDataSource {
         if value == 0 {
             noData = true
             value = 1
+            tableView.separatorStyle = .none
         } else {
             noData = false
+            tableView.separatorStyle = .singleLine
         }
         return value
     }
@@ -906,7 +908,6 @@ extension SecondTabViewController: UITableViewDelegate, UITableViewDataSource {
                 labelNochat.textColor = .black
                 content.addSubview(labelNochat)
                 labelNochat.anchor(centerX: content.centerXAnchor, centerY: content.centerYAnchor)
-                cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
                 cell.backgroundColor = .clear
                 return cell
             }

+ 3 - 0
appbuilder-ios/AppBuilder/AppBuilder/ThirdTabViewController.swift

@@ -173,6 +173,9 @@ class ThirdTabViewController: UIViewController, UIScrollViewDelegate, UIGestureR
     }
     
     override func viewWillDisappear(_ animated: Bool) {
+        if self.webView.scrollView.contentOffset.y < 0 { // Move tableView to top
+            self.webView.scrollView.setContentOffset(CGPoint.zero, animated: true)
+        }
         self.webView.evaluateJavaScript("{if(pauseAll){pauseAll();}}")
         view.endEditing(true)
         resignFirstResponder()

+ 10 - 6
appbuilder-ios/AppBuilder/AppBuilder/ViewController.swift

@@ -194,7 +194,11 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
                         labelCounterFB.font = .systemFont(ofSize: 10)
                         labelCounterFB.textColor = .white
                     }
-                    labelCounterFB.text = "\(counter)"
+                    if counter > 99 {
+                        labelCounterFB.text = "99+"
+                    } else {
+                        labelCounterFB.text = "\(counter)"
+                    }
                 } else {
                     if indicatorCounterFB.isDescendant(of: viewSecondTab) {
                         indicatorCounterFB.removeFromSuperview()
@@ -989,7 +993,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
                                             if count == 0 {
                                                 if !icon.isEmpty {
                                                     DispatchQueue.global().async {
-                                                        ViewController.getDataImageFromUrl(from: URL(string: "http://\(Nexilis.ADDRESS)/filepalio/image/\(icon)")!) { data, response, error in
+                                                        ViewController.getDataImageFromUrl(from: URL(string: "https://newuniverse.io/get_file?account=\(Nexilis.sAPIKey)&image=\(icon)")!) { data, response, error in
                                                             guard let data = data, error == nil else { return }
                                                             // always update the UI from the main thread
                                                             DispatchQueue.main.async() {
@@ -1003,7 +1007,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
                                             } else if count == 1 {
                                                 if !icon.isEmpty {
                                                     DispatchQueue.global().async {
-                                                        ViewController.getDataImageFromUrl(from: URL(string: "http://\(Nexilis.ADDRESS)/filepalio/image/\(icon)")!) { data, response, error in
+                                                        ViewController.getDataImageFromUrl(from: URL(string: "https://newuniverse.io/get_file?account=\(Nexilis.sAPIKey)&image=\(icon)")!) { data, response, error in
                                                             guard let data = data, error == nil else { return }
                                                             // always update the UI from the main thread
                                                             DispatchQueue.main.async() {
@@ -1017,7 +1021,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
                                             } else if count == 2 {
                                                 if !icon.isEmpty {
                                                     DispatchQueue.global().async {
-                                                        ViewController.getDataImageFromUrl(from: URL(string: "http://\(Nexilis.ADDRESS)/filepalio/image/\(icon)")!) { data, response, error in
+                                                        ViewController.getDataImageFromUrl(from: URL(string: "https://newuniverse.io/get_file?account=\(Nexilis.sAPIKey)&image=\(icon)")!) { data, response, error in
                                                             guard let data = data, error == nil else { return }
                                                             // always update the UI from the main thread
                                                             DispatchQueue.main.async() {
@@ -1031,7 +1035,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
                                             } else if count == 3 {
                                                 if !icon.isEmpty {
                                                     DispatchQueue.global().async {
-                                                        ViewController.getDataImageFromUrl(from: URL(string: "http://\(Nexilis.ADDRESS)/filepalio/image/\(icon)")!) { data, response, error in
+                                                        ViewController.getDataImageFromUrl(from: URL(string: "https://newuniverse.io/get_file?account=\(Nexilis.sAPIKey)&image=\(icon)")!) { data, response, error in
                                                             guard let data = data, error == nil else { return }
                                                             // always update the UI from the main thread
                                                             DispatchQueue.main.async() {
@@ -1045,7 +1049,7 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
                                             } else if count == 4 {
                                                 if !icon.isEmpty {
                                                     DispatchQueue.global().async {
-                                                        ViewController.getDataImageFromUrl(from: URL(string: "http://\(Nexilis.ADDRESS)/filepalio/image/\(icon)")!) { data, response, error in
+                                                        ViewController.getDataImageFromUrl(from: URL(string: "https://newuniverse.io/get_file?account=\(Nexilis.sAPIKey)&image=\(icon)")!) { data, response, error in
                                                             guard let data = data, error == nil else { return }
                                                             // always update the UI from the main thread
                                                             DispatchQueue.main.async() {

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

@@ -176,7 +176,9 @@
 "Friends" = "Teman";
 "Video call is over" = "Panngilan video telah berakhir";
 "End Video Call" = "Akhiri Panggilan Video";
+"End Audio Call" = "Akhiri Panggilan Suara";
 "Are you sure you want to end video call?" = "Apakah anda yakin ingin mengakhiri panggilan video?";
+"Are you sure you want to end audio call?" = "Apakah anda yakin ingin mengakhiri panggilan suara?";
 "Please wait..." = "Mohon tunggu...";
 "Unable to access servers. Try again later" = "Tidak dapat mengakses server. Coba lagi nanti";
 "Unregistered email account" = "Akun email tidak terdaftar";
@@ -219,7 +221,7 @@
 "Please select the communication media do you want" = "Silakan pilih media komunikasi yang Anda inginkan";
 "Chat with a Representative" = "Obrolan";
 "Video Call a Representative" = "Panggilan Video";
-"Call a Representative" = "Paggilan Suara";
+"Call a Representative" = "Panggilan Suara";
 "Unfavorite all messages" = "Hapus semua pesan favorit";
 "Successfully changed name" = "Berhasil mengubah nama";
 "Please select your Consultation Topic:" = "Silakan pilih Topik Konsultasi Anda:";
@@ -256,3 +258,4 @@
 "Broadcast Message Sent" = "Pesan Siaran Terkirim";
 "Successfully changed" = "Berhasil diubah";
 "You can't request Call Center more than one" = "Anda tidak dapat meminta pusat panggilan lebih dari satu kali";
+"You have requested Call Center, please wait for response." = "Anda telah meminta Pusat Panggilan, harap tunggu tanggapan.";

+ 1 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/FloatingButton/FloatingButton.swift

@@ -152,7 +152,7 @@ public class FloatingButton: UIView {
                                         newButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
                                         newButton.translatesAutoresizingMaskIntoConstraints = false
                                         DispatchQueue.global().async {
-                                            let data = try? Data(contentsOf: URL(string: "http://\(Nexilis.ADDRESS)/filepalio/image/\(icon)")!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
+                                            let data = try? Data(contentsOf: URL(string: "https://newuniverse.io/get_file?account=\(Nexilis.sAPIKey)&image=\(icon)")!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
                                             DispatchQueue.main.async {
                                                 if data != nil {
                                                     newButton.setImage(UIImage(data: data!), for: .normal)

+ 23 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/Model/User.swift

@@ -118,4 +118,27 @@ public class User: Model {
         return user
     }
     
+    public static func getDataCanNil(pin: String?) -> User? {
+        guard let pin = pin else {
+            return nil
+        }
+        var user: User?
+        Database.shared.database?.inTransaction({ fmdb, rollback in
+            if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select f_pin, first_name, last_name, image_id, user_type, privacy_flag, offline_mode, ex_block, device_id, official_account from BUDDY where f_pin = '\(pin)' OR device_id = '\(pin)'"), cursor.next() {
+                user = User(pin: cursor.string(forColumnIndex: 0) ?? "",
+                            firstName: cursor.string(forColumnIndex: 1) ?? "",
+                            lastName: cursor.string(forColumnIndex: 2) ?? "",
+                            thumb: cursor.string(forColumnIndex: 3) ?? "",
+                            userType: cursor.string(forColumnIndex: 4) ?? "",
+                            privacy_flag: cursor.string(forColumnIndex: 5) ?? "",
+                            offline_mode: cursor.string(forColumnIndex: 6) ?? "",
+                            ex_block: cursor.string(forColumnIndex: 7) ?? "",
+                            official: cursor.string(forColumnIndex: 9) ?? "",
+                            device_id: cursor.string(forColumnIndex: 8) ?? "")
+                cursor.close()
+            }
+        })
+        return user
+    }
+    
 }

+ 17 - 5
appbuilder-ios/NexilisLite/NexilisLite/Source/Nexilis.swift

@@ -74,6 +74,9 @@ public class Nexilis: NSObject {
             IncomingThread.default.run()
             
             let address = Nexilis.getAddress(apiKey:apiKey)
+            if address.count == 0 {
+                return
+            }
             UserDefaults.standard.set(address, forKey: "address")
             UserDefaults.standard.set(address[0], forKey: "server")
             
@@ -1551,6 +1554,8 @@ public enum AppStoryBoard: String {
     
 }
 
+public var uuidOngoing = UUID()
+
 extension Nexilis: CallDelegate {
     
     func displayIncomingCall(uuid: UUID, handle: String, hasVideo: Bool = false, completion: ((Error?) -> Void)? = nil) {
@@ -1592,14 +1597,15 @@ extension Nexilis: CallDelegate {
             if (state == 21 && message.split(separator: ",")[1] != "joining Ac.room on channel 0") {
                 if onGoingCC.isEmpty {
                     let backgroundTaskIdentifier = UIApplication.shared.beginBackgroundTask(expirationHandler: nil)
-                    let data = User.getData(pin: String(deviceId))
+                    let data = User.getDataCanNil(pin: String(deviceId))
                     if data == nil {
                         DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                             API.terminateCall(sParty: nil)
                         })
                         return
                     }
-                    self.displayIncomingCall(uuid: UUID(), handle: String(deviceId), hasVideo: false) { error in
+                    uuidOngoing = UUID()
+                    self.displayIncomingCall(uuid: uuidOngoing, handle: String(deviceId), hasVideo: false) { error in
                         UIApplication.shared.endBackgroundTask(backgroundTaskIdentifier)
                     }
                 } else {
@@ -1617,8 +1623,8 @@ extension Nexilis: CallDelegate {
                         API.receiveCCall(sParty: String(deviceId))
                     })
                 }
-            } else if (state != -3 && state != 21) {
-                let dataUser = User.getData(pin: String(deviceId))
+            } else if state == 31 {
+                let dataUser = User.getDataCanNil(pin: String(deviceId))
                 if dataUser == nil {
                     DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
                         API.terminateCall(sParty: nil)
@@ -1713,6 +1719,12 @@ extension Nexilis: CallDelegate {
                     call.answerCall()
                 }
             }
+        } else if state == 28 {
+            DispatchQueue.main.async {
+                if QmeraAudioViewController().viewIfLoaded?.window == nil {
+                    Nexilis.shared.callManager.end(call: Call(uuid: uuidOngoing))
+                }
+            }
         }
         var dataCall: [AnyHashable : Any] = [:]
         dataCall["state"] = state
@@ -1927,7 +1939,7 @@ extension Nexilis: MessageDelegate {
                         }
                     } else if fileType == BroadcastViewController.FILE_TYPE_VIDEO {
                         //https://qmera.io/filepalio/image/
-                        let player = AVPlayer(url: URL(string: "https://\(Nexilis.ADDRESS)/filepalio/image/\(video)")!)
+                        let player = AVPlayer(url: URL(string: "https://newuniverse.io/get_file?account=\(Nexilis.sAPIKey)&image=\(video)")!)
                         let playerVC = AVPlayerViewController()
                         playerVC.player = player
                         playerVC.modalPresentationStyle = .custom

+ 23 - 3
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraAudioViewController.swift

@@ -384,8 +384,25 @@ class QmeraAudioViewController: UIViewController {
     }
     
     @objc func didPressEnd(sender: Any?) {
-        isEndByMe = true
-        self.didEnd(sender: nil)
+        let alert = UIAlertController(title: "End Audio Call".localized(), message: "Are you sure you want to end audio call?".localized(), preferredStyle: .alert)
+        alert.addAction(UIAlertAction(title: "No".localized(), style: UIAlertAction.Style.default, handler: nil))
+        alert.addAction(UIAlertAction(title: "Yes".localized(), style: UIAlertAction.Style.default, handler: {(_) in
+            DispatchQueue.main.async {
+                self.timer?.invalidate()
+                self.timer = nil
+                self.status.text = "Audio Call Ended"
+                self.end.isEnabled = false
+                self.invite.isEnabled = false
+                self.speaker.isEnabled = false
+                let controller = self.presentedViewController
+                if controller != nil {
+                    controller!.dismiss(animated: true)
+                }
+            }
+            self.isEndByMe = true
+            self.didEnd(sender: nil)
+        }))
+        self.present(alert, animated: true, completion: nil)
     }
     
     @objc func didEnd(sender: Any?) {
@@ -482,14 +499,17 @@ class QmeraAudioViewController: UIViewController {
                 for i in 0..<Nexilis.shared.callManager.calls.count {
                     Nexilis.shared.callManager.end(call: Nexilis.shared.callManager.calls[i])
                 }
+                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
+                    self.dismiss(animated: false, completion: nil)
+                }
             } else {
                 if let user = self.user, let call = Nexilis.shared.callManager.call(with: user.pin) {
                     Nexilis.shared.callManager.end(call: call)
                 } else {
                     API.terminateCall(sParty: nil)
                 }
+                self.dismiss(animated: false, completion: nil)
             }
-            dismiss(animated: false, completion: nil)
         }
     }
     

+ 41 - 8
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraVideoViewController.swift

@@ -373,8 +373,6 @@ class QmeraVideoViewController: UIViewController {
                 } catch {
                 }
             }
-            print("AUDIO 1 \(AVAudioSession.sharedInstance().category)")
-            print("AUDIO 2 \(AVAudioSession.sharedInstance().mode)")
             API.initiateCCall(sParty: dataPerson[0]["f_pin"]!, nCamIdx: 1, nResIdx: 2, nVQuality: 4, ivRemoteView: listRemoteViewFix, ivLocalView: cameraView, ivRemoteZ: zoomView)
         } else {
             let systemSoundID: SystemSoundID = 1254
@@ -490,13 +488,40 @@ class QmeraVideoViewController: UIViewController {
             let alert = UIAlertController(title: "End Video Call".localized(), message: "Are you sure you want to end video call?".localized(), preferredStyle: .alert)
             alert.addAction(UIAlertAction(title: "No".localized(), style: UIAlertAction.Style.default, handler: nil))
             alert.addAction(UIAlertAction(title: "Yes".localized(), style: UIAlertAction.Style.default, handler: {(_) in
+                if self.labelIncomingOutgoing.isDescendant(of: self.view) {
+                    self.labelIncomingOutgoing.text = "Video call is over".localized()
+                }
+                if self.stackViewToolbar.isDescendant(of: self.view){
+                    self.stackViewToolbar.removeFromSuperview()
+                }
+                if self.stackViewToolbar2.isDescendant(of: self.view){
+                    self.stackViewToolbar2.removeFromSuperview()
+                }
+                if self.buttonWB.isDescendant(of: self.view){
+                    self.buttonWB.removeFromSuperview()
+                }
+                if self.buttonDecline.isDescendant(of: self.view) {
+                    self.buttonDecline.removeFromSuperview()
+                }
+                if self.buttonAccept.isDescendant(of: self.view) {
+                    self.buttonAccept.removeFromSuperview()
+                }
+                if self.buttonRotate.isDescendant(of: self.view) {
+                    self.buttonRotate.removeFromSuperview()
+                }
+                if self.wbVC != nil{
+                    self.wbVC!.close?()
+                }
                 self.wbTimer.invalidate()
                 self.vcTimer.invalidate()
+                self.labelTimerVC.text = "Video call is over".localized()
                 self.endAllCall()
-                if self.isInisiator {
-                    self.navigationController?.popViewController(animated: true)
-                } else {
-                    self.dismiss(animated: true, completion: nil)
+                DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
+                    if self.isInisiator {
+                        self.navigationController?.popViewController(animated: true)
+                    } else {
+                        self.dismiss(animated: true, completion: nil)
+                    }
                 }
             }))
             self.present(alert, animated: true, completion: nil)
@@ -873,8 +898,7 @@ class QmeraVideoViewController: UIViewController {
             }
         }
         else if (state == 34){
-            let channel = arrayMessage[arrayMessage.count - 1]
-            if(remoteChannel[String(channel)] != "2"){
+            if(arrayMessage[3] == "0"){
                 DispatchQueue.main.async {
                     self.zoomView.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: (CGFloat.pi)/2)
                 }
@@ -1088,9 +1112,12 @@ class QmeraVideoViewController: UIViewController {
                     let indexPerson = self.dataPerson.firstIndex(where: {$0["f_pin"]!! == arrayMessage[0]})
                     if indexPerson != nil {
                         if (self.dataPerson.count == 2) {
+                            self.containerLabelName.forEach({ $0.subviews.forEach({ $0.removeFromSuperview() }) })
                             self.scrollRemoteView.subviews.forEach({ $0.removeFromSuperview() })
                         } else {
+                            self.containerLabelName[indexPerson! + indexPerson!].subviews.forEach({ $0.removeFromSuperview() })
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
+                            self.containerLabelName[indexPerson! + indexPerson!].subviews.forEach({ $0.removeFromSuperview() })
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
                             if indexPerson! + 1 <= self.listRemoteViewFix.count {
                                 let iLoop = (self.listRemoteViewFix.count - 1) - (indexPerson! + 1)
@@ -1138,9 +1165,12 @@ class QmeraVideoViewController: UIViewController {
                     let indexPerson = self.dataPerson.firstIndex(where: {$0["f_pin"]!! == arrayMessage[0]})
                     if indexPerson != nil {
                         if (self.dataPerson.count == 2) {
+                            self.containerLabelName.forEach({ $0.subviews.forEach({ $0.removeFromSuperview() }) })
                             self.scrollRemoteView.subviews.forEach({ $0.removeFromSuperview() })
                         } else {
+                            self.containerLabelName[indexPerson! + indexPerson!].subviews.forEach({ $0.removeFromSuperview() })
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
+                            self.containerLabelName[indexPerson! + indexPerson!].subviews.forEach({ $0.removeFromSuperview() })
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
                             if indexPerson! + 1 <= self.listRemoteViewFix.count {
                                 let viewAfterRemote = self.listRemoteViewFix[indexPerson! + 1]
@@ -1201,9 +1231,12 @@ class QmeraVideoViewController: UIViewController {
                     let indexPerson = self.dataPerson.firstIndex(where: {$0["f_pin"]!! == arrayMessage[0]})
                     if indexPerson != nil {
                         if (self.dataPerson.count == 2) {
+                            self.containerLabelName.forEach({ $0.subviews.forEach({ $0.removeFromSuperview() }) })
                             self.scrollRemoteView.subviews.forEach({ $0.removeFromSuperview() })
                         } else {
+                            self.containerLabelName[indexPerson! + indexPerson!].subviews.forEach({ $0.removeFromSuperview() })
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
+                            self.containerLabelName[indexPerson! + indexPerson!].subviews.forEach({ $0.removeFromSuperview() })
                             self.scrollRemoteView.subviews[indexPerson! + indexPerson!].removeFromSuperview()
                             if indexPerson! + 1 <= self.listRemoteViewFix.count {
                                 let viewAfterRemote = self.listRemoteViewFix[indexPerson! + 1]

+ 3 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ContactChatViewController.swift

@@ -725,8 +725,10 @@ extension ContactChatViewController {
         if value == 0 {
             noData = true
             value = 1
+            tableView.separatorStyle = .none
         } else {
             noData = false
+            tableView.separatorStyle = .singleLine
         }
         return value
     }
@@ -747,7 +749,7 @@ extension ContactChatViewController {
                 labelNochat.textColor = .black
                 content.addSubview(labelNochat)
                 labelNochat.anchor(centerX: content.centerXAnchor, centerY: content.centerYAnchor)
-                cell.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: .greatestFiniteMagnitude)
+                cell.backgroundColor = .clear
                 return cell
             }
             let data: Chat

+ 58 - 40
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ProfileViewController.swift

@@ -63,6 +63,8 @@ public class ProfileViewController: UITableViewController {
     
     var isLoadingAddFriend = false
     
+    var publicBanner = FloatingNotificationBanner()
+    
     private func reload() {
         if let user = self.user {
             self.navigationController?.navigationBar.topItem?.title = "\(user.firstName) \(user.lastName)"
@@ -248,8 +250,9 @@ public class ProfileViewController: UITableViewController {
         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()
+            publicBanner.dismiss()
+            publicBanner = 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)
+            publicBanner.show()
             self.switchPrivateAccount.setOn(!value, animated: true)
             return
         }
@@ -263,18 +266,20 @@ public class ProfileViewController: UITableViewController {
                             "offline_mode" : value ? "0" : "1"
                         ], _where: "f_pin = '\(self.data)'")
                     })
-                    DispatchQueue.main.async {
+                    DispatchQueue.main.async { [self] in
                         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()
+                        publicBanner.dismiss()
+                        publicBanner = 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)
+                        publicBanner.show()
                     }
                 } else {
-                    DispatchQueue.main.async {
+                    DispatchQueue.main.async { [self] in
                         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: .center)
-                        banner.show()
+                        publicBanner.dismiss()
+                        publicBanner = 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: .center)
+                        publicBanner.show()
                         self.switchPrivateAccount.setOn(!value, animated: true)
                     }
                 }
@@ -287,8 +292,9 @@ public class ProfileViewController: UITableViewController {
         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()
+            publicBanner.dismiss()
+            publicBanner = 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)
+            publicBanner.show()
             self.switchPrivateAccount.setOn(!value, animated: true)
             return
         }
@@ -302,18 +308,20 @@ public class ProfileViewController: UITableViewController {
                             "privacy_flag" : value ? "1" : "0"
                         ], _where: "f_pin = '\(self.data)'")
                     })
-                    DispatchQueue.main.async {
+                    DispatchQueue.main.async { [self] in
                         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()
+                        publicBanner.dismiss()
+                        publicBanner = 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)
+                        publicBanner.show()
                     }
                 } else {
-                    DispatchQueue.main.async {
+                    DispatchQueue.main.async { [self] in
                         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: .center)
-                        banner.show()
+                        publicBanner.dismiss()
+                        publicBanner = 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: .center)
+                        publicBanner.show()
                         self.switchPrivateAccount.setOn(!value, animated: true)
                     }
                 }
@@ -345,15 +353,17 @@ public class ProfileViewController: UITableViewController {
             }
             let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
             imageView.tintColor = .white
-            let banner = FloatingNotificationBanner(title: title, 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()
+            publicBanner.dismiss()
+            publicBanner = FloatingNotificationBanner(title: title, 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)
+            publicBanner.show()
             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()
+            publicBanner.dismiss()
+            publicBanner = 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)
+            publicBanner.show()
             return
         }
         let controller = QmeraAudioViewController()
@@ -372,15 +382,17 @@ public class ProfileViewController: UITableViewController {
             }
             let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
             imageView.tintColor = .white
-            let banner = FloatingNotificationBanner(title: title, 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()
+            publicBanner.dismiss()
+            publicBanner = FloatingNotificationBanner(title: title, 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)
+            publicBanner.show()
             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()
+            publicBanner.dismiss()
+            publicBanner = 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)
+            publicBanner.show()
             return
         }
         if let user = user {
@@ -458,14 +470,15 @@ public class ProfileViewController: UITableViewController {
                         })
                         NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
                         
-                        DispatchQueue.main.async {
+                        DispatchQueue.main.async { [self] in
                             self.profile.image = UIImage(systemName: "person.circle.fill")!
                             self.profile.backgroundColor = .white
                             self.user?.thumb = ""
                             let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
                             imageView.tintColor = .white
-                            let banner = FloatingNotificationBanner(title: "Successfully removed profile picture".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()
+                            publicBanner.dismiss()
+                            publicBanner = FloatingNotificationBanner(title: "Successfully removed profile picture".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)
+                            publicBanner.show()
                             self.dismissImage?(UIImage(systemName: "person.circle.fill")!, "")
                         }
                     }
@@ -494,19 +507,21 @@ public class ProfileViewController: UITableViewController {
         }
         isLoadingAddFriend = true
         addFriend { result in
-            DispatchQueue.main.async {
+            DispatchQueue.main.async { [self] in
                 if result {
                     let imageView = UIImageView(image: UIImage(systemName: "checkmark.circle.fill"))
                     imageView.tintColor = .white
-                    let banner = FloatingNotificationBanner(title: "Successfully add friend".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()
+                    publicBanner.dismiss()
+                    publicBanner = FloatingNotificationBanner(title: "Successfully add friend".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)
+                    publicBanner.show()
                     self.isDismiss?()
                     self.navigationController?.popViewController(animated: true)
                 } else {
                     let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
                     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)
-                    banner.show()
+                    publicBanner.dismiss()
+                    publicBanner = 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)
+                    publicBanner.show()
                     self.isLoadingAddFriend = false
                 }
             }
@@ -532,7 +547,7 @@ public class ProfileViewController: UITableViewController {
         alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
             Nexilis.showLoader()
             self.unFriend { result in
-                DispatchQueue.main.async {
+                DispatchQueue.main.async { [self] in
                     if result {
                         Database.shared.database?.inTransaction({ (fmdb, rollback) in
                             if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "select * from BUDDY where f_pin = '\(self.data)'"), cursor.next() {
@@ -566,8 +581,9 @@ public class ProfileViewController: UITableViewController {
                         Nexilis.hideLoader(completion: {})
                         let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
                         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)
-                        banner.show()
+                        publicBanner.dismiss()
+                        publicBanner = 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)
+                        publicBanner.show()
                     }
                 }
             }
@@ -597,8 +613,9 @@ public class ProfileViewController: UITableViewController {
             }
             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()
+            self.publicBanner.dismiss()
+            self.publicBanner = 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)
+            self.publicBanner.show()
         }
         navigationItem.backButtonTitle = ""
         navigationController?.show(controller, sender: nil)
@@ -667,13 +684,14 @@ extension ProfileViewController: ImageVideoPickerDelegate {
                                 NotificationCenter.default.post(name: NSNotification.Name(rawValue: "updateFifthTab"), object: nil, userInfo: nil)
                                 
                                 DispatchQueue.main.async {
-                                    Nexilis.hideLoader(completion: {
+                                    Nexilis.hideLoader(completion: { [self] in
                                         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 profile picture".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()
+                                        publicBanner.dismiss()
+                                        publicBanner = FloatingNotificationBanner(title: "Successfully changed profile picture".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)
+                                        publicBanner.show()
                                         self.dismissImage?(image, fileDir.lastPathComponent)
                                     })
                                 }