alqindiirsyam 3 years ago
parent
commit
382c1e3557

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

@@ -233,6 +233,7 @@ public class FourthTabViewController: UIViewController, UITableViewDelegate, UIT
         let randomInt = Int.random(in: 1..<10)
         backgroundImage.image = UIImage(named: "pb_lbackground_\(randomInt)")
         self.navigationController?.navigationBar.topItem?.title = "Settings".localized();
+        self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
         navigationController?.setNavigationBarHidden(false, animated: false)
         navigationController?.navigationBar.backgroundColor = .clear
         navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)

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

@@ -269,7 +269,7 @@ class SecondTabViewController: UIViewController, UIScrollViewDelegate, UIGesture
     
     override func viewWillAppear(_ animated: Bool) {
 //        tabBarController?.navigationItem.leftBarButtonItem = cancelSearchButton
-        self.navigationController?.navigationBar.topItem?.title = Bundle.main.displayName
+        self.navigationController?.navigationBar.topItem?.title = "Chats".localized() + " & " + "Groups".localized()
         self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
         navigationController?.navigationBar.backgroundColor = .clear
         navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)

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

@@ -69,7 +69,7 @@ public class EditorGroup: UIViewController {
     
     public override func viewDidAppear(_ animated: Bool) {
         navigationController?.navigationBar.isTranslucent = false
-        navigationController?.navigationBar.barTintColor = UIColor.mainColor
+        navigationController?.navigationBar.backgroundColor = .mainColor
         navigationController?.navigationBar.tintColor = .white
         if self.navigationController?.isNavigationBarHidden ?? false {
             self.navigationController?.setNavigationBarHidden(false, animated: false)
@@ -1768,149 +1768,7 @@ extension EditorGroup: UIContextMenuInteractionDelegate {
         }
         
         let reply = UIAction(title: "Reply".localized(), image: UIImage(systemName: "arrowshape.turn.up.left.fill"), handler: {(_) in
-            self.deleteReplyView()
-            self.textFieldSend.becomeFirstResponder()
-            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)
-            if (self.currentIndexpath != nil) {
-                DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
-                    self.tableChatView.scrollToRow(at: IndexPath(row: self.currentIndexpath!.row, section: self.currentIndexpath!.section), at: .none, animated: false)
-                }
-            } else {
-                self.tableChatView.scrollToBottom()
-            }
-            
-            self.viewTextfield.addSubview(self.containerPreviewReply)
-            self.containerPreviewReply.translatesAutoresizingMaskIntoConstraints = false
-            self.containerPreviewReply.leadingAnchor.constraint(equalTo: self.viewTextfield.leadingAnchor).isActive = true
-            self.containerPreviewReply.topAnchor.constraint(equalTo: self.viewTextfield.topAnchor).isActive = true
-            if !self.containerLink.isDescendant(of: self.viewTextfield) {
-                self.bottomAnchorPreviewReply = self.containerPreviewReply.bottomAnchor.constraint(equalTo: self.textFieldSend.topAnchor)
-            } else {
-                self.bottomAnchorPreviewReply = self.containerPreviewReply.bottomAnchor.constraint(equalTo: self.containerLink.topAnchor)
-            }
-            self.bottomAnchorPreviewReply.isActive = true
-            self.containerPreviewReply.trailingAnchor.constraint(equalTo: self.viewTextfield.trailingAnchor).isActive = true
-            self.containerPreviewReply.backgroundColor = .secondaryColor
-            
-            let leftReply = UIView()
-            self.containerPreviewReply.addSubview(leftReply)
-            leftReply.translatesAutoresizingMaskIntoConstraints = false
-            leftReply.leadingAnchor.constraint(equalTo: self.viewTextfield.leadingAnchor).isActive = true
-            leftReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor).isActive = true
-            leftReply.bottomAnchor.constraint(equalTo: self.containerPreviewReply.bottomAnchor).isActive = true
-            leftReply.widthAnchor.constraint(equalToConstant: 3).isActive = true
-            leftReply.backgroundColor = .orangeColor
-            
-            let titleReply = UILabel()
-            self.containerPreviewReply.addSubview(titleReply)
-            titleReply.translatesAutoresizingMaskIntoConstraints = false
-            titleReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
-            titleReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor, constant: 10).isActive = true
-            titleReply.font = UIFont.systemFont(ofSize: 12).bold
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
-            if (dataMessages[indexPath!.row]["f_pin"] as? String == idMe) {
-                titleReply.text = "You".localized()
-            } else {
-                if dataMessages[indexPath!.row]["f_pin"] as? String != "-999" {
-                    let dataPerson = self.getDataProfile(f_pin: dataMessages[indexPath!.row]["f_pin"] as! String, message_id: dataMessages[indexPath!.row]["message_id"] as! String)
-                    titleReply.text = dataPerson["name"]
-                } else {
-                    titleReply.text = "Bot"
-                }
-            }
-            titleReply.textColor = .orangeColor
-            
-            let contentReply = UILabel()
-            self.containerPreviewReply.addSubview(contentReply)
-            contentReply.translatesAutoresizingMaskIntoConstraints = false
-            contentReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
-            contentReply.topAnchor.constraint(equalTo: titleReply.bottomAnchor).isActive = true
-            contentReply.font = UIFont.systemFont(ofSize: 10)
-            let message_text = dataMessages[indexPath!.row]["message_text"] as! String
-            let attachment_flag = dataMessages[indexPath!.row]["attachment_flag"] as! String
-            let thumb_chat = dataMessages[indexPath!.row]["thumb_id"] as! String
-            let image_chat = dataMessages[indexPath!.row]["image_id"] as! String
-            let video_chat = dataMessages[indexPath!.row]["video_id"] as! String
-            let file_chat = dataMessages[indexPath!.row]["file_id"] as! String
-            if (attachment_flag == "0" && thumb_chat == "") {
-                contentReply.attributedText = message_text.richText()
-            } else if (attachment_flag == "1" || image_chat != "") {
-                if (message_text == "") {
-                    contentReply.text = "📷 Photo".localized()
-                } else {
-                    contentReply.attributedText = message_text.richText()
-                }
-            } else if (attachment_flag == "2" || video_chat != "") {
-                if (message_text == "") {
-                    contentReply.text = "📹 Video".localized()
-                } else {
-                    contentReply.attributedText = message_text.richText()
-                }
-            } else if (attachment_flag == "6" || file_chat != ""){
-                contentReply.text = "📄 \(message_text.components(separatedBy: "|")[0])"
-            } else if (attachment_flag == "11") {
-                contentReply.text = "❤️ Sticker"
-            } else if attachment_flag == "27" {
-                contentReply.text = "📄 " + "Live Streaming".localized()
-            } else if attachment_flag == "26" {
-                contentReply.text = "📄 " + "Seminar".localized()
-            }
-            contentReply.textColor = .gray
-            
-            let buttonCancelReply = UIButton(type: .custom)
-            self.containerPreviewReply.addSubview(buttonCancelReply)
-            buttonCancelReply.translatesAutoresizingMaskIntoConstraints = false
-            buttonCancelReply.trailingAnchor.constraint(equalTo: self.containerPreviewReply.trailingAnchor, constant: -10).isActive = true
-            buttonCancelReply.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
-            buttonCancelReply.setImage(UIImage(systemName: "xmark.circle" , withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular, scale: .default)), for: .normal)
-            buttonCancelReply.addTarget(nil, action: #selector(self.deleteReplyView), for: .touchUpInside)
-            buttonCancelReply.backgroundColor = .clear
-            buttonCancelReply.tintColor = .mainColor
-            
-            if (attachment_flag == "1" || attachment_flag == "2" || image_chat != "" || video_chat != "") {
-                let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
-                let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
-                let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
-                if let dirPath = paths.first {
-                    let thumbURL = URL(fileURLWithPath: dirPath).appendingPathComponent(thumb_chat)
-                    let image    = UIImage(contentsOfFile: thumbURL.path)
-                    let imageThumb = UIImageView(image: image)
-                    self.containerPreviewReply.addSubview(imageThumb)
-                    imageThumb.layer.cornerRadius = 2.0
-                    imageThumb.clipsToBounds = true
-                    imageThumb.translatesAutoresizingMaskIntoConstraints = false
-                    imageThumb.trailingAnchor.constraint(equalTo: buttonCancelReply.leadingAnchor, constant: -10).isActive = true
-                    imageThumb.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
-                    imageThumb.widthAnchor.constraint(equalToConstant: 30).isActive = true
-                    imageThumb.heightAnchor.constraint(equalToConstant: 30).isActive = true
-                    
-                    if (attachment_flag == "2") {
-                        let imagePlay = UIImageView(image: UIImage(systemName: "play.circle.fill"))
-                        imageThumb.addSubview(imagePlay)
-                        imagePlay.clipsToBounds = true
-                        imagePlay.translatesAutoresizingMaskIntoConstraints = false
-                        imagePlay.centerYAnchor.constraint(equalTo: imageThumb.centerYAnchor).isActive = true
-                        imagePlay.centerXAnchor.constraint(equalTo: imageThumb.centerXAnchor).isActive = true
-                        imagePlay.widthAnchor.constraint(equalToConstant: 10).isActive = true
-                        imagePlay.heightAnchor.constraint(equalToConstant: 10).isActive = true
-                        imagePlay.tintColor = .white
-                    }
-                }
-            }
-            if (attachment_flag == "11") {
-                let imageSticker = UIImageView(image: UIImage(named: (message_text.components(separatedBy: "/")[1]), in: Bundle.resourceBundle(for: Nexilis.self), with: nil))
-                self.containerPreviewReply.addSubview(imageSticker)
-                imageSticker.layer.cornerRadius = 2.0
-                imageSticker.clipsToBounds = true
-                imageSticker.translatesAutoresizingMaskIntoConstraints = false
-                imageSticker.trailingAnchor.constraint(equalTo: buttonCancelReply.leadingAnchor, constant: -10).isActive = true
-                imageSticker.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
-                imageSticker.widthAnchor.constraint(equalToConstant: 30).isActive = true
-                imageSticker.heightAnchor.constraint(equalToConstant: 30).isActive = true
-            }
+            self.handleReply(indexPath: indexPath!)
         })
         let forward = UIAction(title: "Forward".localized(), image: UIImage(systemName: "arrowshape.turn.up.right.fill"), handler: {(_) in
             self.forwardSession = true
@@ -1973,12 +1831,6 @@ extension EditorGroup: UIContextMenuInteractionDelegate {
         else if dataMessages[indexPath!.row]["f_pin"] as! String == "-999" {
             children = [star, reply ,delete]
         }
-        else if self.removed {
-            children = [copy]
-            if !(dataMessages[indexPath!.row]["image_id"] as! String).isEmpty || !(dataMessages[indexPath!.row]["video_id"] as! String).isEmpty {
-                children = []
-            }
-        }
         else if !(dataMessages[indexPath!.row]["image_id"] as! String).isEmpty || !(dataMessages[indexPath!.row]["video_id"] as! String).isEmpty || !(dataMessages[indexPath!.row]["file_id"] as! String).isEmpty || dataMessages[indexPath!.row]["attachment_flag"] as! String == "11" {
             children = [star, reply, forward ,delete]
         }
@@ -2507,7 +2359,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
         profileMessage.addGestureRecognizer(tapGestureRecognizer)
         
         let containerMessage = UIView()
-        if !copySession && !forwardSession && !deleteSession && !isHistoryCC {
+        if !copySession && !forwardSession && !deleteSession && !isHistoryCC && !removed {
             let interaction = UIContextMenuInteraction(delegate: self)
             containerMessage.addInteraction(interaction)
             containerMessage.isUserInteractionEnabled = true
@@ -2565,8 +2417,10 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
                 selectedImage.translatesAutoresizingMaskIntoConstraints = false
                 selectedImage.frame.size = CGSize(width: 20, height: 20)
                 var leading = selectedImage.leadingAnchor.constraint(equalTo: cellMessage.contentView.leadingAnchor, constant: -20)
+                selectedImage.isHidden = true
                 if copySession || forwardSession || deleteSession {
                     leading = selectedImage.leadingAnchor.constraint(equalTo: cellMessage.contentView.leadingAnchor, constant: 15)
+                    selectedImage.isHidden = false
                 }
                 NSLayoutConstraint.activate([
                     leading,
@@ -3484,4 +3338,177 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
         guard let url = URL(string: stringURl) else { return }
         UIApplication.shared.open(url)
     }
+    
+    // public func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
+    //     if copySession || forwardSession || deleteSession {
+    //         return nil
+    //     }
+    //     let idMe = UserDefaults.standard.string(forKey: "me") as String?
+    //     if (dataMessages[indexPath.row]["f_pin"] as? String != idMe) {
+    //         return nil
+    //     }
+    //     let messageInfoVC = MessageInfo()
+    //     self.navigationController?.show(messageInfoVC, sender: nil)
+    //     return UISwipeActionsConfiguration()
+    // }
+    
+    // public func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
+    //     if copySession || forwardSession || deleteSession {
+    //         return nil
+    //     }
+    //     let action = UIContextualAction(style: .normal,
+    //                                     title: "") { [weak self] (action, view, completionHandler) in
+    //                                         self?.handleReply(indexPath: indexPath)
+    //                                         completionHandler(true)
+    //     }
+    //     action.backgroundColor = .white
+    //     action.image = UIImage(systemName: "arrowshape.turn.up.left.fill")?.withTintColor(.black, renderingMode: .alwaysOriginal)
+    //     return UISwipeActionsConfiguration(actions: [action])
+    // }
+    
+    private func handleReply(indexPath: IndexPath) {
+        self.deleteReplyView()
+        self.textFieldSend.becomeFirstResponder()
+        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)
+        if (self.currentIndexpath != nil) {
+            DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
+                self.tableChatView.scrollToRow(at: IndexPath(row: self.currentIndexpath!.row, section: self.currentIndexpath!.section), at: .none, animated: false)
+            }
+        } else {
+            self.tableChatView.scrollToBottom()
+        }
+        
+        self.viewTextfield.addSubview(self.containerPreviewReply)
+        self.containerPreviewReply.translatesAutoresizingMaskIntoConstraints = false
+        self.containerPreviewReply.leadingAnchor.constraint(equalTo: self.viewTextfield.leadingAnchor).isActive = true
+        self.containerPreviewReply.topAnchor.constraint(equalTo: self.viewTextfield.topAnchor).isActive = true
+        if !self.containerLink.isDescendant(of: self.viewTextfield) {
+            self.bottomAnchorPreviewReply = self.containerPreviewReply.bottomAnchor.constraint(equalTo: self.textFieldSend.topAnchor)
+        } else {
+            self.bottomAnchorPreviewReply = self.containerPreviewReply.bottomAnchor.constraint(equalTo: self.containerLink.topAnchor)
+        }
+        self.bottomAnchorPreviewReply.isActive = true
+        self.containerPreviewReply.trailingAnchor.constraint(equalTo: self.viewTextfield.trailingAnchor).isActive = true
+        self.containerPreviewReply.backgroundColor = .secondaryColor
+        
+        let leftReply = UIView()
+        self.containerPreviewReply.addSubview(leftReply)
+        leftReply.translatesAutoresizingMaskIntoConstraints = false
+        leftReply.leadingAnchor.constraint(equalTo: self.viewTextfield.leadingAnchor).isActive = true
+        leftReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor).isActive = true
+        leftReply.bottomAnchor.constraint(equalTo: self.containerPreviewReply.bottomAnchor).isActive = true
+        leftReply.widthAnchor.constraint(equalToConstant: 3).isActive = true
+        leftReply.backgroundColor = .orangeColor
+        
+        let titleReply = UILabel()
+        self.containerPreviewReply.addSubview(titleReply)
+        titleReply.translatesAutoresizingMaskIntoConstraints = false
+        titleReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
+        titleReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor, constant: 10).isActive = true
+        titleReply.font = UIFont.systemFont(ofSize: 12).bold
+        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        if (dataMessages[indexPath.row]["f_pin"] as? String == idMe) {
+            titleReply.text = "You".localized()
+        } else {
+            if dataMessages[indexPath.row]["f_pin"] as? String != "-999" {
+                let dataPerson = self.getDataProfile(f_pin: dataMessages[indexPath.row]["f_pin"] as! String, message_id: dataMessages[indexPath.row]["message_id"] as! String)
+                titleReply.text = dataPerson["name"]
+            } else {
+                titleReply.text = "Bot"
+            }
+        }
+        titleReply.textColor = .orangeColor
+        
+        let contentReply = UILabel()
+        self.containerPreviewReply.addSubview(contentReply)
+        contentReply.translatesAutoresizingMaskIntoConstraints = false
+        contentReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
+        contentReply.topAnchor.constraint(equalTo: titleReply.bottomAnchor).isActive = true
+        contentReply.font = UIFont.systemFont(ofSize: 10)
+        let message_text = dataMessages[indexPath.row]["message_text"] as! String
+        let attachment_flag = dataMessages[indexPath.row]["attachment_flag"] as! String
+        let thumb_chat = dataMessages[indexPath.row]["thumb_id"] as! String
+        let image_chat = dataMessages[indexPath.row]["image_id"] as! String
+        let video_chat = dataMessages[indexPath.row]["video_id"] as! String
+        let file_chat = dataMessages[indexPath.row]["file_id"] as! String
+        if (attachment_flag == "0" && thumb_chat == "") {
+            contentReply.attributedText = message_text.richText()
+        } else if (attachment_flag == "1" || image_chat != "") {
+            if (message_text == "") {
+                contentReply.text = "📷 Photo".localized()
+            } else {
+                contentReply.attributedText = message_text.richText()
+            }
+        } else if (attachment_flag == "2" || video_chat != "") {
+            if (message_text == "") {
+                contentReply.text = "📹 Video".localized()
+            } else {
+                contentReply.attributedText = message_text.richText()
+            }
+        } else if (attachment_flag == "6" || file_chat != ""){
+            contentReply.text = "📄 \(message_text.components(separatedBy: "|")[0])"
+        } else if (attachment_flag == "11") {
+            contentReply.text = "❤️ Sticker"
+        } else if attachment_flag == "27" {
+            contentReply.text = "📄 " + "Live Streaming".localized()
+        } else if attachment_flag == "26" {
+            contentReply.text = "📄 " + "Seminar".localized()
+        }
+        contentReply.textColor = .gray
+        
+        let buttonCancelReply = UIButton(type: .custom)
+        self.containerPreviewReply.addSubview(buttonCancelReply)
+        buttonCancelReply.translatesAutoresizingMaskIntoConstraints = false
+        buttonCancelReply.trailingAnchor.constraint(equalTo: self.containerPreviewReply.trailingAnchor, constant: -10).isActive = true
+        buttonCancelReply.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
+        buttonCancelReply.setImage(UIImage(systemName: "xmark.circle" , withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular, scale: .default)), for: .normal)
+        buttonCancelReply.addTarget(nil, action: #selector(self.deleteReplyView), for: .touchUpInside)
+        buttonCancelReply.backgroundColor = .clear
+        buttonCancelReply.tintColor = .mainColor
+        
+        if (attachment_flag == "1" || attachment_flag == "2" || image_chat != "" || video_chat != "") {
+            let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
+            let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
+            let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
+            if let dirPath = paths.first {
+                let thumbURL = URL(fileURLWithPath: dirPath).appendingPathComponent(thumb_chat)
+                let image    = UIImage(contentsOfFile: thumbURL.path)
+                let imageThumb = UIImageView(image: image)
+                self.containerPreviewReply.addSubview(imageThumb)
+                imageThumb.layer.cornerRadius = 2.0
+                imageThumb.clipsToBounds = true
+                imageThumb.translatesAutoresizingMaskIntoConstraints = false
+                imageThumb.trailingAnchor.constraint(equalTo: buttonCancelReply.leadingAnchor, constant: -10).isActive = true
+                imageThumb.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
+                imageThumb.widthAnchor.constraint(equalToConstant: 30).isActive = true
+                imageThumb.heightAnchor.constraint(equalToConstant: 30).isActive = true
+                
+                if (attachment_flag == "2") {
+                    let imagePlay = UIImageView(image: UIImage(systemName: "play.circle.fill"))
+                    imageThumb.addSubview(imagePlay)
+                    imagePlay.clipsToBounds = true
+                    imagePlay.translatesAutoresizingMaskIntoConstraints = false
+                    imagePlay.centerYAnchor.constraint(equalTo: imageThumb.centerYAnchor).isActive = true
+                    imagePlay.centerXAnchor.constraint(equalTo: imageThumb.centerXAnchor).isActive = true
+                    imagePlay.widthAnchor.constraint(equalToConstant: 10).isActive = true
+                    imagePlay.heightAnchor.constraint(equalToConstant: 10).isActive = true
+                    imagePlay.tintColor = .white
+                }
+            }
+        }
+        if (attachment_flag == "11") {
+            let imageSticker = UIImageView(image: UIImage(named: (message_text.components(separatedBy: "/")[1]), in: Bundle.resourceBundle(for: Nexilis.self), with: nil))
+            self.containerPreviewReply.addSubview(imageSticker)
+            imageSticker.layer.cornerRadius = 2.0
+            imageSticker.clipsToBounds = true
+            imageSticker.translatesAutoresizingMaskIntoConstraints = false
+            imageSticker.trailingAnchor.constraint(equalTo: buttonCancelReply.leadingAnchor, constant: -10).isActive = true
+            imageSticker.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
+            imageSticker.widthAnchor.constraint(equalToConstant: 30).isActive = true
+            imageSticker.heightAnchor.constraint(equalToConstant: 30).isActive = true
+        }
+    }
 }

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

@@ -14,7 +14,7 @@ import NotificationBannerSwift
 import Photos
 import nuSDKService
 
-public class EditorPersonal: UIViewController, ImageVideoPickerDelegate {
+public class EditorPersonal: UIViewController, ImageVideoPickerDelegate, UIGestureRecognizerDelegate {
     @IBOutlet var viewButton: UIView!
     @IBOutlet var constraintViewTextField: NSLayoutConstraint!
     @IBOutlet var buttonVoice: UIButton!
@@ -70,10 +70,10 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate {
     var showToastTwiceClick = false
     var showToast30s = false
     var allowTyping = true
+    var hapticSwipeLeft = false
     
     public override func viewDidDisappear(_ animated: Bool) {
         if self.isMovingFromParent {
-            print("MASUK Disappear EDITOR PERSONAL")
             self.timeoutCC.invalidate()
             UserDefaults.standard.removeObject(forKey: "inEditorPersonal")
             NotificationCenter.default.removeObserver(self)
@@ -82,7 +82,7 @@ public class EditorPersonal: UIViewController, ImageVideoPickerDelegate {
     
     public override func viewDidAppear(_ animated: Bool) {
         navigationController?.navigationBar.isTranslucent = false
-        navigationController?.navigationBar.barTintColor = UIColor.mainColor
+        navigationController?.navigationBar.backgroundColor = .mainColor
         navigationController?.navigationBar.tintColor = .white
         if self.navigationController?.isNavigationBarHidden ?? false {
             self.navigationController?.setNavigationBarHidden(false, animated: false)
@@ -2565,145 +2565,7 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
         }
         
         let reply = UIAction(title: "Reply".localized(), image: UIImage(systemName: "arrowshape.turn.up.left.fill"), handler: {(_) in
-            self.deleteReplyView()
-            self.textFieldSend.becomeFirstResponder()
-            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)
-            if (self.currentIndexpath != nil) {
-                DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
-                    self.tableChatView.scrollToRow(at: IndexPath(row: self.currentIndexpath!.row, section: self.currentIndexpath!.section), at: .none, animated: false)
-                }
-            } else {
-                self.tableChatView.scrollToBottom()
-            }
-            
-            self.viewTextfield.addSubview(self.containerPreviewReply)
-            self.containerPreviewReply.translatesAutoresizingMaskIntoConstraints = false
-            self.containerPreviewReply.leadingAnchor.constraint(equalTo: self.viewTextfield.leadingAnchor).isActive = true
-            self.containerPreviewReply.topAnchor.constraint(equalTo: self.viewTextfield.topAnchor).isActive = true
-            if !self.containerLink.isDescendant(of: self.viewTextfield) {
-                self.bottomAnchorPreviewReply = self.containerPreviewReply.bottomAnchor.constraint(equalTo: self.textFieldSend.topAnchor)
-            } else {
-                self.bottomAnchorPreviewReply = self.containerPreviewReply.bottomAnchor.constraint(equalTo: self.containerLink.topAnchor)
-            }
-            self.bottomAnchorPreviewReply.isActive = true
-            self.containerPreviewReply.trailingAnchor.constraint(equalTo: self.viewTextfield.trailingAnchor).isActive = true
-            self.containerPreviewReply.backgroundColor = .secondaryColor
-            
-            let leftReply = UIView()
-            self.containerPreviewReply.addSubview(leftReply)
-            leftReply.translatesAutoresizingMaskIntoConstraints = false
-            leftReply.leadingAnchor.constraint(equalTo: self.viewTextfield.leadingAnchor).isActive = true
-            leftReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor).isActive = true
-            leftReply.bottomAnchor.constraint(equalTo: self.containerPreviewReply.bottomAnchor).isActive = true
-            leftReply.widthAnchor.constraint(equalToConstant: 3).isActive = true
-            leftReply.backgroundColor = .orangeColor
-            
-            let titleReply = UILabel()
-            self.containerPreviewReply.addSubview(titleReply)
-            titleReply.translatesAutoresizingMaskIntoConstraints = false
-            titleReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
-            titleReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor, constant: 10).isActive = true
-            titleReply.font = UIFont.systemFont(ofSize: 12).bold
-            let idMe = UserDefaults.standard.string(forKey: "me") as String?
-            if (dataMessages[indexPath!.row]["f_pin"] as? String == idMe) {
-                titleReply.text = "You".localized()
-            } else {
-                if self.isContactCenter {
-                    let user: [User] = self.users.filter({$0.pin == dataMessages[indexPath!.row]["f_pin"] as? String})
-                    titleReply.text = user.first!.fullName
-                } else {
-                    titleReply.text = self.dataPerson["name"]!!
-                }
-            }
-            titleReply.textColor = .orangeColor
-            
-            let contentReply = UILabel()
-            self.containerPreviewReply.addSubview(contentReply)
-            contentReply.translatesAutoresizingMaskIntoConstraints = false
-            contentReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
-            contentReply.topAnchor.constraint(equalTo: titleReply.bottomAnchor).isActive = true
-            contentReply.font = UIFont.systemFont(ofSize: 10)
-            let message_text = dataMessages[indexPath!.row]["message_text"] as! String
-            let attachment_flag = dataMessages[indexPath!.row]["attachment_flag"] as! String
-            let thumb_chat = dataMessages[indexPath!.row]["thumb_id"] as! String
-            let image_chat = dataMessages[indexPath!.row]["image_id"] as! String
-            let video_chat = dataMessages[indexPath!.row]["video_id"] as! String
-            let file_chat = dataMessages[indexPath!.row]["file_id"] as! String
-            if (attachment_flag == "0" && thumb_chat == "") {
-                contentReply.attributedText = message_text.richText()
-            } else if (attachment_flag == "1" || image_chat != "") {
-                if (message_text == "") {
-                    contentReply.text = "📷 Photo".localized()
-                } else {
-                    contentReply.attributedText = message_text.richText()
-                }
-            } else if (attachment_flag == "2" || video_chat != "") {
-                if (message_text == "") {
-                    contentReply.text = "📹 Video".localized()
-                } else {
-                    contentReply.attributedText = message_text.richText()
-                }
-            } else if (attachment_flag == "6" || file_chat != ""){
-                contentReply.text = "📄 \(message_text.components(separatedBy: "|")[0])"
-            } else if (attachment_flag == "11") {
-                contentReply.text = "❤️ Sticker"
-            }
-            contentReply.textColor = .gray
-            
-            let buttonCancelReply = UIButton(type: .custom)
-            self.containerPreviewReply.addSubview(buttonCancelReply)
-            buttonCancelReply.translatesAutoresizingMaskIntoConstraints = false
-            buttonCancelReply.trailingAnchor.constraint(equalTo: self.containerPreviewReply.trailingAnchor, constant: -10).isActive = true
-            buttonCancelReply.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
-            buttonCancelReply.setImage(UIImage(systemName: "xmark.circle" , withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular, scale: .default)), for: .normal)
-            buttonCancelReply.addTarget(nil, action: #selector(self.deleteReplyView), for: .touchUpInside)
-            buttonCancelReply.backgroundColor = .clear
-            buttonCancelReply.tintColor = .mainColor
-            
-            if (attachment_flag == "1" || attachment_flag == "2" || image_chat != "" || video_chat != "") {
-                let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
-                let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
-                let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
-                if let dirPath = paths.first {
-                    let thumbURL = URL(fileURLWithPath: dirPath).appendingPathComponent(thumb_chat)
-                    let image    = UIImage(contentsOfFile: thumbURL.path)
-                    let imageThumb = UIImageView(image: image)
-                    self.containerPreviewReply.addSubview(imageThumb)
-                    imageThumb.layer.cornerRadius = 2.0
-                    imageThumb.clipsToBounds = true
-                    imageThumb.translatesAutoresizingMaskIntoConstraints = false
-                    imageThumb.trailingAnchor.constraint(equalTo: buttonCancelReply.leadingAnchor, constant: -10).isActive = true
-                    imageThumb.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
-                    imageThumb.widthAnchor.constraint(equalToConstant: 30).isActive = true
-                    imageThumb.heightAnchor.constraint(equalToConstant: 30).isActive = true
-                    
-                    if (attachment_flag == "2") {
-                        let imagePlay = UIImageView(image: UIImage(systemName: "play.circle.fill"))
-                        imageThumb.addSubview(imagePlay)
-                        imagePlay.clipsToBounds = true
-                        imagePlay.translatesAutoresizingMaskIntoConstraints = false
-                        imagePlay.centerYAnchor.constraint(equalTo: imageThumb.centerYAnchor).isActive = true
-                        imagePlay.centerXAnchor.constraint(equalTo: imageThumb.centerXAnchor).isActive = true
-                        imagePlay.widthAnchor.constraint(equalToConstant: 10).isActive = true
-                        imagePlay.heightAnchor.constraint(equalToConstant: 10).isActive = true
-                        imagePlay.tintColor = .white
-                    }
-                }
-            }
-            if (attachment_flag == "11") {
-                let imageSticker = UIImageView(image: UIImage(named: (message_text.components(separatedBy: "/")[1]), in: Bundle.resourceBundle(for: Nexilis.self), with: nil))
-                self.containerPreviewReply.addSubview(imageSticker)
-                imageSticker.layer.cornerRadius = 2.0
-                imageSticker.clipsToBounds = true
-                imageSticker.translatesAutoresizingMaskIntoConstraints = false
-                imageSticker.trailingAnchor.constraint(equalTo: buttonCancelReply.leadingAnchor, constant: -10).isActive = true
-                imageSticker.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
-                imageSticker.widthAnchor.constraint(equalToConstant: 30).isActive = true
-                imageSticker.heightAnchor.constraint(equalToConstant: 30).isActive = true
-            }
+            self.handleReply(indexPath: indexPath!)
         })
         let forward = UIAction(title: "Forward".localized(), image: UIImage(systemName: "arrowshape.turn.up.right.fill"), handler: {(_) in
             self.forwardSession = true
@@ -2782,10 +2644,10 @@ extension EditorPersonal: UIContextMenuInteractionDelegate {
             children = [reply, copy]
         } else if (dataMessages[indexPath!.row]["lock"] != nil && dataMessages[indexPath!.row]["lock"] as! String == "1") || dataMessages[indexPath!.row]["message_scope_id"] as! String == "18" || dataPerson["f_pin"] == "-999" {
             children = [delete]
-        } else if self.removed || blocking == "1" || blocking == "-1" {
-            children = [copy]
+        } else if blocking == "1" || blocking == "-1" {
+            children = [star, forward, copy ,delete]
             if !(dataMessages[indexPath!.row]["image_id"] as! String).isEmpty || !(dataMessages[indexPath!.row]["video_id"] as! String).isEmpty {
-                children = []
+                children = [star, forward ,delete]
             }
         }
         else if !(dataMessages[indexPath!.row]["image_id"] as! String).isEmpty || !(dataMessages[indexPath!.row]["video_id"] as! String).isEmpty || !(dataMessages[indexPath!.row]["file_id"] as! String).isEmpty || dataMessages[indexPath!.row]["attachment_flag"] as! String == "11" {
@@ -3562,7 +3424,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
         }
         
         let containerMessage = UIView()
-        if !copySession && !forwardSession && !deleteSession {
+        if !copySession && !forwardSession && !deleteSession && !self.removed {
             let interaction = UIContextMenuInteraction(delegate: self)
             containerMessage.addInteraction(interaction)
             containerMessage.isUserInteractionEnabled = true
@@ -3603,8 +3465,10 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                 selectedImage.translatesAutoresizingMaskIntoConstraints = false
                 selectedImage.frame.size = CGSize(width: 20, height: 20)
                 var leading = selectedImage.leadingAnchor.constraint(equalTo: cellMessage.contentView.leadingAnchor, constant: -20)
+                selectedImage.isHidden = true
                 if copySession || forwardSession || deleteSession {
                     leading = selectedImage.leadingAnchor.constraint(equalTo: cellMessage.contentView.leadingAnchor, constant: 15)
+                    selectedImage.isHidden = false
                 }
                 NSLayoutConstraint.activate([
                     leading,
@@ -4252,9 +4116,65 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                 }
             }
         }
+//        let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(panGestureCellAction))
+//        panGestureRecognizer.delegate = self
+//        cellMessage.addGestureRecognizer(panGestureRecognizer)
         return cellMessage
     }
     
+//    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
+//        let velocity : CGPoint = gestureRecognizer.location(in: tableChatView)
+//        if velocity.x < 0 {
+//            return false
+//        }
+//        return abs(Float(velocity.x)) > abs(Float(velocity.y))
+//    }
+//
+//    @objc func panGestureCellAction(recognizer: UIPanGestureRecognizer)  {
+//        let translation = recognizer.translation(in: tableChatView)
+//        let x = recognizer.view?.frame.origin.x ?? 0
+//        if x >= -(recognizer.view?.frame.size.width ?? 0) * 0.05 {
+//            recognizer.view?.center = CGPoint(
+//                x: (recognizer.view?.center.x ?? 0) + translation.x,
+//                y: (recognizer.view?.center.y ?? 0))
+//            recognizer.setTranslation(CGPoint(x: 0, y: 0), in: view)
+//            if (recognizer.view?.frame.origin.x ?? 0) > UIScreen.main.bounds.size.width * 0.9 {
+//                UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut, animations: {
+//                    recognizer.view?.frame = CGRect(x: 0, y: recognizer.view?.frame.origin.y ?? 0, width: recognizer.view?.frame.size.width ?? 0, height: recognizer.view?.frame.size.height ?? 0)
+//                })
+//            }
+//        }
+//        if x <= -(recognizer.view?.frame.size.width ?? 0) * 0.05 {
+//            let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//            let indexPath = self.tableChatView.indexPath(for: recognizer.view! as! UITableViewCell)
+//            let dataMessages = self.dataMessages.filter({ $0["chat_date"] as! String == dataDates[indexPath!.section]})
+//            if (dataMessages[indexPath!.row]["f_pin"] as? String == idMe) {
+//                let messageInfoVC = MessageInfo()
+//                messageInfoVC.data = dataMessages[indexPath!.row]
+//                self.navigationController?.pushViewController(messageInfoVC, animated: true)
+//                return
+//            }
+//        }
+//        if x >= ((recognizer.view?.frame.size.width ?? 0) * 0.2) {
+//            if !hapticSwipeLeft {
+//                UINotificationFeedbackGenerator().notificationOccurred(.success)
+//            }
+//            hapticSwipeLeft = true
+//        } else if x < ((recognizer.view?.frame.size.width ?? 0) * 0.2) {
+//            hapticSwipeLeft = false
+//        }
+//        if recognizer.state == .ended {
+//            UIView.animate(withDuration: 0.25, delay: 0, options: .curveEaseOut) {
+//                recognizer.view?.frame = CGRect(x: 0, y: recognizer.view?.frame.origin.y ?? 0, width: recognizer.view?.frame.size.width ?? 0, height: recognizer.view?.frame.size.height ?? 0)
+//            } completion: { (finished) in
+//                if x > ((recognizer.view?.frame.size.width ?? 0) * 0.2) {
+//                    self.hapticSwipeLeft = false
+//
+//                }
+//            }
+//        }
+//    }
+    
     public func numberOfSections(in tableView: UITableView) -> Int {
         dataDates.count
     }
@@ -4492,6 +4412,176 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
         guard let url = URL(string: stringURl) else { return }
         UIApplication.shared.open(url)
     }
+    
+//    public func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
+//        if copySession || forwardSession || deleteSession {
+//            return nil
+//        }
+//        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+//        if (dataMessages[indexPath.row]["f_pin"] as? String != idMe) {
+//            return nil
+//        }
+//        let messageInfoVC = MessageInfo()
+//        messageInfoVC.data = dataMessages[indexPath.row]
+//        self.navigationController?.show(messageInfoVC, sender: nil)
+//        return UISwipeActionsConfiguration()
+//    }
+//
+//    public func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
+//        if copySession || forwardSession || deleteSession {
+//            return nil
+//        }
+//        let action = UIContextualAction(style: .normal,
+//                                        title: "") { [weak self] (action, view, completionHandler) in
+//                                            self?.handleReply(indexPath: indexPath)
+//                                            completionHandler(true)
+//        }
+//        action.backgroundColor = .white
+//        action.image = UIImage(systemName: "arrowshape.turn.up.left.fill")?.withTintColor(.black, renderingMode: .alwaysOriginal)
+//        return UISwipeActionsConfiguration(actions: [action])
+//    }
+    
+    private func handleReply(indexPath: IndexPath) {
+        self.deleteReplyView()
+        self.textFieldSend.becomeFirstResponder()
+        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)
+        if (self.currentIndexpath != nil) {
+            DispatchQueue.main.asyncAfter(deadline: .now() + 0.25) {
+                self.tableChatView.scrollToRow(at: IndexPath(row: self.currentIndexpath!.row, section: self.currentIndexpath!.section), at: .none, animated: false)
+            }
+        } else {
+            self.tableChatView.scrollToBottom()
+        }
+        
+        self.viewTextfield.addSubview(self.containerPreviewReply)
+        self.containerPreviewReply.translatesAutoresizingMaskIntoConstraints = false
+        self.containerPreviewReply.leadingAnchor.constraint(equalTo: self.viewTextfield.leadingAnchor).isActive = true
+        self.containerPreviewReply.topAnchor.constraint(equalTo: self.viewTextfield.topAnchor).isActive = true
+        if !self.containerLink.isDescendant(of: self.viewTextfield) {
+            self.bottomAnchorPreviewReply = self.containerPreviewReply.bottomAnchor.constraint(equalTo: self.textFieldSend.topAnchor)
+        } else {
+            self.bottomAnchorPreviewReply = self.containerPreviewReply.bottomAnchor.constraint(equalTo: self.containerLink.topAnchor)
+        }
+        self.bottomAnchorPreviewReply.isActive = true
+        self.containerPreviewReply.trailingAnchor.constraint(equalTo: self.viewTextfield.trailingAnchor).isActive = true
+        self.containerPreviewReply.backgroundColor = .secondaryColor
+        
+        let leftReply = UIView()
+        self.containerPreviewReply.addSubview(leftReply)
+        leftReply.translatesAutoresizingMaskIntoConstraints = false
+        leftReply.leadingAnchor.constraint(equalTo: self.viewTextfield.leadingAnchor).isActive = true
+        leftReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor).isActive = true
+        leftReply.bottomAnchor.constraint(equalTo: self.containerPreviewReply.bottomAnchor).isActive = true
+        leftReply.widthAnchor.constraint(equalToConstant: 3).isActive = true
+        leftReply.backgroundColor = .orangeColor
+        
+        let titleReply = UILabel()
+        self.containerPreviewReply.addSubview(titleReply)
+        titleReply.translatesAutoresizingMaskIntoConstraints = false
+        titleReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
+        titleReply.topAnchor.constraint(equalTo: self.containerPreviewReply.topAnchor, constant: 10).isActive = true
+        titleReply.font = UIFont.systemFont(ofSize: 12).bold
+        let idMe = UserDefaults.standard.string(forKey: "me") as String?
+        if (dataMessages[indexPath.row]["f_pin"] as? String == idMe) {
+            titleReply.text = "You".localized()
+        } else {
+            if self.isContactCenter {
+                let user: [User] = self.users.filter({$0.pin == dataMessages[indexPath.row]["f_pin"] as? String})
+                titleReply.text = user.first!.fullName
+            } else {
+                titleReply.text = self.dataPerson["name"]!!
+            }
+        }
+        titleReply.textColor = .orangeColor
+        
+        let contentReply = UILabel()
+        self.containerPreviewReply.addSubview(contentReply)
+        contentReply.translatesAutoresizingMaskIntoConstraints = false
+        contentReply.leadingAnchor.constraint(equalTo: leftReply.leadingAnchor, constant: 10).isActive = true
+        contentReply.topAnchor.constraint(equalTo: titleReply.bottomAnchor).isActive = true
+        contentReply.font = UIFont.systemFont(ofSize: 10)
+        let message_text = dataMessages[indexPath.row]["message_text"] as! String
+        let attachment_flag = dataMessages[indexPath.row]["attachment_flag"] as! String
+        let thumb_chat = dataMessages[indexPath.row]["thumb_id"] as! String
+        let image_chat = dataMessages[indexPath.row]["image_id"] as! String
+        let video_chat = dataMessages[indexPath.row]["video_id"] as! String
+        let file_chat = dataMessages[indexPath.row]["file_id"] as! String
+        if (attachment_flag == "0" && thumb_chat == "") {
+            contentReply.attributedText = message_text.richText()
+        } else if (attachment_flag == "1" || image_chat != "") {
+            if (message_text == "") {
+                contentReply.text = "📷 Photo".localized()
+            } else {
+                contentReply.attributedText = message_text.richText()
+            }
+        } else if (attachment_flag == "2" || video_chat != "") {
+            if (message_text == "") {
+                contentReply.text = "📹 Video".localized()
+            } else {
+                contentReply.attributedText = message_text.richText()
+            }
+        } else if (attachment_flag == "6" || file_chat != ""){
+            contentReply.text = "📄 \(message_text.components(separatedBy: "|")[0])"
+        } else if (attachment_flag == "11") {
+            contentReply.text = "❤️ Sticker"
+        }
+        contentReply.textColor = .gray
+        
+        let buttonCancelReply = UIButton(type: .custom)
+        self.containerPreviewReply.addSubview(buttonCancelReply)
+        buttonCancelReply.translatesAutoresizingMaskIntoConstraints = false
+        buttonCancelReply.trailingAnchor.constraint(equalTo: self.containerPreviewReply.trailingAnchor, constant: -10).isActive = true
+        buttonCancelReply.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
+        buttonCancelReply.setImage(UIImage(systemName: "xmark.circle" , withConfiguration: UIImage.SymbolConfiguration(pointSize: 20, weight: .regular, scale: .default)), for: .normal)
+        buttonCancelReply.addTarget(nil, action: #selector(self.deleteReplyView), for: .touchUpInside)
+        buttonCancelReply.backgroundColor = .clear
+        buttonCancelReply.tintColor = .mainColor
+        
+        if (attachment_flag == "1" || attachment_flag == "2" || image_chat != "" || video_chat != "") {
+            let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
+            let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
+            let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
+            if let dirPath = paths.first {
+                let thumbURL = URL(fileURLWithPath: dirPath).appendingPathComponent(thumb_chat)
+                let image    = UIImage(contentsOfFile: thumbURL.path)
+                let imageThumb = UIImageView(image: image)
+                self.containerPreviewReply.addSubview(imageThumb)
+                imageThumb.layer.cornerRadius = 2.0
+                imageThumb.clipsToBounds = true
+                imageThumb.translatesAutoresizingMaskIntoConstraints = false
+                imageThumb.trailingAnchor.constraint(equalTo: buttonCancelReply.leadingAnchor, constant: -10).isActive = true
+                imageThumb.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
+                imageThumb.widthAnchor.constraint(equalToConstant: 30).isActive = true
+                imageThumb.heightAnchor.constraint(equalToConstant: 30).isActive = true
+                
+                if (attachment_flag == "2") {
+                    let imagePlay = UIImageView(image: UIImage(systemName: "play.circle.fill"))
+                    imageThumb.addSubview(imagePlay)
+                    imagePlay.clipsToBounds = true
+                    imagePlay.translatesAutoresizingMaskIntoConstraints = false
+                    imagePlay.centerYAnchor.constraint(equalTo: imageThumb.centerYAnchor).isActive = true
+                    imagePlay.centerXAnchor.constraint(equalTo: imageThumb.centerXAnchor).isActive = true
+                    imagePlay.widthAnchor.constraint(equalToConstant: 10).isActive = true
+                    imagePlay.heightAnchor.constraint(equalToConstant: 10).isActive = true
+                    imagePlay.tintColor = .white
+                }
+            }
+        }
+        if (attachment_flag == "11") {
+            let imageSticker = UIImageView(image: UIImage(named: (message_text.components(separatedBy: "/")[1]), in: Bundle.resourceBundle(for: Nexilis.self), with: nil))
+            self.containerPreviewReply.addSubview(imageSticker)
+            imageSticker.layer.cornerRadius = 2.0
+            imageSticker.clipsToBounds = true
+            imageSticker.translatesAutoresizingMaskIntoConstraints = false
+            imageSticker.trailingAnchor.constraint(equalTo: buttonCancelReply.leadingAnchor, constant: -10).isActive = true
+            imageSticker.centerYAnchor.constraint(equalTo: self.containerPreviewReply.centerYAnchor).isActive = true
+            imageSticker.widthAnchor.constraint(equalToConstant: 30).isActive = true
+            imageSticker.heightAnchor.constraint(equalToConstant: 30).isActive = true
+        }
+    }
 }
 
 extension UITableView {

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

@@ -143,8 +143,10 @@ public class ProfileViewController: UITableViewController {
     }
     
     public override func viewWillAppear(_ animated: Bool) {
-        if navigationController?.navigationBar.barTintColor == .mainColor {
+        if navigationController?.navigationBar.backgroundColor != .clear {
             navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
+        } else {
+            navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.black]
         }
     }