Pārlūkot izejas kodu

update fix bugs

alqindiirsyam 2 gadi atpakaļ
vecāks
revīzija
c88bad29c2

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

@@ -108,6 +108,12 @@ class ViewController: UITabBarController, UITabBarControllerDelegate, SettingMAB
                 }
             }
         }
+        
+        let topBorder = CALayer()
+        topBorder.backgroundColor = UIColor.gray.withAlphaComponent(0.5).cgColor
+        topBorder.frame = CGRect(x: 0, y: 0, width: tabBar.frame.size.width, height: 1)
+        tabBar.layer.addSublayer(topBorder)
+        
         ViewController.def = self
         title = Bundle.main.displayName
         let customTab = PrefsUtil.getCustomTab().split(separator: ",")

+ 5 - 0
appbuilder-ios/DigiXLite/DigiXLite/Source/View/Chat/EditorGroup.swift

@@ -3508,6 +3508,10 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
         
         messageText.isUserInteractionEnabled = false
         if !textChat!.isEmpty {
+            if textChat!.contains("■"){
+                textChat = textChat?.components(separatedBy: "■")[0]
+                textChat = textChat?.trimmingCharacters(in: .whitespacesAndNewlines)
+            }
             let listTextEnter = textChat!.split(separator: "\n")
             for j in 0...listTextEnter.count - 1 {
                 let listText = listTextEnter[j].split(separator: " ")
@@ -4033,6 +4037,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
                                     "data_link" : json,
                                     "retry": 0
                                 ], replace: true)
+                                dataURL = json
                                 showLink()
                             } catch {
                                 rollback.pointee = true

+ 5 - 0
appbuilder-ios/DigiXLite/DigiXLite/Source/View/Chat/EditorPersonal.swift

@@ -4889,6 +4889,10 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
         
         messageText.isUserInteractionEnabled = false
         if !textChat.isEmpty {
+            if textChat.contains("■"){
+                textChat = textChat.components(separatedBy: "■")[0]
+                textChat = textChat.trimmingCharacters(in: .whitespacesAndNewlines)
+            }
             let listTextEnter = textChat.split(separator: "\n")
             for j in 0...listTextEnter.count - 1 {
                 let listText = listTextEnter[j].split(separator: " ")
@@ -5415,6 +5419,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                                     "data_link" : json,
                                     "retry": 0
                                 ], replace: true)
+                                dataURL = json
                                 showLink()
                             } catch {
                                 rollback.pointee = true

+ 143 - 0
appbuilder-ios/DigiXLite/DigiXLite/Source/View/Chat/EditorStarMessages.swift

@@ -18,6 +18,10 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
     var dataDates: [String] = []
     var previewItem = NSURL()
     var fromNotification = false
+    var timerCheckLink: Timer?
+    var isLinkCopied = false
+    var touchedSubview = UIView()
+    var lastTouchPoint: CGPoint = .zero
 
     public override func viewDidLoad() {
         super.viewDidLoad()
@@ -421,6 +425,34 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
             messageText.attributedText = textChat!.richText()
         }
         messageText.font = UIFont.systemFont(ofSize: 12)
+        
+        messageText.isUserInteractionEnabled = false
+        if !textChat!.isEmpty {
+            if textChat!.contains("■"){
+                textChat = textChat?.components(separatedBy: "■")[0]
+                textChat = textChat?.trimmingCharacters(in: .whitespacesAndNewlines)
+            }
+            let listTextEnter = textChat!.split(separator: "\n")
+            for j in 0...listTextEnter.count - 1 {
+                let listText = listTextEnter[j].split(separator: " ")
+                if listText.count > 0 {
+                    for i in 0...listText.count - 1 {
+                        if listText[i].lowercased().checkStartWithLink() {
+                            let rangeTapLink = (textChat! as NSString).range(of: String(listText[i]))
+                            // Add tap gesture recognizer to the range of text
+                            let attributedString = textChat!.richText()
+                            attributedString.addAttributes([.foregroundColor: UIColor.blue, .underlineStyle: NSUnderlineStyle.single.rawValue], range: rangeTapLink)
+                            messageText.attributedText = attributedString
+                            messageText.isUserInteractionEnabled = true
+                            let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressLink(_:)))
+                            longPress.minimumPressDuration = 0.1
+                            containerMessage.addGestureRecognizer(longPress)
+                        }
+                    }
+                }
+            }
+        }
+        
         if (dataMessages[indexPath.row]["f_pin"] as? String == idMe) {
             messageText.textColor = .white
         } else {
@@ -772,6 +804,7 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
                                     "data_link" : json,
                                     "retry": 0
                                 ], replace: true)
