|
@@ -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.") {
|