Explorar el Código

update fix bugs

alqindiirsyam hace 2 años
padre
commit
d864b16125

+ 8 - 46
appbuilder-ios/AppBuilder/AppBuilder/Base.lproj/Main.storyboard

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="nD6-T3-59p">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="nD6-T3-59p">
     <device id="retina6_7" orientation="portrait" appearance="dark"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
         <capability name="Safe area layout guides" minToolsVersion="9.0"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@@ -32,28 +32,9 @@
                     <view key="view" contentMode="scaleToFill" id="OUO-5T-AtV">
                         <rect key="frame" x="0.0" y="0.0" width="428" height="926"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                        <subviews>
-                            <wkWebView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zT9-mO-2xu">
-                                <rect key="frame" x="0.0" y="44" width="428" height="882"/>
-                                <color key="backgroundColor" red="0.36078431372549019" green="0.38823529411764707" blue="0.40392156862745099" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                                <wkWebViewConfiguration key="configuration" allowsInlineMediaPlayback="YES">
-                                    <audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
-                                    <wkPreferences key="preferences"/>
-                                </wkWebViewConfiguration>
-                            </wkWebView>
-                        </subviews>
                         <viewLayoutGuide key="safeArea" id="f2x-TV-t0G"/>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                        <constraints>
-                            <constraint firstItem="zT9-mO-2xu" firstAttribute="leading" secondItem="f2x-TV-t0G" secondAttribute="leading" id="IO4-cU-dmV"/>
-                            <constraint firstItem="zT9-mO-2xu" firstAttribute="top" secondItem="f2x-TV-t0G" secondAttribute="top" id="NUS-DV-p70"/>
-                            <constraint firstItem="f2x-TV-t0G" firstAttribute="trailing" secondItem="zT9-mO-2xu" secondAttribute="trailing" id="OHq-JX-jnE"/>
-                            <constraint firstAttribute="bottom" secondItem="zT9-mO-2xu" secondAttribute="bottom" id="OUP-JZ-QoH"/>
-                        </constraints>
                     </view>
-                    <connections>
-                        <outlet property="webView" destination="zT9-mO-2xu" id="9yf-9r-PmW"/>
-                    </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="1UN-B6-dct" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
             </objects>
@@ -71,14 +52,14 @@
                                 <rect key="frame" x="0.0" y="0.0" width="428" height="926"/>
                             </imageView>
                             <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oT8-Uw-cgS">
-                                <rect key="frame" x="0.0" y="44" width="428" height="848"/>
+                                <rect key="frame" x="0.0" y="47" width="428" height="845"/>
                                 <subviews>
                                     <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="4Jc-b8-aeF">
-                                        <rect key="frame" x="0.0" y="0.0" width="428" height="848"/>
+                                        <rect key="frame" x="0.0" y="0.0" width="428" height="845"/>
                                         <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                         <prototypes>
                                             <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="reuseIdentifierChat" id="Tz5-0s-zFj">
-                                                <rect key="frame" x="0.0" y="44.666666030883789" width="428" height="43.666667938232422"/>
+                                                <rect key="frame" x="0.0" y="50" width="428" height="43.666667938232422"/>
                                                 <autoresizingMask key="autoresizingMask"/>
                                                 <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="Tz5-0s-zFj" id="4MW-eb-afV">
                                                     <rect key="frame" x="0.0" y="0.0" width="428" height="43.666667938232422"/>
@@ -86,7 +67,7 @@
                                                 </tableViewCellContentView>
                                             </tableViewCell>
                                             <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="reuseIdentifierGroup" id="im7-ks-lTd">
-                                                <rect key="frame" x="0.0" y="88.333333969116211" width="428" height="43.666667938232422"/>
+                                                <rect key="frame" x="0.0" y="93.666667938232422" width="428" height="43.666667938232422"/>
                                                 <autoresizingMask key="autoresizingMask"/>
                                                 <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="im7-ks-lTd" id="lNo-4T-eyr">
                                                     <rect key="frame" x="0.0" y="0.0" width="428" height="43.666667938232422"/>
@@ -152,7 +133,7 @@
             <objects>
                 <navigationController title="test" id="nD6-T3-59p" sceneMemberID="viewController">
                     <navigationBar key="navigationBar" opaque="NO" contentMode="scaleToFill" id="mEs-FV-nQc">
-                        <rect key="frame" x="0.0" y="44" width="428" height="44"/>
+                        <rect key="frame" x="0.0" y="47" width="428" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                         <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                         <color key="tintColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -252,28 +233,9 @@
                     <view key="view" contentMode="scaleToFill" id="zlx-Nr-4qk">
                         <rect key="frame" x="0.0" y="0.0" width="428" height="926"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-                        <subviews>
-                            <wkWebView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bvD-XN-Tvh">
-                                <rect key="frame" x="0.0" y="44" width="428" height="882"/>
-                                <color key="backgroundColor" red="0.36078431372549019" green="0.38823529411764707" blue="0.40392156862745099" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                                <wkWebViewConfiguration key="configuration" allowsInlineMediaPlayback="YES">
-                                    <audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
-                                    <wkPreferences key="preferences"/>
-                                </wkWebViewConfiguration>
-                            </wkWebView>
-                        </subviews>
                         <viewLayoutGuide key="safeArea" id="gQh-2u-SN6"/>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                        <constraints>
