diff --git a/Telegram/Resources/picker_html/picker.css b/Telegram/Resources/picker_html/picker.css
index 0c791008d..4d8f378ae 100644
--- a/Telegram/Resources/picker_html/picker.css
+++ b/Telegram/Resources/picker_html/picker.css
@@ -50,7 +50,7 @@ html.custom_scroll ::-webkit-scrollbar-thumb:hover {
}
#marker {
pointer-events: none;
- display: flex;
+ display: none;
z-index: 2;
position: absolute;
width: 100%;
@@ -58,3 +58,13 @@ html.custom_scroll ::-webkit-scrollbar-thumb:hover {
justify-content: center;
align-items: center;
}
+#marker_drop {
+ margin-bottom: 0px;
+ transition: margin 160ms ease-in-out;
+}
+#marker_drop.moving {
+ margin-bottom: 24px;
+}
+#marker_shadow {
+ position: absolute;
+}
diff --git a/Telegram/Resources/picker_html/picker.js b/Telegram/Resources/picker_html/picker.js
index cb936cf0b..27ffd3b6c 100644
--- a/Telegram/Resources/picker_html/picker.js
+++ b/Telegram/Resources/picker_html/picker.js
@@ -70,16 +70,41 @@ var LocationPicker = {
center = [0, 0];
}
LocationPicker.map = new mapboxgl.Map(options);
-
- const marker = new mapboxgl.Marker()
- .setLngLat(center)
- .addTo(LocationPicker.map);
- const drop = document.getElementById('marker_drop');
- const element = marker.getElement();
- drop.innerHTML = element.innerHTML;
- const offset = marker.getOffset();
- drop.style.transform = 'translate(' + offset.x + 'px, ' + offset.y + 'px)';
- marker.remove();
+ LocationPicker.createMarker(center);
+ LocationPicker.trackMovement();
+ },
+ marker: function() {
+ return document.getElementById('marker_drop');
+ },
+ createMarker: function(center) {
+ document.getElementById('marker').style.display = 'flex';
+ },
+ clearMovingTimer: function() {
+ if (LocationPicker.clearMovingTimeoutId) {
+ clearTimeout(LocationPicker.clearMovingTimeoutId);
+ LocationPicker.clearMovingTimeoutId = 0;
+ }
+ },
+ startMovingTimer: function(done) {
+ LocationPicker.clearMovingTimer();
+ LocationPicker.clearMovingTimeoutId = setTimeout(done, 500);
+ },
+ trackMovement: function() {
+ LocationPicker.map.on('movestart', function() {
+ LocationPicker.marker().classList.add('moving');
+ LocationPicker.clearMovingTimer();
+ LocationPicker.notify({ event: 'movestart' });
+ });
+ LocationPicker.map.on('moveend', function() {
+ LocationPicker.startMovingTimer(function() {
+ LocationPicker.marker().classList.remove('moving');
+ LocationPicker.notify({
+ event: 'moveend',
+ latitude: LocationPicker.map.getCenter().lat,
+ longitude: LocationPicker.map.getCenter().lng
+ });
+ });
+ });
},
narrowTo: function (point) {
LocationPicker.map.flyTo({
diff --git a/Telegram/SourceFiles/core/current_geo_location.cpp b/Telegram/SourceFiles/core/current_geo_location.cpp
index b649ea2ea..818ea361a 100644
--- a/Telegram/SourceFiles/core/current_geo_location.cpp
+++ b/Telegram/SourceFiles/core/current_geo_location.cpp
@@ -27,14 +27,51 @@ namespace {
constexpr auto kDestroyManagerTimeout = 20 * crl::time(1000);
+[[nodiscard]] QString ChooseLanguage(const QString &language) {
+ // https://docs.mapbox.com/api/search/geocoding#language-coverage
+ auto result = language.toLower().replace('-', '_');
+ static const auto kGood = std::array{
+ // Global coverage.
+ u"de"_q, u"en"_q, u"es"_q, u"fr"_q, u"it"_q, u"nl"_q, u"pl"_q,
+
+ // Local coverage.
+ u"az"_q, u"bn"_q, u"ca"_q, u"cs"_q, u"da"_q, u"el"_q, u"fa"_q,
+ u"fi"_q, u"ga"_q, u"hu"_q, u"id"_q, u"is"_q, u"ja"_q, u"ka"_q,
+ u"km"_q, u"ko"_q, u"lt"_q, u"lv"_q, u"mn"_q, u"pt"_q, u"ro"_q,
+ u"sk"_q, u"sq"_q, u"sv"_q, u"th"_q, u"tl"_q, u"uk"_q, u"vi"_q,
+ u"zh"_q, u"zh_Hans"_q, u"zh_TW"_q,
+
+ // Limited coverage.
+ u"ar"_q, u"bs"_q, u"gu"_q, u"he"_q, u"hi"_q, u"kk"_q, u"lo"_q,
+ u"my"_q, u"nb"_q, u"ru"_q, u"sr"_q, u"te"_q, u"tk"_q, u"tr"_q,
+ u"zh_Hant"_q,
+ };
+ for (const auto &known : kGood) {
+ if (known.toLower() == result) {
+ return known;
+ }
+ }
+ if (const auto delimeter = result.indexOf('_'); delimeter > 0) {
+ result = result.mid(0, delimeter);
+ for (const auto &known : kGood) {
+ if (known == result) {
+ return known;
+ }
+ }
+ }
+ return u"en"_q;
+}
+
void ResolveLocationAddressGeneric(
const GeoLocation &location,
+ const QString &language,
const QString &token,
Fn callback) {
const auto partialUrl = u"https://api.mapbox.com/search/geocode/v6"
- "/reverse?longitude=%1&latitude=%2&access_token=%3"_q
+ "/reverse?longitude=%1&latitude=%2&language=%3&access_token=%4"_q
.arg(location.point.y())
- .arg(location.point.x());
+ .arg(location.point.x())
+ .arg(ChooseLanguage(language));
static auto Cache = base::flat_map();
const auto i = Cache.find(partialUrl);
if (i != end(Cache)) {
@@ -161,16 +198,21 @@ void ResolveCurrentGeoLocation(Fn callback) {
void ResolveLocationAddress(
const GeoLocation &location,
+ const QString &language,
const QString &token,
Fn callback) {
auto done = [=, done = std::move(callback)](GeoAddress result) mutable {
if (!result && !token.isEmpty()) {
- ResolveLocationAddressGeneric(location, token, std::move(done));
+ ResolveLocationAddressGeneric(
+ location,
+ language,
+ token,
+ std::move(done));
} else {
done(result);
}
};
- Platform::ResolveLocationAddress(location, std::move(done));
+ Platform::ResolveLocationAddress(location, language, std::move(done));
}
} // namespace Core
diff --git a/Telegram/SourceFiles/core/current_geo_location.h b/Telegram/SourceFiles/core/current_geo_location.h
index e3b92222e..dab4ffd00 100644
--- a/Telegram/SourceFiles/core/current_geo_location.h
+++ b/Telegram/SourceFiles/core/current_geo_location.h
@@ -55,6 +55,7 @@ void ResolveCurrentGeoLocation(Fn callback);
void ResolveLocationAddress(
const GeoLocation &location,
+ const QString &language,
const QString &token,
Fn callback);
diff --git a/Telegram/SourceFiles/platform/linux/current_geo_location_linux.cpp b/Telegram/SourceFiles/platform/linux/current_geo_location_linux.cpp
index 6f42c0afd..f87c343d3 100644
--- a/Telegram/SourceFiles/platform/linux/current_geo_location_linux.cpp
+++ b/Telegram/SourceFiles/platform/linux/current_geo_location_linux.cpp
@@ -16,6 +16,7 @@ void ResolveCurrentExactLocation(Fn callback) {
}
void ResolveLocationAddress(
const Core::GeoLocation &location,
+ const QString &language,
Fn callback) {
callback({});
}
diff --git a/Telegram/SourceFiles/platform/mac/current_geo_location_mac.mm b/Telegram/SourceFiles/platform/mac/current_geo_location_mac.mm
index 452bc6e3a..1a5382f19 100644
--- a/Telegram/SourceFiles/platform/mac/current_geo_location_mac.mm
+++ b/Telegram/SourceFiles/platform/mac/current_geo_location_mac.mm
@@ -118,6 +118,7 @@ void ResolveCurrentExactLocation(Fn callback) {
void ResolveLocationAddress(
const Core::GeoLocation &location,
+ const QString &language,
Fn callback) {
callback({});
}
diff --git a/Telegram/SourceFiles/platform/platform_current_geo_location.h b/Telegram/SourceFiles/platform/platform_current_geo_location.h
index 9feb4b376..269ee81f3 100644
--- a/Telegram/SourceFiles/platform/platform_current_geo_location.h
+++ b/Telegram/SourceFiles/platform/platform_current_geo_location.h
@@ -17,6 +17,7 @@ namespace Platform {
void ResolveCurrentExactLocation(Fn callback);
void ResolveLocationAddress(
const Core::GeoLocation &location,
+ const QString &language,
Fn callback);
} // namespace Platform
diff --git a/Telegram/SourceFiles/platform/win/current_geo_location_win.cpp b/Telegram/SourceFiles/platform/win/current_geo_location_win.cpp
index a83dedb88..9c7967588 100644
--- a/Telegram/SourceFiles/platform/win/current_geo_location_win.cpp
+++ b/Telegram/SourceFiles/platform/win/current_geo_location_win.cpp
@@ -61,6 +61,7 @@ void ResolveCurrentExactLocation(Fn callback) {
void ResolveLocationAddress(
const Core::GeoLocation &location,
+ const QString &language,
Fn callback) {
callback({});
}
diff --git a/Telegram/SourceFiles/ui/controls/location_picker.cpp b/Telegram/SourceFiles/ui/controls/location_picker.cpp
index a4658e7be..2eef9d698 100644
--- a/Telegram/SourceFiles/ui/controls/location_picker.cpp
+++ b/Telegram/SourceFiles/ui/controls/location_picker.cpp
@@ -17,6 +17,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_location.h"
#include "data/data_session.h"
#include "data/data_user.h"
+#include "lang/lang_instance.h"
#include "lang/lang_keys.h"
#include "main/session/session_show.h"
#include "main/main_session.h"
@@ -46,6 +47,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
namespace {
+constexpr auto kResolveAddressDelay = 3 * crl::time(1000);
+
#ifdef Q_OS_MAC
const auto kProtocolOverride = "mapboxapihelper";
#else // Q_OS_MAC
@@ -355,7 +358,30 @@ void LinksController::rowPaintIcon(
-
+
+
+
+
+
+
@@ -408,26 +434,26 @@ void LinksController::rowPaintIcon(
raw,
rpl::duplicate(statusText),
st::pickLocationButtonStatus);
- status->showOn(std::move(
+ status->showOn(rpl::duplicate(
statusText
) | rpl::map([](const QString &text) {
return !text.isEmpty();
}) | rpl::distinct_until_changed());
rpl::combine(
result->widthValue(),
- status->shownValue()
- ) | rpl::start_with_next([=](int width, bool statusShown) {
+ std::move(statusText)
+ ) | rpl::start_with_next([=](int width, const QString &statusText) {
const auto available = width
- st->namePosition.x()
- st->button.padding.right();
const auto namePosition = st->namePosition;
const auto statusPosition = st->statusPosition;
name->resizeToWidth(available);
- const auto nameTop = statusShown
- ? namePosition.y()
- : (st->height - name->height()) / 2;
+ const auto nameTop = statusText.isEmpty()
+ ? ((st->height - name->height()) / 2)
+ : namePosition.y();
name->moveToLeft(namePosition.x(), nameTop, width);
- status->resizeToWidth(available);
+ status->resizeToNaturalWidth(available);
status->moveToLeft(statusPosition.x(), statusPosition.y(), width);
}, name->lifetime());
@@ -501,6 +527,7 @@ LocationPicker::LocationPicker(Descriptor &&descriptor)
_webview->eval("LocationPicker.updateStyles('" + str + "');");
}
})
+, _geocoderResolveTimer([=] { resolveAddressByTimer(); })
, _venueState(PickerVenueLoading())
, _session(descriptor.session)
, _api(&_session->mtp()) {
@@ -660,6 +687,17 @@ void LocationPicker::setupWebview(const Descriptor &descriptor) {
const auto lon = object.value("longitude").toDouble();
_callback({ lat, lon });
close();
+ } else if (event == u"movestart"_q) {
+ _geocoderAddress = QString();
+ _geocoderResolveTimer.cancel();
+ } else if (event == u"moveend"_q) {
+ const auto lat = object.value("latitude").toDouble();
+ const auto lon = object.value("longitude").toDouble();
+ _geocoderResolvePostponed = Core::GeoLocation{
+ .point = { lat, lon },
+ .accuracy = Core::GeoLocationAccuracy::Exact,
+ };
+ _geocoderResolveTimer.callOnce(kResolveAddressDelay);
}
});
});
@@ -714,6 +752,12 @@ void LocationPicker::setupWebview(const Descriptor &descriptor) {
raw->navigateToData("location/picker.html");
}
+void LocationPicker::resolveAddressByTimer() {
+ if (const auto location = base::take(_geocoderResolvePostponed)) {
+ resolveAddress(location);
+ }
+}
+
void LocationPicker::resolveAddress(Core::GeoLocation location) {
if (_geocoderResolvingFor == location) {
return;
@@ -730,8 +774,14 @@ void LocationPicker::resolveAddress(Core::GeoLocation location) {
.arg(location.point.y(), 0, 'f');
}
};
+ const auto baseLangId = Lang::GetInstance().baseId();
+ const auto langId = baseLangId.isEmpty()
+ ? Lang::GetInstance().id()
+ : baseLangId;
+ const auto nonEmptyId = langId.isEmpty() ? u"en"_q : langId;
Core::ResolveLocationAddress(
location,
+ langId,
GeocodingProviderToken,
crl::guard(this, done));
}
diff --git a/Telegram/SourceFiles/ui/controls/location_picker.h b/Telegram/SourceFiles/ui/controls/location_picker.h
index 9a4ca56d5..e9c0d9801 100644
--- a/Telegram/SourceFiles/ui/controls/location_picker.h
+++ b/Telegram/SourceFiles/ui/controls/location_picker.h
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "base/invoke_queued.h"
+#include "base/timer.h"
#include "base/weak_ptr.h"
#include "core/current_geo_location.h"
#include "mtproto/sender.h"
@@ -106,6 +107,7 @@ private:
void setupWebview(const Descriptor &descriptor);
void processKey(const QString &key, const QString &modifier);
void resolveCurrentLocation();
+ void resolveAddressByTimer();
void resolveAddress(Core::GeoLocation location);
void mapReady();
@@ -124,6 +126,8 @@ private:
SingleQueuedInvokation _updateStyles;
bool _subscribedToColors = false;
+ base::Timer _geocoderResolveTimer;
+ Core::GeoLocation _geocoderResolvePostponed;
Core::GeoLocation _geocoderResolvingFor;
rpl::variable _geocoderAddress;