Sfoglia il codice sorgente

update fix notification APN and release for 5.0.71

alqindiirsyam 1 mese fa
parent
commit
4a22537996

+ 4 - 4
AppBuilder/AppBuilder.xcodeproj/project.pbxproj

@@ -568,7 +568,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 5.0.68;
+				MARKETING_VERSION = 5.0.71;
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -604,7 +604,7 @@
 					"$(inherited)",
 					"@executable_path/Frameworks",
 				);
-				MARKETING_VERSION = 5.0.68;
+				MARKETING_VERSION = 5.0.71;
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -640,7 +640,7 @@
 					"@executable_path/../../Frameworks",
 				);
 				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
-				MARKETING_VERSION = 5.0.68;
+				MARKETING_VERSION = 5.0.71;
 				OTHER_CFLAGS = "-fstack-protector-strong";
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder.AppBuilderShare;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -679,7 +679,7 @@
 					"@executable_path/../../Frameworks",
 				);
 				LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
-				MARKETING_VERSION = 5.0.68;
+				MARKETING_VERSION = 5.0.71;
 				OTHER_CFLAGS = "-fstack-protector-strong";
 				PRODUCT_BUNDLE_IDENTIFIER = io.nexilis.appbuilder.AppBuilderShare;
 				PRODUCT_NAME = "$(TARGET_NAME)";

+ 33 - 25
NexilisLite/NexilisLite/Source/APIS.swift