-                            <constraint firstAttribute="bottom" secondItem="bvD-XN-Tvh" secondAttribute="bottom" id="7Q0-Pz-a2B"/>
-                            <constraint firstItem="bvD-XN-Tvh" firstAttribute="leading" secondItem="gQh-2u-SN6" secondAttribute="leading" id="Xt6-nC-kXW"/>
-                            <constraint firstItem="gQh-2u-SN6" firstAttribute="trailing" secondItem="bvD-XN-Tvh" secondAttribute="trailing" id="d1o-4Y-rDd"/>
-                            <constraint firstItem="bvD-XN-Tvh" firstAttribute="top" secondItem="gQh-2u-SN6" secondAttribute="top" id="wKy-eu-cvh"/>
-                        </constraints>
                     </view>
-                    <connections>
-                        <outlet property="webView" destination="bvD-XN-Tvh" id="4YE-s2-y3Z"/>
-                    </connections>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="crD-Us-xmX" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
             </objects>
@@ -297,7 +259,7 @@
                                 <color key="sectionIndexBackgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                                 <prototypes>
                                     <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="2" reuseIdentifier="reuseIdentifier" id="IEo-SX-4um">
-                                        <rect key="frame" x="20" y="49" width="388" height="43.666667938232422"/>
+                                        <rect key="frame" x="20" y="55.333332061767578" width="388" height="43.666667938232422"/>
                                         <autoresizingMask key="autoresizingMask"/>
                                         <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="left" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="IEo-SX-4um" id="je4-kr-tvF">
                                             <rect key="frame" x="0.0" y="0.0" width="388" height="43.666667938232422"/>

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

@@ -12,7 +12,7 @@ import Speech
 
 class FirstTabViewController: UIViewController, UIScrollViewDelegate, UIGestureRecognizerDelegate, WKScriptMessageHandler {
     
-    @IBOutlet weak var webView: WKWebView!
+    var webView: WKWebView!
     var address = ""
     private var lastContentOffset: CGFloat = 0
     
@@ -35,6 +35,20 @@ class FirstTabViewController: UIViewController, UIScrollViewDelegate, UIGestureR
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(collapseDocked))
         tapGesture.cancelsTouchesInView = false
         tapGesture.delegate = self
+        let configuration = WKWebViewConfiguration()
+        let defaultUserAgent = WKWebView(frame: .zero, configuration: configuration).evaluateJavaScript("navigator.userAgent") as? String
+        let customUserAgent = "easySoftIndonesia"
+        let finalUserAgent = "\(defaultUserAgent ?? "") \(customUserAgent)"
+        configuration.applicationNameForUserAgent = finalUserAgent
+        webView = WKWebView(frame: .zero, configuration: configuration)
+        view.addSubview(webView)
+        webView.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
+            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
+            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
+            webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
+        ])
         webView.scrollView.addGestureRecognizer(tapGesture)
         let refreshControl = UIRefreshControl()
         refreshControl.addTarget(self, action: #selector(reloadWebView(_:)), for: .valueChanged)

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

@@ -126,6 +126,7 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
         NotificationCenter.default.addObserver(self, selector: #selector(onReceiveMessage(notification:)), name: NSNotification.Name(rawValue: Nexilis.listenerReceiveChat), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(onReload(notification:)), name: NSNotification.Name(rawValue: "onMember"), object: nil)
         NotificationCenter.default.addObserver(self, selector: #selector(onReload(notification:)), name: NSNotification.Name(rawValue: "onUpdatePersonInfo"), object: nil)
+        NotificationCenter.default.addObserver(self, selector: #selector(onReloadTab(notification:)), name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil)
         
         
         
@@ -145,6 +146,7 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
         tapGesture.cancelsTouchesInView = false
         tapGesture.delegate = self
         self.view.addGestureRecognizer(tapGesture)
+        getData()
     }
     
     @objc func collapseDocked() {
@@ -400,7 +402,7 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
             searchController.searchBar.placeholder = "Search groups name".localized()
         }
 //        removeAllData()
-        getData()
+//        getData()
     }
     
 //    func removeAllData() {
@@ -421,6 +423,12 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
         }
     }
     
+    @objc func onReloadTab(notification: NSNotification) {
+        DispatchQueue.main.async {
+            self.getData()
+        }
+    }
+    
     @objc func onReload(notification: NSNotification) {
         let data:[AnyHashable : Any] = notification.userInfo!
         if data["member"] as? String == UserDefaults.standard.string(forKey: "me")! {

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

@@ -12,7 +12,7 @@ import Speech
 
 class ThirdTabViewController: UIViewController, UIScrollViewDelegate, UIGestureRecognizerDelegate, WKNavigationDelegate, WKScriptMessageHandler  {
 
-    @IBOutlet weak var webView: WKWebView!
+    var webView: WKWebView!
     var address = ""
     private var lastContentOffset: CGFloat = 0
     
@@ -36,6 +36,20 @@ class ThirdTabViewController: UIViewController, UIScrollViewDelegate, UIGestureR
         let tapGesture = UITapGestureRecognizer(target: self, action: #selector(collapseDocked))
         tapGesture.cancelsTouchesInView = false
         tapGesture.delegate = self
+        let configuration = WKWebViewConfiguration()
+        let defaultUserAgent = WKWebView(frame: .zero, configuration: configuration).evaluateJavaScript("navigator.userAgent") as? String
+        let customUserAgent = "easySoftIndonesia"
+        let finalUserAgent = "\(defaultUserAgent ?? "") \(customUserAgent)"
+        configuration.applicationNameForUserAgent = finalUserAgent
+        webView = WKWebView(frame: .zero, configuration: configuration)
+        view.addSubview(webView)
+        webView.translatesAutoresizingMaskIntoConstraints = false
+        NSLayoutConstraint.activate([
+            webView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
+            webView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
+            webView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
+            webView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor)
+        ])
         webView.scrollView.addGestureRecognizer(tapGesture)
         let refreshControl = UIRefreshControl()
         refreshControl.addTarget(self, action: #selector(reloadWebView(_:)), for: .valueChanged)

+ 2 - 0
appbuilder-ios/DigiXLite/DigiXLite/Source/OutgoingThread.swift

@@ -240,6 +240,7 @@ class OutgoingThread {
                     ], _where: "id = '\(messageId)'")
                 }
                 if let delegate = DigiX.shared.messageDelegate {
+                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                     delegate.onMessage(message: message)
                 }
             } else {
@@ -265,6 +266,7 @@ class OutgoingThread {
                             "counter" : 0
                         ], replace: true)
                     }
