diff --git a/Telegram/Resources/picker_html/picker.js b/Telegram/Resources/picker_html/picker.js index 6a35060f00..54eb60abae 100644 --- a/Telegram/Resources/picker_html/picker.js +++ b/Telegram/Resources/picker_html/picker.js @@ -37,17 +37,21 @@ var LocationPicker = { document.getElementsByTagName('html')[0].style = styles; } }, - init: function (token, center, bounds) { - mapboxgl.accessToken = token; + init: function (params) { + mapboxgl.accessToken = params.token; + if (params.protocol) { + mapboxgl.config.API_URL = params.protocol + '://domain/api.mapbox.com'; + } var options = { container: 'map' }; + var center = params.center; if (center) { center = [center[1], center[0]]; options.center = center; options.zoom = LocationPicker.startZoom; - } else if (bounds) { - options.bounds = bounds; - center = new mapboxgl.LngLatBounds(bounds).getCenter(); + } else if (params.bounds) { + options.bounds = params.bounds; + center = new mapboxgl.LngLatBounds(params.bounds).getCenter(); } else { center = [0, 0]; } diff --git a/Telegram/SourceFiles/core/current_geo_location.cpp b/Telegram/SourceFiles/core/current_geo_location.cpp index 295bde8244..eb2125bf54 100644 --- a/Telegram/SourceFiles/core/current_geo_location.cpp +++ b/Telegram/SourceFiles/core/current_geo_location.cpp @@ -40,7 +40,7 @@ GeoLocation ResolveCurrentCountryLocation() { void ResolveCurrentGeoLocation(Fn callback) { using namespace Platform; return ResolveCurrentExactLocation([done = std::move(callback)]( - GeoLocation result) { + GeoLocation result) { done(result.accuracy != GeoLocationAccuracy::Failed ? result : ResolveCurrentCountryLocation()); diff --git a/Telegram/SourceFiles/platform/mac/current_geo_location_mac.mm b/Telegram/SourceFiles/platform/mac/current_geo_location_mac.mm index 03bf727ede..2812a0c333 100644 --- a/Telegram/SourceFiles/platform/mac/current_geo_location_mac.mm +++ b/Telegram/SourceFiles/platform/mac/current_geo_location_mac.mm @@ -9,10 +9,111 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/current_geo_location.h" +#include + +@interface LocationDelegate : NSObject + +- (id) initWithCallback:(Fn)callback; +- (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations; +- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error; +- (void) locationManager:(CLLocationManager *) manager didChangeAuthorizationStatus:(CLAuthorizationStatus) status; +- (void) dealloc; + +@end + +@implementation LocationDelegate { +CLLocationManager *_manager; +Fn _callback; +} + +- (void) fail { + [_manager stopUpdatingLocation]; + + const auto onstack = _callback; + [self release]; + + onstack({}); +} + +- (void) processWithStatus:(CLAuthorizationStatus)status { + switch (status) { + case kCLAuthorizationStatusNotDetermined: + if (@available(macOS 10.15, *)) { + [_manager requestWhenInUseAuthorization]; + } else { + [_manager startUpdatingLocation]; + } + break; + case kCLAuthorizationStatusAuthorizedAlways: + [_manager startUpdatingLocation]; + return; + case kCLAuthorizationStatusRestricted: + case kCLAuthorizationStatusDenied: + default: + [self fail]; + return; + } +} + +- (id) initWithCallback:(Fn)callback { + if (self = [super init]) { + _callback = std::move(callback); + _manager = [[CLLocationManager alloc] init]; + _manager.desiredAccuracy = kCLLocationAccuracyThreeKilometers; + _manager.delegate = self; + if ([CLLocationManager locationServicesEnabled]) { + if (@available(macOS 11, *)) { + [self processWithStatus:[_manager authorizationStatus]]; + } else { + [self processWithStatus:[CLLocationManager authorizationStatus]]; + } + } else { + [self fail]; + } + } + return self; +} + +- (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray*)locations { + [_manager stopUpdatingLocation]; + + auto result = Core::GeoLocation(); + if ([locations count] > 0) { + const auto coordinate = [locations lastObject].coordinate; + result.accuracy = Core::GeoLocationAccuracy::Exact; + result.point = QPointF(coordinate.latitude, coordinate.longitude); + } + + const auto onstack = _callback; + [self release]; + + onstack(result); +} + +- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { + if (error.code != kCLErrorLocationUnknown) { + [self fail]; + } +} + +- (void) locationManager:(CLLocationManager *) manager didChangeAuthorizationStatus:(CLAuthorizationStatus) status { + [self processWithStatus:status]; +} + +- (void) dealloc { + if (_manager) { + _manager.delegate = nil; + [_manager release]; + } + [super dealloc]; +} + +@end + namespace Platform { void ResolveCurrentExactLocation(Fn callback) { - callback({}); + [[LocationDelegate alloc] initWithCallback:std::move(callback)]; } } // namespace Platform diff --git a/Telegram/SourceFiles/ui/controls/location_picker.cpp b/Telegram/SourceFiles/ui/controls/location_picker.cpp index 21c5b9861d..804593b077 100644 --- a/Telegram/SourceFiles/ui/controls/location_picker.cpp +++ b/Telegram/SourceFiles/ui/controls/location_picker.cpp @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "styles/style_dialogs.h" #include "styles/style_window.h" +#include #include #include #include @@ -27,6 +28,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Ui { namespace { +#ifdef Q_OS_MAC +const auto kProtocolOverride = "mapboxapihelper"; +#else // Q_OS_MAC +const auto kProtocolOverride = ""; +#endif // Q_OS_MAC + Core::GeoLocation LastExactLocation; QString MapsProviderToken; @@ -35,9 +42,9 @@ QString MapsProviderToken; return "null"; } return "["_q - + QByteArray::number(LastExactLocation.point.x() - 1) + + QByteArray::number(LastExactLocation.point.x()) + ","_q - + QByteArray::number(LastExactLocation.point.y() - 1) + + QByteArray::number(LastExactLocation.point.y()) + "]"_q; } @@ -189,6 +196,7 @@ void LocationPicker::setupWebview(const Descriptor &descriptor) { Webview::WindowConfig{ .opaqueBg = st::windowBg->c, .storageId = descriptor.storageId, + .dataProtocolOverride = kProtocolOverride, }); const auto raw = _webview.get(); @@ -293,18 +301,25 @@ void LocationPicker::initMap() { const auto token = MapsProviderToken.toUtf8(); const auto center = DefaultCenter(); const auto bounds = DefaultBounds(); - const auto arguments = "'" + token + "', " + center + ", " + bounds; - _webview->eval("LocationPicker.init(" + arguments + ");"); + const auto protocol = *kProtocolOverride + ? "'"_q + kProtocolOverride + "'" + : "null"; + const auto params = "token: '" + token + "'" + + ", center: " + center + + ", bounds: " + bounds + + ", protocol: " + protocol; + _webview->eval("LocationPicker.init({ " + params + " });"); } void LocationPicker::resolveCurrentLocation() { using namespace Core; const auto window = _window.get(); ResolveCurrentGeoLocation(crl::guard(window, [=](GeoLocation location) { - if (location) { - LastExactLocation = location; + if (location.accuracy != GeoLocationAccuracy::Exact) { + return; } - if (_webview && location.accuracy == GeoLocationAccuracy::Exact) { + LastExactLocation = location; + if (_webview) { const auto point = QByteArray::number(location.point.x()) + ","_q + QByteArray::number(location.point.y()); @@ -327,7 +342,10 @@ void LocationPicker::processKey( } void LocationPicker::close() { - _window->close(); + crl::on_main(this, [=] { + _window = nullptr; + delete this; + }); } void LocationPicker::minimize() { diff --git a/Telegram/Telegram.plist b/Telegram/Telegram.plist index 53b8daf8b9..b68e2109c5 100644 --- a/Telegram/Telegram.plist +++ b/Telegram/Telegram.plist @@ -12,12 +12,20 @@ Icon.icns CFBundleIdentifier @bundle_identifier_plist@ + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + @output_name@ CFBundlePackageType APPL CFBundleShortVersionString @desktop_app_version_string@ CFBundleSignature ???? + CFBundleSupportedPlatforms + + MacOSX + CFBundleURLTypes @@ -39,16 +47,18 @@ LSApplicationCategoryType public.app-category.social-networking - LSMinimumSystemVersion - @CMAKE_OSX_DEPLOYMENT_TARGET@ LSFileQuarantineEnabled + LSMinimumSystemVersion + @CMAKE_OSX_DEPLOYMENT_TARGET@ NOTE NSMicrophoneUsageDescription We need access to your microphone so that you can record voice messages and make calls. NSCameraUsageDescription We need access to your camera so that you can record video messages and make video calls. + NSLocationUsageDescription + We need access to your location so that you can send your current locations. NSPrincipalClass NSApplication NSSupportsAutomaticGraphicsSwitching diff --git a/Telegram/Telegram/Telegram Lite.entitlements b/Telegram/Telegram/Telegram Lite.entitlements index 46355b637b..050eea08f0 100644 --- a/Telegram/Telegram/Telegram Lite.entitlements +++ b/Telegram/Telegram/Telegram Lite.entitlements @@ -18,5 +18,7 @@ com.apple.security.device.camera + com.apple.security.personal-information.location + diff --git a/Telegram/Telegram/Telegram.entitlements b/Telegram/Telegram/Telegram.entitlements index 97c1f6d587..af28832209 100644 --- a/Telegram/Telegram/Telegram.entitlements +++ b/Telegram/Telegram/Telegram.entitlements @@ -6,5 +6,7 @@ com.apple.security.device.camera + com.apple.security.personal-information.location + diff --git a/cmake b/cmake index 4a4bc4cd34..78b441c9c6 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 4a4bc4cd34b3ade038541a2b8b2c79f05393d67b +Subproject commit 78b441c9c6ad8a14a8f97a28825babcadc6bf781