From 65fcffb721684c4042b2c6d6f2f2cb3ba3f39278 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20Machado?= Date: Mon, 11 Mar 2019 08:02:38 +0000 Subject: [PATCH] Location Sharing feature --- Rocket.Chat.xcodeproj/project.pbxproj | 40 ++ .../Chat/ChatSections/MessageSection.swift | 45 +- .../Chat/MessagesViewController.swift | 23 +- ...gesViewControllerMessageCellProtocol.swift | 14 +- .../MessagesViewControllerUploading.swift | 40 ++ .../Location/LocationPopover.swift | 78 +++ .../Location/LocationShareDelegate.swift | 14 + .../Location/LocationViewController.swift | 319 +++++++++++++ .../SharedLocationViewController.swift | 447 ++++++++++++++++++ Rocket.Chat/Info.plist | 4 + .../Attach/Location.imageset/Contents.json | 21 + .../Attach/Location.imageset/location2.pdf | Bin 0 -> 1840 bytes .../ShareLocation/Contents.json | 6 + .../arrow.imageset/Contents.json | 23 + .../ShareLocation/arrow.imageset/arrow.png | Bin 0 -> 1063 bytes .../ShareLocation/arrow.imageset/arrow@2x.png | Bin 0 -> 1753 bytes .../ShareLocation/arrow.imageset/arrow@3x.png | Bin 0 -> 2560 bytes .../car_map.imageset/Contents.json | 21 + .../car_map.imageset/car_map.png | Bin 0 -> 1690 bytes .../ShareLocation/map.imageset/Contents.json | 23 + .../ShareLocation/map.imageset/map.png | Bin 0 -> 5354 bytes .../ShareLocation/map.imageset/map@2x.png | Bin 0 -> 11858 bytes .../ShareLocation/map.imageset/map@3x.png | Bin 0 -> 18155 bytes .../satellite.imageset/Contents.json | 23 + .../satellite.imageset/satellite.png | Bin 0 -> 11497 bytes .../satellite.imageset/satellite@2x.png | Bin 0 -> 24035 bytes .../satellite.imageset/satellite@3x.png | Bin 0 -> 35727 bytes .../Resources/cs.lproj/Localizable.strings | 11 + .../Resources/de.lproj/Localizable.strings | 11 + .../Resources/el.lproj/Localizable.strings | 11 + .../Resources/en.lproj/Localizable.strings | 11 + .../Resources/es.lproj/Localizable.strings | 11 + .../Resources/fr.lproj/Localizable.strings | 11 + .../Resources/it.lproj/Localizable.strings | 11 + .../Resources/ja.lproj/Localizable.strings | 11 + .../Resources/pl.lproj/Localizable.strings | 11 + .../Resources/pt-BR.lproj/Localizable.strings | 11 + .../Resources/pt-PT.lproj/Localizable.strings | 11 + .../Resources/ru.lproj/Localizable.strings | 11 + .../zh-Hans.lproj/Localizable.strings | 11 + Rocket.Chat/Storyboards/Location.storyboard | 235 +++++++++ Rocket.Chat/Views/Avatar/AvatarView.swift | 5 + .../Views/Cells/Chat/ChatMessageURLView.swift | 2 +- .../Chat/New Chat/Cells/LocationCell.swift | 116 +++++ .../Chat/New Chat/Cells/LocationCell.xib | 97 ++++ .../Chat/New Chat/Cells/MessageURLCell.swift | 2 +- .../New Chat/ChatItems/LocationChatItem.swift | 125 +++++ 47 files changed, 1844 insertions(+), 22 deletions(-) create mode 100644 Rocket.Chat/Controllers/Location/LocationPopover.swift create mode 100644 Rocket.Chat/Controllers/Location/LocationShareDelegate.swift create mode 100644 Rocket.Chat/Controllers/Location/LocationViewController.swift create mode 100644 Rocket.Chat/Controllers/Location/SharedLocationViewController.swift create mode 100644 Rocket.Chat/Resources/Assets.xcassets/Composer/Attach/Location.imageset/Contents.json create mode 100644 Rocket.Chat/Resources/Assets.xcassets/Composer/Attach/Location.imageset/location2.pdf create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/Contents.json create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/arrow.imageset/Contents.json create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/arrow.imageset/arrow.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/arrow.imageset/arrow@2x.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/arrow.imageset/arrow@3x.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/car_map.imageset/Contents.json create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/car_map.imageset/car_map.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/Contents.json create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/map.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/map@2x.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/map@3x.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/Contents.json create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/satellite.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/satellite@2x.png create mode 100644 Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/satellite@3x.png create mode 100644 Rocket.Chat/Storyboards/Location.storyboard create mode 100644 Rocket.Chat/Views/Chat/New Chat/Cells/LocationCell.swift create mode 100644 Rocket.Chat/Views/Chat/New Chat/Cells/LocationCell.xib create mode 100644 Rocket.Chat/Views/Chat/New Chat/ChatItems/LocationChatItem.swift diff --git a/Rocket.Chat.xcodeproj/project.pbxproj b/Rocket.Chat.xcodeproj/project.pbxproj index 61ddeb225e..d2cb508b22 100644 --- a/Rocket.Chat.xcodeproj/project.pbxproj +++ b/Rocket.Chat.xcodeproj/project.pbxproj @@ -537,6 +537,14 @@ 805DEC351FFC03380033151B /* CustomEmojiManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 805DEC341FFC03380033151B /* CustomEmojiManager.swift */; }; 805DEC371FFC08870033151B /* CustomEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 805DEC361FFC08870033151B /* CustomEmoji.swift */; }; 805DEC391FFE54820033151B /* CustomEmojiSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 805DEC381FFE54820033151B /* CustomEmojiSpec.swift */; }; + 80607DDF2232306800B84D91 /* SharedLocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80607DDB2232306800B84D91 /* SharedLocationViewController.swift */; }; + 80607DE02232306800B84D91 /* LocationShareDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80607DDC2232306800B84D91 /* LocationShareDelegate.swift */; }; + 80607DE12232306800B84D91 /* LocationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80607DDD2232306800B84D91 /* LocationViewController.swift */; }; + 80607DE22232306800B84D91 /* LocationPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80607DDE2232306800B84D91 /* LocationPopover.swift */; }; + 80607DE4223230B700B84D91 /* Location.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 80607DE3223230B700B84D91 /* Location.storyboard */; }; + 80607DE6223230CF00B84D91 /* LocationChatItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80607DE5223230CF00B84D91 /* LocationChatItem.swift */; }; + 80607DE9223230E000B84D91 /* LocationCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 80607DE7223230E000B84D91 /* LocationCell.xib */; }; + 80607DEA223230E000B84D91 /* LocationCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 80607DE8223230E000B84D91 /* LocationCell.swift */; }; 8062E327209E19BB0044F407 /* AuthClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8062E326209E19BB0044F407 /* AuthClient.swift */; }; 8062E32920A1CAAB0044F407 /* SubscriptionsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8062E32820A1CAAB0044F407 /* SubscriptionsRequest.swift */; }; 8062E32C20A1F8100044F407 /* RoomsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8062E32B20A1F8100044F407 /* RoomsRequest.swift */; }; @@ -1508,6 +1516,14 @@ 805DEC341FFC03380033151B /* CustomEmojiManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiManager.swift; sourceTree = ""; }; 805DEC361FFC08870033151B /* CustomEmoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmoji.swift; sourceTree = ""; }; 805DEC381FFE54820033151B /* CustomEmojiSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiSpec.swift; sourceTree = ""; }; + 80607DDB2232306800B84D91 /* SharedLocationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharedLocationViewController.swift; sourceTree = ""; }; + 80607DDC2232306800B84D91 /* LocationShareDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationShareDelegate.swift; sourceTree = ""; }; + 80607DDD2232306800B84D91 /* LocationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationViewController.swift; sourceTree = ""; }; + 80607DDE2232306800B84D91 /* LocationPopover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationPopover.swift; sourceTree = ""; }; + 80607DE3223230B700B84D91 /* Location.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Location.storyboard; sourceTree = ""; }; + 80607DE5223230CF00B84D91 /* LocationChatItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationChatItem.swift; sourceTree = ""; }; + 80607DE7223230E000B84D91 /* LocationCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LocationCell.xib; sourceTree = ""; }; + 80607DE8223230E000B84D91 /* LocationCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationCell.swift; sourceTree = ""; }; 8062E326209E19BB0044F407 /* AuthClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthClient.swift; sourceTree = ""; }; 8062E32820A1CAAB0044F407 /* SubscriptionsRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionsRequest.swift; sourceTree = ""; }; 8062E32B20A1F8100044F407 /* RoomsRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomsRequest.swift; sourceTree = ""; }; @@ -2516,6 +2532,7 @@ 41E2FA031D414ED400238DFD /* Subscriptions */, 414EE62721CD1F80003693D2 /* Video Conferencing */, 41865AF01FC8B1EC00A5E48F /* WebViewEmbedded */, + 80607DDA2232304B00B84D91 /* Location */, ); path = Controllers; sourceTree = ""; @@ -2532,6 +2549,7 @@ 41CD52D420BEFA3B00336892 /* New Room.storyboard */, 4102E3A91E532323004BAA82 /* Preferences.storyboard */, 41E2FA001D414EA100238DFD /* Subscriptions.storyboard */, + 80607DE3223230B700B84D91 /* Location.storyboard */, ); path = Storyboards; sourceTree = ""; @@ -3335,6 +3353,17 @@ path = UIAlertAction; sourceTree = ""; }; + 80607DDA2232304B00B84D91 /* Location */ = { + isa = PBXGroup; + children = ( + 80607DDE2232306800B84D91 /* LocationPopover.swift */, + 80607DDC2232306800B84D91 /* LocationShareDelegate.swift */, + 80607DDD2232306800B84D91 /* LocationViewController.swift */, + 80607DDB2232306800B84D91 /* SharedLocationViewController.swift */, + ); + path = Location; + sourceTree = ""; + }; 8062E32F20A3A2A30044F407 /* Subscription */ = { isa = PBXGroup; children = ( @@ -3934,6 +3963,8 @@ 4190694121D0E82E00FE2573 /* MessageVideoCallCell.swift */, 4101B02A21A2EF8C00772F7C /* HeaderCell.xib */, 4101B02C21A2EF9300772F7C /* HeaderCell.swift */, + 80607DE8223230E000B84D91 /* LocationCell.swift */, + 80607DE7223230E000B84D91 /* LocationCell.xib */, ); path = Cells; sourceTree = ""; @@ -3959,6 +3990,7 @@ 9977D85A217E999800FE5EC6 /* MessageActionsChatItem.swift */, 4190693E21D0E7F600FE2573 /* MessageVideoCallChatItem.swift */, 4101B02821A2EF6B00772F7C /* HeaderChatItem.swift */, + 80607DE5223230CF00B84D91 /* LocationChatItem.swift */, ); path = ChatItems; sourceTree = ""; @@ -4442,8 +4474,10 @@ 14F8A288202E659000175FDC /* White-60@3x.png in Resources */, 419EB5B3215E3C2200E591BF /* AudioCell.xib in Resources */, 333032A02073940800A9514D /* RCEmojiKit.strings in Resources */, + 80607DE9223230E000B84D91 /* LocationCell.xib in Resources */, 9977D857217E942200FE5EC6 /* MessageActionsCell.xib in Resources */, 994C90B62174BA5100383AFF /* VideoMessageCell.xib in Resources */, + 80607DE4223230B700B84D91 /* Location.storyboard in Resources */, 41CD52D520BEFA3B00336892 /* New Room.storyboard in Resources */, 14F8A25E202E64B200175FDC /* BnW-76@2x.png in Resources */, 411D40C920D27A5E001A1035 /* ChannelInfoDescriptionCell.xib in Resources */, @@ -4822,6 +4856,7 @@ 8013F86B1FD6B59A00EE1A4E /* Version.swift in Sources */, 41BFA0AA2146D23D008B9611 /* MessageManager.swift in Sources */, 994D1EDF205AB945007F29C8 /* UINavigationControllerExtension.swift in Sources */, + 80607DEA223230E000B84D91 /* LocationCell.swift in Sources */, 80B2D98920E5496E002F4149 /* UserDetailFieldCellModel.swift in Sources */, 4192054C1D52F4FC004EEC5F /* SubscriptionCell.swift in Sources */, 412E1F3B1DB6D55000531FDA /* ChatMessageURLView.swift in Sources */, @@ -4969,6 +5004,7 @@ 419FEAA62181F115000DF2EC /* UnreadMarkerChatItem.swift in Sources */, 41E53A171E546F5500C3FBB3 /* UINibExtensions.swift in Sources */, 8013F8711FD6B5B000EE1A4E /* InfoClient.swift in Sources */, + 80607DE02232306800B84D91 /* LocationShareDelegate.swift in Sources */, 994C90B82174BCAF00383AFF /* VideoMessageCell.swift in Sources */, 8076FDA02048519D00114F28 /* AuthManagerSocket.swift in Sources */, D32E28241DFD86C300D6019C /* AnalyticsCoordinator.swift in Sources */, @@ -4996,6 +5032,7 @@ 80CC78CF20DAE334002FBEBC /* SubscriptionsViewModel.swift in Sources */, 4190693D21D0DE0500FE2573 /* JitsiViewModel.swift in Sources */, 33E33ED620E0E59B00EF4560 /* AuthNavigationController.swift in Sources */, + 80607DE22232306800B84D91 /* LocationPopover.swift in Sources */, 9990751D21766ECE00CAB7C8 /* BaseImageMessageCell.swift in Sources */, 33F73B302073F24200F03F29 /* NotificationViewController.swift in Sources */, 99DBB8742090360600382DB2 /* MessagesListControllerSearch.swift in Sources */, @@ -5095,6 +5132,7 @@ 41FB7138215B0FD6002B5187 /* MessagesSizingManager.swift in Sources */, 995F711A20C7910800B7535F /* AuthTableViewControllerLoginServices.swift in Sources */, 80EE865321A82E6100BFEEC8 /* UIViewControllerDimming.swift in Sources */, + 80607DE6223230CF00B84D91 /* LocationChatItem.swift in Sources */, 999075252177795700CAB7C8 /* QuoteMessageCell.swift in Sources */, 809B53101FE2F17D00833DD2 /* ReactionView.swift in Sources */, D15C83861F70991F001AB155 /* APIResponse.swift in Sources */, @@ -5248,6 +5286,7 @@ 996735D221585CA70049BB63 /* BasicMessageChatItem.swift in Sources */, 800F38ED2019492D0005CB78 /* DeepLink.swift in Sources */, 998E64982161ADE200E7C45A /* TextAttachmentCell.swift in Sources */, + 80607DDF2232306800B84D91 /* SharedLocationViewController.swift in Sources */, 419EB5BD215E69FF00E591BF /* ReactionsCell.swift in Sources */, 99BE4D822152D56E001A43E2 /* MessagesViewController.swift in Sources */, 4151B4581E2D1D2E00F8AA1B /* MessageModelMapping.swift in Sources */, @@ -5255,6 +5294,7 @@ 414B3B25203E2F2C0078D3D9 /* MainSplitViewController.swift in Sources */, 99907513217622A900CAB7C8 /* FileMessageCell.swift in Sources */, 414A1FF61D46320F00093E10 /* ResponseMessage.swift in Sources */, + 80607DE12232306800B84D91 /* LocationViewController.swift in Sources */, 996735CF21582E790049BB63 /* BasicMessageCell.swift in Sources */, 4151B44E1E2CF19A00F8AA1B /* UserModelHandler.swift in Sources */, 1496A87220FA469C005C2E14 /* Dynamic.swift in Sources */, diff --git a/Rocket.Chat/Controllers/Chat/ChatSections/MessageSection.swift b/Rocket.Chat/Controllers/Chat/ChatSections/MessageSection.swift index 1d69aeed08..208a8229eb 100644 --- a/Rocket.Chat/Controllers/Chat/ChatSections/MessageSection.swift +++ b/Rocket.Chat/Controllers/Chat/ChatSections/MessageSection.swift @@ -209,15 +209,24 @@ final class MessageSection: ChatSection { } } } - + var isLocationMessage: Bool = false object.message.urls.forEach { messageURL in - cells.insert(MessageURLChatItem( - url: messageURL.url, - imageURL: messageURL.imageURL, - title: messageURL.title, - subtitle: messageURL.subtitle, - message: object.message - ).wrapped, at: 0) + if messageURL.url.range(of: "https://maps.google.com/?q=") != nil { + isLocationMessage = true + cells.insert(LocationChatItem( + url: messageURL.url, + title: object.message.text, + message: object.message + ).wrapped, at: 0) + } else { + cells.insert(MessageURLChatItem( + url: messageURL.url, + imageURL: messageURL.imageURL, + title: messageURL.title, + subtitle: messageURL.subtitle, + message: object.message + ).wrapped, at: 0) + } } if object.message.isBroadcastReplyAvailable() { @@ -242,15 +251,19 @@ final class MessageSection: ChatSection { } if !object.isSequential && shouldAppendMessageHeader { - cells.append(BasicMessageChatItem( - user: user, - message: object.message - ).wrapped) + if !isLocationMessage { + cells.append(BasicMessageChatItem( + user: user, + message: object.message + ).wrapped) + } } else if object.isSequential { - cells.append(SequentialMessageChatItem( - user: user, - message: object.message - ).wrapped) + if !isLocationMessage { + cells.append(SequentialMessageChatItem( + user: user, + message: object.message + ).wrapped) + } } if let daySeparator = object.daySeparator { diff --git a/Rocket.Chat/Controllers/Chat/MessagesViewController.swift b/Rocket.Chat/Controllers/Chat/MessagesViewController.swift index 39c24bc7b7..0f5c542fad 100644 --- a/Rocket.Chat/Controllers/Chat/MessagesViewController.swift +++ b/Rocket.Chat/Controllers/Chat/MessagesViewController.swift @@ -304,7 +304,8 @@ final class MessagesViewController: RocketChatViewController { (nib: MessageURLCell.nib, cellIdentifier: MessageURLCell.identifier), (nib: MessageActionsCell.nib, cellIdentifier: MessageActionsCell.identifier), (nib: MessageVideoCallCell.nib, cellIdentifier: MessageVideoCallCell.identifier), - (nib: HeaderCell.nib, cellIdentifier: HeaderCell.identifier) + (nib: HeaderCell.nib, cellIdentifier: HeaderCell.identifier), + (nib: LocationCell.nib, cellIdentifier: LocationCell.identifier) ] collectionViewCells.forEach { @@ -650,3 +651,23 @@ extension MessagesViewController: SocketConnectionHandler { } } + +extension MessagesViewController { + func openSharedLocationMap(for url: String, username: String) { + let storyboard = UIStoryboard(name: "Location", bundle: Bundle.main) + + let backButton = UIBarButtonItem(title: "", style: .plain, target: self, action: nil) + navigationItem.backBarButtonItem = backButton + + let coordinates = url.getCoordinates() + var isSelf: Bool = false + if let currentUser = AuthManager.currentUser(), let currentUsername = currentUser.username { + isSelf = currentUsername.isContentEqual(to: username) + } + + if let controller = storyboard.instantiateViewController(withIdentifier: "SharedLocation") as? SharedLocationViewController { + controller.setup(sharedLocation: coordinates, username: username, isSelf: isSelf) + self.navigationController?.pushViewController(controller, animated: true) + } + } +} diff --git a/Rocket.Chat/Controllers/Chat/MessagesViewControllerMessageCellProtocol.swift b/Rocket.Chat/Controllers/Chat/MessagesViewControllerMessageCellProtocol.swift index 099138bad3..1e0733af63 100644 --- a/Rocket.Chat/Controllers/Chat/MessagesViewControllerMessageCellProtocol.swift +++ b/Rocket.Chat/Controllers/Chat/MessagesViewControllerMessageCellProtocol.swift @@ -109,12 +109,20 @@ extension MessagesViewController: ChatMessageCellProtocol { } func openURL(url: URL) { - WebBrowserManager.open(url: url) + if url.absoluteString.range(of: "https://maps.google.com/?q=") != nil { + openSharedLocationMap(for: url.absoluteString, username: "") + } else { + WebBrowserManager.open(url: url) + } } - func openURLFromCell(url: String) { + func openURLFromCell(url: String, username: String) { guard let destinyURL = URL(string: url) else { return } - WebBrowserManager.open(url: destinyURL) + if url.range(of: "https://maps.google.com/?q=") != nil { + openSharedLocationMap(for: destinyURL.absoluteString, username: username) + } else { + WebBrowserManager.open(url: destinyURL) + } } func openVideoFromCell(attachment: UnmanagedAttachment) { diff --git a/Rocket.Chat/Controllers/Chat/MessagesViewControllerUploading.swift b/Rocket.Chat/Controllers/Chat/MessagesViewControllerUploading.swift index 059e4d8c48..4756287f44 100644 --- a/Rocket.Chat/Controllers/Chat/MessagesViewControllerUploading.swift +++ b/Rocket.Chat/Controllers/Chat/MessagesViewControllerUploading.swift @@ -43,6 +43,10 @@ extension MessagesViewController: MediaPicker, UIImagePickerControllerDelegate, self.openDrawing() } + addAction("chat.upload.location", image: #imageLiteral(resourceName: "Location")) { _ in + self.openLocationShare() + } + alert.addAction(UIAlertAction(title: localized("global.cancel"), style: .cancel, handler: nil)) if let presenter = alert.popoverPresentationController { @@ -291,3 +295,39 @@ extension MessagesViewController: DrawingControllerDelegate { } } + +// MARK: Share location + +extension MessagesViewController: LocationControllerDelegate { + + func openLocationShare() { + let storyboard = UIStoryboard(name: "Location", bundle: Bundle.main) + + if let controller = storyboard.instantiateInitialViewController() as? UINavigationController { + + if let locationController = controller.viewControllers.first as? LocationViewController { + locationController.delegate = self + } + + self.present(controller, animated: true, completion: nil) + } + } + + func shareLocation(with coordinates: CLLocationCoordinate2D, address: Address?) { + + let googleString = "https://maps.google.com/?q=\(coordinates.latitude),\(coordinates.longitude)" + var finalString = googleString + + if let address = address { + if address.completeAddress.isEmpty { + finalString = "\(address.placeName)\n\(googleString)" + } else { + finalString = "\(address.placeName)\n\(address.completeAddress)\n\(googleString)" + } + } + + DispatchQueue.main.async { + self.viewModel.sendTextMessage(text: finalString) + } + } +} diff --git a/Rocket.Chat/Controllers/Location/LocationPopover.swift b/Rocket.Chat/Controllers/Location/LocationPopover.swift new file mode 100644 index 0000000000..8f88fbc181 --- /dev/null +++ b/Rocket.Chat/Controllers/Location/LocationPopover.swift @@ -0,0 +1,78 @@ +// +// LocationPopover.swift +// Rocket.Chat +// +// Created by Luís Machado on 29/01/2019. +// Copyright © 2019 Rocket.Chat. All rights reserved. +// + +import UIKit + +class MyCustomButton: UIButton { + + override open var isHighlighted: Bool { + didSet { + backgroundColor = isHighlighted ? UIColor.init(displayP3Red: 240/255, green: 240/255, blue: 240/255, alpha: 0.8) : UIColor.clear + } + } +} + +class LocationPopover: UIViewController { + + @IBOutlet weak var addressLabel: UILabel! + @IBOutlet weak var acceptButton: UIButton! + @IBOutlet weak var spinner: UIActivityIndicatorView! + @IBOutlet weak var spinnerWidth: NSLayoutConstraint! + @IBOutlet weak var spinnerLeading: NSLayoutConstraint! + @IBOutlet weak var sendLocationButton: MyCustomButton! + + weak var locationViewController: LocationViewController? + var address: Address? + + override func viewDidLoad() { + super.viewDidLoad() + + acceptButton.setTitle(localized("location.send_location"), for: .normal) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + spinner.startAnimating() + setup(for: nil, stopLoad: false) + + } + + func setup(for address: Address?, stopLoad: Bool = true) { + self.address = address + addressLabel.text = address?.shortAddress ?? localized("location.loading") + + if stopLoad { + spinner.stopAnimating() + spinnerWidth.constant = 0 + spinnerLeading.constant = 0 + spinner.isHidden = true + } + + let minWidth = acceptButton.frame.size.width + 24 + + var calculatedWidth = estimateFrameForText(width: 500, text: addressLabel.text ?? "", font: UIFont.systemFont(ofSize: 13.0)).width + if !stopLoad { + calculatedWidth = 220 + } else { + calculatedWidth = (calculatedWidth < minWidth) ? minWidth : calculatedWidth + 20 + } + + self.preferredContentSize = CGSize(width: calculatedWidth + 20, height: 49) + } + + @IBAction func acceptPressed(_ sender: Any) { + locationViewController?.locationSelected(address: address) + } +} + +func estimateFrameForText(width: CGFloat, text: String, font: UIFont) -> CGRect { + let size = CGSize(width: width, height: 30) + let options = NSStringDrawingOptions.usesFontLeading.union(.usesLineFragmentOrigin) + return NSString(string: text).boundingRect(with: size, options: options, attributes: [NSAttributedString.Key.font: font], context: nil) +} diff --git a/Rocket.Chat/Controllers/Location/LocationShareDelegate.swift b/Rocket.Chat/Controllers/Location/LocationShareDelegate.swift new file mode 100644 index 0000000000..0034db195a --- /dev/null +++ b/Rocket.Chat/Controllers/Location/LocationShareDelegate.swift @@ -0,0 +1,14 @@ +// +// LocationShareDelegate.swift +// Rocket.Chat +// +// Created by Luís Machado on 30/01/2019. +// Copyright © 2019 Rocket.Chat. All rights reserved. +// + +import UIKit +import MapKit + +protocol LocationControllerDelegate: class { + func shareLocation(with coordinates: CLLocationCoordinate2D, address: Address?) +} diff --git a/Rocket.Chat/Controllers/Location/LocationViewController.swift b/Rocket.Chat/Controllers/Location/LocationViewController.swift new file mode 100644 index 0000000000..038ff30259 --- /dev/null +++ b/Rocket.Chat/Controllers/Location/LocationViewController.swift @@ -0,0 +1,319 @@ +// +// LocationViewController.swift +// Rocket.Chat +// +// Created by Luís Machado on 28/01/2019. +// Copyright © 2019 Rocket.Chat. All rights reserved. +// + +import UIKit +import MapKit + +class LocationViewController: UIViewController, UIGestureRecognizerDelegate { + + var selectedLocation: CLLocationCoordinate2D? + var userLocation: CLLocationCoordinate2D? + let locationManager = CLLocationManager() + var currentPopover: LocationPopover? + var showingSatellite: Bool = false + + let myAnnotation = MKPointAnnotation() + var mapRegionTimer: Timer? + var locationWasAllowed: Bool = false + + weak var delegate: LocationControllerDelegate? + + @IBOutlet weak var map: MKMapView! + @IBOutlet weak var mapOptionsButton: UIButton! + + override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) { + super.willTransition(to: newCollection, with: coordinator) + + dismissPopover() + self.map.removeAnnotations(self.map.annotations) + coordinator.animate(alongsideTransition: nil) { (_) in + self.map.addAnnotation(self.myAnnotation) + self.map.selectAnnotation(self.myAnnotation, animated: true) + } + } + + override func viewDidLoad() { + super.viewDidLoad() + + self.navigationItem.rightBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "arrow"), style: .plain, target: self, action: #selector(centerOnUser)) + + // For use in foreground + self.locationManager.delegate = self + self.locationManager.requestWhenInUseAuthorization() + self.map.showsUserLocation = true + self.map.showsCompass = false + self.map.delegate = self + + self.title = localized("location.title") + + if CLLocationManager.locationServicesEnabled() { + locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters + locationManager.startUpdatingLocation() + } + + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) { //Wait 1 second to see if user location is available + if !self.locationWasAllowed { + self.selectedLocation = self.map.centerCoordinate + self.setupForLocation(location: self.map.centerCoordinate) + } + } + } + + @objc func centerOnUser() { + if let userLocation = map.userLocation.location?.coordinate { + let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005) + let mapRegion = MKCoordinateRegion(center: userLocation, span: span) + map.setRegion(mapRegion, animated: true) + } else { + Alert(key: "location_disabled").present() + } + } + + @IBAction func mapOptionsPressed(_ sender: Any) { + showingSatellite = !showingSatellite + self.changeMapView(showSatellite: showingSatellite) + } + + @IBAction func cancelPressed(_ sender: Any) { + dismissController() + } + + func locationSelected(address: Address?) { + delegate?.shareLocation(with: myAnnotation.coordinate, address: address) + dismissController() + } + + func changeMapView(showSatellite: Bool) { + mapOptionsButton.setImage(showSatellite ? #imageLiteral(resourceName: "map") : #imageLiteral(resourceName: "satellite"), for: .normal) + map.mapType = showSatellite ? .hybrid : .standard + } + + override func viewWillDisappear(_ animated: Bool) { + locationManager.stopUpdatingLocation() + } + + private func dismissController() { + dismissPopover() + dismiss(animated: true, completion: nil) + } + + private func dismissPopover() { + currentPopover?.dismiss(animated: false, completion: nil) + currentPopover = nil + } +} + +extension LocationViewController: MKMapViewDelegate { + + func mapView(_ mapView: MKMapView, regionWillChangeAnimated animated: Bool) { + dismissPopover() + mapView.view(for: myAnnotation)?.setDragState(.starting, animated: false) + setMapRegionTimer() + } + + func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) { + mapView.view(for: myAnnotation)?.setDragState(.ending, animated: false) + mapRegionTimer?.invalidate() + map.selectAnnotation(myAnnotation, animated: true) + } + + private func setMapRegionTimer() { + mapRegionTimer?.invalidate() + mapRegionTimer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(mapRegionTimerFired), userInfo: nil, repeats: true) + mapRegionTimer?.fire() + } + + @objc func mapRegionTimerFired() { + myAnnotation.coordinate = self.map.centerCoordinate + } +} + +extension LocationViewController: CLLocationManagerDelegate { + + func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { + if status == .denied || status == .restricted || status == .notDetermined { + locationWasAllowed = false + } + } + + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let location = manager.location { + + if !locationWasAllowed { + locationWasAllowed = true + selectedLocation = location.coordinate + setupForLocation(location: location.coordinate) + } + } + } + + func setupForLocation(location: CLLocationCoordinate2D) { + let viewRegion = MKCoordinateRegion(center: location, latitudinalMeters: 200, longitudinalMeters: 200) + map.setRegion(viewRegion, animated: true) + + myAnnotation.coordinate = location + + map.removeAnnotations(map.annotations) + map.addAnnotation(myAnnotation) + } + + func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) { + + mapView.deselectAnnotation(view.annotation, animated: false) + + let storyboard = UIStoryboard(name: "Location", bundle: nil) + guard let popover = storyboard.instantiateViewController(withIdentifier: "locationPopover") as? LocationPopover else { return } + _ = popover.view + + popover.locationViewController = self + + myAnnotation.coordinate.getLocationName { (address) in + popover.setup(for: address) + } + + popover.modalPresentationStyle = .popover + popover.popoverPresentationController?.permittedArrowDirections = .any + popover.popoverPresentationController?.delegate = self + popover.popoverPresentationController?.sourceView = view + popover.popoverPresentationController?.sourceRect = view.bounds + popover.popoverPresentationController?.backgroundColor = UIColor(red: 240/255, green: 240/255, blue: 240/255, alpha: 0.85) + + // Allow these views to be accessible while popover is being displayed + var passthroughViews: [UIView] = [mapOptionsButton, map] + + if let closeButtonView = navigationController?.navigationBar { + passthroughViews.append(closeButtonView) + } + + popover.popoverPresentationController?.passthroughViews = passthroughViews + + currentPopover = popover + present(popover, animated: true, completion: nil) + } +} + +extension LocationViewController: UIPopoverPresentationControllerDelegate { + + func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { + return .none + } +} + +struct Address { + let shortAddress: String + let placeName: String + let completeAddress: String + let headerAddress: String +} + +extension CLLocationCoordinate2D { + + func getLocationName(callback: @escaping (_ address: Address) -> Void) { + // Add below code to get address for touch coordinates. + + let geoCoder = CLGeocoder() + let location = CLLocation(latitude: latitude, longitude: longitude) + + var shortAddress: String = "" // (PIN) Street name (thoroughfare) number (sub thoroughfare), locality + var placeName: String = "" //Name + var completeAddress: String = "" //thoroughfare subthoroughfare, postal code, locality, country + var headerAddress: String = "" //thoroughfare subthoroughfare, postal code, locality, country + + geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, _) -> Void in + + // Place details + var placeMark: CLPlacemark! + + guard let placemarks = placemarks else { return } + + if placemarks.count == 0 { + return + } + + placeMark = placemarks[0] + + // Short Address + shortAddress = placeMark.name ?? "" + var shortAddressComponents: [String] = [] + var streetComponents: [String] = [] + if let thoroughfare = placeMark.thoroughfare, !thoroughfare.isEmpty { + streetComponents.append(thoroughfare) + } + if let subThoroughfare = placeMark.subThoroughfare, !subThoroughfare.isEmpty { + streetComponents.append(subThoroughfare) + } + + let streetComponentsJoined = streetComponents.joined(separator: " ") + if !streetComponentsJoined.isEmpty { + shortAddressComponents.append(streetComponentsJoined) + } + + if let locality = placeMark.locality, !locality.isEmpty { + shortAddressComponents.append(locality) + } + + let shortAddressJoined = shortAddressComponents.joined(separator: ", ") + if !shortAddressJoined.isEmpty { + shortAddress = shortAddressJoined + } + + // Place Name + placeName = placeMark.name ?? shortAddress + + // Complete Address + var addressComponentsList: [String] = [] + var addressComponentsListWOCountry: String = "" + //// Street + let streetAndNumber = streetComponents.joined(separator: " ") + if !streetAndNumber.isEmpty { + addressComponentsList.append(streetAndNumber) + } + //// Postal Code and Locality + var postalCodeAndLocalityList: [String] = [] + var postalCodeAndLocality: String = "" + + if let postalCode = placeMark.postalCode, !postalCode.isEmpty { + postalCodeAndLocalityList.append(postalCode) + } + if let locality = placeMark.locality, !locality.isEmpty { + postalCodeAndLocalityList.append(locality) + } + + postalCodeAndLocality = postalCodeAndLocalityList.joined(separator: " ") + + if !postalCodeAndLocality.isEmpty { + addressComponentsList.append(postalCodeAndLocality) + } + //// Country + addressComponentsListWOCountry = addressComponentsList.joined(separator: ", ") //Used for the header title + if let country = placeMark.country, !country.isEmpty { + addressComponentsList.append(country) + } + completeAddress = addressComponentsList.joined(separator: ", ") + + // Header Address + if placeName.isContentEqual(to: streetAndNumber) { + headerAddress = postalCodeAndLocality + } else if streetAndNumber.isEmpty { + if postalCodeAndLocality.isEmpty { + if let country = placeMark.country, !country.isEmpty { + headerAddress = "\(placeName), \(country)" + } else { + headerAddress = placeName + } + } else { + headerAddress = "\(placeName), \(postalCodeAndLocality)" + } + } else { + headerAddress = addressComponentsListWOCountry + } + + callback(Address(shortAddress: shortAddress, placeName: placeName, completeAddress: completeAddress, headerAddress: headerAddress)) + }) + } +} diff --git a/Rocket.Chat/Controllers/Location/SharedLocationViewController.swift b/Rocket.Chat/Controllers/Location/SharedLocationViewController.swift new file mode 100644 index 0000000000..4323ac4271 --- /dev/null +++ b/Rocket.Chat/Controllers/Location/SharedLocationViewController.swift @@ -0,0 +1,447 @@ +// +// SharedLocationViewController.swift +// Rocket.Chat +// +// Created by Luís Machado on 07/02/2019. +// Copyright © 2019 Rocket.Chat. All rights reserved. +// + +import UIKit +import MapKit + +enum CurrentFocus { + case sharedLocation + case userLocation + case both +} + +class SharedLocationViewController: UIViewController, UIGestureRecognizerDelegate { + + var sharedLocation: CLLocationCoordinate2D? + var usernameWhoShared: String = "" + var isSelf: Bool = true + var locationWasAllowed: Bool = false + + var currentFocus: CurrentFocus = .sharedLocation + @IBOutlet weak var changeFocusButton: UIBarButtonItem! + + var userLocation: CLLocationCoordinate2D? + let locationManager = CLLocationManager() + var currentPopover: LocationPopover? + var showingSatellite: Bool = false + + let myAnnotation = MKPointAnnotation() + var timeDistanceButton: UIButton? + var mapRegionTimer: Timer? + + weak var delegate: LocationControllerDelegate? + + @IBOutlet weak var map: MKMapView! + @IBOutlet weak var mapOptionsButton: UIButton! + + func setTitle2(title: String, subtitle: String) -> UIView { + let titleLabel = UILabel(frame: CGRect(x: 0, y: -5, width: 0, height: 0)) + + titleLabel.backgroundColor = UIColor.clear + titleLabel.textColor = UIColor.gray + titleLabel.font = UIFont.boldSystemFont(ofSize: 17) + titleLabel.text = title + titleLabel.sizeToFit() + + let subtitleLabel = UILabel(frame: CGRect(x: 0, y: 18, width: 0, height: 0)) + subtitleLabel.backgroundColor = UIColor.clear + subtitleLabel.textColor = UIColor.black + subtitleLabel.font = UIFont.systemFont(ofSize: 12) + subtitleLabel.text = subtitle + subtitleLabel.sizeToFit() + + let titleView = UIView(frame: CGRect(x: 0, y: 0, width: max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), height: 30)) + titleView.addSubview(titleLabel) + titleView.addSubview(subtitleLabel) + + let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width + + if widthDiff > 0 { + var frame = titleLabel.frame + frame.origin.x = widthDiff / 2 + titleLabel.frame = frame.integral + } else { + var frame = subtitleLabel.frame + frame.origin.x = abs(widthDiff) / 2 + titleLabel.frame = frame.integral + } + + return titleView + } + + func setTitle(title: String, subtitle: String) -> UIView { + let titleLabel = UILabel(frame: CGRect(x: 0, y: -2, width: 0, height: 0)) + + titleLabel.backgroundColor = .clear + titleLabel.textColor = .gray + titleLabel.font = UIFont.boldSystemFont(ofSize: 17) + titleLabel.text = title + titleLabel.sizeToFit() + + let subtitleLabel = UILabel(frame: CGRect(x: 0, y: 18, width: 0, height: 0)) + subtitleLabel.backgroundColor = .clear + subtitleLabel.textColor = .black + subtitleLabel.font = UIFont.systemFont(ofSize: 12) + subtitleLabel.text = subtitle + subtitleLabel.sizeToFit() + + let maxWidth = self.view.frame.width - 50 + + let titleView = UIView(frame: CGRect(x: 0, y: 0, width: min(max(titleLabel.frame.size.width, subtitleLabel.frame.size.width), maxWidth), height: 30)) + + if titleLabel.frame.size.width > maxWidth { + titleLabel.frame = CGRect(x: titleLabel.frame.origin.x, y: titleLabel.frame.origin.y, width: maxWidth, height: titleLabel.frame.size.height) + } + + if subtitleLabel.frame.size.width > maxWidth { + subtitleLabel.frame = CGRect(x: subtitleLabel.frame.origin.x, y: subtitleLabel.frame.origin.y, width: maxWidth, height: subtitleLabel.frame.size.height) + } + + titleView.addSubview(titleLabel) + titleView.addSubview(subtitleLabel) + + let widthDiff = subtitleLabel.frame.size.width - titleLabel.frame.size.width + + if widthDiff < 0 { + let newX = widthDiff / 2 + subtitleLabel.frame.origin.x = abs(newX) + } else { + let newX = widthDiff / 2 + titleLabel.frame.origin.x = newX + } + + return titleView + } + + override func viewDidLoad() { + super.viewDidLoad() + + // For use in foreground + self.locationManager.requestWhenInUseAuthorization() + self.map.showsUserLocation = true + self.map.showsCompass = false + self.map.delegate = self + + if CLLocationManager.locationServicesEnabled() { + locationManager.delegate = self + locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters + locationManager.startUpdatingLocation() + } + } + + func setup(sharedLocation: CLLocationCoordinate2D, username: String, isSelf: Bool) { + self.sharedLocation = sharedLocation + self.usernameWhoShared = username + self.isSelf = isSelf + + sharedLocation.getLocationName { (address) in + let vie = self.setTitle(title: address.placeName, subtitle: address.headerAddress) + self.navigationItem.titleView = vie + } + } + + @IBAction func sharePressed(_ sender: Any) { + guard let sharedLoc = sharedLocation else { return } + openMaps(location: sharedLoc, region: map.region, driving: false) + } + + @IBAction func changeFocusPressed(_ sender: Any) { + + if !locationWasAllowed { + currentFocus = .sharedLocation + changeMapFocus() + Alert(key: "location_disabled").present() + return + } + + switch currentFocus { + case .sharedLocation: + currentFocus = .userLocation + case .userLocation: + currentFocus = .both + case .both: + currentFocus = .sharedLocation + } + changeMapFocus() + } + + private func changeMapFocus() { + var annotationsToShow: [MKAnnotation] = [] + + for annotation in self.map.annotations { + map.deselectAnnotation(annotation, animated: true) + if annotation is MKPointAnnotation && (currentFocus == .sharedLocation || currentFocus == .both) { + annotationsToShow.append(annotation) + } else if annotation is MKUserLocation && (currentFocus == .userLocation || currentFocus == .both) { + annotationsToShow.append(annotation) + } + } + + map.showAnnotations(annotationsToShow, animated: true) + if annotationsToShow.count == 1 { + map.selectAnnotation(annotationsToShow[0], animated: true) + } + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + if let location = self.sharedLocation { + setupForLocation(location: location) + } + } + + @objc func centerOnUser() { + if let userLocation = map.userLocation.location?.coordinate { + let span = MKCoordinateSpan(latitudeDelta: 0.005, longitudeDelta: 0.005) + let mapRegion = MKCoordinateRegion(center: userLocation, span: span) + map.setRegion(mapRegion, animated: true) + } + } + + @IBAction func mapOptionsPressed(_ sender: Any) { + showingSatellite = !showingSatellite + self.changeMapView(showSatellite: showingSatellite) + } + + func changeMapView(showSatellite: Bool) { + mapOptionsButton.setImage(showSatellite ? #imageLiteral(resourceName: "map") : #imageLiteral(resourceName: "satellite"), for: .normal) + map.mapType = showSatellite ? .hybrid : .standard + } + + override func viewWillDisappear(_ animated: Bool) { + locationManager.stopUpdatingLocation() + dismissPopover() + } + + private func dismissPopover() { + currentPopover?.dismiss(animated: false, completion: nil) + currentPopover = nil + } +} + +extension SharedLocationViewController { + private func openMaps(location: CLLocationCoordinate2D, region: MKCoordinateRegion, driving: Bool) { + + let alert = UIAlertController(title: nil, message: driving ? localized("maps.choose_application") : nil, preferredStyle: .actionSheet) + + let apple = UIAlertAction(title: "Apple Maps", style: .default, handler: { _ in + self.openAppleMaps(location: location, region: region, driving: driving) + }) + + let google = UIAlertAction(title: "Google Maps", style: .default, handler: { _ in + self.openGoogleMaps(location: location, driving: driving) + }) + + let waze = UIAlertAction(title: "Waze", style: .default, handler: { _ in + self.openWaze(location: location, driving: driving) + }) + + alert.addAction(UIAlertAction(title: localized("global.cancel"), style: .cancel, handler: nil)) + alert.addAction(apple) + if canOpenGoogleMaps() { + alert.addAction(google) + } + + if canOpenWaze() { + alert.addAction(waze) + } + + present(alert, animated: true) + } + + private func canOpenGoogleMaps() -> Bool { + guard let baseURL = URL(string: "comgooglemaps://") else { return false } + return UIApplication.shared.canOpenURL(baseURL) + } + + private func canOpenWaze() -> Bool { + guard let baseURL = URL(string: "waze://") else { return false } + return UIApplication.shared.canOpenURL(baseURL) + } + + private func openWaze(location: CLLocationCoordinate2D, driving: Bool) { + if canOpenWaze() { + let urlString: String = "waze://?ll=\(location.latitude),\(location.longitude)&navigate=\(driving ? "yes" : "no")" + guard let mapsURL = URL(string: urlString) else { + Alert(key: "maps.open_external_error").present() + return + } + + UIApplication.shared.open(mapsURL, options: [:], completionHandler: nil) + } + } + private func openAppleMaps(location: CLLocationCoordinate2D, region: MKCoordinateRegion, driving: Bool) { + let regionSpan = region + var options: [String: Any] = [ + MKLaunchOptionsMapCenterKey: NSValue(mkCoordinate: regionSpan.center), + MKLaunchOptionsMapSpanKey: NSValue(mkCoordinateSpan: regionSpan.span) + ] + + if driving { + options[MKLaunchOptionsDirectionsModeKey] = MKLaunchOptionsDirectionsModeDriving + } + + let placemark = MKPlacemark(coordinate: location, addressDictionary: nil) + let mapItem = MKMapItem(placemark: placemark) + mapItem.name = usernameWhoShared + mapItem.openInMaps(launchOptions: options) + } + + private func openGoogleMaps(location: CLLocationCoordinate2D, driving: Bool) { + if canOpenGoogleMaps() { + let urlString = driving ? + "comgooglemaps://?saddr=&daddr=\(location.latitude),\(location.longitude)&directionsmode=driving" : + "comgooglemaps://?center=\(location.latitude),\(location.longitude)&zoom=14&views=traffic&q=\(location.latitude),\(location.longitude)" + guard let mapsURL = URL(string: urlString) else { + Alert(key: "maps.open_external_error").present() + return + } + + UIApplication.shared.open(mapsURL, options: [:], completionHandler: nil) + } + } +} + +extension SharedLocationViewController: MKMapViewDelegate { + + func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { + if annotation is MKUserLocation { + return nil + } + + if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: "pin") { + annotationView.annotation = annotation + return annotationView + } else { + let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: "pin") + annotationView.canShowCallout = true + + // Action Button + let smallSquare = CGSize(width: 50, height: 50) + let button = UIButton(frame: CGRect(origin: CGPoint.zero, size: smallSquare)) + button.backgroundColor = UIColor(red: 26/255, green: 105/255, blue: 243/255, alpha: 1) + button.setImage(UIImage(named: "car_map")?.withRenderingMode(.alwaysTemplate), for: .normal) + button.imageView?.tintColor = .white + button.tintColor = .white + button.setTitle(" ", for: .normal) + button.titleLabel?.font = UIFont.systemFont(ofSize: 11) + button.imageEdgeInsets = UIEdgeInsets(top: 3, left: 8, bottom: 3, right: 1) + button.imageView?.contentMode = .scaleAspectFit + timeDistanceButton = button + annotationView.leftCalloutAccessoryView = button + + return annotationView + } + } + + func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { + guard let sharedLoc = sharedLocation else { return } + + if let reuseId = view.reuseIdentifier, reuseId.isContentEqual(to: "pin") { + openMaps(location: sharedLoc, region: map.region, driving: true) + } + } +} + +extension SharedLocationViewController: CLLocationManagerDelegate { + func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { + if status == .denied || status == .restricted || status == .notDetermined { + locationWasAllowed = false + } + } + + func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + guard let location = manager.location, let sharedLoc = sharedLocation else { return } + userLocation = location.coordinate + locationWasAllowed = true + + if !isSelf { + // Distance + let distance = calculateDistance(between: location.coordinate, pointB: sharedLoc) + let formatted = formatMetersToString(distance: distance) + myAnnotation.subtitle = formatted + } + + // ETA + let sourcePlacemark = MKPlacemark(coordinate: location.coordinate, addressDictionary: nil) + let sourceMapItem = MKMapItem(placemark: sourcePlacemark) + let destinationPlacemark = MKPlacemark(coordinate: sharedLoc, addressDictionary: nil) + let destinationMapItem = MKMapItem(placemark: destinationPlacemark) + + let request = MKDirections.Request() + request.source = sourceMapItem + request.destination = destinationMapItem + request.transportType = MKDirectionsTransportType.automobile + request.requestsAlternateRoutes = false + let directions = MKDirections(request: request) + directions.calculate { (response, _) in + if let route = response?.routes.first { + // Distances inferior to 1 min are returned as null (no need to show) + guard let formatted = self.formatSecondsToMinutesOrHours(time: route.expectedTravelTime) else { return } + + self.timeDistanceButton?.setTitle(formatted, for: .normal) + self.timeDistanceButton?.titleEdgeInsets = UIEdgeInsets(top: 30, left: -38, bottom: 0, right: 0) + self.timeDistanceButton?.imageEdgeInsets = UIEdgeInsets(top: 0, left: 6, bottom: 16, right: 0) + } + } + } + + func setupForLocation(location: CLLocationCoordinate2D) { + let viewRegion = MKCoordinateRegion(center: location, latitudinalMeters: 200, longitudinalMeters: 200) + map.setRegion(viewRegion, animated: true) + + myAnnotation.coordinate = location + + var title = self.usernameWhoShared + if isSelf { + title.append(" (\(localized("maps.me")))") + } + + myAnnotation.title = title + map.removeAnnotations(map.annotations) + map.addAnnotation(myAnnotation) + map.selectAnnotation(myAnnotation, animated: true) + } + + private func calculateDistance(between pointA: CLLocationCoordinate2D, pointB: CLLocationCoordinate2D) -> Double { + let loc1 = CLLocation(latitude: pointA.latitude, longitude: pointA.longitude) + let loc2 = CLLocation(latitude: pointB.latitude, longitude: pointB.longitude) + + return loc1.distance(from: loc2) + } + + private func formatMetersToString(distance: Double) -> String { + + if distance < 1000 { + return "\(Int(distance)) m" + } else { + let roundedToKms: Int = Int(distance / 1000) + return "\(roundedToKms) km" + } + } + + private func formatSecondsToMinutesOrHours(time: Double) -> String? { + + if time < 80 { + return nil + } else if time < 3600 { + let min = Int(time / 60) + return "\(min) min" + } else { + let hours = Int(time / 60 / 60) + return "\(hours) hr" + } + } +} + +extension SharedLocationViewController: UIPopoverPresentationControllerDelegate { + + func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle { + return .none + } +} diff --git a/Rocket.Chat/Info.plist b/Rocket.Chat/Info.plist index 35d84ce793..23a8e4f4a7 100644 --- a/Rocket.Chat/Info.plist +++ b/Rocket.Chat/Info.plist @@ -242,6 +242,8 @@ LSApplicationQueriesSchemes org-appextension-feature-password-management + comgooglemaps + waze googlechromes googlechrome opera-http @@ -272,6 +274,8 @@ NSPhotoLibraryAddUsageDescription NSPhotoLibraryUsageDescription NSPhotoLibraryUsageDescription + NSLocationWhenInUseUsageDescription + Location access is needed in order to determine and share your location RC_MIN_SERVER_VERSION 0.62.0 UIApplicationShortcutItems diff --git a/Rocket.Chat/Resources/Assets.xcassets/Composer/Attach/Location.imageset/Contents.json b/Rocket.Chat/Resources/Assets.xcassets/Composer/Attach/Location.imageset/Contents.json new file mode 100644 index 0000000000..de5141533f --- /dev/null +++ b/Rocket.Chat/Resources/Assets.xcassets/Composer/Attach/Location.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "location2.pdf", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rocket.Chat/Resources/Assets.xcassets/Composer/Attach/Location.imageset/location2.pdf b/Rocket.Chat/Resources/Assets.xcassets/Composer/Attach/Location.imageset/location2.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7b4aa56d053019b2ee41aa1cb09a65e63599c5b9 GIT binary patch literal 1840 zcmd5-`)?Fg6kaG|86MV#!VgBh5Zko1?982gHx<|2K6X<#U3V!Ev9Z(H+uf<#opI(a z*`jGEF2*L>s{CMtiV{Stga!;%8i_VB+9nMK6V!^Y&{&m(1{=^=(Bi$b50+j204I}~ zz27}^&pF>Y=i73Bed8u*G&AL+b0gOoGvI*S(Z$r&0rpW83*!i|5GcR^0N6$;ijhj* zQ30cRB+4PgY~IXhSVclNlNd5>;S8=eHxMF+ULKlioh%#nPolTOA*Pi7#&k#j`XklJ z2Y*>IJHE8!-gQiSLrL4U{^iWY&zWmwos4nei9Tns;r^OZkwLLg`b_eRMnglOZxV#f zM7Qa}lnqr6t|5V&f|vvb>gp&!E>_^k0+6SNY0oW})3IeQO2qRDqpzhNzs3?ZXu^EPZC?p9kIRSPMhy&10?>61mEypl1 z)&QkA#b=W$$CaFLQyz3QlR=R9RfU+QP)}k{2KEB1#!+VFCRX)mrzE04lZ%4s`~pam zK)DL!c`pPXwWi_Y>BB3!AZj&nLDY0I{jjG7BudtJ)U z>#?)z!&fC;qJXhI7!%9>2I3B!7L4NiJVZuB^CvcK@=~HA5?W zu1&7v8#f*pJwKsc{`#->x%eml+M~{nikAL=YEDm{h`#<#>�l4?2#VdEm((26pyL zf7pKbtI_cdU~1PJ-;RUzFtB#tg_HXocaGdQvF6l^j)C{*g~k#zv!}?uc=o{0uNGh7 zr+SCBT6%nk2FI2i=Ds`X^js>vYvRo>cL$F7JflnPvn!&dzrQzs;o#*ByT1?240ula zr}v#~a9>R>_WkXvUakCCbaa*VgE`y0C;Z&?^V=^e%^$BCK6mESr+=7^om=SYz5A7W zW`A0!=(|$%?7KS*wPPo~7}>g~jDP;d)6e`i_V9EU{kbZce$TH*K>N(#SMZ zAqZqAIZlT@XPh7%_RI->RSv~PqLY=PAgMBdMrbv1pfZB7qSdlQhX@*01tlVhno(B6 zRaL3+AS#L_IaW`Hpt8P}=b(dwCXTa_x8?DwTz`cTy9F#n<*%Ld^>9a205O{QJ$TJBMje) zL5?G7=3%_G;9F=ild9&~nXNhBVpWi$NY&LYDD6U&11etuStfO)T&DEc8|x(HqP0vn Tl%QgrHE4n453;!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z%2~Ij105p zNH8!kMrMXYltlRYSS9D@>LsS+C#C9DVstT4fPE4;bsH1+JHo@{EISEfi{E8 zw==W>t3(ll+GC>+vK+}V5TAlYfnK%aveAbJn;nas|yAHEZL+g-3|!`oFWFV`l- zX0@I(tzfi2u)sWF%P$%EQ*BS6?K_G3)?HKD)S8~E-k`aQ1Lym9AZ z*{jbhCf=O>P_U+X-Q)Q;wnC$xe=+Te*rGG|J_`3!g6guN`~54E2p zXNO0u+acq9yYTkBiL++pmoI#5T)=qlpkv3M6PA`gZv4(-USVAtI)8cJeTT55w+Cl_ zU$aU^I!iq?t}S`Ns_b`XEqR_l6x-8&X`+0e=j8h-fv>lOewV!(c8a+`EbmaZ2J^JO zU1h&_hQ{STE!=YI?XSZpR_wOnz5Y=3Na6R3nf|MMJ`1h5H&-Iy`Q3)PEj-x^E-z7Q zy!>5u_CI8n z_`>}|d9_j8ca6dIuX mC7s_h^UAX0{}($x-_L0K^Pr03-#86WcJy@hb6Mw<&;$VM8mq$q literal 0 HcmV?d00001 diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/arrow.imageset/arrow@2x.png b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/arrow.imageset/arrow@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..fc717323ce4cee7f22e13a0d7f6fb12dedf47f2e GIT binary patch literal 1753 zcmY*ad05j&8vY>&Ne~1Qjv_W8RKP$I4!b}MK`sL>1c*Q(D5oI=$w3lGkf5RjDCHD_ z;dI&RQZV>H%3&j{ZYYt%0%Z}DTV=(nRSvg6frm}hy1Vl{GxN)f$oDM-BvlbJhTGF$VyC zS3wtF06>}p0KAL^0GtE>Oxd;a5WH#w%=U}q0)Q@5-8F#fS~CF9h@^)`@FD^Oa0x61 zChiO?o{AAL*eW&v-~~8U$e{A#5CTRDlZz9$Bi}P{s#pzUk%;#c-dT5KL|`z&o5i6b zzQi2CI3NiS1OkEQoJquyeU5)jSFPNUNjx4KhsE;wd<@?i!{X4ej&5#lSO+JplM`CS zKyx#gyf^`x$+h|*@`sKOm7Bn!vw3tD6QS0Pi)W?r+>uDN(Wmy|oIHBsf1Q}zk7cO} z#Hx3&ju;2*Cv82{H`K3vu|yglw?yguzVCSPFzJOFAs779U8p z#GHE3%>1$Lwvm?0=?bsI=$(X|r;5&a)9hR?m}%}6QAI(^B}?C;3nN(PC8|^R)?5}g zV|`A@e!e^7Ht(`DT(gy%*O}*TUA+K*ayMsH7j+G${{^GS&P$kgtbS^(x!dLe_yXAV zw}w$$JEVtov9&87+FNg=54kV;O0=X^GqRJ;S(8L_Y89B=l%oB2LIND zOY5h7Kn^-KItido4%q zJ_<`6f9`pmU=_PbKR_uTf4e6m`BX6JISio7>9=@%jeF%oD1Ft+oicxgvUD+EOZ$si}?jlLwu@|zE)6@d*gG<&ltnh1ehi{Kv9{vuC066hd4DbM6yrbw_6iemyRtArij}qy3M2h(UrzF7R7%$5uUCn z``5DH7by~f?^rxS<#I5$R{RN%%ElhW0Q=Z~r hw#R+PsdJsX8b+{hmxsRZBB?(Re_xW%Ew9*1{{e;9^SuB7 literal 0 HcmV?d00001 diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/arrow.imageset/arrow@3x.png b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/arrow.imageset/arrow@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..7c99320b2c1a091ffaf137ce6c17dfa1dce98106 GIT binary patch literal 2560 zcmY*bdpy(YAOE`5Y&l0Rqo}hjw=x?dSu^GqGIugY#>B!f!-zvemRl;9q=+b&nzh0S^H6mmy!tQldR9z{Z6D0Pz|Ckemttn<6NA4gjKc z0bt$_05I19Kq=xT&lxK^kdCk+MgagserJjSH*P8efEbbL=E?9R*kc01!%$>OxPKsu z85SX80|1tZ5v5^)3^I%v7D|i4FijBO7#LB$1EUeJZxlv|3Br@$1hWXI2f_?d1}I$w z4h)0Auyo2d;>z|Ix7wj0&JrBN)_h8f-_G>>nP@FhL-8jQ$ya)ybfq{jU=(>hHEh4Wf5W z(0V9c^gr67tJobB<4C6likx@!aeCNq%>Tpw_Q9fe%>SpDzdHSfidw~ivFLxE4F|U8 zYZ3tfwAa=W@5U5cykT2KvQoI1_?@$wvKw30emP84JOidIRl2Gw+f9U{7-j6*mS3|$ ztV|>+P#w&ol+g@QEN&wDAZq@SR(pbBC^@z*?5(WAoyf00aW*X~eJ2Hr!sauRLiFzK z8eVh=Ch3-|doxed;e`6xw+!_sru-yC>C?_`(+pUaJdYs_WY3vEs630eIeT%LS^_L2UQ;0c`DgJ=gUpA`4(cZg zth1;*?BEO{)MM@;(Qm-qag_&_T!gxe{`unQnb){q?=JP|gdNyGS@Afh+n-DbpxlZD zNt}N;6eWkee%Oy7F{3uRkefF>b4%jzO+VSnRI9JPQ-%yJmRDVH>|6k zee}x~-(2hi4|4Ie=J%QGJHOGVsN~w^HoqY@Ty7P6`;(9BP)z4(LkBgZoLp}``%BM) z-pW1PNL?;@@}*dA$Zh)LzUGj2n@N;%O+KVUFndDn#0R^n=&9sfx%5iIPM@%q^M(hL z*5B{CefsHM`NBa#+y17GN4C6{UI*2Y&-8zZ3V5h;snv*u^nf~e_r;=-;et0@(@ zdd?@3*G-)euPwxer^WB8>9RkY@dhSF`jZ^i?T>3zydxGF)Nz`GZ|>lV%qRkqE+cl8 zs}xDX*U90a>w!}K5yL!?ov;fRr-#ybhZQXhXB9oF?;ucs@Xzmx%5nwM+- z{CIzbDJZ4OWk{i6s59RFhwfj7`YW;(Di-M~>Ca>Eg--__nQOn0u^gGb7}M!Pn^Z;%crWnf-?`OC>h9j zgnI4E4N^k*Na0w_;Rw^jZbB1MfvcX#`GmU=iE-?EEXCUUr@>@1#HF>GQl<*tf+rk- zx%bh%yOv_SYTkICH!Hyvny(lNb~3bHCpt@6udd(ET#hR+x`dGb{Nc52+)Y z$t16-rB3L9AG|CclCIp^OB!u}6*hP(jlH$GCZm?c^`A>yCyz7_1zxgyw#42#9fO}Y zx)qqSr}x-Ykl3k|)Q0JXfF+hj7pK>uzzg!hmkXiS_v-A@&yC#UX8g(Y({s*Kf|!4Z zv}1Rfkp#`ZwcG6Ud&RN&mAf(&B3|JA71xLHxTsq=F8et=g%eqoV&%a&rPd#G4`I{< zIq1I8_wu2z3VZc}O4USElA?*AffF1u!J&NtzlilsGHK>E_3=mn&FLn9TRA$ z!8kjQ!edtg(-MusSLus{>CJUMw5YJyXmESO^e2TT$TmWw;03{>7zugZ;UwgRhFvL~ z`BT5dxd$({&{)}OKid*UAx74DTg{lxvh=0vOd)x{$?sbIm=S~Dwr}<{BjKeBSAGhr{kp}TxJ}h3OyH%-%nE^W{q>^h7)Ke;jT7U-=|N+L2pQIliSZE zV}Ed}*V;}?X(2Id;GwmFQyDj(M;fONsz{De25MeQQQNaAdNhb>_o2}MA0}4u?w*(3 zC^rpGy7oa?s5E;r{oW1pK^wxr0P$#UO6`_bXm-bsRqO2J%y@Zr-Tb9jcF H`?3BF>iTdt literal 0 HcmV?d00001 diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/car_map.imageset/Contents.json b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/car_map.imageset/Contents.json new file mode 100644 index 0000000000..50107dd8c0 --- /dev/null +++ b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/car_map.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "car_map.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/car_map.imageset/car_map.png b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/car_map.imageset/car_map.png new file mode 100644 index 0000000000000000000000000000000000000000..5688462c9165aaec9377408fb7b6f6b1b1f14d99 GIT binary patch literal 1690 zcmZuy3pkT&9REs%B-|zqX{on6-zVmJ_4$3es7ytmu zj#xW)Xx5Vrg=NsY7f4TsrX>^`oDBdJUsyg%S_+>n8jkC5Qwm_FnE|5oX(^mOf4)d5GF_j5@`%&7>96zStPb` zaER^#$#)(*{}3{h%3x9H!Jv$nbclY8h0)QG75eck=wwj?epU(&`DP0;h>)EiOyMSo z|ARqhf9U%K#U?QpK=ZB^ilJpxC|4%cACfB*Wo3$AZXJX-KXM^`t zl(aS6+~@JzlaD;aecSY8bwAI8#@CG03T&bneIl*W6FzCrjaph#o)AbRfuP6_0l}#L&$r3l#d%qk|>Neqo z_XSCAm#^}bSiWeR$_^E^U&Gx*R-)SFRN`4;kI$0KQ^=Xo**HaQ-m2D2BQ=Gq`&SX} z)yxvt#4jy1SD6dW3UXf0d)PxdQDNM@dg#tr;M7KM1&UAuLq#QY-uhU0&=Bl*(%U>4 zEfzL{Ny@#6CU$9pp(kL`1!3*jiKL_YYa^PjrTZvRcJ^?aCnoDX%>C?Mw+~f?2gKtx ztq*bi;+wJh1x|Cy?1LgbmM8Z`Ju$}h;m4W^AT|Ga!CI&M)X5kJVJpeO&@$-33YF+j z+!3}ZRyF2MRLap%lls`)=dZ%#2tk4dd2Ul>-Ygdt1;5_fyr$NE=&t+M=_Q9ZwC0OL zak1hTo!k=zX*-q3broAz=0y@y2MTL4QqzP~!toAbJg!{&=DjsDnP!tPs(NI!MFJ~D zM5x(~tiflbmyeeVdaEn9HAP#>DY_{UA}cdeYA5^C#t3iPHxJV|pc|LiSzr3TBU@gs zD`HF^Tm2`)T{Ply(1@31|DML)TygGlF2^F-qg;B3pxJRxU!k6zmSa1dUX(BBmwwF_ z=vmHcC+Fz)R)XOjo4kk{9KSeWfk&=A!h%?(^SQ0M(ix6g^a{noh9t`4&SL8HL}H0o zhScb@>RD+@)Aa`!!;Gi?kNOZo>0HN@yNCIyb7xl8j=vFZ=ex!<7$2vrmYRv~7DiO_O{)XiV(3w&ZL0kx!zoo4Upb$Z%Uh#`=MFG5 z9SM`HF!~d^-fM~wMUC2Z46QMsDe!C)4({gjN3PzrzMbMb(nY4OSItdp zDQ?zgzRS@sX*V8A%V(_z67(mWwuY7o$X6C8J>L``Gv~`O zn$pO@>{uuNY(r|D!$-DSsx3_6?Y5r5eR-qC%;afCZr8JbI|EEJe3(5@?Wk`h9VxA% zU+Qz8vgp>z8o+PY_8H}G=C!#jw-%h-Ftz>ikQ6TI>cy(9eq69N@sjtM+NBbn;qXiC z8`wbdeL-31MhQ4W+mVF_Zrg@Y^xvwKWqKBb_KsI8dCL_Jmds9wf3KDO0UUR^*cI+1 GM*agEx9eK~ literal 0 HcmV?d00001 diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/Contents.json b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/Contents.json new file mode 100644 index 0000000000..c3dc9d099b --- /dev/null +++ b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "map.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "map@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "map@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/map.png b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/map.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d17315646f5d0d0a1db85ed6e632c9f8b64d37 GIT binary patch literal 5354 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 P?<*(R)jDW0W99Nf3k(Bt$2oixyoN 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 literal 0 HcmV?d00001 diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/map@3x.png b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/map.imageset/map@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..fdb1d228d3d263bff5eabe13df2b9ea226dacace GIT binary patch literal 18155 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 Q0(1h6r>mdKI;Vst0OnMVzW@LL literal 0 HcmV?d00001 diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/Contents.json b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/Contents.json new file mode 100644 index 0000000000..9b76f514c9 --- /dev/null +++ b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "satellite.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "satellite@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "satellite@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/satellite.png b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/satellite.png new file mode 100644 index 0000000000000000000000000000000000000000..4cf5ad9f946238a962f41861a34d1e968421a849 GIT binary patch literal 11497 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�$8W#eDYopj?wGES-eqfywEOXeko1+)F(G!S(#&Ud zi~?@&8z{bA>bxyNe7;I}V&i`&UD*JjmyJH}c)aJ~o#Xb(!y22{vxAF%f@yprm-tI; zGcRmeg$NLqwWS>Y4D->tR1$*Mc?Ta<$!}P8iJtmZJcW7=oq>{XErg6^tI#(vv;2-e zYm@7T8=3{Srun3FPaI|o@?!;NblPLOz^Vnb*~SHNw>Fi+2AX#JNE+rA9JM-;IWF7i&^s@{3V`vhi zoLcdxiM$<4eKQ~d?hRV8q`oD5&I{~_p@qzl<#R{hBd!_GKALY*A38{j`?$enNInUX z!F{6$u^#c+DeQgMcoqq7k|Oo@3+TEEqM!jMBA2Ir$uyffO=Uybn8P?7ihW6~xR#LHZ!6l9Af=*>;YJyp2~kxp_4Y zn}yGE5e(Y?I&)nPI0Q#DlH|*B**evI_8)@p(ZIBUC#Ei%WzS1RC9yu1MJ!5^y2Ltp z;|=<8b#I;TBwAq9lz`+rshOp8NHYldB>G+;mg#jGb(q$nMorHY43!ChYNe3IvVb=P zN;D*$-yan>MnNTVUBgnW!-0 zk`yv^uW*Or;NcG+FN5UK6Z6Bd-12AV3K1P+vrUUK60Iq!=Ljqni7Iury zO$Ab9YXJphZ0n+!@3=DJX)@^LJ;{e3{ju6#U@|Y@JmSc@-)C-FT%QBNjs{y%Pt2N0 d$L(L^o-?j0lp&2ze*U3YT~$Zrxsr9*{{eR+4MzX~ literal 0 HcmV?d00001 diff --git a/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/satellite@2x.png b/Rocket.Chat/Resources/Assets.xcassets/ShareLocation/satellite.imageset/satellite@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5b24458858a0c2721dd6c0b63e39d47523b40e71 GIT binary patch literal 24035 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 z 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 P1pFw-s=lq3HVOKFg*=eE literal 0 HcmV?d00001 diff --git a/Rocket.Chat/Resources/cs.lproj/Localizable.strings b/Rocket.Chat/Resources/cs.lproj/Localizable.strings index 0b05e78391..73be4ac222 100644 --- a/Rocket.Chat/Resources/cs.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/cs.lproj/Localizable.strings @@ -250,6 +250,17 @@ "chat.upload.choose_from_library" = "Vybrat z knihovny"; "chat.upload.import_file" = "Importovat soubor z"; "chat.upload.draw" = "Draw something"; // TODO +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "Stahuji \"%@\""; diff --git a/Rocket.Chat/Resources/de.lproj/Localizable.strings b/Rocket.Chat/Resources/de.lproj/Localizable.strings index 4e01f9ffb1..86bd5b6ee6 100644 --- a/Rocket.Chat/Resources/de.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/de.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Foto & Video Mediathek"; "chat.upload.import_file" = "Importiere Datei aus"; "chat.upload.draw" = "Bild malen"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "Wird heruntergeladen \"%@\""; diff --git a/Rocket.Chat/Resources/el.lproj/Localizable.strings b/Rocket.Chat/Resources/el.lproj/Localizable.strings index 421952a8cf..00de4ff520 100644 --- a/Rocket.Chat/Resources/el.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/el.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Επιλέξτε από τη Βιβλιοθήκη"; "chat.upload.import_file" = "Εισαγωγή Αρχείου Από"; "chat.upload.draw" = "Σχεδιάστε κάτι"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "Κατεβάζουμε \"%@\""; diff --git a/Rocket.Chat/Resources/en.lproj/Localizable.strings b/Rocket.Chat/Resources/en.lproj/Localizable.strings index c00d96c4f2..367b3a53db 100644 --- a/Rocket.Chat/Resources/en.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/en.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Choose from library"; "chat.upload.import_file" = "Attach files"; "chat.upload.draw" = "Draw something"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; +"location.send_location" = "Send this location"; +"location.title" = "Location"; +"maps.open_external_error" = "Unable to open application"; +"maps.choose_application" = "Choose an application"; +"maps.me" = "Me"; +"location_disabled.title" = "Location Sharing Disabled"; +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; // Chat Download "chat.download.downloading_file" = "Downloading \"%@\""; diff --git a/Rocket.Chat/Resources/es.lproj/Localizable.strings b/Rocket.Chat/Resources/es.lproj/Localizable.strings index 145f7406b2..b67e8e2a60 100644 --- a/Rocket.Chat/Resources/es.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/es.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Elige de la biblioteca"; "chat.upload.import_file" = "Importar archivo desde"; "chat.upload.draw" = "Dibujar algo"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "Descargando \"%@\""; diff --git a/Rocket.Chat/Resources/fr.lproj/Localizable.strings b/Rocket.Chat/Resources/fr.lproj/Localizable.strings index 721a24ba02..e67676a1b4 100644 --- a/Rocket.Chat/Resources/fr.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/fr.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Choisir dans les photos"; "chat.upload.import_file" = "Importer un fichier depuis..."; "chat.upload.draw" = "Dessiner quelque chose"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "Téléchargement de \"%@\""; diff --git a/Rocket.Chat/Resources/it.lproj/Localizable.strings b/Rocket.Chat/Resources/it.lproj/Localizable.strings index 46a81a4bf0..fccb8f37a4 100644 --- a/Rocket.Chat/Resources/it.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/it.lproj/Localizable.strings @@ -250,6 +250,17 @@ "chat.upload.choose_from_library" = "Scegliere dalla libreria"; "chat.upload.import_file" = "Aggiungere dei documenti"; "chat.upload.draw" = "Disegnare qualcosa"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "Scarico \"%@\""; diff --git a/Rocket.Chat/Resources/ja.lproj/Localizable.strings b/Rocket.Chat/Resources/ja.lproj/Localizable.strings index d013927885..6a04f0bd03 100644 --- a/Rocket.Chat/Resources/ja.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/ja.lproj/Localizable.strings @@ -250,6 +250,17 @@ "chat.upload.choose_from_library" = "ライブラリから選択"; "chat.upload.import_file" = "添付ファイル"; "chat.upload.draw" = "絵を描く"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "\"%@\" ダウンロード"; diff --git a/Rocket.Chat/Resources/pl.lproj/Localizable.strings b/Rocket.Chat/Resources/pl.lproj/Localizable.strings index 2891c47105..486a586b4b 100644 --- a/Rocket.Chat/Resources/pl.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/pl.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Wybierz plik z biblioteki"; "chat.upload.import_file" = "Importuj plik z"; "chat.upload.draw" = "Narysuj obrazek"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "Pobieranie \"%@\""; diff --git a/Rocket.Chat/Resources/pt-BR.lproj/Localizable.strings b/Rocket.Chat/Resources/pt-BR.lproj/Localizable.strings index f596b6d19f..1faec75724 100644 --- a/Rocket.Chat/Resources/pt-BR.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/pt-BR.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Escolher da biblioteca"; "chat.upload.import_file" = "Importar arquivos"; "chat.upload.draw" = "Desenhar algo"; +"chat.upload.location" = "Partilhar localização"; + +// Location Share +"location.loading" = "Carregando..."; +"location.send_location" = "Enviar esta localização"; +"location.title" = "Localização"; +"maps.open_external_error" = "Erro ao abrir a aplicação"; +"maps.choose_application" = "Escolha uma aplicação"; +"maps.me" = "Eu"; +"location_disabled.title" = "Serviços de localização desactivados"; +"location_disabled.message" = "Os serviços de localização estão desactivados para o RocketChat. Por favor active-os nas configurações do aparelho."; // Chat Download "chat.download.downloading_file" = "Baixando \"%@\""; diff --git a/Rocket.Chat/Resources/pt-PT.lproj/Localizable.strings b/Rocket.Chat/Resources/pt-PT.lproj/Localizable.strings index 3cdec41577..5e12b15c59 100644 --- a/Rocket.Chat/Resources/pt-PT.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/pt-PT.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Escolher da biblioteca"; "chat.upload.import_file" = "Anexar ficheiros"; "chat.upload.draw" = "Desenhe algo"; +"chat.upload.location" = "Partilhar localização"; + +// Location Share +"location.loading" = "Carregando..."; +"location.send_location" = "Enviar esta localização"; +"location.title" = "Localização"; +"maps.open_external_error" = "Erro ao abrir a aplicação"; +"maps.choose_application" = "Escolha uma aplicação"; +"maps.me" = "Eu"; +"location_disabled.title" = "Serviços de localização desactivados"; +"location_disabled.message" = "Os serviços de localização estão desactivados para o RocketChat. Por favor active-os nas configurações do aparelho."; // Chat Download "chat.download.downloading_file" = "Descarregando \"%@\""; diff --git a/Rocket.Chat/Resources/ru.lproj/Localizable.strings b/Rocket.Chat/Resources/ru.lproj/Localizable.strings index a14a64498f..075a70c803 100644 --- a/Rocket.Chat/Resources/ru.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/ru.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "Выбрать из библиотеки"; "chat.upload.import_file" = "Прикрепить файлы"; "chat.upload.draw" = "Нарисовать что-нибудь"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "Загрузки \"%@\""; diff --git a/Rocket.Chat/Resources/zh-Hans.lproj/Localizable.strings b/Rocket.Chat/Resources/zh-Hans.lproj/Localizable.strings index 3265b83430..134048b555 100644 --- a/Rocket.Chat/Resources/zh-Hans.lproj/Localizable.strings +++ b/Rocket.Chat/Resources/zh-Hans.lproj/Localizable.strings @@ -249,6 +249,17 @@ "chat.upload.choose_from_library" = "从图库选择"; "chat.upload.import_file" = "附件"; "chat.upload.draw" = "手绘画图"; +"chat.upload.location" = "Share location"; // TODO + +// Location Share +"location.loading" = "Loading..."; // TODO +"location.send_location" = "Send this location"; // TODO +"location.title" = "Location"; // TODO +"maps.open_external_error" = "Unable to open application"; // TODO +"maps.choose_application" = "Choose an application"; // TODO +"maps.me" = "Me"; // TODO +"location_disabled.title" = "Location Sharing Disabled"; //TODO +"location_disabled.message" = "Location sharing isn't enabled for RocketChat. Please enable it first on your phone settings."; //TODO // Chat Download "chat.download.downloading_file" = "下载中\"%@\""; diff --git a/Rocket.Chat/Storyboards/Location.storyboard b/Rocket.Chat/Storyboards/Location.storyboard new file mode 100644 index 0000000000..cf8da38e8d --- /dev/null +++ b/Rocket.Chat/Storyboards/Location.storyboard @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rocket.Chat/Views/Avatar/AvatarView.swift b/Rocket.Chat/Views/Avatar/AvatarView.swift index d9b5bdee5e..07d80ffed5 100644 --- a/Rocket.Chat/Views/Avatar/AvatarView.swift +++ b/Rocket.Chat/Views/Avatar/AvatarView.swift @@ -49,6 +49,11 @@ final class AvatarView: UIView { } } + override func layoutSubviews() { + super.layoutSubviews() + self.layer.cornerRadius = self.frame.size.width / 2 + } + func updateAvatar() { if let emoji = emoji { let emojiCharacter = Emojione.transform(string: emoji) diff --git a/Rocket.Chat/Views/Cells/Chat/ChatMessageURLView.swift b/Rocket.Chat/Views/Cells/Chat/ChatMessageURLView.swift index 1bea66a382..1ec1611adb 100644 --- a/Rocket.Chat/Views/Cells/Chat/ChatMessageURLView.swift +++ b/Rocket.Chat/Views/Cells/Chat/ChatMessageURLView.swift @@ -9,7 +9,7 @@ import UIKit protocol ChatMessageURLViewProtocol: class { - func openURLFromCell(url: String) + func openURLFromCell(url: String, username: String) } final class ChatMessageURLView: UIView { diff --git a/Rocket.Chat/Views/Chat/New Chat/Cells/LocationCell.swift b/Rocket.Chat/Views/Chat/New Chat/Cells/LocationCell.swift new file mode 100644 index 0000000000..8e4c345cdd --- /dev/null +++ b/Rocket.Chat/Views/Chat/New Chat/Cells/LocationCell.swift @@ -0,0 +1,116 @@ +// +// LocationCell.swift +// Rocket.Chat +// +// Created by Luís Machado on 06/02/2019. +// Copyright © 2019 Rocket.Chat. All rights reserved. +// + +import UIKit +import RocketChatViewController +import MapKit + +final class LocationCell: BaseMessageCell, SizingCell { + static let identifier = String(describing: LocationCell.self) + + static let sizingCell: UICollectionViewCell & ChatCell = { + guard let cell = LocationCell.instantiateFromNib() else { + return LocationCell() + } + + return cell + }() + + @IBOutlet weak var containerView: UIView! { + didSet { + containerView.layer.borderWidth = 1 + containerView.layer.cornerRadius = 4 + } + } + + @IBOutlet weak var title: UILabel! + @IBOutlet weak var subtitle: UILabel! + @IBOutlet weak var thumbnail: UIImageView! + @IBOutlet weak var activityIndicator: UIActivityIndicatorView! + @IBOutlet weak var host: UILabel! + + @IBOutlet weak var thumbnailHeightConstraint: NSLayoutConstraint! + @IBOutlet weak var containerWidthConstraint: NSLayoutConstraint! + @IBOutlet weak var containerLeadingConstraint: NSLayoutConstraint! + @IBOutlet weak var containerTrailingConstraint: NSLayoutConstraint! + var containerWidth: CGFloat { + return + messageWidth - + containerLeadingConstraint.constant - + containerTrailingConstraint.constant - + layoutMargins.left - + layoutMargins.right + } + + var thumbnailHeightInitialConstant: CGFloat = 0 + + override func prepareForReuse() { + super.prepareForReuse() + thumbnail.image = nil + host.text = "" + subtitle.text = "" + } + + override func awakeFromNib() { + super.awakeFromNib() + + thumbnailHeightInitialConstant = thumbnailHeightConstraint.constant + + let gesture = UITapGestureRecognizer(target: self, action: #selector(didTapContainerView)) + gesture.delegate = self + containerView.addGestureRecognizer(gesture) + + insertGesturesIfNeeded(with: nil) + } + + override func configure(completeRendering: Bool) { + guard let viewModel = viewModel?.base as? LocationChatItem else { + return + } + + containerWidthConstraint.constant = containerWidth + + // Generate map + if viewModel.coordinates.latitude != 0 && viewModel.coordinates.longitude != 0 { + thumbnailHeightConstraint.constant = thumbnailHeightInitialConstant + activityIndicator.startAnimating() + viewModel.generateImage {[weak self] (image) in + self?.thumbnail.image = image + self?.activityIndicator.stopAnimating() + } + } else { + thumbnailHeightConstraint.constant = 0 + } + + host.text = viewModel.shortAddress + subtitle.text = viewModel.longAdress + } + + @objc func didTapContainerView() { + guard + let viewModel = viewModel, + let locationChatItemItem = viewModel.base as? LocationChatItem + else { + return + } + + delegate?.openURLFromCell(url: locationChatItemItem.url, username: locationChatItemItem.message?.user?.username ?? "") + } +} + +extension LocationCell { + override func applyTheme() { + super.applyTheme() + + let theme = self.theme ?? .light + containerView.backgroundColor = theme.chatComponentBackground + host.textColor = theme.auxiliaryText + subtitle.textColor = theme.controlText + containerView.layer.borderColor = theme.borderColor.cgColor + } +} diff --git a/Rocket.Chat/Views/Chat/New Chat/Cells/LocationCell.xib b/Rocket.Chat/Views/Chat/New Chat/Cells/LocationCell.xib new file mode 100644 index 0000000000..4314793b3b --- /dev/null +++ b/Rocket.Chat/Views/Chat/New Chat/Cells/LocationCell.xib @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rocket.Chat/Views/Chat/New Chat/Cells/MessageURLCell.swift b/Rocket.Chat/Views/Chat/New Chat/Cells/MessageURLCell.swift index 3ff76c3f46..95aaa16d1a 100644 --- a/Rocket.Chat/Views/Chat/New Chat/Cells/MessageURLCell.swift +++ b/Rocket.Chat/Views/Chat/New Chat/Cells/MessageURLCell.swift @@ -93,7 +93,7 @@ final class MessageURLCell: BaseMessageCell, SizingCell { return } - delegate?.openURLFromCell(url: messageURLChatItem.url) + delegate?.openURLFromCell(url: messageURLChatItem.url, username: "") } } diff --git a/Rocket.Chat/Views/Chat/New Chat/ChatItems/LocationChatItem.swift b/Rocket.Chat/Views/Chat/New Chat/ChatItems/LocationChatItem.swift new file mode 100644 index 0000000000..51a4e1bb77 --- /dev/null +++ b/Rocket.Chat/Views/Chat/New Chat/ChatItems/LocationChatItem.swift @@ -0,0 +1,125 @@ +// +// LocationChatItem.swift +// Rocket.Chat +// +// Created by Luís Machado on 06/02/2019. +// Copyright © 2019 Rocket.Chat. All rights reserved. +// + +import Foundation +import DifferenceKit +import RocketChatViewController +import MapKit + +extension String { + func getCoordinates() -> CLLocationCoordinate2D { + var coordinates: CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 0, longitude: 0) + let coordinatesText = self.replacingOccurrences(of: "https://maps.google.com/?q=", with: "") + + let splitCoordinates = coordinatesText.split(separator: ",") + if splitCoordinates.count == 2, let latitude = Double(splitCoordinates[0]), let longitude = Double(splitCoordinates[1]) { + coordinates = CLLocationCoordinate2D(latitude: latitude, longitude: longitude) + } + + return coordinates + } +} + +final class LocationChatItem: BaseMessageChatItem, ChatItem, Differentiable { + var relatedReuseIdentifier: String { + return LocationCell.identifier + } + + var url: String + var coordinates: CLLocationCoordinate2D + var shortAddress: String + var longAdress: String + + init(url: String, title: String, message: UnmanagedMessage?) { + + self.url = url + self.coordinates = url.getCoordinates() + self.shortAddress = "" + self.longAdress = "" + let completeAddress = title.replacingOccurrences(of: "\n\(url)", with: "") + + let splitAddresses = completeAddress.split(separator: "\n") + + if splitAddresses.count <= 1 { + let addressParts = completeAddress.split(separator: ",") + if addressParts.count > 0 { + self.shortAddress = String(addressParts[0]) + } + + self.longAdress = completeAddress + } else if splitAddresses.count == 2 { + self.shortAddress = String(splitAddresses[0]) + self.longAdress = String(splitAddresses[1]) + } + + super.init(user: nil, message: message) + } + + func generateImage(completion: @escaping (UIImage?) -> Void) { + let mapSnapshotOptions = MKMapSnapshotter.Options() + + let span = MKCoordinateSpan(latitudeDelta: 0.008, longitudeDelta: 0.006) + let region = MKCoordinateRegion(center: coordinates, span: span) + + // Set the region of the map that is rendered. + mapSnapshotOptions.region = region + + // Set the scale of the image. We'll just use the scale of the current device, which is 2x scale on Retina screens. + mapSnapshotOptions.scale = UIScreen.main.scale + + // Set the size of the image output. + mapSnapshotOptions.size = CGSize(width: 300, height: 300) + + // Show buildings and Points of Interest on the snapshot + mapSnapshotOptions.showsBuildings = true + mapSnapshotOptions.showsPointsOfInterest = true + + let snapShotter = MKMapSnapshotter(options: mapSnapshotOptions) + let rect = CGRect(x: 0, y: 0, width: 300, height: 300) + + snapShotter.start { (snapshot, error) in + guard let snapshot = snapshot, error == nil else { + completion(nil) + return + } + + UIGraphicsBeginImageContextWithOptions(mapSnapshotOptions.size, true, 0) + snapshot.image.draw(at: .zero) + + let pinView = MKPinAnnotationView(annotation: nil, reuseIdentifier: nil) + let pinImage = pinView.image + + var point = snapshot.point(for: self.coordinates) + + if rect.contains(point) { + let pinCenterOffset = pinView.centerOffset + point.x -= pinView.bounds.size.width / 2 + point.y -= pinView.bounds.size.height / 2 + point.x += pinCenterOffset.x + point.y += pinCenterOffset.y + pinImage?.draw(at: point) + } + + let image = UIGraphicsGetImageFromCurrentImageContext() + + UIGraphicsEndImageContext() + + completion(image) + } + } + + var differenceIdentifier: String { + return url + } + + func isContentEqual(to source: LocationChatItem) -> Bool { + return shortAddress == source.shortAddress && + longAdress == source.longAdress && + url == source.url + } +}