+                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                 } catch {
                     rollback.pointee = true
                     //print(error)

+ 28 - 20
appbuilder-ios/DigiXLite/DigiXLite/Source/View/Chat/EditorGroup.swift

@@ -87,7 +87,6 @@ public class EditorGroup: UIViewController {
     var lastPositionCursorMention = 0
     var timerLongPressLink: Timer?
     var timerFakeProgress: Timer?
-    var lastTouchPoint: CGPoint = .zero
     var showMenuContext = false
     var touchedSubview = UIView()
     var listViewOnSection: [UIView] = []
@@ -244,6 +243,7 @@ public class EditorGroup: UIViewController {
                         _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(l_pin='\(self.dataGroup["group_id"]!!)' and chat_id='\(self.dataTopic["chat_id"]!!)') and message_scope_id='4'")
                         _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(l_pin)'")
                         UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
+                        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                         if self.fromNotification {
                             self.didTapExit()
                         } else {
@@ -392,7 +392,7 @@ public class EditorGroup: UIViewController {
                 }
                 
                 if !last_r.isEmpty {
-                    reffId = last_r
+                    handleReply(indexPath: IndexPath(row: 0, section: 0), reffId: last_r)
                 }
             }
             tableChatView.scrollToBottom(isAnimated: false)
@@ -892,7 +892,7 @@ public class EditorGroup: UIViewController {
                     }
                 }
             } else {
-                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
+//                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
             }
         }
     }
@@ -2845,6 +2845,7 @@ extension EditorGroup: UIContextMenuInteractionDelegate {
                         self.dataMessages[idx!]["reff_id"] = ""
                     }
                 }
+                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                 cancelAction()
             }
         }
@@ -3727,7 +3728,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
                 imageThumb.frame = CGRect(x: 0, y: 0, width: ListGroupImages.getImageSize(image: thumbChat, screenWidth: self.view.frame.size.width * 0.6, screenHeight: 305)!.width, height: ListGroupImages.getImageSize(image: thumbChat, screenWidth: self.view.frame.size.width * 0.6, screenHeight: 305)!.height)
                 let data = queryMessageReply(message_id: reffChat)
                 if reffChat.isEmpty || data.count == 0 {
-                    imageThumb.topAnchor.constraint(equalTo: containerMessage.topAnchor, constant: 32).isActive = true
+                    imageThumb.topAnchor.constraint(equalTo: containerMessage.topAnchor, constant: 37).isActive = true
                 }
                 imageThumb.leadingAnchor.constraint(equalTo: containerMessage.leadingAnchor, constant: 15).isActive = true
                 imageThumb.bottomAnchor.constraint(equalTo: messageText.topAnchor, constant: -5).isActive = true
@@ -3867,7 +3868,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
             containerViewFile.translatesAutoresizingMaskIntoConstraints = false
             let data = queryMessageReply(message_id: reffChat)
             if reffChat.isEmpty || data.count == 0 {
-                containerViewFile.topAnchor.constraint(equalTo: containerMessage.topAnchor, constant: 32).isActive = true
+                containerViewFile.topAnchor.constraint(equalTo: containerMessage.topAnchor, constant: 37).isActive = true
             }
             containerViewFile.leadingAnchor.constraint(equalTo: containerMessage.leadingAnchor, constant: 15).isActive = true
             containerViewFile.bottomAnchor.constraint(equalTo:messageText.topAnchor, constant: -5).isActive = true
