diff --git a/Telegram/Resources/picker_html/picker.css b/Telegram/Resources/picker_html/picker.css
index 4d8f378ae..ac3d5912b 100644
--- a/Telegram/Resources/picker_html/picker.css
+++ b/Telegram/Resources/picker_html/picker.css
@@ -1,7 +1,5 @@
:root {
--font-sans: -apple-system, BlinkMacSystemFont, avenir next, avenir, Segoe UI Variable Text, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, tahoma, arial, sans-serif;
- --font-serif: Iowan Old Style, Apple Garamond, Baskerville, Georgia, Times New Roman, Droid Serif, Times, Source Serif Pro, serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
- --font-mono: Menlo, Cascadia Code, Consolas, Monaco, Liberation Mono, Lucida Console, monospace;
}
html {
@@ -13,8 +11,6 @@ html {
body {
font-family: var(--font-sans);
- font-size: 17px;
- line-height: 25px;
width: 100%;
height: 100%;
padding: 0;
@@ -68,3 +64,57 @@ html.custom_scroll ::-webkit-scrollbar-thumb:hover {
#marker_shadow {
position: absolute;
}
+#search_venues {
+ position: absolute;
+ left: 50%;
+ transform: translateX(-50%);
+ z-index: 2;
+ top: -30px;
+ transition: top 200ms ease-in-out;
+}
+#search_venues.shown {
+ top: 6px;
+}
+#search_venues_inner {
+ position: relative;
+ overflow: hidden;
+ font-size: 13px;
+ font-weight: 500;
+ background: var(--td-window-bg);
+ color: var(--td-window-active-text-fg);
+ cursor: pointer;
+ border-radius: 14px;
+ padding: 5px 12px 6px;
+ box-shadow: 0 0 3px 0px var(--td-history-to-down-shadow);
+}
+#search_venues_inner:hover {
+ background: var(--td-window-bg-over);
+}
+#search_venues_content {
+ position: relative;
+ z-index: 2;
+}
+#search_venues_content:before {
+ content: var(--td-lng-maps-places-in-area);
+}
+#search_venues_inner .ripple .inner {
+ position: absolute;
+ border-radius: 50%;
+ transform: scale(0);
+ opacity: 1;
+ animation: ripple 650ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
+ background-color: var(--td-window-bg-ripple);
+}
+#search_venues_inner .ripple.hiding {
+ animation: fadeOut 200ms linear forwards;
+}
+@keyframes ripple {
+ to {
+ transform: scale(2);
+ }
+}
+@keyframes fadeOut {
+ to {
+ opacity: 0;
+ }
+}
diff --git a/Telegram/Resources/picker_html/picker.js b/Telegram/Resources/picker_html/picker.js
index 27ffd3b6c..e44fd51a9 100644
--- a/Telegram/Resources/picker_html/picker.js
+++ b/Telegram/Resources/picker_html/picker.js
@@ -72,6 +72,7 @@ var LocationPicker = {
LocationPicker.map = new mapboxgl.Map(options);
LocationPicker.createMarker(center);
LocationPicker.trackMovement();
+ LocationPicker.initSearchVenueRipple();
},
marker: function() {
return document.getElementById('marker_drop');
@@ -93,13 +94,14 @@ var LocationPicker = {
LocationPicker.map.on('movestart', function() {
LocationPicker.marker().classList.add('moving');
LocationPicker.clearMovingTimer();
- LocationPicker.notify({ event: 'movestart' });
+ LocationPicker.toggleSearchVenues(false);
+ LocationPicker.notify({ event: 'move_start' });
});
LocationPicker.map.on('moveend', function() {
LocationPicker.startMovingTimer(function() {
LocationPicker.marker().classList.remove('moving');
LocationPicker.notify({
- event: 'moveend',
+ event: 'move_end',
latitude: LocationPicker.map.getCenter().lat,
longitude: LocationPicker.map.getCenter().lng
});
@@ -119,5 +121,79 @@ var LocationPicker = {
latitude: LocationPicker.map.getCenter().lat,
longitude: LocationPicker.map.getCenter().lng
});
- }
+ },
+ addRipple: function (button, x, y) {
+ const ripple = document.createElement('span');
+ ripple.classList.add('ripple');
+
+ const inner = document.createElement('span');
+ inner.classList.add('inner');
+
+ var rect = button.getBoundingClientRect();
+ x -= rect.x;
+ y -= rect.y;
+
+ const mx = button.clientWidth - x;
+ const my = button.clientHeight - y;
+ const sq1 = x * x + y * y;
+ const sq2 = mx * mx + y * y;
+ const sq3 = x * x + my * my;
+ const sq4 = mx * mx + my * my;
+ const radius = Math.sqrt(Math.max(sq1, sq2, sq3, sq4));
+
+ inner.style.width = inner.style.height = `${2 * radius}px`;
+ inner.style.left = `${x - radius}px`;
+ inner.style.top = `${y - radius}px`;
+ inner.classList.add('inner');
+
+ ripple.addEventListener('animationend', function (e) {
+ if (e.animationName === 'fadeOut') {
+ ripple.remove();
+ }
+ });
+
+ ripple.appendChild(inner);
+ button.appendChild(ripple);
+ },
+ stopRipples: function (button) {
+ const id = button.id ? button.id : button;
+ button = document.getElementById(id);
+ const ripples = button.getElementsByClassName('ripple');
+ for (var i = 0; i < ripples.length; ++i) {
+ const ripple = ripples[i];
+ if (!ripple.classList.contains('hiding')) {
+ ripple.classList.add('hiding');
+ }
+ }
+ },
+ initSearchVenueRipple: function() {
+ var button = document.getElementById('search_venues_inner');
+ button.addEventListener('mousedown', function (e) {
+ LocationPicker.addRipple(e.currentTarget, e.clientX, e.clientY);
+ LocationPicker.searchVenuesPressed = true;
+ });
+ button.addEventListener('mouseup', function (e) {
+ const id = e.currentTarget.id;
+ setTimeout(function () {
+ LocationPicker.stopRipples(id);
+ }, 0);
+ if (LocationPicker.searchVenuesPressed) {
+ LocationPicker.searchVenuesPressed = false;
+ LocationPicker.toggleSearchVenues(false);
+ LocationPicker.notify({
+ event: 'search_venues',
+ latitude: LocationPicker.map.getCenter().lat,
+ longitude: LocationPicker.map.getCenter().lng
+ });
+ }
+ });
+ button.addEventListener('mouseleave', function (e) {
+ LocationPicker.stopRipples(e.currentTarget);
+ LocationPicker.searchVenuesPressed = false;
+ });
+ },
+ toggleSearchVenues: function(shown) {
+ var button = document.getElementById('search_venues');
+ button.classList.toggle('shown', shown);
+ },
};
diff --git a/Telegram/SourceFiles/core/current_geo_location.cpp b/Telegram/SourceFiles/core/current_geo_location.cpp
index 818ea361a..2ec4a9cfe 100644
--- a/Telegram/SourceFiles/core/current_geo_location.cpp
+++ b/Telegram/SourceFiles/core/current_geo_location.cpp
@@ -148,7 +148,7 @@ void ResolveLocationAddressGeneric(
}
}
};
- add({ u"address"_q, u"street"_q, u"neighborhood"_q });
+ add({ /*u"address"_q, u"street"_q, */u"neighborhood"_q });
add({ u"place"_q, u"region"_q });
add({ u"country"_q });
finishWith({ .name = names.join(", ") });
@@ -215,4 +215,29 @@ void ResolveLocationAddress(
Platform::ResolveLocationAddress(location, language, std::move(done));
}
+bool AreTheSame(const GeoLocation &a, const GeoLocation &b) {
+ if (a.accuracy != GeoLocationAccuracy::Exact
+ || b.accuracy != GeoLocationAccuracy::Exact) {
+ return false;
+ }
+ const auto normalize = [](float64 value) {
+ value = std::fmod(value + 180., 360.);
+ return (value + (value < 0. ? 360. : 0.)) - 180.;
+ };
+ constexpr auto kEpsilon = 0.0001;
+ const auto lon1 = normalize(a.point.y());
+ const auto lon2 = normalize(b.point.y());
+ const auto diffLat = std::abs(a.point.x() - b.point.x());
+ if (std::abs(a.point.x()) >= (90. - kEpsilon)
+ || std::abs(b.point.x()) >= (90. - kEpsilon)) {
+ return diffLat <= kEpsilon;
+ }
+ auto diffLon = std::abs(lon1 - lon2);
+ if (diffLon > 180.) {
+ diffLon = 360. - diffLon;
+ }
+
+ return diffLat <= kEpsilon && diffLon <= kEpsilon;
+}
+
} // namespace Core
diff --git a/Telegram/SourceFiles/core/current_geo_location.h b/Telegram/SourceFiles/core/current_geo_location.h
index dab4ffd00..3b495f115 100644
--- a/Telegram/SourceFiles/core/current_geo_location.h
+++ b/Telegram/SourceFiles/core/current_geo_location.h
@@ -33,12 +33,10 @@ struct GeoLocation {
explicit operator bool() const {
return !failed();
}
-
- friend inline bool operator==(
- const GeoLocation&,
- const GeoLocation&) = default;
};
+[[nodiscard]] bool AreTheSame(const GeoLocation &a, const GeoLocation &b);
+
struct GeoAddress {
QString name;
diff --git a/Telegram/SourceFiles/ui/controls/location_picker.cpp b/Telegram/SourceFiles/ui/controls/location_picker.cpp
index 2eef9d698..b5920e131 100644
--- a/Telegram/SourceFiles/ui/controls/location_picker.cpp
+++ b/Telegram/SourceFiles/ui/controls/location_picker.cpp
@@ -102,6 +102,7 @@ VenueRow::VenueRow(
void VenueRow::update(const VenueData &data) {
_data = data;
setCustomStatus(data.address);
+ refreshName(st::pickLocationVenueItem);
}
VenueData VenueRow::data() const {
@@ -128,12 +129,12 @@ PaintRoundImageCallback VenueRow::generatePaintUserpicCallback(
};
}
-class LinksController final
+class VenuesController final
: public PeerListController
, public VenueRowDelegate
, public base::has_weak_ptr {
public:
- LinksController(
+ VenuesController(
not_null session,
rpl::producer> content);
@@ -176,21 +177,21 @@ private:
return query.trimmed().toLower();
}
-LinksController::LinksController(
+VenuesController::VenuesController(
not_null session,
rpl::producer> content)
: _session(session)
, _rows(std::move(content)) {
}
-void LinksController::prepare() {
+void VenuesController::prepare() {
_rows.value(
) | rpl::start_with_next([=](const std::vector &rows) {
rebuild(rows);
}, _lifetime);
}
-void LinksController::rebuild(const std::vector &rows) {
+void VenuesController::rebuild(const std::vector &rows) {
auto i = 0;
auto count = delegate()->peerListFullRowsCount();
while (i < rows.size()) {
@@ -209,24 +210,24 @@ void LinksController::rebuild(const std::vector &rows) {
delegate()->peerListRefreshRows();
}
-void LinksController::rowClicked(not_null row) {
+void VenuesController::rowClicked(not_null row) {
const auto venue = static_cast(row.get())->data();
venue;
}
-void LinksController::rowRightActionClicked(not_null row) {
+void VenuesController::rowRightActionClicked(not_null row) {
delegate()->peerListShowRowMenu(row, true);
}
-Main::Session &LinksController::session() const {
+Main::Session &VenuesController::session() const {
return *_session;
}
-void LinksController::appendRow(const VenueData &data) {
+void VenuesController::appendRow(const VenueData &data) {
delegate()->peerListAppendRow(std::make_unique(this, data));
}
-void LinksController::rowPaintIcon(
+void VenuesController::rowPaintIcon(
QPainter &p,
int x,
int y,
@@ -331,6 +332,7 @@ void LinksController::rowPaintIcon(
{ "window-bg-over", &st::windowBgOver },
{ "window-bg-ripple", &st::windowBgRipple },
{ "window-active-text-fg", &st::windowActiveTextFg },
+ { "history-to-down-shadow", &st::historyToDownShadow },
};
static const auto phrases = base::flat_map>{
{ "maps-places-in-area", tr::lng_maps_places_in_area },
@@ -358,6 +360,9 @@ void LinksController::rowPaintIcon(
+