diff --git a/DcCore/DcCore/DC/events.swift b/DcCore/DcCore/DC/events.swift index 97046696a..f3dc260d5 100644 --- a/DcCore/DcCore/DC/events.swift +++ b/DcCore/DcCore/DC/events.swift @@ -13,7 +13,6 @@ public let eventEphemeralTimerModified = Notification.Name(rawValue: "eventEphe public let eventMsgsNoticed = Notification.Name(rawValue: "eventMsgsNoticed") public let eventConnectivityChanged = Notification.Name(rawValue: "eventConnectivityChanged") public let eventWebxdcStatusUpdate = Notification.Name(rawValue: "eventWebxdcStatusUpdate") -public let eventLocationChanged = Notification.Name(rawValue: "eventLocationChanged") public class DcEventHandler { let dcAccounts: DcAccounts @@ -175,15 +174,6 @@ public class DcEventHandler { ]) } - case DC_EVENT_LOCATION_CHANGED: - if accountId != dcAccounts.getSelected().id { - return - } - logger.info("📡[\(accountId)] location changed for contact \(data1)") - DispatchQueue.main.async { - NotificationCenter.default.post(name: eventLocationChanged, object: nil) - } - default: break } diff --git a/DcCore/DcCore/Extensions/UIColor+Extensions.swift b/DcCore/DcCore/Extensions/UIColor+Extensions.swift index 2de0a517d..2cae4ad1b 100644 --- a/DcCore/DcCore/Extensions/UIColor+Extensions.swift +++ b/DcCore/DcCore/Extensions/UIColor+Extensions.swift @@ -64,16 +64,4 @@ public extension UIColor { return UIColor(red: red / 255, green: green / 255, blue: blue / 255, alpha: 1) } - var hexValue: String { - var color = self - if color.cgColor.numberOfComponents < 4 { - let c = color.cgColor.components! - color = UIColor(red: c[0], green: c[0], blue: c[0], alpha: c[1]) - } - if color.cgColor.colorSpace!.model != .rgb { - return "#FFFFFF" - } - let c = color.cgColor.components! - return String(format: "#%02X%02X%02X", Int(c[0]*255.0), Int(c[1]*255.0), Int(c[2]*255.0)) - } } diff --git a/deltachat-ios/Controller/MapViewController.swift b/deltachat-ios/Controller/MapViewController.swift index 7e3901a8d..91fe5a1c8 100644 --- a/deltachat-ios/Controller/MapViewController.swift +++ b/deltachat-ios/Controller/MapViewController.swift @@ -3,27 +3,15 @@ import WebKit import DcCore class MapViewController: WebxdcViewController { - private let chatId: Int - private var locationChangedObserver: NSObjectProtocol? - private var lastLocationId: Int = 0 + private let isGlobalMap: Bool init(dcContext: DcContext, chatId: Int) { - self.chatId = chatId - let msgIdConfigKey = "maps_webxdc_msg_id16." - var msgId = UserDefaults.standard.integer(forKey: msgIdConfigKey + String(dcContext.id)) - if !dcContext.msgExists(id: msgId) { + isGlobalMap = chatId == 0 + var msgId = dcContext.initWebxdcIntegration(for: chatId) + if msgId == 0 { if let path = Bundle.main.url(forResource: "maps", withExtension: "xdc", subdirectory: "Assets") { - let chatId = dcContext.createChatByContactId(contactId: Int(DC_CONTACT_ID_SELF)) - let msg = dcContext.newMessage(viewType: DC_MSG_WEBXDC) - msg.setFile(filepath: path.path) - msg.text = "Thanks for trying out the experimental feature 🧪 \"Location streaming\"\n\n" - + "This message is needed temporarily for development and debugging. " - + "To see locations, POIs and tracks on the map, " - + "do not open it here but from \"All Media\" or from chat \"Profiles\".\n\n" - + "If you want to quit the experimental feature, " - + "you can disable it at \"Settings / Advanced\" and delete this message." - msgId = dcContext.sendMessage(chatId: chatId, message: msg) - UserDefaults.standard.setValue(msgId, forKey: msgIdConfigKey + String(dcContext.id)) + dcContext.setWebxdcIntegration(filepath: path.path) + msgId = dcContext.initWebxdcIntegration(for: chatId) } } super.init(dcContext: dcContext, messageId: msgId) @@ -38,55 +26,8 @@ class MapViewController: WebxdcViewController { navigationItem.rightBarButtonItem = nil } - override func willMove(toParent parent: UIViewController?) { - super.willMove(toParent: parent) - if parent == nil { - removeObservers() - } else { - addObservers() - } - } - override func refreshWebxdcInfo() { super.refreshWebxdcInfo() - title = String.localized(chatId == 0 ? "menu_show_global_map" : "locations") - } - - // MARK: - setup - - private func addObservers() { - locationChangedObserver = NotificationCenter.default.addObserver(forName: eventLocationChanged, object: nil, queue: nil) { [weak self]_ in - self?.updateWebxdc() - } - } - - private func removeObservers() { - if let locationChangedObserver = self.locationChangedObserver { - NotificationCenter.default.removeObserver(locationChangedObserver) - } - } - - - // MARK: - handle updates - - override func sendWebxdcStatusUpdate(payload: String, description: String) -> Bool { - guard let data: Data = payload.data(using: .utf8), - let dict = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: AnyObject], - let payload = dict["payload"] as? [String: AnyObject] else { - return false - } - - let msg = dcContext.newMessage(viewType: DC_MSG_TEXT) - msg.text = payload["label"] as? String ?? "ErrLabel" - msg.setLocation(lat: payload["lat"] as? Double ?? 0.0, lng: payload["lng"] as? Double ?? 0.0) - return dcContext.sendMessage(chatId: chatId == 0 ? dcContext.createChatByContactId(contactId: Int(DC_CONTACT_ID_SELF)) : chatId, message: msg) != 0 - } - - override func getWebxdcStatusUpdates(lastKnownSerial: Int) -> String { - let end = Int64(Date().timeIntervalSince1970) - let begin = end - 24*60*60 - let (json, maxLocationId) = dcContext.getLocations(chatId: chatId, timestampBegin: begin, timestampEnd: 0, lastLocationId: lastLocationId) - lastLocationId = max(maxLocationId, lastLocationId) - return json + title = String.localized(isGlobalMap ? "menu_show_global_map" : "locations") } } diff --git a/deltachat-ios/Controller/WebxdcViewController.swift b/deltachat-ios/Controller/WebxdcViewController.swift index 224acd6e0..047a31c3f 100644 --- a/deltachat-ios/Controller/WebxdcViewController.swift +++ b/deltachat-ios/Controller/WebxdcViewController.swift @@ -372,7 +372,7 @@ class WebxdcViewController: WebViewViewController { } } - func updateWebxdc() { + private func updateWebxdc() { webView.evaluateJavaScript("window.__webxdcUpdate()", completionHandler: nil) } @@ -414,14 +414,6 @@ class WebxdcViewController: WebViewViewController { private func shareWebxdc(_ action: UIAlertAction) { Utils.share(message: dcContext.getMessage(id: messageId), parentViewController: self, sourceItem: moreButton) } - - func sendWebxdcStatusUpdate(payload: String, description: String) -> Bool { - return dcContext.sendWebxdcStatusUpdate(msgId: messageId, payload: payload, description: description) - } - - func getWebxdcStatusUpdates(lastKnownSerial: Int) -> String { - return dcContext.getWebxdcStatusUpdates(msgId: messageId, lastKnownSerial: lastKnownSerial) - } } extension WebxdcViewController: WKScriptMessageHandler { @@ -444,7 +436,7 @@ extension WebxdcViewController: WKScriptMessageHandler { logger.error("Failed to parse status update parameters \(message.body)") return } - _ = sendWebxdcStatusUpdate(payload: payloadString, description: description) + _ = dcContext.sendWebxdcStatusUpdate(msgId: messageId, payload: payloadString, description: description) case .sendToChat: if let dict = message.body as? [String: AnyObject] { @@ -485,7 +477,8 @@ extension WebxdcViewController: WKURLSchemeHandler { let statusCode: Int if url.path == "/webxdc-update.json" || url.path == "webxdc-update.json" { let lastKnownSerial = Int(url.query ?? "0") ?? 0 - data = Data(getWebxdcStatusUpdates(lastKnownSerial: lastKnownSerial).utf8) + data = Data( + dcContext.getWebxdcStatusUpdates(msgId: messageId, lastKnownSerial: lastKnownSerial).utf8) mimeType = "application/json; charset=utf-8" statusCode = 200 } else { diff --git a/deltachat-ios/DC/DcContext.swift b/deltachat-ios/DC/DcContext.swift index 621926fb4..fa8359451 100644 --- a/deltachat-ios/DC/DcContext.swift +++ b/deltachat-ios/DC/DcContext.swift @@ -54,25 +54,13 @@ public class DcContext { return DcMsg(pointer: messagePointer) } - public func msgExists(id: Int) -> Bool { - if id <= DC_MSG_ID_LAST_SPECIAL { - return false - } else { - let messagePointer = dc_get_msg(contextPointer, UInt32(id)) - let exists = messagePointer != nil && dc_msg_get_chat_id(messagePointer) != DC_CHAT_ID_TRASH - dc_msg_unref(messagePointer) - return exists - } - } - public func getMessage(id: Int) -> DcMsg { let messagePointer = dc_get_msg(contextPointer, UInt32(id)) return DcMsg(pointer: messagePointer) } - @discardableResult - public func sendMessage(chatId: Int, message: DcMsg) -> Int { - return Int(dc_send_msg(contextPointer, UInt32(chatId), message.messagePointer)) + public func sendMessage(chatId: Int, message: DcMsg) { + dc_send_msg(contextPointer, UInt32(chatId), message.messagePointer) } public func downloadFullMessage(id: Int) { @@ -90,6 +78,14 @@ public class DcContext { return swiftString } + public func setWebxdcIntegration(filepath: String?) { + dc_set_webxdc_integration(contextPointer, filepath) + } + + public func initWebxdcIntegration(for chatId: Int) -> Int { + return Int(dc_init_webxdc_integration(contextPointer, UInt32(chatId))) + } + public func sendVideoChatInvitation(chatId: Int) -> Int { return Int(dc_send_videochat_invitation(contextPointer, UInt32(chatId))) } @@ -544,72 +540,6 @@ public class DcContext { dc_set_location(contextPointer, latitude, longitude, accuracy) } - public func getLocations(chatId: Int, timestampBegin: Int64, timestampEnd: Int64, lastLocationId: Int) -> (String, Int) { - var names = [Int: String]() - var colors = [Int: String]() - var maxLocationId = 0 - - let jsonEncoder = JSONEncoder() - var json: String - json = "[" - let array = dc_get_locations(contextPointer, UInt32(chatId), 0, timestampBegin, timestampEnd) - let arrayCnt = dc_array_get_cnt(array) - for i in (0 ..< arrayCnt).reversed() { // most recent position is reported last - let locationId = Int(dc_array_get_id(array, i)) - if locationId > lastLocationId { - maxLocationId = max(maxLocationId, locationId) - if json != "[" { - json += "," // JSON is picky about commas after the last element - } - - let contactId = Int(dc_array_get_contact_id(array, i)) - if names[contactId] == nil { - let contact = getContact(id: contactId) - names[contactId] = contact.displayName - colors[contactId] = contact.color.hexValue - } - - let isIndependet = dc_array_is_independent(array, i) != 0 - var label: String = "" - let name: String = names[contactId] ?? "ErrName" - if isIndependet { - if let cString = dc_array_get_marker(array, i) { - label = String(cString: cString) // get_marker() returns one-char labels only - dc_str_unref(cString) - } else { - let msgId = Int(dc_array_get_msg_id(array, i)) - if msgId != 0 { - label = String((getMessage(id: msgId).text ?? "").prefix(256)) - } - } - } - - let jsonName = (try? String(data: jsonEncoder.encode(name), encoding: .utf8) ?? "\"\"") ?? "\"\"" - let jsonLabel = (try? String(data: jsonEncoder.encode(label), encoding: .utf8) ?? "\"\"") ?? "\"\"" - json += """ - { - "payload": { - "action": "pos", - "contactId": \(contactId), - "lat": \(dc_array_get_latitude(array, i)), - "lng": \(dc_array_get_longitude(array, i)), - "independent": \(isIndependet), - "timestamp": \(dc_array_get_timestamp(array, i)), - "label": \(jsonLabel), - "name": \(jsonName), - "color": "\(colors[contactId] ?? "#ff0000")" - }, - "serial": \(locationId), - "max_serial": \(locationId) - } - """ - } - } - dc_array_unref(array) - json += "]" - return (json, maxLocationId) - } - public func searchMessages(chatId: Int = 0, searchText: String) -> [Int] { let start = CFAbsoluteTimeGetCurrent() guard let arrayPointer = dc_search_msgs(contextPointer, UInt32(chatId), searchText) else { diff --git a/deltachat-ios/DC/DcMsg.swift b/deltachat-ios/DC/DcMsg.swift index da534d087..190dea60d 100644 --- a/deltachat-ios/DC/DcMsg.swift +++ b/deltachat-ios/DC/DcMsg.swift @@ -226,10 +226,6 @@ public class DcMsg { dc_msg_set_dimension(messagePointer, Int32(width), Int32(height)) } - public func setLocation(lat: Double, lng: Double) { - dc_msg_set_location(messagePointer, lat, lng) - } - public var filesize: Int { return Int(dc_msg_get_filebytes(messagePointer)) }