Эх сурвалжийг харах

Mailto in webxdc (#1597)

* rename RelayHelper's singleton instance name to more commonly used 'shared' instead of 'sharedInstance'

* unconditionally ask to chat with email contact after tapping on a mailto link in webxdcs
cyBerta 3 жил өмнө
parent
commit
2a091b1ab2

+ 1 - 1
deltachat-ios/AppDelegate.swift

@@ -558,7 +558,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
         setStockTranslations()
         locationManager.reloadDcContext()
         notificationManager.reloadDcContext()
-        RelayHelper.sharedInstance.cancel()
+        RelayHelper.shared.cancel()
         _ = RelayHelper.setup(dcAccounts.getSelected())
         if dcAccounts.getSelected().isConfigured() {
             appCoordinator.resetTabBarRootViewControllers()

+ 8 - 8
deltachat-ios/Chat/ChatViewController.swift

@@ -208,7 +208,7 @@ class ChatViewController: UITableViewController {
             onPerform: { [weak self] indexPath in
                 guard let self = self else { return }
                 let msg = self.dcContext.getMessage(id: self.messageIds[indexPath.row])
-                RelayHelper.sharedInstance.setForwardMessage(messageId: msg.id)
+                RelayHelper.shared.setForwardMessage(messageId: msg.id)
                 self.navigationController?.popViewController(animated: true)
             }
         )
@@ -444,11 +444,11 @@ class ChatViewController: UITableViewController {
             })
         }
 
