mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show empty venue search states.
This commit is contained in:
parent
b4dfc25df5
commit
8aac07b3c0
4 changed files with 100 additions and 12 deletions
|
@ -3198,6 +3198,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_maps_or_choose" = "Or choose a venue";
|
"lng_maps_or_choose" = "Or choose a venue";
|
||||||
"lng_maps_places_in_area" = "Places in this area";
|
"lng_maps_places_in_area" = "Places in this area";
|
||||||
"lng_maps_no_places" = "No places found";
|
"lng_maps_no_places" = "No places found";
|
||||||
|
"lng_maps_choose_to_search" = "Choose location to see places nearby.";
|
||||||
"lng_live_location" = "Live Location";
|
"lng_live_location" = "Live Location";
|
||||||
"lng_live_location_now" = "updated just now";
|
"lng_live_location_now" = "updated just now";
|
||||||
"lng_live_location_minutes#one" = "updated {count} minute ago";
|
"lng_live_location_minutes#one" = "updated {count} minute ago";
|
||||||
|
|
|
@ -1476,3 +1476,8 @@ pickLocationVenueList: PeerList(defaultPeerList) {
|
||||||
padding: margins(0px, 0px, 0px, 0px);
|
padding: margins(0px, 0px, 0px, 0px);
|
||||||
}
|
}
|
||||||
pickLocationIconSkip: 6px;
|
pickLocationIconSkip: 6px;
|
||||||
|
pickLocationLoading: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
|
||||||
|
size: size(56px, 56px);
|
||||||
|
color: windowSubTextFg;
|
||||||
|
thickness: 4px;
|
||||||
|
}
|
||||||
|
|
|
@ -17,11 +17,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_location.h"
|
#include "data/data_location.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "dialogs/ui/chat_search_empty.h" // Dialogs::SearchEmpty.
|
||||||
#include "lang/lang_instance.h"
|
#include "lang/lang_instance.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/session/session_show.h"
|
#include "main/session/session_show.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "mtproto/mtproto_config.h"
|
#include "mtproto/mtproto_config.h"
|
||||||
|
#include "ui/effects/radial_animation.h"
|
||||||
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/separate_panel.h"
|
#include "ui/widgets/separate_panel.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
@ -468,17 +471,95 @@ void VenuesController::rowPaintIcon(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetupLoadingView(not_null<RpWidget*> container) {
|
||||||
|
class Loading final : public RpWidget {
|
||||||
|
public:
|
||||||
|
explicit Loading(QWidget *parent)
|
||||||
|
: RpWidget(parent)
|
||||||
|
, animation(
|
||||||
|
[=] { if (!anim::Disabled()) update(); },
|
||||||
|
st::pickLocationLoading) {
|
||||||
|
animation.start(st::pickLocationLoading.sineDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void paintEvent(QPaintEvent *e) override {
|
||||||
|
auto p = QPainter(this);
|
||||||
|
const auto size = st::pickLocationLoading.size;
|
||||||
|
const auto inner = QRect(QPoint(), size);
|
||||||
|
const auto positioned = style::centerrect(rect(), inner);
|
||||||
|
animation.draw(p, positioned.topLeft(), size, width());
|
||||||
|
}
|
||||||
|
|
||||||
|
InfiniteRadialAnimation animation;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto view = CreateChild<Loading>(container);
|
||||||
|
view->resize(container->width(), st::recentPeersEmptyHeightMin);
|
||||||
|
view->show();
|
||||||
|
|
||||||
|
ResizeFitChild(container, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupEmptyView(
|
||||||
|
not_null<RpWidget*> container,
|
||||||
|
std::optional<QString> query) {
|
||||||
|
using Icon = Dialogs::SearchEmptyIcon;
|
||||||
|
const auto view = CreateChild<Dialogs::SearchEmpty>(
|
||||||
|
container,
|
||||||
|
(query ? Icon::NoResults : Icon::Search),
|
||||||
|
(query
|
||||||
|
? tr::lng_maps_no_places
|
||||||
|
: tr::lng_maps_choose_to_search)(Ui::Text::WithEntities));
|
||||||
|
view->setMinimalHeight(st::recentPeersEmptyHeightMin);
|
||||||
|
view->show();
|
||||||
|
|
||||||
|
ResizeFitChild(container, view);
|
||||||
|
|
||||||
|
InvokeQueued(view, [=] { view->animate(); });
|
||||||
|
}
|
||||||
|
|
||||||
void SetupVenues(
|
void SetupVenues(
|
||||||
not_null<VerticalLayout*> container,
|
not_null<VerticalLayout*> container,
|
||||||
std::shared_ptr<Main::SessionShow> show,
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
rpl::producer<std::vector<VenueData>> value,
|
rpl::producer<PickerVenueState> value,
|
||||||
Fn<void(VenueData)> callback) {
|
Fn<void(VenueData)> callback) {
|
||||||
|
const auto otherWrap = container->add(object_ptr<SlideWrap<RpWidget>>(
|
||||||
|
container,
|
||||||
|
object_ptr<RpWidget>(container)));
|
||||||
|
const auto other = otherWrap->entity();
|
||||||
|
rpl::duplicate(
|
||||||
|
value
|
||||||
|
) | rpl::start_with_next([=](const PickerVenueState &state) {
|
||||||
|
while (!other->children().isEmpty()) {
|
||||||
|
delete other->children()[0];
|
||||||
|
}
|
||||||
|
if (v::is<PickerVenueList>(state)) {
|
||||||
|
otherWrap->hide(anim::type::instant);
|
||||||
|
return;
|
||||||
|
} else if (v::is<PickerVenueLoading>(state)) {
|
||||||
|
SetupLoadingView(other);
|
||||||
|
} else {
|
||||||
|
const auto n = std::get_if<PickerVenueNothingFound>(&state);
|
||||||
|
SetupEmptyView(other, n ? n->query : std::optional<QString>());
|
||||||
|
}
|
||||||
|
otherWrap->show(anim::type::instant);
|
||||||
|
}, otherWrap->lifetime());
|
||||||
|
|
||||||
auto &lifetime = container->lifetime();
|
auto &lifetime = container->lifetime();
|
||||||
|
auto venuesList = rpl::duplicate(
|
||||||
|
value
|
||||||
|
) | rpl::map([=](PickerVenueState &&state) {
|
||||||
|
return v::is<PickerVenueList>(state)
|
||||||
|
? std::move(v::get<PickerVenueList>(state).list)
|
||||||
|
: std::vector<VenueData>();
|
||||||
|
});
|
||||||
const auto delegate = lifetime.make_state<PeerListContentDelegateShow>(
|
const auto delegate = lifetime.make_state<PeerListContentDelegateShow>(
|
||||||
show);
|
show);
|
||||||
const auto controller = lifetime.make_state<VenuesController>(
|
const auto controller = lifetime.make_state<VenuesController>(
|
||||||
&show->session(),
|
&show->session(),
|
||||||
std::move(value),
|
std::move(venuesList),
|
||||||
std::move(callback));
|
std::move(callback));
|
||||||
controller->setStyleOverrides(&st::pickLocationVenueList);
|
controller->setStyleOverrides(&st::pickLocationVenueList);
|
||||||
const auto content = container->add(object_ptr<PeerListContent>(
|
const auto content = container->add(object_ptr<PeerListContent>(
|
||||||
|
@ -601,8 +682,7 @@ void LocationPicker::setupWindow(const Descriptor &descriptor) {
|
||||||
_mapControlsWrap = controls->add(
|
_mapControlsWrap = controls->add(
|
||||||
object_ptr<SlideWrap<VerticalLayout>>(
|
object_ptr<SlideWrap<VerticalLayout>>(
|
||||||
controls,
|
controls,
|
||||||
object_ptr<VerticalLayout>(controls))
|
object_ptr<VerticalLayout>(controls)));
|
||||||
)->setDuration(0);
|
|
||||||
_mapControlsWrap->show(anim::type::instant);
|
_mapControlsWrap->show(anim::type::instant);
|
||||||
const auto mapControls = _mapControlsWrap->entity();
|
const auto mapControls = _mapControlsWrap->entity();
|
||||||
|
|
||||||
|
@ -619,12 +699,8 @@ void LocationPicker::setupWindow(const Descriptor &descriptor) {
|
||||||
AddSkip(mapControls);
|
AddSkip(mapControls);
|
||||||
AddSubsectionTitle(mapControls, tr::lng_maps_or_choose());
|
AddSubsectionTitle(mapControls, tr::lng_maps_or_choose());
|
||||||
|
|
||||||
SetupVenues(controls, uiShow(), _venueState.value(
|
auto state = _venueState.value();
|
||||||
) | rpl::filter([=](const PickerVenueState &state) {
|
SetupVenues(controls, uiShow(), std::move(state), [=](VenueData info) {
|
||||||
return v::is<PickerVenueList>(state);
|
|
||||||
}) | rpl::map([=](PickerVenueState &&state) {
|
|
||||||
return std::move(v::get<PickerVenueList>(state).list);
|
|
||||||
}), [=](VenueData info) {
|
|
||||||
_callback(std::move(info));
|
_callback(std::move(info));
|
||||||
close();
|
close();
|
||||||
});
|
});
|
||||||
|
@ -706,6 +782,9 @@ void LocationPicker::setupWebview(const Descriptor &descriptor) {
|
||||||
if (event == u"ready"_q) {
|
if (event == u"ready"_q) {
|
||||||
mapReady();
|
mapReady();
|
||||||
resolveCurrentLocation();
|
resolveCurrentLocation();
|
||||||
|
if (_webview) {
|
||||||
|
_webview->focus();
|
||||||
|
}
|
||||||
} else if (event == u"keydown"_q) {
|
} else if (event == u"keydown"_q) {
|
||||||
const auto key = object.value("key").toString();
|
const auto key = object.value("key").toString();
|
||||||
const auto modifier = object.value("modifier").toString();
|
const auto modifier = object.value("modifier").toString();
|
||||||
|
@ -974,7 +1053,6 @@ void LocationPicker::venuesSearchChanged(
|
||||||
_mapControlsWrap->toggle(!shown, anim::type::instant);
|
_mapControlsWrap->toggle(!shown, anim::type::instant);
|
||||||
if (shown) {
|
if (shown) {
|
||||||
_venuesNoSearchLocation = _venuesRequestLocation;
|
_venuesNoSearchLocation = _venuesRequestLocation;
|
||||||
_venueState = PickerVenueLoading();
|
|
||||||
} else if (_venuesNoSearchLocation) {
|
} else if (_venuesNoSearchLocation) {
|
||||||
if (!venuesFromCache(_venuesNoSearchLocation)) {
|
if (!venuesFromCache(_venuesNoSearchLocation)) {
|
||||||
venuesRequest(_venuesNoSearchLocation);
|
venuesRequest(_venuesNoSearchLocation);
|
||||||
|
@ -986,6 +1064,7 @@ void LocationPicker::venuesSearchChanged(
|
||||||
&& !venuesFromCache(
|
&& !venuesFromCache(
|
||||||
*_venuesSearchLocation,
|
*_venuesSearchLocation,
|
||||||
*_venuesSearchQuery)) {
|
*_venuesSearchQuery)) {
|
||||||
|
_venueState = PickerVenueLoading();
|
||||||
_venuesSearchDebounceTimer.callOnce(kSearchDebounceDelay);
|
_venuesSearchDebounceTimer.callOnce(kSearchDebounceDelay);
|
||||||
} else {
|
} else {
|
||||||
_venuesSearchDebounceTimer.cancel();
|
_venuesSearchDebounceTimer.cancel();
|
||||||
|
@ -998,6 +1077,9 @@ void LocationPicker::resolveCurrentLocation() {
|
||||||
ResolveCurrentGeoLocation(crl::guard(window, [=](GeoLocation location) {
|
ResolveCurrentGeoLocation(crl::guard(window, [=](GeoLocation location) {
|
||||||
const auto changed = !AreTheSame(LastExactLocation, location);
|
const auto changed = !AreTheSame(LastExactLocation, location);
|
||||||
if (location.accuracy != GeoLocationAccuracy::Exact || !changed) {
|
if (location.accuracy != GeoLocationAccuracy::Exact || !changed) {
|
||||||
|
if (!_venuesSearchLocation) {
|
||||||
|
_venueState = PickerVenueWaitingForLocation();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LastExactLocation = location;
|
LastExactLocation = location;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit a95caea1adac69ca6d95b55fe920eac33cdf9580
|
Subproject commit f046725ecde41bf5779d69393cc592786ee0440c
|
Loading…
Add table
Reference in a new issue