@@ -3959,10 +3960,10 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
             if !text.isEmpty {
                 func showLink() {
                     if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
-                        let title = data["title"] as! String
-                        let description = data["description"] as! String
+                        let title = data["title"] as? String
+                        let description = data["description"] as? String
                         let imageUrl = data["imageUrl"] as? String
-                        let link = data["link"] as! String
+                        let link = data["link"] as? String
                         
                         topMarginText.constant = topMarginText.constant + 85
                         
@@ -4698,15 +4699,17 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
         guard let text = label.text else { return nil }
         
         let layoutManager = NSLayoutManager()
-        let textContainer = NSTextContainer(size: label.frame.size)
-        let textStorage = NSTextStorage(attributedString: NSAttributedString(string: text))
+        let textContainer = NSTextContainer(size: .zero)
+        let textStorage = NSTextStorage(attributedString: label.attributedText ?? NSAttributedString())
         
         layoutManager.addTextContainer(textContainer)
         textStorage.addLayoutManager(layoutManager)
-        textContainer.lineFragmentPadding = 0
+        
+        textContainer.lineFragmentPadding = 0.0
+        textContainer.lineBreakMode = label.lineBreakMode
         textContainer.maximumNumberOfLines = label.numberOfLines
+        textContainer.size = label.bounds.size
         
-        lastTouchPoint = point
         let characterIndex = layoutManager.characterIndex(for: point, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
         
         if characterIndex == text.count - 1 {
@@ -4740,8 +4743,8 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
     }
     
     @objc func tapMessageText(_ sender: ObjectGesture) {
-        var stringURl = sender.message_id.lowercased()
-        if stringURl.starts(with: "www.") {
+        var stringURl = sender.message_id
+        if stringURl.lowercased().starts(with: "www.") {
             stringURl = "https://" + stringURl.replacingOccurrences(of: "www.", with: "")
         }
         guard let url = URL(string: stringURl) else { return }
@@ -4775,15 +4778,20 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
 //        return UISwipeActionsConfiguration(actions: [action])
 //    }
     
-    private func handleReply(indexPath: IndexPath, dataMessagesImage: [String: Any?] = [:]) {
-        self.deleteReplyView()
+    private func handleReply(indexPath: IndexPath, dataMessagesImage: [String: Any?] = [:], reffId: String = "") {
         var dataMessages = self.dataMessages.filter({ $0["chat_date"] as! String == dataDates[indexPath.section]})
-        if dataMessagesImage.count != 0 {
-            dataMessages = [dataMessagesImage]
+        if reffId.isEmpty {
+            self.deleteReplyView()
+            if dataMessagesImage.count != 0 {
+                dataMessages = [dataMessagesImage]
+            } else {
+                self.textFieldSend.becomeFirstResponder()
+            }
+            self.reffId = dataMessages[indexPath.row]["message_id"] as? String
         } else {
-            self.textFieldSend.becomeFirstResponder()
+            dataMessages = self.dataMessages.filter({ $0["message_id"] as! String == reffId })
+            self.reffId = reffId
         }
-        self.reffId = dataMessages[indexPath.row]["message_id"] as? String
         UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
             self.constraintTopTextField.constant = self.constraintTopTextField.constant + 50
             if self.contraintBottomMention.constant > 0 {

+ 69 - 164
appbuilder-ios/DigiXLite/DigiXLite/Source/View/Chat/EditorPersonal.swift

@@ -97,7 +97,6 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
     var timerCheckLink: Timer?
     var timerLongPressLink: Timer?
     var timerFakeProgress: Timer?
-    var lastTouchPoint: CGPoint = .zero
     var showMenuContext = false
     var touchedSubview = UIView()
     var listViewOnSection: [UIView] = []
@@ -287,70 +286,55 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
     
     private func setRightButtonItem() {
         navigationItem.rightBarButtonItems = nil
-        var menu = UIMenu(title: "", children: [
-            UIAction(title: "Search".localized(), handler: {(_) in
-                self.isSearching = true
-                if self.reffId != nil {
-                    self.deleteReplyView()
-                }
-                DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
-                    let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
-                    cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
-                    if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
-                        self.navigationItem.rightBarButtonItems = nil
-                    }
-                    self.navigationItem.rightBarButtonItem = cancelButton
-                    if self.isContactCenter || self.fromNotification {
-                        self.navigationItem.leftBarButtonItem = nil
-                    }
-                    self.changeAppBar()
-                    self.addMultipleSelectSession()
-                }
-            }),
-            UIAction(title: "Delete Conversation".localized(), handler: {(_) in
-                if !self.isContactCenter {
-                    let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
-                    alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
-                    alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
-                        Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                            _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
-                            _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
-                            let l_pin = self.dataPerson["f_pin"]!!
-                            UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
-                            if self.fromNotification {
-                                self.didTapExit()
-                            } else {
-                                self.navigationController?.popViewController(animated: true)
-                            }
-                        })
-                    }))
-                    self.present(alert, animated: true, completion: nil)
+        let actionDelete = UIAction(title: "Delete Conversation".localized(), handler: {(_) in
+            if !self.isContactCenter {
+                let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
+                alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
+                alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
+                    Database.shared.database?.inTransaction({ (fmdb, rollback) in
+                        _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
+                        _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
+                        let l_pin = self.dataPerson["f_pin"]!!
+                        UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
+                        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
+                        if self.fromNotification {
+                            self.didTapExit()
+                        } else {
+                            self.navigationController?.popViewController(animated: true)
+                        }
+                    })
+                }))
+                self.present(alert, animated: true, completion: nil)
+            }
+        })
+        let actionSearch = UIAction(title: "Search".localized(), handler: {(_) in
+            self.isSearching = true
+            if self.reffId != nil {
+                self.deleteReplyView()
+            }
+            DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
+                let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
+                cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
+                if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
+                    self.navigationItem.rightBarButtonItems = nil
                 }
-            })
+                self.navigationItem.rightBarButtonItem = cancelButton
+                if self.isContactCenter || self.fromNotification {
+                    self.navigationItem.leftBarButtonItem = nil
+                }
+                self.changeAppBar()
+                self.addMultipleSelectSession()
+            }
+        })
+        var menu = UIMenu(title: "", children: [
+            actionSearch,
+            actionDelete
         ])
         let exblock = User.getDataCanNil(pin: self.dataPerson["f_pin"]!!)?.ex_block
         blocking = exblock == nil ? "0" : exblock!.isEmpty ? "0" : exblock!
         if blocking == "1" && self.dataPerson["f_pin"]!! != "-999" {
             menu = UIMenu(title: "", children: [
-                UIAction(title: "Search".localized(), handler: {(_) in
-                    self.isSearching = true
-                    if self.reffId != nil {
-                        self.deleteReplyView()
-                    }
-                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
-                        let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
-                        cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
-                        if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
-                            self.navigationItem.rightBarButtonItems = nil
-                        }
-                        self.navigationItem.rightBarButtonItem = cancelButton
-                        if self.isContactCenter || self.fromNotification {
-                            self.navigationItem.leftBarButtonItem = nil
-                        }
-                        self.changeAppBar()
-                        self.addMultipleSelectSession()
-                    }
-                }),
+                actionSearch,
                 UIAction(title: "Unblock".localized(), handler: {(_) in
                     if !self.isContactCenter {
                         DispatchQueue.global().async {
@@ -386,48 +370,13 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                         }
                     }
                 }),
-                UIAction(title: "Delete Conversation".localized(), handler: {(_) in
-                    if !self.isContactCenter {
-                        let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
-                        alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
-                        alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
-                            Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                                _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
-                                _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
-                                if self.fromNotification {
-                                    self.didTapExit()
-                                } else {
-                                    self.navigationController?.popViewController(animated: true)
-                                }
-                            })
-                        }))
-                        self.present(alert, animated: true, completion: nil)
-                    }
-                })
+                actionDelete
             ])
             blockedView(blocked: "1")
         } else if blocking == "0" {
             if self.dataPerson["f_pin"]!! != "-999"{
                 menu = UIMenu(title: "", children: [
-                    UIAction(title: "Search".localized(), handler: {(_) in
-                        self.isSearching = true
-                        if self.reffId != nil {
-                            self.deleteReplyView()
-                        }
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
-                            let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
-                            cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
-                            if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
-                                self.navigationItem.rightBarButtonItems = nil
-                            }
-                            self.navigationItem.rightBarButtonItem = cancelButton
-                            if self.isContactCenter || self.fromNotification {
-                                self.navigationItem.leftBarButtonItem = nil
-                            }
-                            self.changeAppBar()
-                            self.addMultipleSelectSession()
-                        }
-                    }),
+                    actionSearch,
                     UIAction(title: "Block".localized(), handler: {(_) in
                         if !self.isContactCenter {
                             DispatchQueue.global().async {
@@ -461,64 +410,12 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                             }
                         }
                     }),
-                    UIAction(title: "Delete Conversation".localized(), handler: {(_) in
-                        if !self.isContactCenter {
-                            let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
-                            alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
-                            alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
-                                Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                                    _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
-                                    _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
-                                    if self.fromNotification {
-                                        self.didTapExit()
-                                    } else {
-                                        self.navigationController?.popViewController(animated: true)
-                                    }
-                                })
-                            }))
-                            self.present(alert, animated: true, completion: nil)
-                        }
-                    })
+                    actionDelete
                 ])
             } else {
                 menu = UIMenu(title: "", children: [
-                    UIAction(title: "Search".localized(), handler: {(_) in
-                        self.isSearching = true
-                        if self.reffId != nil {
-                            self.deleteReplyView()
-                        }
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
-                            let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
-                            cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
-                            if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
-                                self.navigationItem.rightBarButtonItems = nil
-                            }
-                            self.navigationItem.rightBarButtonItem = cancelButton
-                            if self.isContactCenter || self.fromNotification {
-                                self.navigationItem.leftBarButtonItem = nil
-                            }
-                            self.changeAppBar()
-                            self.addMultipleSelectSession()
-                        }
-                    }),
-                    UIAction(title: "Delete Conversation".localized(), handler: {(_) in
-                        if !self.isContactCenter {
-                            let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
-                            alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
-                            alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
-                                Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                                    _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
-                                    _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
-                                    if self.fromNotification {
-                                        self.didTapExit()
-                                    } else {
-                                        self.navigationController?.popViewController(animated: true)
-                                    }
-                                })
-                            }))
-                            self.present(alert, animated: true, completion: nil)
-                        }
-                    })
+                    actionSearch,
+                    actionDelete
                 ])
             }
             if containerAction.isDescendant(of: self.view) {
@@ -634,7 +531,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     }
                     
                     if !last_r.isEmpty {
-                        reffId = last_r
+                        handleReply(indexPath: IndexPath(row: 0, section: 0), reffId: last_r)
                     }
                 }
                 tableChatView.scrollToBottom(isAnimated: false)
