mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
219 lines
10 KiB
Swift
219 lines
10 KiB
Swift
import UIKit
|
|
import TelegramCore
|
|
import CoreLocation
|
|
import MapKit
|
|
|
|
enum OpenInItem {
|
|
case url(_ url: String)
|
|
case location(_ location: TelegramMediaMap, withDirections: Bool)
|
|
}
|
|
|
|
enum OpenInApplication {
|
|
case safari
|
|
case maps
|
|
case other(title: String, identifier: Int64, scheme: String)
|
|
}
|
|
|
|
enum OpenInAction {
|
|
case openUrl(_ url: String)
|
|
case openLocation(latitude: Double, longitude: Double, withDirections: Bool)
|
|
}
|
|
|
|
final class OpenInOption {
|
|
let application: OpenInApplication
|
|
let action: () -> OpenInAction
|
|
|
|
init(application: OpenInApplication, action: @escaping () -> OpenInAction) {
|
|
self.application = application
|
|
self.action = action
|
|
}
|
|
|
|
var title: String {
|
|
get {
|
|
switch self.application {
|
|
case .safari:
|
|
return "Safari"
|
|
case .maps:
|
|
return "Maps"
|
|
case let .other(title, _, _):
|
|
return title
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func availableOpenInOptions(applicationContext: TelegramApplicationContext, item: OpenInItem) -> [OpenInOption] {
|
|
return allOpenInOptions(applicationContext: applicationContext, item: item).filter { option in
|
|
if case let .other(_, _, scheme) = option.application {
|
|
return applicationContext.applicationBindings.canOpenUrl("\(scheme)://")
|
|
} else {
|
|
return true
|
|
}
|
|
}
|
|
}
|
|
|
|
private func allOpenInOptions(applicationContext: TelegramApplicationContext, item: OpenInItem) -> [OpenInOption] {
|
|
var options: [OpenInOption] = []
|
|
switch item {
|
|
case let .url(url):
|
|
options.append(OpenInOption(application: .safari, action: {
|
|
return .openUrl(url)
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Chrome", identifier: 535886823, scheme: "chrome"), action: {
|
|
// NSURL *url = (NSURL *)self.object;
|
|
// NSString *scheme = [url.scheme lowercaseString];
|
|
//
|
|
// bool secure = [scheme isEqualToString:@"https"];
|
|
// if (!secure && ![scheme isEqualToString:@"http"])
|
|
// return;
|
|
//
|
|
// NSURL *openInURL = nil;
|
|
// if (iosMajorVersion() >= 7)
|
|
// {
|
|
// NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true];
|
|
// components.scheme = secure ? @"googlechromes" : @"googlechrome";
|
|
// openInURL = components.URL;
|
|
// }
|
|
// else
|
|
// {
|
|
// NSString *str = url.absoluteString;
|
|
// NSInteger colon = [str rangeOfString:@":"].location;
|
|
// if (colon != NSNotFound)
|
|
// str = [(secure ? @"googlechromes" : @"googlechrome") stringByAppendingString:[str substringFromIndex:colon]];
|
|
// openInURL = [NSURL URLWithString:str];
|
|
// }
|
|
|
|
return .openUrl(url)
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Firefox", identifier: 989804926, scheme: "firefox"), action: {
|
|
// NSURL *url = (NSURL *)self.object;
|
|
// NSString *scheme = [url.scheme lowercaseString];
|
|
//
|
|
// if (![scheme isEqualToString:@"http"] && ![scheme isEqualToString:@"https"])
|
|
// return;
|
|
//
|
|
// NSURL *openInURL = [NSURL URLWithString:[NSString stringWithFormat:@"firefox://open-url?url=%@", [TGStringUtils stringByEscapingForURL:url.absoluteString]]];
|
|
// [TGOpenInBrowserItem openURL:openInURL];
|
|
|
|
return .openUrl(url)
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Opera Mini", identifier: 363729560, scheme: "opera-http"), action: {
|
|
// bool secure = [scheme isEqualToString:@"https"];
|
|
// if (!secure && ![scheme isEqualToString:@"http"])
|
|
// return;
|
|
//
|
|
// NSURL *openInURL = nil;
|
|
// if (iosMajorVersion() >= 7)
|
|
// {
|
|
// NSURLComponents *components = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:true];
|
|
// components.scheme = secure ? @"opera-https" : @"opera-http";
|
|
// openInURL = components.URL;
|
|
// }
|
|
// else
|
|
// {
|
|
// NSString *str = url.absoluteString;
|
|
// NSInteger colon = [str rangeOfString:@":"].location;
|
|
// if (colon != NSNotFound)
|
|
// str = [(secure ? @"opera-https" : @"opera-http") stringByAppendingString:[str substringFromIndex:colon]];
|
|
// openInURL = [NSURL URLWithString:str];
|
|
// }
|
|
return .openUrl(url)
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Yandex", identifier: 483693909, scheme: "yandexbrowser-open-url"), action: {
|
|
// NSURL *url = (NSURL *)self.object;
|
|
// NSString *scheme = [url.scheme lowercaseString];
|
|
//
|
|
// if (![scheme isEqualToString:@"http"] && ![scheme isEqualToString:@"https"])
|
|
// return;
|
|
//
|
|
// NSURL *openInURL = [NSURL URLWithString:[NSString stringWithFormat:@"yandexbrowser-open-url://%@", [TGStringUtils stringByEscapingForURL:url.absoluteString]]];
|
|
// [TGOpenInBrowserItem openURL:openInURL];
|
|
return .openUrl(url)
|
|
}))
|
|
|
|
|
|
case let .location(location, withDirections):
|
|
let lat = location.latitude
|
|
let lon = location.longitude
|
|
|
|
if let venue = location.venue, let venueId = venue.id, let provider = venue.provider, provider == "foursquare" {
|
|
options.append(OpenInOption(application: .other(title: "Foursquare", identifier: 306934924, scheme: "foursquare"), action: {
|
|
return .openUrl("foursquare://venues/\(venueId)")
|
|
}))
|
|
}
|
|
|
|
options.append(OpenInOption(application: .maps, action: {
|
|
return .openLocation(latitude: lat, longitude: lon, withDirections: withDirections)
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Google Maps", identifier: 585027354, scheme: "comgooglemaps-x-callback"), action: {
|
|
let coordinates = "\(lat),\(lon)"
|
|
if withDirections {
|
|
return .openUrl("comgooglemaps-x-callback://?daddr=\(coordinates)&directionsmode=driving&x-success=telegram://?resume=true&&x-source=Telegram")
|
|
} else {
|
|
return .openUrl("comgooglemaps-x-callback://?center=\(coordinates)&q=\(coordinates)&x-success=telegram://?resume=true&&x-source=Telegram")
|
|
}
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Yandex.Maps", identifier: 313877526, scheme: "yandexmaps"), action: {
|
|
if withDirections {
|
|
return .openUrl("yandexmaps://build_route_on_map?lat_to=\(lat)&lon_to=\(lon)")
|
|
} else {
|
|
return .openUrl("yandexmaps://maps.yandex.ru/?pt=\(lat),\(lon)&z=16")
|
|
}
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Uber", identifier: 368677368, scheme: "uber"), action: {
|
|
var dropoffName = ""
|
|
var dropoffAddress = ""
|
|
if let title = location.venue?.title.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), title.count > 0 {
|
|
dropoffName = title
|
|
}
|
|
if let address = location.venue?.address?.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), address.count > 0 {
|
|
dropoffAddress = address
|
|
}
|
|
return .openUrl("uber://?client_id=&action=setPickup&pickup=my_location&dropoff[latitude]=\(lat)&dropoff[longitude]=\(lon)&dropoff[nickname]=\(dropoffName)&dropoff[formatted_address]=\(dropoffAddress)")
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Lyft", identifier: 529379082, scheme: "lyft"), action: {
|
|
return .openUrl("lyft://ridetype?id=lyft&destination[latitude]=\(lat)&destination[longitude]=\(lon)")
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Citymapper", identifier: 469463298, scheme: "citymapper"), action: {
|
|
var endName = ""
|
|
var endAddress = ""
|
|
if let title = location.venue?.title.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), title.count > 0 {
|
|
endName = title
|
|
}
|
|
if let address = location.venue?.address?.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), address.count > 0 {
|
|
endAddress = address
|
|
}
|
|
return .openUrl("citymapper://directions?endcoord=\(lat),\(lon)&endname=\(endName)&endaddress=\(endAddress)")
|
|
}))
|
|
|
|
if withDirections {
|
|
options.append(OpenInOption(application: .other(title: "Yandex.Navi", identifier: 474500851, scheme: "yandexnavi"), action: {
|
|
return .openUrl("yandexnavi://build_route_on_map?lat_to=\(lat)&lon_to=\(lon)")
|
|
}))
|
|
}
|
|
|
|
options.append(OpenInOption(application: .other(title: "HERE Maps", identifier: 955837609, scheme: "here-location"), action: {
|
|
return .openUrl("here-location://\(lat),\(lon)")
|
|
}))
|
|
|
|
options.append(OpenInOption(application: .other(title: "Waze", identifier: 323229106, scheme: "waze"), action: {
|
|
let url = "waze://?ll=\(lat),\(lon)"
|
|
if withDirections {
|
|
return .openUrl(url.appending("&navigate=yes"))
|
|
} else {
|
|
return .openUrl(url)
|
|
}
|
|
}))
|
|
}
|
|
return options
|
|
}
|