+                                dataURL = json
                                 showLink()
                             } catch {
                                 rollback.pointee = true
@@ -789,6 +822,116 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
         return cellMessage
     }
     
+    @objc func handleLongPressLink(_ gestureRecognizer: UILongPressGestureRecognizer) {
+        func showMenuContext() {
+            if gestureRecognizer.state == .cancelled || gestureRecognizer.state == .ended{
+                timerCheckLink?.invalidate()
+            } else if gestureRecognizer.state == .began {
+                timerCheckLink = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false, block: {_ in
+                    let interaction = UIContextMenuInteraction(delegate: self)
+                    gestureRecognizer.view!.addInteraction(interaction)
+                    guard let interaction = gestureRecognizer.view!.interactions.first,
+                          let data = Data(base64Encoded: "X3ByZXNlbnRNZW51QXRMb2NhdGlvbjo="),
+                          let str = String(data: data, encoding: .utf8)
+                    else {
+                        return
+                    }
+                    let selector = NSSelectorFromString(str)
+                    guard interaction.responds(to: selector) else {
+                        return
+                    }
+                    let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
+                    impactHeavy.impactOccurred()
+                    interaction.perform(selector, with: self.view)
+                    self.isLinkCopied = true
+                })
+            }
+        }
+        if gestureRecognizer.state == .began {
+            let touchPoint = gestureRecognizer.location(in: self.view)
+            touchedSubview = self.view.hitTest(touchPoint, with: nil) ?? UIView()
+            if !(touchedSubview is UILabel) {
+                showMenuContext()
+            }
+        }
+        guard let label = touchedSubview as? UILabel else { return }
+        let touchPointLabel = gestureRecognizer.location(in: label)
+
+        if let text = label.text, let range = getWordRange(at: touchPointLabel, in: label) {
+            let word = String(text[range])
+            if word.starts(with: "www.") || word.starts(with: "https://") || word.starts(with: "http://") {
+                if gestureRecognizer.state == .cancelled || gestureRecognizer.state == .ended{
+                    timerCheckLink?.invalidate()
+                    if !isLinkCopied {
+                        var stringURl = word
+                        if stringURl.starts(with: "www.") {
+                            stringURl = "https://" + stringURl.replacingOccurrences(of: "www.", with: "")
+                        }
+                        guard let url = URL(string: stringURl) else { return }
+                        UIApplication.shared.open(url)
+                        label.attributedText = removeHighlightedText(for: text, in: range, label: label)
+                    }
+                    isLinkCopied = false
+                } else if gestureRecognizer.state == .began {
+                    label.attributedText = highlightedText(for: text, in: range, label: label)
+                    timerCheckLink = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: {_ in
+                        self.isLinkCopied = true
+                        UIPasteboard.general.string = word
+                        self.showToast(message: "Link Copied".localized(), font: UIFont.systemFont(ofSize: 12, weight: .medium), controller: self)
+                        label.attributedText = self.removeHighlightedText(for: text, in: range, label: label)
+                    })
+                }
+            } else {
+                showMenuContext()
+            }
+        } else {
+            showMenuContext()
+        }
+    }
+    
+    func getWordRange(at point: CGPoint, in label: UILabel) -> Range<String.Index>? {
+        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))
+        
+        layoutManager.addTextContainer(textContainer)
+        textStorage.addLayoutManager(layoutManager)
+        textContainer.lineFragmentPadding = 0
+        textContainer.maximumNumberOfLines = label.numberOfLines
+        
+        lastTouchPoint = point
+        let characterIndex = layoutManager.characterIndex(for: point, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
+        
+        if characterIndex == text.count - 1 {
+            return nil
+        }
+        var wordStartIndex = characterIndex
+        while wordStartIndex > 0 && text[text.index(text.startIndex, offsetBy: wordStartIndex - 1)] != " " && text[text.index(text.startIndex, offsetBy: wordStartIndex - 1)] != "\n" {
+            wordStartIndex -= 1
+        }
+        
+        var wordEndIndex = characterIndex
+        while wordEndIndex < text.count && text[text.index(text.startIndex, offsetBy: wordEndIndex)] != " " && text[text.index(text.startIndex, offsetBy: wordEndIndex)] != "\n" {
+            wordEndIndex += 1
+        }
+        
+        return text.index(text.startIndex, offsetBy: wordStartIndex)..<text.index(text.startIndex, offsetBy: wordEndIndex)
+    }
+
+    func highlightedText(for text: String, in range: Range<String.Index>, label: UILabel) -> NSAttributedString {
+        let mutableAttributedString = label.attributedText!.mutableCopy() as! NSMutableAttributedString
+        mutableAttributedString.addAttribute(.backgroundColor, value: UIColor.lightGray.withAlphaComponent(0.5), range: NSRange(range, in: text))
+        return mutableAttributedString
+    }
+    
+    func removeHighlightedText(for text: String, in range: Range<String.Index>, label: UILabel) -> NSAttributedString {
+        let mutableAttributedString = label.attributedText!.mutableCopy() as! NSMutableAttributedString
+        mutableAttributedString.removeAttribute(.backgroundColor, range: NSRange(range, in: text))
+        return mutableAttributedString
+    }
+    
     @objc func tapMessageText(_ sender: ObjectGesture) {
         var stringURl = sender.message_id.lowercased()
         if stringURl.starts(with: "www.") {

+ 3 - 6
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorGroup.swift

@@ -3509,11 +3509,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
         messageText.isUserInteractionEnabled = false
         if !textChat!.isEmpty {
             if textChat!.contains("■"){
-                textChat = textChat?.replacingOccurrences(of: "■", with: "\n")
-                textChat = textChat?.replacingOccurrences(of: "UPL02cc73b8441692181388714.jpg", with: "")
-                textChat = textChat?.replacingOccurrences(of: "accounts.google.com", with: "")
-                textChat = textChat?.replacingOccurrences(of: "Google Drive: Sign-in", with: "")
-                textChat = textChat?.replacingOccurrences(of: "Access Google Drive with a Google account (for personal use) or Google Workspace account (for...", with: "")
+                textChat = textChat?.components(separatedBy: "■")[0]
                 textChat = textChat?.trimmingCharacters(in: .whitespacesAndNewlines)
             }
             let listTextEnter = textChat!.split(separator: "\n")
@@ -3921,7 +3917,7 @@ 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] {
+                    if !dataURL.isEmpty, 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 imageUrl = data["imageUrl"] as? String
@@ -4043,6 +4039,7 @@ extension EditorGroup: UITableViewDelegate, UITableViewDataSource {
                                     "data_link" : json,
                                     "retry": 0
                                 ], replace: true)
+                                dataURL = json
                                 showLink()
                             } catch {
                                 rollback.pointee = true

+ 2 - 5
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorPersonal.swift

@@ -4890,11 +4890,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
         messageText.isUserInteractionEnabled = false
         if !textChat.isEmpty {
             if textChat.contains("■"){
-                textChat = textChat.replacingOccurrences(of: "■", with: "\n")
-                textChat = textChat.replacingOccurrences(of: "UPL02cc73b8441692181388714.jpg", with: "")
-                textChat = textChat.replacingOccurrences(of: "accounts.google.com", with: "")
-                textChat = textChat.replacingOccurrences(of: "Google Drive: Sign-in", with: "")
-                textChat = textChat.replacingOccurrences(of: "Access Google Drive with a Google account (for personal use) or Google Workspace account (for...", with: "")
+                textChat = textChat.components(separatedBy: "■")[0]
                 textChat = textChat.trimmingCharacters(in: .whitespacesAndNewlines)
             }
             let listTextEnter = textChat.split(separator: "\n")
@@ -5434,6 +5430,7 @@ extension EditorPersonal: UITableViewDelegate, UITableViewDataSource {
                                     "data_link" : json,
                                     "retry": 0
                                 ], replace: true)
+                                dataURL = json
                                 showLink()
                             } catch {
                                 rollback.pointee = true

+ 143 - 0
appbuilder-ios/NexilisLite/NexilisLite/Source/View/Chat/EditorStarMessages.swift

@@ -18,6 +18,10 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
     var dataDates: [String] = []
     var previewItem = NSURL()
     var fromNotification = false
+    var timerCheckLink: Timer?
+    var isLinkCopied = false
+    var touchedSubview = UIView()
+    var lastTouchPoint: CGPoint = .zero
 
     public override func viewDidLoad() {
         super.viewDidLoad()
@@ -421,6 +425,34 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
             messageText.attributedText = textChat!.richText()
         }
         messageText.font = UIFont.systemFont(ofSize: 12)
+        
+        messageText.isUserInteractionEnabled = false
+        if !textChat!.isEmpty {
+            if textChat!.contains("■"){
+                textChat = textChat?.components(separatedBy: "■")[0]
+                textChat = textChat?.trimmingCharacters(in: .whitespacesAndNewlines)
+            }
+            let listTextEnter = textChat!.split(separator: "\n")
+            for j in 0...listTextEnter.count - 1 {
+                let listText = listTextEnter[j].split(separator: " ")
+                if listText.count > 0 {
+                    for i in 0...listText.count - 1 {
+                        if listText[i].lowercased().checkStartWithLink() {
+                            let rangeTapLink = (textChat! as NSString).range(of: String(listText[i]))
+                            // Add tap gesture recognizer to the range of text
+                            let attributedString = textChat!.richText()
+                            attributedString.addAttributes([.foregroundColor: UIColor.blue, .underlineStyle: NSUnderlineStyle.single.rawValue], range: rangeTapLink)
+                            messageText.attributedText = attributedString
+                            messageText.isUserInteractionEnabled = true
+                            let longPress = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPressLink(_:)))
+                            longPress.minimumPressDuration = 0.1
+                            containerMessage.addGestureRecognizer(longPress)
+                        }
+                    }
+                }
+            }
+        }
+        
         if (dataMessages[indexPath.row]["f_pin"] as? String == idMe) {
             messageText.textColor = .white
         } else {
@@ -772,6 +804,7 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
                                     "data_link" : json,
                                     "retry": 0
                                 ], replace: true)