@@ -2449,6 +2346,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         }
         deleteReplyView()
         deleteLinkPreview()
+        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
         DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
             self.tableChatView.scrollToBottom()
             if self.markerCounter != nil {
@@ -6140,15 +6038,17 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
         guard let text = label.text else { return nil }
         
         let layoutManager = NSLayoutManager()
-        let textContainer = NSTextContainer(size: label.frame.size)
-        let textStorage = NSTextStorage(attributedString: NSAttributedString(string: text))
+        let textContainer = NSTextContainer(size: .zero)
+        let textStorage = NSTextStorage(attributedString: label.attributedText ?? NSAttributedString())
         
         layoutManager.addTextContainer(textContainer)
         textStorage.addLayoutManager(layoutManager)
-        textContainer.lineFragmentPadding = 0
+        
+        textContainer.lineFragmentPadding = 0.0
+        textContainer.lineBreakMode = label.lineBreakMode
         textContainer.maximumNumberOfLines = label.numberOfLines
+        textContainer.size = label.bounds.size
         
-        lastTouchPoint = point
         let characterIndex = layoutManager.characterIndex(for: point, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
         
         if characterIndex == text.count - 1 {
@@ -6182,8 +6082,8 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
     }
     
     @objc func tapMessageText(_ sender: ObjectGesture) {
-        var stringURl = sender.message_id.lowercased()
-        if stringURl.starts(with: "www.") {
+        var stringURl = sender.message_id
+        if stringURl.lowercased().starts(with: "www.") {
             stringURl = "https://" + stringURl.replacingOccurrences(of: "www.", with: "")
         }
         guard let url = URL(string: stringURl) else { return }
@@ -6218,15 +6118,20 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
 //        return UISwipeActionsConfiguration(actions: [action])
 //    }
     
-    private func handleReply(indexPath: IndexPath, dataMessagesImage: [String: Any?] = [:]) {
-        self.deleteReplyView()
+    private func handleReply(indexPath: IndexPath, dataMessagesImage: [String: Any?] = [:], reffId: String = "") {
         var dataMessages = self.dataMessages.filter({ $0["chat_date"] as! String == dataDates[indexPath.section]})
-        if dataMessagesImage.count != 0 {
-            dataMessages = [dataMessagesImage]
+        if reffId.isEmpty {
+            self.deleteReplyView()
+            if dataMessagesImage.count != 0 {
+                dataMessages = [dataMessagesImage]
+            } else {
+                self.textFieldSend.becomeFirstResponder()
+            }
+            self.reffId = dataMessages[indexPath.row]["message_id"] as? String
         } else {
-            self.textFieldSend.becomeFirstResponder()
+            dataMessages = self.dataMessages.filter({ $0["message_id"] as! String == reffId })
+            self.reffId = reffId
         }
-        self.reffId = dataMessages[indexPath.row]["message_id"] as? String
         UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
             self.constraintTopTextField.constant = self.constraintTopTextField.constant + 50
         }, completion: nil)

+ 2 - 1
appbuilder-ios/DigiXLite/DigiXLite/Source/View/Control/ContactChatViewController.swift

@@ -189,6 +189,7 @@ class ContactChatViewController: UITableViewController {
         tableView.tableFooterView = UIView()
         
         pullBuddy()
+        getData()
         
     }
     
@@ -201,7 +202,7 @@ class ContactChatViewController: UITableViewController {
         navigationController?.navigationBar.standardAppearance = navBarAppearance
         navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
 //        removeAllData()
-        getData()
+//        getData()
     }
     
     override func viewWillDisappear(_ animated: Bool) {

+ 2 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/OutgoingThread.swift

@@ -240,6 +240,7 @@ class OutgoingThread {
                     ], _where: "id = '\(messageId)'")
                 }
                 if let delegate = Nexilis.shared.messageDelegate {
+                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                     delegate.onMessage(message: message)
                 }
             } else {
@@ -265,6 +266,7 @@ class OutgoingThread {
                             "counter" : 0
                         ], replace: true)
                     }
+                    NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                 } catch {
                     rollback.pointee = true
                     //print(error)

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

@@ -243,6 +243,7 @@ public class EditorGroup: UIViewController {
                         _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(l_pin='\(self.dataGroup["group_id"]!!)' and chat_id='\(self.dataTopic["chat_id"]!!)') and message_scope_id='4'")
                         _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(l_pin)'")
                         UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
+                        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                         if self.fromNotification {
                             self.didTapExit()
                         } else {
@@ -391,7 +392,7 @@ public class EditorGroup: UIViewController {
                 }
                 
                 if !last_r.isEmpty {
-                    reffId = last_r
+                    handleReply(indexPath: IndexPath(row: 0, section: 0), reffId: last_r)
                 }
             }
             tableChatView.scrollToBottom(isAnimated: false)
@@ -891,7 +892,7 @@ public class EditorGroup: UIViewController {
                     }
                 }
             } else {
-                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
+//                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
             }
         }
     }
