alqindiirsyam 2 年之前
父节点
当前提交
f7946ece7f

+ 2 - 2
appbuilder-ios/AppBuilder/AppBuilder.xcodeproj/project.pbxproj

@@ -444,7 +444,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 2.2.4;
+				MARKETING_VERSION = 2.2.5;
 				PRODUCT_BUNDLE_IDENTIFIER = io.newuniverse.AppBuilder;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -474,7 +474,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 2.2.4;
+				MARKETING_VERSION = 2.2.5;
 				PRODUCT_BUNDLE_IDENTIFIER = io.newuniverse.AppBuilder;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";

+ 7 - 0
appbuilder-ios/AppBuilder/AppBuilder/FourthTabViewController.swift

@@ -474,6 +474,13 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
             let alert = UIAlertController(title: "Sign-Out".localized(), message: "Are you sure want to logout?".localized(), preferredStyle: .alert)
             alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
             alert.addAction(UIAlertAction(title: "Yes".localized(), style: .destructive, handler: {(_) in
+                var viewController = UIApplication.shared.windows.first!.rootViewController
+                if !(viewController is ViewController) {
+                    viewController = self.parent
+                }
+                if !(viewController?.tabBarController?.selectedViewController is FourthTabViewController) {
+                    return
+                }
                 if !CheckConnection.isConnectedToNetwork()  || API.nGetCLXConnState() == 0 {
                     let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
                     imageView.tintColor = .white

+ 2 - 2
appbuilder-ios/AppBuilder/AppBuilder/Info.plist

@@ -22,8 +22,6 @@
 	<string>$(CURRENT_PROJECT_VERSION)</string>
 	<key>LSRequiresIPhoneOS</key>
 	<true/>
-    <key>UIViewControllerBasedStatusBarAppearance</key>
-    <true/>
 	<key>NSCameraUsageDescription</key>
 	<string>Video Call, Conference Room, Content Creation and Live Streaming.</string>
 	<key>NSContactsUsageDescription</key>
@@ -100,5 +98,7 @@
 	</array>
 	<key>UIUserInterfaceStyle</key>
 	<string>Light</string>
+	<key>UIViewControllerBasedStatusBarAppearance</key>
+	<true/>
 </dict>
 </plist>

+ 46 - 0
appbuilder-ios/AppBuilder/AppBuilder/ViewController.swift

@@ -51,6 +51,8 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
     let term = "Terms of Service.".localized()
     var firstLoad = true
     let privacyWV = WKWebView()
+    let indicatorCounterFB = UIView()
+    let labelCounterFB = UILabel()
     
     public static var def: ViewController?
 
@@ -167,6 +169,50 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
             tabBar.selectionIndicatorImage = UIImage.imageWithColor(color: UIColor.gray, size: tabBarItemSize).resizableImage(withCapInsets: .zero)
         }
         UIFont.overrideInitialize()
+        let center: NotificationCenter = NotificationCenter.default
+        center.addObserver(self, selector: #selector(checkCounter), name: NSNotification.Name(rawValue: "onReceiveChat"), object: nil)
+        center.addObserver(self, selector: #selector(checkCounter), name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil)
+        checkCounter()
+    }
+    
+    @objc func checkCounter() {
+        DispatchQueue.main.async { [self] in
+            if self.viewControllers?.firstIndex(of: secondTab!) != nil {
+                let counter = queryCountCounter()
+                let indexSecondTab = self.viewControllers?.firstIndex(of: secondTab!)
+                let viewSecondTab = self.tabBar.items?[indexSecondTab!].value(forKey: "view") as! UIView
+                if counter > 0 {
+                    if !indicatorCounterFB.isDescendant(of: viewSecondTab) {
+                        let viewSecondTab = self.tabBar.items?[indexSecondTab!].value(forKey: "view") as! UIView
+                        indicatorCounterFB.backgroundColor = .red
+                        indicatorCounterFB.layer.cornerRadius = 7.5
+                        indicatorCounterFB.clipsToBounds = true
+                        viewSecondTab.addSubview(indicatorCounterFB)
+                        indicatorCounterFB.anchor(top: viewSecondTab.topAnchor, right: viewSecondTab.rightAnchor, paddingRight: 20, height: 15, minWidth: 15, maxWidth: 20)
+                        indicatorCounterFB.addSubview(labelCounterFB)
+                        labelCounterFB.anchor(left: indicatorCounterFB.leftAnchor, right: indicatorCounterFB.rightAnchor, paddingLeft: 5, paddingRight: 5, centerX: indicatorCounterFB.centerXAnchor, centerY: indicatorCounterFB.centerYAnchor)
+                        labelCounterFB.font = .systemFont(ofSize: 10)
+                        labelCounterFB.textColor = .white
+                    }
+                    labelCounterFB.text = "\(counter)"
+                } else {
+                    if indicatorCounterFB.isDescendant(of: viewSecondTab) {
+                        indicatorCounterFB.removeFromSuperview()
+                    }
+                }
+            }
+        }
+    }
+    
+    private func queryCountCounter() -> Int32 {
+        var counter: Int32?
+        Database.shared.database?.inTransaction({ (fmdb, rollback) in
+            if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT SUM(counter) FROM MESSAGE_SUMMARY"), cursor.next() {
+                counter = cursor.int(forColumnIndex: 0)
+                cursor.close()
+            }
+        })
+        return counter ?? 0
     }
 
 //    override func viewDidLayoutSubviews() {

+ 1 - 4
appbuilder-ios/NexilisLite/NexilisLite/Resource/Palio.storyboard

@@ -43,9 +43,6 @@
                                                         <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AvU-Lw-e4I">
                                                             <rect key="frame" x="359.5" y="10" width="24.5" height="40"/>
                                                             <state key="normal" image="video" catalog="system"/>
-                                                            <connections>
-                                                                <segue destination="gD1-QK-4o7" kind="show" identifier="videoVC" id="gV7-Kp-ySR"/>
-                                                            </connections>
                                                         </button>
                                                         <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cRU-ZV-Wgk">
                                                             <rect key="frame" x="318.5" y="10" width="21" height="40"/>
@@ -1824,7 +1821,7 @@
             <objects>
                 <viewController storyboardIdentifier="videoVCQmera" id="gD1-QK-4o7" customClass="QmeraVideoViewController" customModule="NexilisLite" customModuleProvider="target" sceneMemberID="viewController">
                     <view key="view" contentMode="scaleToFill" id="v1l-Ih-Bwq">
-                        <rect key="frame" x="0.0" y="0.0" width="414" height="838"/>
+                        <rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                         <viewLayoutGuide key="safeArea" id="ls5-RN-thL"/>
                         <color key="backgroundColor" systemColor="systemBackgroundColor"/>

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

@@ -254,3 +254,5 @@
 "Title and message must not be empty" = "Judul dan pesan tidak boleh kosong";
 "Please select at least one contact" = "Harap pilih setidaknya satu kontak";
 "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";

+ 6 - 1
appbuilder-ios/NexilisLite/NexilisLite/Source/IncomingThread.swift

@@ -55,7 +55,9 @@ class IncomingThread {
             pushMyself(message: message)
         } else if message.getCode() == CoreMessage_TMessageCode.PUSH_BUDDY {
             makeNotifAddFriend(message: message)
-            initBatchBuddy(message: message)
+            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
+                self.initBatchBuddy(message: message)
+            })
         } else if message.getCode() == CoreMessage_TMessageCode.INIT_BATCH_BUDDY {
             initBatchBuddy(message: message)
         } else if message.getCode() == CoreMessage_TMessageCode.CHANGE_BATCH_PERSON_INFO {
@@ -165,6 +167,9 @@ class IncomingThread {
                 DispatchQueue.main.async {
                     let f_pin = CoreMessage_TMessageUtil.getString(json: json, key: CoreMessage_TMessageKey.F_PIN)
                     Database.shared.database?.inTransaction({ (fmdb, rollback) in
+                        if message.getPIN() == User.getMyPin() {
+                            return
+                        }
                         if let cursorUser = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin FROM BUDDY where f_pin='\(f_pin)'"), cursorUser.next() {
                             return
                         }

+ 0 - 7
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/CallProviderDelegate.swift

@@ -190,13 +190,6 @@ extension CallProviderDelegate: CXProviderDelegate {
     
     func provider(_ provider: CXProvider, didDeactivate audioSession: AVAudioSession) {
         print("Received", #function)
-        
-//        do {
-//            try AVAudioSession.sharedInstance().setCategory(.ambient)
-//            try AVAudioSession.sharedInstance().setMode(.default)
-//            try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
-//        } catch {
-//        }
         /*
          Restart any non-call related audio now that the app's audio session is deactivated,
          after having its priority restored to normal.

+ 9 - 10
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraAudioViewController.swift

@@ -188,8 +188,8 @@ class QmeraAudioViewController: UIViewController {
         button.imageEdgeInsets = UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
         button.contentVerticalAlignment = .fill
         button.contentHorizontalAlignment = .fill
-        button.frame.size.width = 30
-        button.frame.size.height = 30
+//        button.frame.size.width = 30
+//        button.frame.size.height = 30
         return button
     }()
     
@@ -201,8 +201,8 @@ class QmeraAudioViewController: UIViewController {
         button.imageEdgeInsets = UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
         button.contentVerticalAlignment = .fill
         button.contentHorizontalAlignment = .fill
-        button.frame.size.width = 30
-        button.frame.size.height = 30
+//        button.frame.size.width = 30
+//        button.frame.size.height = 30
         return button
     }()
     
@@ -337,7 +337,6 @@ class QmeraAudioViewController: UIViewController {
         NSLayoutConstraint.activate([
             constraintRightPowered,
             constraintBottomPowered,
-            poweredByView.heightAnchor.constraint(equalToConstant: 40.0),
             nexilisLogo.widthAnchor.constraint(equalToConstant: 30.0),
             nexilisLogo.heightAnchor.constraint(equalToConstant: 30.0)
         ])
@@ -606,7 +605,7 @@ class QmeraAudioViewController: UIViewController {
                                 self.status.text = "Call Center Session has ended..."
                                 self.end.isEnabled = false
                             }
-                            DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
+                            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                                 self.didEnd(sender: true)
                             }
                             return
@@ -624,7 +623,7 @@ class QmeraAudioViewController: UIViewController {
                             self.status.text = "Call Center Session has ended..."
                             self.end.isEnabled = false
                         }
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                             self.didEnd(sender: true)
                         }
                         return
@@ -641,7 +640,7 @@ class QmeraAudioViewController: UIViewController {
                                 controller!.dismiss(animated: true)
                             }
                         }
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                             self.didEnd(sender: true)
                         }
                         return
@@ -674,7 +673,7 @@ class QmeraAudioViewController: UIViewController {
                     DispatchQueue.main.async {
                         self.status.text = "Offline..."
                         self.end.isEnabled = false
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                             self.didEnd(sender: false)
                         }
                     }
@@ -701,7 +700,7 @@ class QmeraAudioViewController: UIViewController {
                     DispatchQueue.main.async {
                         self.status.text = "Busy..."
                         self.end.isEnabled = false
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
+                        DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                             self.didEnd(sender: false)
                         }
                     }

+ 47 - 32
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Call/QmeraVideoViewController.swift

@@ -89,8 +89,8 @@ class QmeraVideoViewController: UIViewController {
         button.imageEdgeInsets = UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
         button.contentVerticalAlignment = .fill
         button.contentHorizontalAlignment = .fill
-        button.frame.size.width = 30
-        button.frame.size.height = 30
+//        button.frame.size.width = 30
+//        button.frame.size.height = 30
         return button
     }()
     
@@ -102,8 +102,8 @@ class QmeraVideoViewController: UIViewController {
         button.imageEdgeInsets = UIEdgeInsets(top: 2, left: 2, bottom: 2, right: 2)
         button.contentVerticalAlignment = .fill
         button.contentHorizontalAlignment = .fill
-        button.frame.size.width = 30
-        button.frame.size.height = 30
+//        button.frame.size.width = 30
+//        button.frame.size.height = 30
         return button
     }()
     
@@ -143,6 +143,9 @@ class QmeraVideoViewController: UIViewController {
         navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
         navigationController?.changeAppearance(clear: true)
         
+        NotificationCenter.default.addObserver(self, selector: #selector(self.onStatusCall(_:)), name: NSNotification.Name(rawValue: "onStatusCall"), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(onReceiveMessage(notification:)), name: NSNotification.Name(rawValue: "onReceiveChat"), object: nil)
+        
         view.backgroundColor = .clear
         navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
         navigationController?.interactivePopGestureRecognizer?.isEnabled = false
@@ -159,8 +162,6 @@ class QmeraVideoViewController: UIViewController {
         Calling()
         addToolbar()
         addTimerVC()
-        NotificationCenter.default.addObserver(self, selector: #selector(self.onStatusCall(_:)), name: NSNotification.Name(rawValue: "onStatusCall"), object: nil)
-        NotificationCenter.default.addObserver(self, selector: #selector(onReceiveMessage(notification:)), name: NSNotification.Name(rawValue: "onReceiveChat"), object: nil)
         if isAutoAccept {
             didTapAcceptCallButton()
         }
@@ -229,7 +230,7 @@ class QmeraVideoViewController: UIViewController {
     
     func addTimerVC() {
         view.addSubview(containerTimerVC)
-        containerTimerVC.anchor(top: view.topAnchor, paddingTop: 20, centerX: view.centerXAnchor, height: 30, minWidth: 40)
+        containerTimerVC.anchor(top: view.topAnchor, paddingTop: 20, centerX: view.centerXAnchor, minWidth: 40)
         containerTimerVC.makeRoundedView(radius: 8)
         containerTimerVC.backgroundColor = .black.withAlphaComponent(0.3)
         containerTimerVC.addSubview(labelTimerVC)
@@ -364,6 +365,16 @@ class QmeraVideoViewController: UIViewController {
         ])
         if isInisiator {
             labelIncomingOutgoing.text = "Outgoing video call".localized() + "..."
+            if AVAudioSession.sharedInstance().category == .playAndRecord {
+                do {
+                    try AVAudioSession.sharedInstance().setCategory(.soloAmbient)
+        //            try AVAudioSession.sharedInstance().setMode(.default)
+        //            try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
+                } 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
@@ -492,22 +503,32 @@ class QmeraVideoViewController: UIViewController {
         }
     }
     
-    @objc func didTapAcceptCallButton(){
-        let goAudioCall = Nexilis.checkMicPermission()
-        let goVideoCall = Nexilis.checkCameraPermission()
-        if goVideoCall == 0 {
-            let alert = UIAlertController(title: "Attention!".localized(), message: !goAudioCall && goVideoCall == 0 ? "Please allow microphone & camera permission in your settings".localized() : !goAudioCall ? "Please allow microphone permission in your settings".localized() : "Please allow camera permission in your settings", preferredStyle: .alert)
-            alert.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: {_ in
-                if let url = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(url) {
-                    UIApplication.shared.open(url, options: [:], completionHandler: nil)
+    @objc func didTapAcceptCallButton() {
+        if !isInisiator{
+            let goAudioCall = Nexilis.checkMicPermission()
+            let goVideoCall = Nexilis.checkCameraPermission()
+            if goVideoCall == 0 {
+                let alert = UIAlertController(title: "Attention!".localized(), message: !goAudioCall && goVideoCall == 0 ? "Please allow microphone & camera permission in your settings".localized() : !goAudioCall ? "Please allow microphone permission in your settings".localized() : "Please allow camera permission in your settings", preferredStyle: .alert)
+                alert.addAction(UIAlertAction(title: "OK".localized(), style: UIAlertAction.Style.default, handler: {_ in
+                    if let url = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(url) {
+                        UIApplication.shared.open(url, options: [:], completionHandler: nil)
+                    }
+                }))
+                self.navigationController?.present(alert, animated: true, completion: nil)
+                return
+            } else if goVideoCall == -1 {
+                return
+            }
+            if AVAudioSession.sharedInstance().category == .playAndRecord {
+                do {
+                    try AVAudioSession.sharedInstance().setCategory(.soloAmbient)
+        //            try AVAudioSession.sharedInstance().setMode(.default)
+        //            try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
+                } catch {
                 }
-            }))
-            self.navigationController?.present(alert, animated: true, completion: nil)
-            return
-        } else if goVideoCall == -1 {
-            return
+            }
+            API.receiveCCall(sParty: dataPerson[0]["f_pin"]!, nCamIdx: 1, nResIdx: 2, nVQuality: 4, ivRemoteView: listRemoteViewFix, ivLocalView: cameraView,ivRemoteZ: zoomView)
         }
-        API.receiveCCall(sParty: dataPerson[0]["f_pin"]!, nCamIdx: 1, nResIdx: 2, nVQuality: 4, ivRemoteView: listRemoteViewFix, ivLocalView: cameraView,ivRemoteZ: zoomView)
         DispatchQueue.main.async {
             self.myImage.removeFromSuperview()
             self.name.removeFromSuperview()
@@ -697,7 +718,6 @@ class QmeraVideoViewController: UIViewController {
         NSLayoutConstraint.activate([
             constraintRightPowered,
             constraintBottomPowered,
-            poweredByView.heightAnchor.constraint(equalToConstant: 40.0),
             nexilisLogo.widthAnchor.constraint(equalToConstant: 30.0),
             nexilisLogo.heightAnchor.constraint(equalToConstant: 30.0)
         ])
@@ -856,12 +876,7 @@ class QmeraVideoViewController: UIViewController {
             let channel = arrayMessage[arrayMessage.count - 1]
             if(remoteChannel[String(channel)] != "2"){
                 DispatchQueue.main.async {
-                    if(arrayMessage[arrayMessage.count - 2] == "0"){ // back camera
-                        self.zoomView.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: (CGFloat.pi)/2)
-                    }
-                    else { // front camera
-                        self.zoomView.transform = CGAffineTransform.init(scaleX: -1.9, y: 1.9).rotated(by: (CGFloat.pi * 3)/2)
-                    }
+                    self.zoomView.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: (CGFloat.pi)/2)
                 }
             }
         }
@@ -1020,7 +1035,7 @@ class QmeraVideoViewController: UIViewController {
                         self.wbTimer.invalidate()
                         _ = Nexilis.getWhiteboardDelegate()?.terminate()
                     }
-                    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
+                    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                         self.endAllCall()
                         self.dismiss(animated: true, completion: nil)
                     }
@@ -1061,7 +1076,7 @@ class QmeraVideoViewController: UIViewController {
                     if controller != nil {
                         controller!.dismiss(animated: true)
                     }
-                    DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
+                    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                         self.endAllCall()
                         if self.isInisiator {
                             self.navigationController?.popViewController(animated: true)
@@ -1160,7 +1175,7 @@ class QmeraVideoViewController: UIViewController {
                 }
             }
             if (self.dataPerson.count == 1) {
-                DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
+                DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                     self.endAllCall()
                     if self.isInisiator && onGoingCC.isEmpty {
                         self.navigationController?.popViewController(animated: true)
@@ -1223,7 +1238,7 @@ class QmeraVideoViewController: UIViewController {
                 }
             }
             if (self.dataPerson.count == 1) {
-                DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
+                DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
                     self.endAllCall()
                     if self.isInisiator && onGoingCC.isEmpty {
                         self.navigationController?.popViewController(animated: true)

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

@@ -1632,6 +1632,9 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
         controller.data = dataPerson["f_pin"]!!
         controller.checkReadMessage = {
+            self.dataPerson.removeAll()
+            self.getDataProfile(fPin: self.unique_l_pin)
+            self.changeAppBar()
             if self.currentIndexpath == nil {
                 var listData = self.dataMessages
                 listData = listData.filter({$0["status"] as! String != "4" && $0["status"] as! String != "8"})
@@ -2385,6 +2388,24 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                             self.fPinContacCenter = data
                         }
                     }
+                } else {
+                    DispatchQueue.main.async {
+                        UserDefaults.standard.removeObject(forKey: "waitingRequestCC")
+                        var row: [String: Any?] = [:]
+                        row["message_id"] = ""
+                        row["chat_date"] = "Today".localized()
+                        row["attachment_flag"] = "504"
+                        let listStringName: [String] = ["Yes".localized(), "No".localized()]
+                        var data : [CategoryCC] = []
+                        for i in 0..<listStringName.count {
+                            data.append(CategoryCC(id: "level\(self.dataMessages.count + 1)_\(i)", service_id: service_id, service_name: listStringName[i], parent: "", description: "", is_tablet: "0"))
+                        }
+                        row["category_cc"] = data
+                        self.dataMessages.append(row)
+                        self.channelContactCenter = "\(channel)"
+                        self.tableChatView.insertRows(at: [IndexPath(row: self.dataMessages.count - 1, section: 0)], with: .none)
+                        self.tableChatView.scrollToBottom()
+                    }
                 }
             }
         }

+ 16 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Contact/ContactCallViewController.swift

@@ -231,6 +231,7 @@ extension ContactCallViewController: UITableViewDataSource {
                 cell.videoCallButton.tag = indexPath.row
                 
                 cell.audioCallButton.addTarget(self, action: #selector(call(sender:)), for: .touchUpInside)
+                cell.videoCallButton.addTarget(self, action: #selector(videoCall(sender:)), for: .touchUpInside)
             }
         }
         return cell
@@ -253,6 +254,21 @@ extension ContactCallViewController: UITableViewDataSource {
             present(controller, animated: true, completion: nil)
         }
     }
+    
+    @objc func videoCall(sender: Any) {
+        let index = sender as! UIButton
+        if !CheckConnection.isConnectedToNetwork() {
+            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+            imageView.tintColor = .white
+            let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+            banner.show()
+            return
+        }
+        let videoVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
+        videoVC.dataPerson.append(dataPerson[index.tag])
+        videoVC.modalPresentationStyle = .overFullScreen
+        self.show(videoVC, sender: nil)
+    }
 }
 
 class ContactCallCell: UITableViewCell {

+ 10 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Control/ProfileViewController.swift

@@ -185,6 +185,8 @@ public class ProfileViewController: UITableViewController {
     public override func viewDidLoad() {
         super.viewDidLoad()
         
+        pullBuddy()
+        
         profile.circle()
         profile.contentMode = .scaleAspectFill
         
@@ -629,6 +631,14 @@ public class ProfileViewController: UITableViewController {
 
         return 200
     }
+    
+    private func pullBuddy() {
+        if let me = UserDefaults.standard.string(forKey: "me") {
+            DispatchQueue.global().async {
+                let _ = Nexilis.write(message: CoreMessage_TMessageBank.getBatchBuddiesInfos(p_f_pin: me, last_update: 0))
+            }
+        }
+    }
 }
 
 extension ProfileViewController: ImageVideoPickerDelegate {