diff --git a/Telegram/Resources/picker_html/picker.js b/Telegram/Resources/picker_html/picker.js index 6a35060f0..54eb60aba 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 295bde824..eb2125bf5 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 03bf727ed..2812a0c33 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 21c5b9861..804593b07 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 53b8daf8b..b68e2109c 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 46355b637..050eea08f 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 97c1f6d58..af2883220 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 4a4bc4cd3..78b441c9c 160000 --- a/cmake +++ b/cmake @@ -1 +1 @@ -Subproject commit 4a4bc4cd34b3ade038541a2b8b2c79f05393d67b +Subproject commit 78b441c9c6ad8a14a8f97a28825babcadc6bf781