diff --git a/deltachat-ios/Chat/ChatViewController.swift b/deltachat-ios/Chat/ChatViewController.swift index 3fc959646..d4a9d944b 100644 --- a/deltachat-ios/Chat/ChatViewController.swift +++ b/deltachat-ios/Chat/ChatViewController.swift @@ -17,6 +17,9 @@ class ChatViewController: UITableViewController, UITableViewDropDelegate { private var wasInputBarFirstResponder = false private var reactionMessageId: Int? private var contextMenuVisible = false + + /// time based workaround to not also open the link on long press + private var linkLongPressTS: Double = 0 private lazy var isGroupChat: Bool = { return dcContext.getChat(chatId: chatId).isGroup @@ -2088,11 +2091,14 @@ extension ChatViewController { if tableView.isEditing || messageId == DC_MSG_ID_MARKER1 || messageId == DC_MSG_ID_DAYMARKER { return nil } + + print("url: 1") // Check if the long tap is on a link (or other message text element with custom long tap behavior) if let msgcell = tableView.cellForRow(at: indexPath) as? BaseMessageCell { let label = msgcell.messageLabel.label let localTouchLocation = tableView.convert(point, to: label) let handled = label.handleGesture(localTouchLocation, longTap: true) + print("url: handled", handled) if handled { return nil } @@ -2428,6 +2434,14 @@ extension ChatViewController: BaseMessageCellDelegate { } @objc func urlTapped(url: URL, indexPath: IndexPath) { + /// this is somtimes also called on long pressing by accident, this is a time based workround to not open the link when it was long pressed before + let secondsSinceLastLongPress = NSDate().timeIntervalSince1970 - self.linkLongPressTS + print("urlTapped: secondsSinceLastLongPress", secondsSinceLastLongPress, self.linkLongPressTS) + if secondsSinceLastLongPress < 1 { + print("timeSinceLastLongPress prevented opening") + return + } + if handleUIMenu() || handleSelection(indexPath: indexPath) { return } @@ -2438,6 +2452,32 @@ extension ChatViewController: BaseMessageCellDelegate { UIApplication.shared.open(url) } } + + @objc func urlLongTapped(url: URL, indexPath: IndexPath) { + self.linkLongPressTS = NSDate().timeIntervalSince1970 + print("urlLongTapped") + let isEmail = Utils.isEmail(url: url) + + let alert = UIAlertController(title: isEmail ? "Email" : "Link", message: url.absoluteString, preferredStyle: .actionSheet) + if isEmail { + let email = Utils.getEmailFrom(url) + alert.addAction(UIAlertAction(title: String.localized("start_chat"), style: .default, handler: { _ in + self.askToChatWith(email: email) + })) + } else { + // TODO: translation string does not exist yet + alert.addAction(UIAlertAction(title: String.localized("menu_open_link"), style: .default, handler: { _ in + UIApplication.shared.open(url) + })) + } + + alert.addAction(UIAlertAction(title: String.localized(isEmail ? "menu_copy_email_to_clipboard" : "menu_copy_link_to_clipboard"), style: .default, handler: { _ in + UIPasteboard.general.string = url.absoluteString + })) + + alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil)) + self.present(alert, animated: true, completion: nil) + } @objc func imageTapped(indexPath: IndexPath, previewError: Bool) { if handleUIMenu() || handleSelection(indexPath: indexPath) { diff --git a/deltachat-ios/Chat/Views/Cells/BaseMessageCell.swift b/deltachat-ios/Chat/Views/Cells/BaseMessageCell.swift index 6ab5a4a8d..7b4d1afdb 100644 --- a/deltachat-ios/Chat/Views/Cells/BaseMessageCell.swift +++ b/deltachat-ios/Chat/Views/Cells/BaseMessageCell.swift @@ -597,6 +597,7 @@ public class BaseMessageCell: UITableViewCell { // MARK: - MessageLabelDelegate extension BaseMessageCell: MessageLabelDelegate { + public func didSelectAddress(_ addressComponents: [String: String]) {} public func didSelectDate(_ date: Date) {} @@ -613,6 +614,12 @@ extension BaseMessageCell: MessageLabelDelegate { baseDelegate?.urlTapped(url: url, indexPath: indexPath) } } + + public func didLongPressURL(_ url: URL) { + if let tableView = self.superview as? UITableView, let indexPath = tableView.indexPath(for: self) { + baseDelegate?.urlLongTapped(url: url, indexPath: indexPath) + } + } public func didSelectTransitInformation(_ transitInformation: [String: String]) {} @@ -641,6 +648,7 @@ public protocol BaseMessageCellDelegate: AnyObject { func commandTapped(command: String, indexPath: IndexPath) // `/command` func phoneNumberTapped(number: String, indexPath: IndexPath) func urlTapped(url: URL, indexPath: IndexPath) // url is eg. `https://foo.bar` + func urlLongTapped(url: URL, indexPath: IndexPath) // url is eg. `https://foo.bar` or email address func imageTapped(indexPath: IndexPath, previewError: Bool) func avatarTapped(indexPath: IndexPath) func textTapped(indexPath: IndexPath) diff --git a/deltachat-ios/Chat/Views/MessageLabel.swift b/deltachat-ios/Chat/Views/MessageLabel.swift index 362297f6a..d576686e5 100644 --- a/deltachat-ios/Chat/Views/MessageLabel.swift +++ b/deltachat-ios/Chat/Views/MessageLabel.swift @@ -481,15 +481,16 @@ open class MessageLabel: UILabel { // transformedAddressComponents[key.rawValue] = value // } // handleAddress(transformedAddressComponents) - case let .phoneNumber(phoneNumber): - guard let phoneNumber = phoneNumber else { return false } - handlePhoneNumber(phoneNumber) +// case let .phoneNumber(phoneNumber): +// guard let phoneNumber = phoneNumber else { return false } +// handlePhoneNumber(phoneNumber) // case let .date(date): // guard let date = date else { return false } // handleDate(date) case let .link(url): guard let url = url else { return false } - handleURL(url) + handleLongPressURL(url) + return true // case let .custom(pattern, match): // guard let match = match else { return false } @@ -506,7 +507,6 @@ open class MessageLabel: UILabel { default: return false } - return false } /// swiftlint:disable cyclomatic_complexity @@ -561,6 +561,10 @@ open class MessageLabel: UILabel { private func handleURL(_ url: URL) { delegate?.didSelectURL(url) } + + private func handleLongPressURL(_ url: URL) { + delegate?.didLongPressURL(url) + } private func handlePhoneNumber(_ phoneNumber: String) { delegate?.didSelectPhoneNumber(phoneNumber) diff --git a/deltachat-ios/Chat/Views/MessageLabelDelegate.swift b/deltachat-ios/Chat/Views/MessageLabelDelegate.swift index 1311bdbda..1cb707457 100644 --- a/deltachat-ios/Chat/Views/MessageLabelDelegate.swift +++ b/deltachat-ios/Chat/Views/MessageLabelDelegate.swift @@ -50,6 +50,9 @@ public protocol MessageLabelDelegate: AnyObject { /// - Parameters: /// - url: The selected URL. func didSelectURL(_ url: URL) + + /// Triggerd when a long press occurs on a detected URL + func didLongPressURL(_ url: URL) /// Triggered when a tap occurs on detected transit information. /// diff --git a/deltachat-ios/Controller/ContactDetailViewController.swift b/deltachat-ios/Controller/ContactDetailViewController.swift index 1d38e5086..e85f6287d 100644 --- a/deltachat-ios/Controller/ContactDetailViewController.swift +++ b/deltachat-ios/Controller/ContactDetailViewController.swift @@ -561,6 +561,7 @@ class ContactDetailViewController: UITableViewController { } extension ContactDetailViewController: MultilineLabelCellDelegate { + func phoneNumberTapped(number: String) { let sanitizedNumber = number.filter("0123456789".contains) if let phoneURL = URL(string: "tel://\(sanitizedNumber)") { @@ -587,4 +588,9 @@ extension ContactDetailViewController: MultilineLabelCellDelegate { UIApplication.shared.open(url) } } + + func urlLongTapped(url: URL) { + // TODO: custom behaviour, also make sure it gets called, currently it's not implemented in the contacts detail table view + self.urlTapped(url: url) + } } diff --git a/deltachat-ios/View/MultilineLabelCell.swift b/deltachat-ios/View/MultilineLabelCell.swift index 989ca318c..34c91e2b7 100644 --- a/deltachat-ios/View/MultilineLabelCell.swift +++ b/deltachat-ios/View/MultilineLabelCell.swift @@ -81,6 +81,10 @@ extension MultilineLabelCell: MessageLabelDelegate { public func didSelectURL(_ url: URL) { multilineDelegate?.urlTapped(url: url) } + + public func didLongPressURL(_ url: URL) { + multilineDelegate?.urlLongTapped(url: url) + } public func didSelectTransitInformation(_ transitInformation: [String: String]) {} @@ -96,4 +100,5 @@ extension MultilineLabelCell: MessageLabelDelegate { public protocol MultilineLabelCellDelegate: AnyObject { func phoneNumberTapped(number: String) func urlTapped(url: URL) + func urlLongTapped(url: URL) }