Implement location sending on macOS.
This commit is contained in:
parent
2a5071b66c
commit
025ab40687
8 changed files with 155 additions and 18 deletions
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ GeoLocation ResolveCurrentCountryLocation() {
|
|||
void ResolveCurrentGeoLocation(Fn<void(GeoLocation)> callback) {
|
||||
using namespace Platform;
|
||||
return ResolveCurrentExactLocation([done = std::move(callback)](
|
||||
GeoLocation result) {
|
||||
GeoLocation result) {
|
||||
done(result.accuracy != GeoLocationAccuracy::Failed
|
||||
? result
|
||||
: ResolveCurrentCountryLocation());
|
||||
|
|
|
@ -9,10 +9,111 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
#include "core/current_geo_location.h"
|
||||
|
||||
#include <CoreLocation/CoreLocation.h>
|
||||
|
||||
@interface LocationDelegate : NSObject<CLLocationManagerDelegate>
|
||||
|
||||
- (id) initWithCallback:(Fn<void(Core::GeoLocation)>)callback;
|
||||
- (void) locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations;
|
||||
- (void) locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;
|
||||
- (void) locationManager:(CLLocationManager *) manager didChangeAuthorizationStatus:(CLAuthorizationStatus) status;
|
||||
- (void) dealloc;
|
||||
|
||||
@end
|
||||
|
||||
@implementation LocationDelegate {
|
||||
CLLocationManager *_manager;
|
||||
Fn<void(Core::GeoLocation)> _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<void(Core::GeoLocation)>)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<CLLocation*>*)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<void(Core::GeoLocation)> callback) {
|
||||
callback({});
|
||||
[[LocationDelegate alloc] initWithCallback:std::move(callback)];
|
||||
}
|
||||
|
||||
} // namespace Platform
|
||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QJsonDocument>
|
||||
#include <QtCore/QJsonObject>
|
||||
#include <QtCore/QJsonValue>
|
||||
|
@ -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() {
|
||||
|
|
|
@ -12,12 +12,20 @@
|
|||
<string>Icon.icns</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>@bundle_identifier_plist@</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>@output_name@</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>@desktop_app_version_string@</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleSupportedPlatforms</key>
|
||||
<array>
|
||||
<string>MacOSX</string>
|
||||
</array>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
@ -39,16 +47,18 @@
|
|||
<false/>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.social-networking</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>@CMAKE_OSX_DEPLOYMENT_TARGET@</string>
|
||||
<key>LSFileQuarantineEnabled</key>
|
||||
<true/>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>@CMAKE_OSX_DEPLOYMENT_TARGET@</string>
|
||||
<key>NOTE</key>
|
||||
<string></string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>We need access to your microphone so that you can record voice messages and make calls.</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>We need access to your camera so that you can record video messages and make video calls.</string>
|
||||
<key>NSLocationUsageDescription</key>
|
||||
<string>We need access to your location so that you can send your current locations.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSSupportsAutomaticGraphicsSwitching</key>
|
||||
|
|
|
@ -18,5 +18,7 @@
|
|||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.location</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -6,5 +6,7 @@
|
|||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.location</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
2
cmake
2
cmake
|
@ -1 +1 @@
|
|||
Subproject commit 4a4bc4cd34b3ade038541a2b8b2c79f05393d67b
|
||||
Subproject commit 78b441c9c6ad8a14a8f97a28825babcadc6bf781
|
Loading…
Reference in a new issue