-        if RelayHelper.sharedInstance.isForwarding() {
+        if RelayHelper.shared.isForwarding() {
             askToForwardMessage()
-        } else if RelayHelper.sharedInstance.isMailtoHandling() {
-            messageInputBar.inputTextView.text = RelayHelper.sharedInstance.mailtoDraft
-            RelayHelper.sharedInstance.finishMailto()
+        } else if RelayHelper.shared.isMailtoHandling() {
+            messageInputBar.inputTextView.text = RelayHelper.shared.mailtoDraft
+            RelayHelper.shared.finishMailto()
         }
 
         prepareContextMenu()
@@ -1375,13 +1375,13 @@ class ChatViewController: UITableViewController {
     private func askToForwardMessage() {
         let chat = dcContext.getChat(chatId: self.chatId)
         if chat.isSelfTalk {
-            RelayHelper.sharedInstance.forward(to: self.chatId)
+            RelayHelper.shared.forward(to: self.chatId)
             refreshMessages()
         } else {
             confirmationAlert(title: String.localizedStringWithFormat(String.localized("ask_forward"), chat.name),
                               actionTitle: String.localized("menu_forward"),
                               actionHandler: { _ in
-                                RelayHelper.sharedInstance.forward(to: self.chatId)
+                                RelayHelper.shared.forward(to: self.chatId)
                                 self.dismiss(animated: true, completion: nil)},
                               cancelHandler: { _ in
                                 self.dismiss(animated: false, completion: nil)
@@ -2051,7 +2051,7 @@ extension ChatViewController: ChatEditingDelegate {
     func onForwardPressed() {
         if let rows = tableView.indexPathsForSelectedRows {
             let messageIdsToForward = rows.compactMap { messageIds[$0.row] }
-            RelayHelper.sharedInstance.setForwardMessages(messageIds: messageIdsToForward)
+            RelayHelper.shared.setForwardMessages(messageIds: messageIdsToForward)
             self.navigationController?.popViewController(animated: true)
         }
     }

+ 19 - 13
deltachat-ios/Controller/ChatListController.swift

@@ -117,7 +117,7 @@ class ChatListController: UITableViewController {
         navigationItem.titleView = titleView
         updateTitle()
 
-        if RelayHelper.sharedInstance.isForwarding() {
+        if RelayHelper.shared.isForwarding() {
             quitSearch(animated: false)
             tableView.scrollToTop()
         }
@@ -297,7 +297,7 @@ class ChatListController: UITableViewController {
 
     @objc func cancelButtonPressed() {
         // cancel forwarding
-        RelayHelper.sharedInstance.cancel()
+        RelayHelper.shared.cancel()
         updateTitle()
         refreshInBg()
     }
@@ -427,7 +427,7 @@ class ChatListController: UITableViewController {
     // MARK: updates
     private func updateTitle() {
         titleView.accessibilityHint = String.localized("a11y_connectivity_hint")
-        if RelayHelper.sharedInstance.isForwarding() {
+        if RelayHelper.shared.isForwarding() {
             titleView.text = String.localized("forward_to")
             if !isArchive {
                 navigationItem.setLeftBarButton(cancelButton, animated: true)
@@ -501,8 +501,8 @@ class ChatListController: UITableViewController {
         timer = nil
     }
 
-    public func handleMailto() {
-        if let mailtoAddress = RelayHelper.sharedInstance.mailtoAddress {
+    public func handleMailto(askToChat: Bool = true) {
+        if let mailtoAddress = RelayHelper.shared.mailtoAddress {
             // FIXME: the line below should work
             // var contactId = dcContext.lookupContactIdByAddress(mailtoAddress)
 
@@ -516,8 +516,11 @@ class ChatListController: UITableViewController {
 
             if contactId != 0 && dcContext.getChatIdByContactId(contactId: contactId) != 0 {
                 showChat(chatId: dcContext.getChatIdByContactId(contactId: contactId), animated: false)
-            } else {
+            } else if askToChat {
                 askToChatWith(address: mailtoAddress)
+            } else {
+                // Attention: we should have already asked in a different view controller!
+                createAndShowNewChat(contactId: 0, email: mailtoAddress)
             }
         }
     }
@@ -537,25 +540,28 @@ class ChatListController: UITableViewController {
     }
 
     private func askToChatWith(address: String, contactId: Int = 0) {
-        var contactId = contactId
         let alert = UIAlertController(title: String.localizedStringWithFormat(String.localized("ask_start_chat_with"), address),
                                       message: nil,
                                       preferredStyle: .safeActionSheet)
         alert.addAction(UIAlertAction(title: String.localized("start_chat"), style: .default, handler: { [weak self] _ in
             guard let self = self else { return }
-            if contactId == 0 {
-                contactId = self.dcContext.createContact(name: nil, email: address)
-            }
-            self.showNewChat(contactId: contactId)
+            self.createAndShowNewChat(contactId: contactId, email: address)
         }))
         alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: { _ in
-            if RelayHelper.sharedInstance.isMailtoHandling() {
-                RelayHelper.sharedInstance.finishMailto()
+            if RelayHelper.shared.isMailtoHandling() {
+                RelayHelper.shared.finishMailto()
             }
         }))
         present(alert, animated: true, completion: nil)
     }
 
+    private func createAndShowNewChat(contactId: Int, email: String) {
+        var contactId = contactId
+        if contactId == 0 {
+            contactId = self.dcContext.createContact(name: nil, email: email)
+        }
+        self.showNewChat(contactId: contactId)
+    }
 
     private func askToChatWith(contactId: Int) {
         let dcContact = dcContext.getContact(id: contactId)

+ 36 - 6
deltachat-ios/Controller/WebxdcViewController.swift

@@ -201,12 +201,17 @@ class WebxdcViewController: WebViewViewController {
     }
     
     override func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
-        // TODO: what about tel:// and mailto://
-        if let url = navigationAction.request.url,
-           url.scheme != INTERNALSCHEMA {
-            logger.debug("cancel loading: \(url)")
-            decisionHandler(.cancel)
-            return
+        // TODO: what about tel://
+        if let url = navigationAction.request.url {
+            if url.scheme == "mailto" {
+                askToChatWith(url: url)
+                decisionHandler(.cancel)
+                return
+            } else if url.scheme != INTERNALSCHEMA {
+                logger.debug("cancel loading: \(url)")
+                decisionHandler(.cancel)
+                return
+            }
         }
         logger.debug("loading: \(String(describing: navigationAction.request.url))")
         decisionHandler(.allow)
@@ -282,6 +287,31 @@ class WebxdcViewController: WebViewViewController {
             UIApplication.shared.open(url)
         }
     }
+
+    private func askToChatWith(url: URL) {
+        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,
+              let emailAddress = parseEmailAddress(from: url) else {
+            return
+        }
+
+        let alert = UIAlertController(title: String.localizedStringWithFormat(String.localized("ask_start_chat_with"), emailAddress),
+                                      message: nil,
+                                      preferredStyle: .safeActionSheet)
+        alert.addAction(UIAlertAction(title: String.localized("start_chat"), style: .default, handler: { _ in
+            RelayHelper.shared.askToChatWithMailto = false
+            _ = appDelegate.application(UIApplication.shared, open: url)
+        }))
+        alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil))
+        present(alert, animated: true, completion: nil)
+    }
+
+    private func parseEmailAddress(from url: URL) -> String? {
+        if let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false),
+           !urlComponents.path.isEmpty {
+             return RelayHelper.shared.splitString(urlComponents.path)[0]
+        }
+        return nil
+    }
 }
 
 extension WebxdcViewController: WKScriptMessageHandler {

+ 3 - 3
deltachat-ios/Coordinator/AppCoordinator.swift

@@ -116,19 +116,19 @@ class AppCoordinator {
     }
 
     func handleMailtoURL(_ url: URL) -> Bool {
-        if RelayHelper.sharedInstance.parseMailtoUrl(url) {
+        if RelayHelper.shared.parseMailtoUrl(url) {
             showTab(index: chatsTab)
             if let rootController = self.tabBarController.selectedViewController as? UINavigationController {
                 rootController.popToRootViewController(animated: false)
                 if let controller = rootController.viewControllers.first as? ChatListController {
-                    controller.handleMailto()
+                    controller.handleMailto(askToChat: RelayHelper.shared.askToChatWithMailto)
                     return true
                 }
             }
         } else {
             logger.warning("Could not parse mailto: URL")
         }
-        RelayHelper.sharedInstance.finishMailto()
+        RelayHelper.shared.finishMailto()
         return false
     }
     

+ 4 - 2
deltachat-ios/Helper/RelayHelper.swift

@@ -2,12 +2,13 @@ import Foundation
 import DcCore
 
 class RelayHelper {
-    static var sharedInstance: RelayHelper = RelayHelper()
+    static var shared: RelayHelper = RelayHelper()
     private static var dcContext: DcContext?
     var messageIds: [Int]?
 
     var mailtoDraft: String = ""
     var mailtoAddress: String?
+    var askToChatWithMailto: Bool = true
 
     private init() {
         guard RelayHelper.dcContext != nil else {
@@ -17,7 +18,7 @@ class RelayHelper {
 
     class func setup(_ dcContext: DcContext) -> RelayHelper {
         RelayHelper.dcContext = dcContext
-        return sharedInstance
+        return shared
     }
 
     func setForwardMessage(messageId: Int) {
@@ -50,6 +51,7 @@ class RelayHelper {
     func finishMailto() {
         mailtoDraft = ""
         mailtoAddress = nil
+        askToChatWithMailto = true
     }
 
 

+ 1 - 1
deltachat-ios/ViewModel/ChatListViewModel.swift

@@ -52,7 +52,7 @@ class ChatListViewModel: NSObject {
         var gclFlags: Int32 = 0
         if isArchive {
             gclFlags |= DC_GCL_ARCHIVED_ONLY
-        } else if RelayHelper.sharedInstance.isForwarding() {
+        } else if RelayHelper.shared.isForwarding() {
             gclFlags |= DC_GCL_FOR_FORWARDING
         }
         self.chatList = dcContext.getChatlist(flags: gclFlags, queryString: nil, queryId: 0)