+                                dataURL = json
                                 showLink()
                             } catch {
                                 rollback.pointee = true
@@ -789,6 +822,116 @@ public class EditorStarMessages: UIViewController, UITableViewDataSource, UITabl
         return cellMessage
     }
     
+    @objc func handleLongPressLink(_ gestureRecognizer: UILongPressGestureRecognizer) {
+        func showMenuContext() {
+            if gestureRecognizer.state == .cancelled || gestureRecognizer.state == .ended{
+                timerCheckLink?.invalidate()
+            } else if gestureRecognizer.state == .began {
+                timerCheckLink = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false, block: {_ in
+                    let interaction = UIContextMenuInteraction(delegate: self)
+                    gestureRecognizer.view!.addInteraction(interaction)
+                    guard let interaction = gestureRecognizer.view!.interactions.first,
+                          let data = Data(base64Encoded: "X3ByZXNlbnRNZW51QXRMb2NhdGlvbjo="),
+                          let str = String(data: data, encoding: .utf8)
+                    else {
+                        return
+                    }
+                    let selector = NSSelectorFromString(str)
+                    guard interaction.responds(to: selector) else {
+                        return
+                    }
+                    let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
+                    impactHeavy.impactOccurred()
+                    interaction.perform(selector, with: self.view)
+                    self.isLinkCopied = true
+                })
+            }
+        }
+        if gestureRecognizer.state == .began {
+            let touchPoint = gestureRecognizer.location(in: self.view)
+            touchedSubview = self.view.hitTest(touchPoint, with: nil) ?? UIView()
+            if !(touchedSubview is UILabel) {
+                showMenuContext()
+            }
+        }
+        guard let label = touchedSubview as? UILabel else { return }
+        let touchPointLabel = gestureRecognizer.location(in: label)
+
+        if let text = label.text, let range = getWordRange(at: touchPointLabel, in: label) {
+            let word = String(text[range])
+            if word.starts(with: "www.") || word.starts(with: "https://") || word.starts(with: "http://") {
+                if gestureRecognizer.state == .cancelled || gestureRecognizer.state == .ended{
+                    timerCheckLink?.invalidate()
+                    if !isLinkCopied {
+                        var stringURl = word
+                        if stringURl.starts(with: "www.") {
+                            stringURl = "https://" + stringURl.replacingOccurrences(of: "www.", with: "")
+                        }
+                        guard let url = URL(string: stringURl) else { return }
+                        UIApplication.shared.open(url)
+                        label.attributedText = removeHighlightedText(for: text, in: range, label: label)
+                    }
+                    isLinkCopied = false
+                } else if gestureRecognizer.state == .began {
+                    label.attributedText = highlightedText(for: text, in: range, label: label)
+                    timerCheckLink = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: {_ in
+                        self.isLinkCopied = true
+                        UIPasteboard.general.string = word
+                        self.showToast(message: "Link Copied".localized(), font: UIFont.systemFont(ofSize: 12, weight: .medium), controller: self)
+                        label.attributedText = self.removeHighlightedText(for: text, in: range, label: label)
+                    })
+                }
+            } else {
+                showMenuContext()
+            }
+        } else {
+            showMenuContext()
+        }
+    }
+    
+    func getWordRange(at point: CGPoint, in label: UILabel) -> Range<String.Index>? {
+        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))
+        
+        layoutManager.addTextContainer(textContainer)
+        textStorage.addLayoutManager(layoutManager)
+        textContainer.lineFragmentPadding = 0
+        textContainer.maximumNumberOfLines = label.numberOfLines
+        
+        lastTouchPoint = point
+        let characterIndex = layoutManager.characterIndex(for: point, in: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)
+        
+        if characterIndex == text.count - 1 {
+            return nil
+        }
+        var wordStartIndex = characterIndex
+        while wordStartIndex > 0 && text[text.index(text.startIndex, offsetBy: wordStartIndex - 1)] != " " && text[text.index(text.startIndex, offsetBy: wordStartIndex - 1)] != "\n" {
+            wordStartIndex -= 1
+        }
+        
+        var wordEndIndex = characterIndex
+        while wordEndIndex < text.count && text[text.index(text.startIndex, offsetBy: wordEndIndex)] != " " && text[text.index(text.startIndex, offsetBy: wordEndIndex)] != "\n" {
+            wordEndIndex += 1
+        }
+        
+        return text.index(text.startIndex, offsetBy: wordStartIndex)..<text.index(text.startIndex, offsetBy: wordEndIndex)
+    }
+
+    func highlightedText(for text: String, in range: Range<String.Index>, label: UILabel) -> NSAttributedString {
+        let mutableAttributedString = label.attributedText!.mutableCopy() as! NSMutableAttributedString
+        mutableAttributedString.addAttribute(.backgroundColor, value: UIColor.lightGray.withAlphaComponent(0.5), range: NSRange(range, in: text))
+        return mutableAttributedString
+    }
+    
+    func removeHighlightedText(for text: String, in range: Range<String.Index>, label: UILabel) -> NSAttributedString {
+        let mutableAttributedString = label.attributedText!.mutableCopy() as! NSMutableAttributedString
+        mutableAttributedString.removeAttribute(.backgroundColor, range: NSRange(range, in: text))
+        return mutableAttributedString
+    }
+    
     @objc func tapMessageText(_ sender: ObjectGesture) {
         var stringURl = sender.message_id.lowercased()
         if stringURl.starts(with: "www.") {