@@ -1568,7 +1568,7 @@ public class APIS: NSObject {
     public static func showNotificationNexilis(_ userInfo: [AnyHashable : Any]) {
         DispatchQueue.main.async {
             if checkAppStateisBackground() {
-                DispatchQueue.global(qos: .userInitiated).async {
+                DispatchQueue.global(qos: .background).async {
                     if let payload = userInfo["payload"] as? [String: Any] {
                         if let messagePayload = payload["message"] as? [String: Any] {
                             if let data = messagePayload["data"] as? [String: Any] {
@@ -1660,6 +1660,10 @@ public class APIS: NSObject {
                             }
                         }
                     } else if let message_id = userInfo["message_id"] as? String {
+                        DispatchQueue.main.async {
+                            let lastBadgeNumber = UIApplication.shared.applicationIconBadgeNumber
+                            UIApplication.shared.applicationIconBadgeNumber = lastBadgeNumber + 1
+                        }
                         getMessageById(id: message_id)
                     }
                 }
@@ -1718,7 +1722,7 @@ public class APIS: NSObject {
     }
     
     static func ackAPN(id: String) {
-        DispatchQueue.global().async {
+        DispatchQueue.global(qos: .background).async {
 //            Nexilis.sendStateToServer(s: "send ack from apn")
 //            if API.nGetCLXConnState() == 0 {
 //                do {
@@ -1797,7 +1801,7 @@ public class APIS: NSObject {
                 let ret = retry + 1
                 if ret <= 5 {
                     let delay = pow(2.0, Double(ret)) // 2, 4, 8, 16...
-                    DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + delay) {
+                    DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + delay) {
                         getMessageById(id: id, retry: ret)
                     }
                 }
@@ -1807,34 +1811,38 @@ public class APIS: NSObject {
             guard let data = data else {
                 let ret = retry + 1
                 if ret <= 5 {
-                    DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 1) {
+                    DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 1) {
                         getMessageById(id: id, retry: ret)
                     }
                 }
                 return
             }
-            
-            do {
-                if let jsonObj = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
-                    let dataObj = jsonObj["data"] as? String ?? ""
-                    let message = TMessage(data: dataObj)
-                    
-                    // simpan message
-                    Nexilis.saveMessage(message: message, withStatus: false, fromAPNS: true)
-                    ackAPN(id: id)
-                    
-                    DispatchQueue.main.async {
-                        UIApplication.shared.applicationIconBadgeNumber = Int(APIS.getTotalCounter())
-                    }
-                } else {
-                    throw NSError(domain: "Invalid JSON", code: -1)
+            DispatchQueue.main.async {
+                if !APIS.checkAppStateisBackground() {
+                    return
                 }
-            } catch {
-                print("Parsing error: \(error)")
-                let ret = retry + 1
-                if ret <= 5 {
-                    DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 1) {
-                        getMessageById(id: id, retry: ret)
+                do {
+                    if let jsonObj = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
+                        let dataObj = jsonObj["data"] as? String ?? ""
+                        let message = TMessage(data: dataObj)
+                        
+                        // simpan message
+                        Nexilis.saveMessage(message: message, withStatus: false, fromAPNS: true)
+                        ackAPN(id: id)
+                        
+                        DispatchQueue.main.async {
+                            UIApplication.shared.applicationIconBadgeNumber = Int(APIS.getTotalCounter())
+                        }
+                    } else {
+                        throw NSError(domain: "Invalid JSON", code: -1)
+                    }
+                } catch {
+                    print("Parsing error: \(error)")
+                    let ret = retry + 1
+                    if ret <= 5 {
+                        DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
+                            getMessageById(id: id, retry: ret)
+                        }
                     }
                 }
             }

+ 1 - 1
NexilisLite/NexilisLite/Source/Nexilis.swift

@@ -19,7 +19,7 @@ import CryptoKit
 import WebKit
 
 public class Nexilis: NSObject {
-    public static var cpaasVersion = "5.0.68"
+    public static var cpaasVersion = "5.0.71"
     public static var sAPIKey = ""
     
     public static var ADDRESS = ""

+ 12 - 13
NexilisLite/NexilisLite/Source/Utils.swift

@@ -742,14 +742,19 @@ public final class Utils {
         request.setValue(Utils.getUserAgent(), forHTTPHeaderField: "User-Agent")
         request.setValue(Utils.getCookiesMobile(), forHTTPHeaderField: "Cookie")
         //print("DATA SEND MOBILE \(Utils.getUserAgent()) <> \(Utils.getCookiesMobile())")
+        let task = self.sharedSession.dataTask(with: request, completionHandler: completion)
+        task.resume()
+    }
+    
+    private static let sharedSession: URLSession = {
         let urlConfig = URLSessionConfiguration.default
         urlConfig.timeoutIntervalForRequest = 30.0
         urlConfig.timeoutIntervalForResource = 60.0
-        let sessionDelegate = SelfSignedURLSessionDelegate()
-        let session = URLSession(configuration: urlConfig, delegate: sessionDelegate, delegateQueue: nil)
-        let task = session.dataTask(with: request, completionHandler: completion)
-        task.resume()
-    }
+        urlConfig.waitsForConnectivity = true
+        urlConfig.isDiscretionary = false
+        urlConfig.sessionSendsLaunchEvents = true
+        return URLSession(configuration: urlConfig, delegate: SelfSignedURLSessionDelegate(), delegateQueue: nil)
+    }()
     
     public static func postDataWithCookiesAndUserAgent(from url: URL, parameter: [String: Any] = [:], parameters: [[String: Any]] = [], isFormData: Bool = false, completion: @escaping (Data?, URLResponse?, Error?) -> ()) {
         let apiKey: String = SecureUserDefaults.shared.value(forKey: "apiKey") ?? ""
@@ -777,6 +782,7 @@ public final class Utils {
         request.httpMethod = "POST"
         request.setValue(Utils.getUserAgent(), forHTTPHeaderField: "User-Agent")
         request.setValue(Utils.getCookiesMobile(), forHTTPHeaderField: "Cookie")
+        request.setValue("keep-alive", forHTTPHeaderField: "Connection")
         if isFormData {
             request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
         } else {
@@ -785,14 +791,7 @@ public final class Utils {
         }
         request.httpBody = jsonData
         //print("DATA SEND MOBILE \(Utils.getUserAgent()) <> \(Utils.getCookiesMobile())")
-        let urlConfig = URLSessionConfiguration.default
-        urlConfig.timeoutIntervalForRequest = 30.0
-        urlConfig.timeoutIntervalForResource = 60.0
-        urlConfig.isDiscretionary = false
-        urlConfig.sessionSendsLaunchEvents = true
-        let sessionDelegate = SelfSignedURLSessionDelegate()
-        let session = URLSession(configuration: urlConfig, delegate: sessionDelegate, delegateQueue: nil)
-        let task = session.dataTask(with: request, completionHandler: completion)
+        let task = self.sharedSession.dataTask(with: request, completionHandler: completion)
         task.resume()
     }
     

+ 57 - 0
NexilisLite/NexilisLite/Source/View/BNIView/BNIBookingWebView.swift

@@ -10,6 +10,8 @@ import UIKit
 import WebKit
 import Speech
 import CommonCrypto
+import nuSDKService
+import NotificationBannerSwift
 
 public class BNIBookingWebView: UIViewController, WKNavigationDelegate, UIScrollViewDelegate, UIGestureRecognizerDelegate, WKScriptMessageHandler, SFSpeechRecognizerDelegate, ImageVideoPickerDelegate {
     var webView: WKWebView!
@@ -159,6 +161,7 @@ public class BNIBookingWebView: UIViewController, WKNavigationDelegate, UIScroll
         contentController.add(self, name: "shareText")
         contentController.add(self, name: "openGalleryiOS")
         contentController.add(self, name: "openChannel")
+        contentController.add(self, name: "setFirstTheme")
         
         let source: String = "var meta = document.createElement('meta');" +
             "meta.name = 'viewport';" +
@@ -624,6 +627,60 @@ public class BNIBookingWebView: UIViewController, WKNavigationDelegate, UIScroll
             }
             alertController.addAction(UIAlertAction(title: "Cancel".localized(), style: .cancel, handler: nil))
             self.present(alertController, animated: true)
+        } else if message.name == "setFirstTheme" {
+            if !CheckConnection.isConnectedToNetwork()  || API.nGetCLXConnState() == 0 {
+                let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                imageView.tintColor = .white
+                let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
+                banner.show()
+                return
+            }
+            Nexilis.showLoader()
+            DispatchQueue.global().async {
+                if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.backToSuperApp(), timeout: 30 * 1000) {
+                    DispatchQueue.main.async {
+                        if response.isOk() {
+                            Utils.setMyTheme(value: "")
+                            Utils.setIsLoadThemeFromOther(value: false)
+                            Utils.resetValueSuperApp()
+                            Utils.setValueInitialApp(data: Utils.getPrefTheme())
+                            Utils.setLastTabSelected(value: 0)
+                            Utils.setIsWATheme(value: false)
+                            UIApplication.shared.setAlternateIconName(nil)
+                            Nexilis.hideLoader {
+                                let alert = LibAlertController(title: "Successfully changed".localized(), message: "Please open the app again to see the changes".localized(), preferredStyle: .alert)
+                                alert.addAction(UIAlertAction(title: "OK".localized(), style: .default, handler: {(_) in
+                                    exit(0)
+                                }))
+                                self.present(alert, animated: true, completion: nil)
+                            }
+                        } else if response.getBody(key: CoreMessage_TMessageKey.ERRCOD, default_value: "99") == "10" {
+                            Nexilis.hideLoader(completion: {
+                                let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
+                                imageView.tintColor = .white
+                                let banner = FloatingNotificationBanner(title: "Failed to back to Company App".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 {
+                            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 {
+                    DispatchQueue.main.async {
+                        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()
+                        })
+                    }
+                }
+            }
         }
     }
     

+ 44 - 44
NexilisLite/NexilisLite/Source/View/Chat/ChatGPTBotView.swift

@@ -104,16 +104,16 @@ public class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
             self.navigationController?.setNavigationBarHidden(false, animated: false)
         }
         gettingDataMessage = false
-        let indexPath = tableChatView.indexPathsForVisibleRows?.first
-        if indexPath != nil {
-            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-            let isPinned = headerRect.origin.y <= tableChatView.contentOffset.y
-            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
-                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                let headerView = listViewOnSection[sect]
-                headerView.isHidden = true
-            }
-        }
+//        let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//        if indexPath != nil {
+//            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//            let isPinned = headerRect.origin.y <= tableChatView.contentOffset.y
+//            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
+//                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                let headerView = listViewOnSection[sect]
+//                headerView.isHidden = true
+//            }
+//        }
     }
     
     public override func viewDidLoad() {
@@ -1253,13 +1253,13 @@ public class ChatGPTBotView: UIViewController, UIGestureRecognizerDelegate {
                     }
                 }
             }
-            let indexPathFirst = tableChatView.indexPathsForVisibleRows?.first
-            if indexPathFirst != nil && listViewOnSection.count != 0 && listViewOnSection.count - 1 >= indexPathFirst!.section {
-                let headerView = listViewOnSection[indexPathFirst!.section]
-                if headerView.isHidden {
-                    headerView.isHidden = false
-                }
-            }
+//            let indexPathFirst = tableChatView.indexPathsForVisibleRows?.first
+//            if indexPathFirst != nil && listViewOnSection.count != 0 && listViewOnSection.count - 1 >= indexPathFirst!.section {
+//                let headerView = listViewOnSection[indexPathFirst!.section]
+//                if headerView.isHidden {
+//                    headerView.isHidden = false
+//                }
+//            }
             var listData = dataMessages[0...currentIndexpath!.row]
             listData = listData.filter({$0["status"] as? String != "4" && $0["status"] as? String != "8"})
             if listData.count != 0 {
@@ -2323,33 +2323,33 @@ extension ChatGPTBotView: UITableViewDelegate, UITableViewDataSource {
         }
     }
     
-    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
-        let indexPath = tableChatView.indexPathsForVisibleRows?.first
-        if indexPath != nil {
-            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-            let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
-            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && indexPath!.row > 0 {
-                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                let headerView = listViewOnSection[sect]
-                headerView.isHidden = true
-            }
-        }
-    }
-    
-    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
-        if !decelerate {
-            let indexPath = tableChatView.indexPathsForVisibleRows?.first
-            if indexPath != nil {
-                let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-                let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
-                if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
-                    let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                    let headerView = listViewOnSection[sect]
-                    headerView.isHidden = true
-                }
-            }
-        }
-    }
+//    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
+//        let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//        if indexPath != nil {
+//            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//            let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
+//            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && indexPath!.row > 0 {
+//                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                let headerView = listViewOnSection[sect]
+//                headerView.isHidden = true
+//            }
+//        }
+//    }
+//    
+//    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
+//        if !decelerate {
+//            let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//            if indexPath != nil {
+//                let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//                let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
+//                if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
+//                    let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                    let headerView = listViewOnSection[sect]
+//                    headerView.isHidden = true
+//                }
+//            }
+//        }
+//    }
 }
 
 extension ChatGPTBotView: UITextViewDelegate {

+ 47 - 44
NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift

@@ -193,16 +193,16 @@ public class EditorGroup: UIViewController, CLLocationManagerDelegate {
         navigationController?.navigationBar.prefersLargeTitles = false
         navigationController?.navigationItem.largeTitleDisplayMode = .never
         updateProfile()
-        let indexPath = tableChatView.indexPathsForVisibleRows?.first
-        if indexPath != nil && currentIndexpath != nil {
-            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-            let isPinned = headerRect.origin.y <= tableChatView.contentOffset.y
-            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
-                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                let headerView = listViewOnSection[sect]
-                headerView.isHidden = true
-            }
-        }
+//        let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//        if indexPath != nil && currentIndexpath != nil {
+//            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//            let isPinned = headerRect.origin.y <= tableChatView.contentOffset.y
+//            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
+//                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                let headerView = listViewOnSection[sect]
+//                headerView.isHidden = true
+//            }
+//        }
     }
     
     public override func viewDidLoad() {
@@ -321,6 +321,9 @@ public class EditorGroup: UIViewController, CLLocationManagerDelegate {
         tableMention.dataSource = self
         tableMention.delegate = self
         tableMention.contentInset = UIEdgeInsets(top: -25, left: 0, bottom: 0, right: 0)
+        
+        tableChatView.rowHeight = UITableView.automaticDimension
+        tableChatView.estimatedRowHeight = 100
     }
     
     public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
@@ -2496,13 +2499,13 @@ public class EditorGroup: UIViewController, CLLocationManagerDelegate {
                     }
                 }
             }
-            let indexPathFirst = tableChatView.indexPathsForVisibleRows?.first
-            if indexPathFirst != nil && listViewOnSection.count != 0 && listViewOnSection.count - 1 >= indexPathFirst!.section {
-                let headerView = listViewOnSection[indexPathFirst!.section]
-                if headerView.isHidden {
-                    headerView.isHidden = false
-                }
-            }
+//            let indexPathFirst = tableChatView.indexPathsForVisibleRows?.first
+//            if indexPathFirst != nil && listViewOnSection.count != 0 && listViewOnSection.count - 1 >= indexPathFirst!.section {
+//                let headerView = listViewOnSection[indexPathFirst!.section]
+//                if headerView.isHidden {
+//                    headerView.isHidden = false
+//                }
+//            }
             if dataMessages.count - 1 < currentIndexpath!.row {
                 return
             }
@@ -8136,33 +8139,33 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource, AVAudioPlayer
         }
     }
     
-    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
-        let indexPath = tableChatView.indexPathsForVisibleRows?.first
-        if indexPath != nil {
-            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-            let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
-            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && indexPath!.row > 0 {
-                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                let headerView = listViewOnSection[sect]
-                headerView.isHidden = true
-            }
-        }
-    }
-    
-    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
-        if !decelerate {
-            let indexPath = tableChatView.indexPathsForVisibleRows?.first
-            if indexPath != nil {
-                let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-                let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
-                if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
-                    let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                    let headerView = listViewOnSection[sect]
-                    headerView.isHidden = true
-                }
-            }
-        }
-    }
+//    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
+//        let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//        if indexPath != nil {
+//            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//            let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
+//            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && indexPath!.row > 0 {
+//                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                let headerView = listViewOnSection[sect]
+//                headerView.isHidden = true
+//            }
+//        }
+//    }
+//    
+//    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
+//        if !decelerate {
+//            let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//            if indexPath != nil {
+//                let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//                let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
+//                if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
+//                    let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                    let headerView = listViewOnSection[sect]
+//                    headerView.isHidden = true
+//                }
+//            }
+//        }
+//    }
 }
     
 extension EditorGroup: UISearchBarDelegate {

+ 60 - 60
NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift

@@ -187,16 +187,16 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         navigationController?.navigationItem.largeTitleDisplayMode = .never
         updateProfile()
         gettingDataMessage = false
-        let indexPath = tableChatView.indexPathsForVisibleRows?.first
-        if indexPath != nil && currentIndexpath != nil {
-            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-            let isPinned = headerRect.origin.y <= tableChatView.contentOffset.y
-            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
-                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                let headerView = listViewOnSection[sect]
-                headerView.isHidden = true
-            }
-        }
+//        let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//        if indexPath != nil && currentIndexpath != nil {
+//            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//            let isPinned = headerRect.origin.y <= tableChatView.contentOffset.y
+//            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
+//                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                let headerView = listViewOnSection[sect]
+//                headerView.isHidden = true
+//            }
+//        }
     }
     
     public override func viewDidLoad() {
@@ -324,6 +324,9 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         tableMention.delegate = self
         tableMention.contentInset = UIEdgeInsets(top: -25, left: 0, bottom: 0, right: 0)
         
+        tableChatView.rowHeight = UITableView.automaticDimension
+        tableChatView.estimatedRowHeight = 100
+        
         if isContactCenter && !isRequestContactCenter && !onGoingCC {
             var companyName = ""
             Database.shared.database?.inTransaction({ fmdb, rollback in
@@ -3897,13 +3900,13 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     }
                 }
             }
-            let indexPathFirst = tableChatView.indexPathsForVisibleRows?.first
-            if indexPathFirst != nil && listViewOnSection.count != 0 && listViewOnSection.count - 1 >= indexPathFirst!.section {
-                let headerView = listViewOnSection[indexPathFirst!.section]
-                if headerView.isHidden {
-                    headerView.isHidden = false
-                }
-            }
+//            let indexPathFirst = tableChatView.indexPathsForVisibleRows?.first
+//            if indexPathFirst != nil && listViewOnSection.count != 0 && listViewOnSection.count - 1 >= indexPathFirst!.section {
+//                let headerView = listViewOnSection[indexPathFirst!.section]
+//                if headerView.isHidden {
+//                    headerView.isHidden = false
+//                }
+//            }
             var listData = dataMessages[0...currentIndexpath!.row]
             listData = listData.filter({$0["status"] as? String != "4" && $0["status"] as? String != "8"})
             if listData.count != 0 && !isContactCenter {
@@ -8557,9 +8560,8 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
         }
         
         if (!reffChat.isEmpty && dataMessages[indexPath.row]["message_scope_id"]  as? String ?? "" != MessageScope.FORM) {
-            let data = queryMessageReply(message_id: reffChat)
             let chatGroup = Chat.getMessageFromId(message_id: reffChat)
-            if data.count != 0 {
+            if chatGroup.count != 0 {
                 let containerReply = UIView()
                 containerMessage.addSubview(containerReply)
                 containerReply.translatesAutoresizingMaskIntoConstraints = false
@@ -8606,21 +8608,19 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
                 titleReply.topAnchor.constraint(equalTo: containerReply.topAnchor, constant: 10).isActive = true
                 titleReply.trailingAnchor.constraint(lessThanOrEqualTo: containerReply.trailingAnchor, constant: -20).isActive = true
                 titleReply.font = UIFont.systemFont(ofSize: 12 + offset()).bold
-                let f_pin = chatGroup.count == 0 ? data["f_pin"] as? String : chatGroup[0].fpin
+                let f_pin = chatGroup[0].fpin
                 if f_pin == idMe {
-                    if chatGroup.count == 0 {
+                    if chatGroup[0].messageScope != MessageScope.GROUP {
                         titleReply.text = "You".localized()
                     } else {
-                        if let dataPerson = User.getData(pin: f_pin) {
-                            titleReply.text = "You".localized() + " ● " + "\(chatGroup[0].groupName)(\(chatGroup[0].name))"
-                        }
+                        titleReply.text = "You".localized() + " ● " + "\(chatGroup[0].groupName)(\(chatGroup[0].name))"
                     }
                 } else {
                     if isContactCenter {
-                        let user: [User] = users.filter({$0.pin == data["f_pin"] as? String})
+                        let user: [User] = users.filter({$0.pin == chatGroup[0].fpin})
                         titleReply.text = user.first!.fullName
                     } else {
-                        if chatGroup.count == 0 {
+                        if chatGroup[0].messageScope != MessageScope.GROUP {
                             titleReply.text = self.dataPerson["name"]!!
                         } else {
                             if let dataPerson = User.getData(pin: f_pin) {
@@ -8648,12 +8648,12 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
                 topConstraintContent.priority = .defaultHigh
                 topConstraintContent.isActive = true
                 contentReply.font = UIFont.systemFont(ofSize: 10 + offset())
-                let message_text = chatGroup.count == 0 ? (data["message_text"] as? String ?? "") : chatGroup[0].messageText
-                let attachment_flag = chatGroup.count == 0 ? (data["attachment_flag"] as? String ?? "") : chatGroup[0].attachmentFlag
-                let thumb_chat = chatGroup.count == 0 ? (data["thumb_id"] as? String ?? "") : chatGroup[0].thumb
-                let image_chat = chatGroup.count == 0 ? (data["image_id"] as? String ?? "") : chatGroup[0].image
-                let video_chat = chatGroup.count == 0 ? (data["video_id"] as? String ?? "") : chatGroup[0].video
-                let file_chat = chatGroup.count == 0 ? (data["file_id"] as? String ?? "") : chatGroup[0].file
+                let message_text = chatGroup[0].messageText
+                let attachment_flag = chatGroup[0].attachmentFlag
+                let thumb_chat = chatGroup[0].thumb
+                let image_chat = chatGroup[0].image
+                let video_chat = chatGroup[0].video
+                let file_chat = chatGroup[0].file
                 if (attachment_flag == "0" && thumb_chat == "") {
                     contentReply.trailingAnchor.constraint(equalTo: containerReply.trailingAnchor, constant: -20).isActive = true
                     contentReply.attributedText = message_text.richText()
@@ -8739,7 +8739,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
                     let objectTap = ObjectGesture(target: self, action: #selector(contentMessageTapped(_:)))
                     containerReply.addGestureRecognizer(objectTap)
                     objectTap.indexPath = indexPath
-                    objectTap.message_id = data["message_id"]  as? String ?? ""
+                    objectTap.message_id = chatGroup[0].messageId
                 }
             }
         }
@@ -10019,33 +10019,33 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource, AVAudioPla
         }
     }
     
-    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
-        let indexPath = tableChatView.indexPathsForVisibleRows?.first
-        if indexPath != nil {
-            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-            let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
-            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && indexPath!.row > 0 {
-                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                let headerView = listViewOnSection[sect]
-                headerView.isHidden = true
-            }
-        }
-    }
-    
-    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
-        if !decelerate {
-            let indexPath = tableChatView.indexPathsForVisibleRows?.first
-            if indexPath != nil {
-                let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
-                let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
-                if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
-                    let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
-                    let headerView = listViewOnSection[sect]
-                    headerView.isHidden = true
-                }
-            }
-        }
-    }
+//    public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
+//        let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//        if indexPath != nil {
+//            let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//            let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
+//            if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && indexPath!.row > 0 {
+//                let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                let headerView = listViewOnSection[sect]
+//                headerView.isHidden = true
+//            }
+//        }
+//    }
+//    
+//    public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
+//        if !decelerate {
+//            let indexPath = tableChatView.indexPathsForVisibleRows?.first
+//            if indexPath != nil {
+//                let headerRect = tableChatView.rectForHeader(inSection: indexPath!.section)
+//                let isPinned = headerRect.origin.y <= scrollView.contentOffset.y
+//                if listViewOnSection.count != 0 && listViewOnSection.count - 1 == indexPath!.section && isPinned {
+//                    let sect = listViewOnSection.count - 1 < currentIndexpath!.section ? listViewOnSection.count - 1 : currentIndexpath!.section
+//                    let headerView = listViewOnSection[sect]
+//                    headerView.isHidden = true
+//                }
+//            }
+//        }
+//    }
 }
 
 extension UITableView {