@@ -2844,6 +2845,7 @@ extension EditorGroup: UIContextMenuInteractionDelegate {
                         self.dataMessages[idx!]["reff_id"] = ""
                     }
                 }
+                NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
                 cancelAction()
             }
         }
@@ -3958,10 +3960,10 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
             if !text.isEmpty {
                 func showLink() {
                     if let data = try! JSONSerialization.jsonObject(with: dataURL.data(using: String.Encoding.utf8)!, options: []) as? [String: Any] {
-                        let title = data["title"] as! String
-                        let description = data["description"] as! String
+                        let title = data["title"] as? String
+                        let description = data["description"] as? String
                         let imageUrl = data["imageUrl"] as? String
-                        let link = data["link"] as! String
+                        let link = data["link"] as? String
                         
                         topMarginText.constant = topMarginText.constant + 85
                         
@@ -4776,15 +4778,20 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
 //        return UISwipeActionsConfiguration(actions: [action])
 //    }
     
-    private func handleReply(indexPath: IndexPath, dataMessagesImage: [String: Any?] = [:]) {
-        self.deleteReplyView()
+    private func handleReply(indexPath: IndexPath, dataMessagesImage: [String: Any?] = [:], reffId: String = "") {
         var dataMessages = self.dataMessages.filter({ $0["chat_date"] as! String == dataDates[indexPath.section]})
-        if dataMessagesImage.count != 0 {
-            dataMessages = [dataMessagesImage]
+        if reffId.isEmpty {
+            self.deleteReplyView()
+            if dataMessagesImage.count != 0 {
+                dataMessages = [dataMessagesImage]
+            } else {
+                self.textFieldSend.becomeFirstResponder()
+            }
+            self.reffId = dataMessages[indexPath.row]["message_id"] as? String
         } else {
-            self.textFieldSend.becomeFirstResponder()
+            dataMessages = self.dataMessages.filter({ $0["message_id"] as! String == reffId })
+            self.reffId = reffId
         }
-        self.reffId = dataMessages[indexPath.row]["message_id"] as? String
         UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
             self.constraintTopTextField.constant = self.constraintTopTextField.constant + 50
             if self.contraintBottomMention.constant > 0 {

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

@@ -286,70 +286,55 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
     
     private func setRightButtonItem() {
         navigationItem.rightBarButtonItems = nil
-        var menu = UIMenu(title: "", children: [
-            UIAction(title: "Search".localized(), handler: {(_) in
-                self.isSearching = true
-                if self.reffId != nil {
-                    self.deleteReplyView()
-                }
-                DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
-                    let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
-                    cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
-                    if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
-                        self.navigationItem.rightBarButtonItems = nil
-                    }
-                    self.navigationItem.rightBarButtonItem = cancelButton
-                    if self.isContactCenter || self.fromNotification {
-                        self.navigationItem.leftBarButtonItem = nil
-                    }
-                    self.changeAppBar()
-                    self.addMultipleSelectSession()
-                }
-            }),
-            UIAction(title: "Delete Conversation".localized(), handler: {(_) in
-                if !self.isContactCenter {
-                    let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
-                    alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
-                    alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
-                        Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                            _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
-                            _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
-                            let l_pin = self.dataPerson["f_pin"]!!
-                            UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
-                            if self.fromNotification {
-                                self.didTapExit()
-                            } else {
-                                self.navigationController?.popViewController(animated: true)
-                            }
-                        })
-                    }))
-                    self.present(alert, animated: true, completion: nil)
+        let actionDelete = UIAction(title: "Delete Conversation".localized(), handler: {(_) in
+            if !self.isContactCenter {
+                let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
+                alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
+                alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
+                    Database.shared.database?.inTransaction({ (fmdb, rollback) in
+                        _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
+                        _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
+                        let l_pin = self.dataPerson["f_pin"]!!
+                        UserDefaults.standard.removeObject(forKey: "saved_\(l_pin)")
+                        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
+                        if self.fromNotification {
+                            self.didTapExit()
+                        } else {
+                            self.navigationController?.popViewController(animated: true)
+                        }
+                    })
+                }))
+                self.present(alert, animated: true, completion: nil)
+            }
+        })
+        let actionSearch = UIAction(title: "Search".localized(), handler: {(_) in
+            self.isSearching = true
+            if self.reffId != nil {
+                self.deleteReplyView()
+            }
+            DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
+                let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
+                cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
+                if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
+                    self.navigationItem.rightBarButtonItems = nil
                 }
-            })
+                self.navigationItem.rightBarButtonItem = cancelButton
+                if self.isContactCenter || self.fromNotification {
+                    self.navigationItem.leftBarButtonItem = nil
+                }
+                self.changeAppBar()
+                self.addMultipleSelectSession()
+            }
+        })
+        var menu = UIMenu(title: "", children: [
+            actionSearch,
+            actionDelete
         ])
         let exblock = User.getDataCanNil(pin: self.dataPerson["f_pin"]!!)?.ex_block
         blocking = exblock == nil ? "0" : exblock!.isEmpty ? "0" : exblock!
         if blocking == "1" && self.dataPerson["f_pin"]!! != "-999" {
             menu = UIMenu(title: "", children: [
-                UIAction(title: "Search".localized(), handler: {(_) in
-                    self.isSearching = true
-                    if self.reffId != nil {
-                        self.deleteReplyView()
-                    }
-                    DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
-                        let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
-                        cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
-                        if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
-                            self.navigationItem.rightBarButtonItems = nil
-                        }
-                        self.navigationItem.rightBarButtonItem = cancelButton
-                        if self.isContactCenter || self.fromNotification {
-                            self.navigationItem.leftBarButtonItem = nil
-                        }
-                        self.changeAppBar()
-                        self.addMultipleSelectSession()
-                    }
-                }),
+                actionSearch,
                 UIAction(title: "Unblock".localized(), handler: {(_) in
                     if !self.isContactCenter {
                         DispatchQueue.global().async {
@@ -385,48 +370,13 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                         }
                     }
                 }),
-                UIAction(title: "Delete Conversation".localized(), handler: {(_) in
-                    if !self.isContactCenter {
-                        let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
-                        alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
-                        alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
-                            Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                                _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
-                                _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
-                                if self.fromNotification {
-                                    self.didTapExit()
-                                } else {
-                                    self.navigationController?.popViewController(animated: true)
-                                }
-                            })
-                        }))
-                        self.present(alert, animated: true, completion: nil)
-                    }
-                })
+                actionDelete
             ])
             blockedView(blocked: "1")
         } else if blocking == "0" {
             if self.dataPerson["f_pin"]!! != "-999"{
                 menu = UIMenu(title: "", children: [
-                    UIAction(title: "Search".localized(), handler: {(_) in
-                        self.isSearching = true
-                        if self.reffId != nil {
-                            self.deleteReplyView()
-                        }
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
-                            let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
-                            cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
-                            if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
-                                self.navigationItem.rightBarButtonItems = nil
-                            }
-                            self.navigationItem.rightBarButtonItem = cancelButton
-                            if self.isContactCenter || self.fromNotification {
-                                self.navigationItem.leftBarButtonItem = nil
-                            }
-                            self.changeAppBar()
-                            self.addMultipleSelectSession()
-                        }
-                    }),
+                    actionSearch,
                     UIAction(title: "Block".localized(), handler: {(_) in
                         if !self.isContactCenter {
                             DispatchQueue.global().async {
@@ -460,64 +410,12 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                             }
                         }
                     }),
-                    UIAction(title: "Delete Conversation".localized(), handler: {(_) in
-                        if !self.isContactCenter {
-                            let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
-                            alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
-                            alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
-                                Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                                    _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
-                                    _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
-                                    if self.fromNotification {
-                                        self.didTapExit()
-                                    } else {
-                                        self.navigationController?.popViewController(animated: true)
-                                    }
-                                })
-                            }))
-                            self.present(alert, animated: true, completion: nil)
-                        }
-                    })
+                    actionDelete
                 ])
             } else {
                 menu = UIMenu(title: "", children: [
-                    UIAction(title: "Search".localized(), handler: {(_) in
-                        self.isSearching = true
-                        if self.reffId != nil {
-                            self.deleteReplyView()
-                        }
-                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) {
-                            let cancelButton = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(self.cancelAction))
-                            cancelButton.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)], for: .normal)
-                            if self.dataPerson["f_pin"] != "-999" && !self.isContactCenter {
-                                self.navigationItem.rightBarButtonItems = nil
-                            }
-                            self.navigationItem.rightBarButtonItem = cancelButton
-                            if self.isContactCenter || self.fromNotification {
-                                self.navigationItem.leftBarButtonItem = nil
-                            }
-                            self.changeAppBar()
-                            self.addMultipleSelectSession()
-                        }
-                    }),
-                    UIAction(title: "Delete Conversation".localized(), handler: {(_) in
-                        if !self.isContactCenter {
-                            let alert = LibAlertController(title: "", message: "Are you sure to delete all message in this conversation?".localized(), preferredStyle: .alert)
-                            alert.addAction(UIAlertAction(title: "Cancel".localized(), style: UIAlertAction.Style.default, handler: nil))
-                            alert.addAction(UIAlertAction(title: "Delete".localized(), style: .destructive, handler: {(_) in
-                                Database.shared.database?.inTransaction({ (fmdb, rollback) in
-                                    _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE_SUMMARY", _where: "l_pin='\(self.dataPerson["f_pin"]!!)'")
-                                    _ = Database.shared.deleteRecord(fmdb: fmdb, table: "MESSAGE", _where: "(f_pin='\(self.dataPerson["f_pin"]!!)' or l_pin='\(self.dataPerson["f_pin"]!!)') and (message_scope_id='3' or message_scope_id='18') and is_call_center = 0")
-                                    if self.fromNotification {
-                                        self.didTapExit()
-                                    } else {
-                                        self.navigationController?.popViewController(animated: true)
-                                    }
-                                })
-                            }))
-                            self.present(alert, animated: true, completion: nil)
-                        }
-                    })
+                    actionSearch,
+                    actionDelete
                 ])
             }
             if containerAction.isDescendant(of: self.view) {
@@ -633,7 +531,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
                     }
                     
                     if !last_r.isEmpty {
-                        reffId = last_r
+                        handleReply(indexPath: IndexPath(row: 0, section: 0), reffId: last_r)
                     }
                 }
                 tableChatView.scrollToBottom(isAnimated: false)
@@ -2448,6 +2346,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestu
         }
         deleteReplyView()
         deleteLinkPreview()
+        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil, userInfo: nil)
         DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
             self.tableChatView.scrollToBottom()
             if self.markerCounter != nil {
@@ -6219,15 +6118,20 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
 //        return UISwipeActionsConfiguration(actions: [action])
 //    }
     
-    private func handleReply(indexPath: IndexPath, dataMessagesImage: [String: Any?] = [:]) {
-        self.deleteReplyView()
+    private func handleReply(indexPath: IndexPath, dataMessagesImage: [String: Any?] = [:], reffId: String = "") {
         var dataMessages = self.dataMessages.filter({ $0["chat_date"] as! String == dataDates[indexPath.section]})
-        if dataMessagesImage.count != 0 {
-            dataMessages = [dataMessagesImage]
+        if reffId.isEmpty {
+            self.deleteReplyView()
+            if dataMessagesImage.count != 0 {
+                dataMessages = [dataMessagesImage]
+            } else {
+                self.textFieldSend.becomeFirstResponder()
+            }
+            self.reffId = dataMessages[indexPath.row]["message_id"] as? String
         } else {
-            self.textFieldSend.becomeFirstResponder()
+            dataMessages = self.dataMessages.filter({ $0["message_id"] as! String == reffId })
+            self.reffId = reffId
         }
-        self.reffId = dataMessages[indexPath.row]["message_id"] as? String
         UIView.animate(withDuration: 0.25, delay: 0.0, options: .curveEaseInOut, animations: {
             self.constraintTopTextField.constant = self.constraintTopTextField.constant + 50
         }, completion: nil)

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

@@ -189,7 +189,7 @@ class ContactChatViewController: UITableViewController {
         tableView.tableFooterView = UIView()
         
         pullBuddy()
-        
+        getData()
     }
     
     override func viewWillAppear(_ animated: Bool) {
@@ -201,7 +201,7 @@ class ContactChatViewController: UITableViewController {
         navigationController?.navigationBar.standardAppearance = navBarAppearance
         navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
 //        removeAllData()
-        getData()
+//        getData()
     }
     
     override func viewWillDisappear(_ animated: Bool) {