mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-21 23:57:38 +00:00
Focus existing location picker.
This commit is contained in:
parent
db0856f71c
commit
3f0f3a3c11
@ -475,6 +475,8 @@ PRIVATE
|
||||
data/business/data_shortcut_messages.h
|
||||
data/components/factchecks.cpp
|
||||
data/components/factchecks.h
|
||||
data/components/location_pickers.cpp
|
||||
data/components/location_pickers.h
|
||||
data/components/recent_peers.cpp
|
||||
data/components/recent_peers.h
|
||||
data/components/scheduled_messages.cpp
|
||||
|
@ -3197,6 +3197,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_unread_bar_some" = "Unread messages";
|
||||
|
||||
"lng_maps_point" = "Location";
|
||||
"lng_maps_select_on_map" = "Select on the Map";
|
||||
"lng_maps_point_send" = "Send This Location";
|
||||
"lng_maps_point_set" = "Set This Location";
|
||||
"lng_maps_or_choose" = "Or choose a venue";
|
||||
|
@ -30,6 +30,10 @@ struct SendOptions {
|
||||
bool invertCaption = false;
|
||||
bool hideViaBot = false;
|
||||
crl::time ttlSeconds = 0;
|
||||
|
||||
friend inline bool operator==(
|
||||
const SendOptions &,
|
||||
const SendOptions &) = default;
|
||||
};
|
||||
[[nodiscard]] SendOptions DefaultSendWhenOnlineOptions();
|
||||
|
||||
@ -52,6 +56,10 @@ struct SendAction {
|
||||
MsgId replaceMediaOf = 0;
|
||||
|
||||
[[nodiscard]] MTPInputReplyTo mtpReplyTo() const;
|
||||
|
||||
friend inline bool operator==(
|
||||
const SendAction &,
|
||||
const SendAction &) = default;
|
||||
};
|
||||
|
||||
struct MessageToSend {
|
||||
|
@ -1475,3 +1475,9 @@ pickLocationLoading: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
|
||||
thickness: 4px;
|
||||
}
|
||||
pickLocationPromoHeight: 32px;
|
||||
pickLocationChooseOnMap: RoundButton(defaultActiveButton) {
|
||||
height: 44px;
|
||||
textTop: 11px;
|
||||
width: -96px;
|
||||
font: font(15px semibold);
|
||||
}
|
||||
|
44
Telegram/SourceFiles/data/components/location_pickers.cpp
Normal file
44
Telegram/SourceFiles/data/components/location_pickers.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "data/components/location_pickers.h"
|
||||
|
||||
#include "api/api_common.h"
|
||||
#include "ui/controls/location_picker.h"
|
||||
|
||||
namespace Data {
|
||||
|
||||
struct LocationPickers::Entry {
|
||||
Api::SendAction action;
|
||||
base::weak_ptr<Ui::LocationPicker> picker;
|
||||
};
|
||||
|
||||
LocationPickers::LocationPickers() = default;
|
||||
|
||||
LocationPickers::~LocationPickers() = default;
|
||||
|
||||
Ui::LocationPicker *LocationPickers::lookup(const Api::SendAction &action) {
|
||||
for (auto i = begin(_pickers); i != end(_pickers);) {
|
||||
if (const auto strong = i->picker.get()) {
|
||||
if (i->action == action) {
|
||||
return i->picker.get();
|
||||
}
|
||||
++i;
|
||||
} else {
|
||||
i = _pickers.erase(i);
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void LocationPickers::emplace(
|
||||
const Api::SendAction &action,
|
||||
not_null<Ui::LocationPicker*> picker) {
|
||||
_pickers.push_back({ action, picker });
|
||||
}
|
||||
|
||||
} // namespace Data
|
39
Telegram/SourceFiles/data/components/location_pickers.h
Normal file
39
Telegram/SourceFiles/data/components/location_pickers.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
|
||||
namespace Api {
|
||||
struct SendAction;
|
||||
} // namespace Api
|
||||
|
||||
namespace Ui {
|
||||
class LocationPicker;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Data {
|
||||
|
||||
class LocationPickers final {
|
||||
public:
|
||||
LocationPickers();
|
||||
~LocationPickers();
|
||||
|
||||
Ui::LocationPicker *lookup(const Api::SendAction &action);
|
||||
void emplace(
|
||||
const Api::SendAction &action,
|
||||
not_null<Ui::LocationPicker*> picker);
|
||||
|
||||
private:
|
||||
struct Entry;
|
||||
|
||||
std::vector<Entry> _pickers;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Data
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/share_box.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "core/shortcuts.h"
|
||||
#include "data/components/location_pickers.h"
|
||||
#include "data/data_bot_app.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_user.h"
|
||||
@ -1776,6 +1777,11 @@ void ChooseAndSendLocation(
|
||||
not_null<Window::SessionController*> controller,
|
||||
const Ui::LocationPickerConfig &config,
|
||||
Api::SendAction action) {
|
||||
const auto session = &controller->session();
|
||||
if (const auto picker = session->locationPickers().lookup(action)) {
|
||||
picker->activate();
|
||||
return;
|
||||
}
|
||||
const auto callback = [=](Data::InputVenue venue) {
|
||||
if (venue.justLocation()) {
|
||||
Api::SendLocation(action, venue.lat, venue.lon);
|
||||
@ -1783,17 +1789,18 @@ void ChooseAndSendLocation(
|
||||
Api::SendVenue(action, venue);
|
||||
}
|
||||
};
|
||||
Ui::LocationPicker::Show({
|
||||
const auto picker = Ui::LocationPicker::Show({
|
||||
.parent = controller->widget(),
|
||||
.config = config,
|
||||
.chooseLabel = tr::lng_maps_point_send(),
|
||||
.recipient = action.history->peer,
|
||||
.session = &controller->session(),
|
||||
.callback = crl::guard(controller, callback),
|
||||
.session = session,
|
||||
.callback = crl::guard(session, callback),
|
||||
.quit = [] { Shortcuts::Launch(Shortcuts::Command::Quit); },
|
||||
.storageId = controller->session().local().resolveStorageIdBots(),
|
||||
.storageId = session->local().resolveStorageIdBots(),
|
||||
.closeRequests = controller->content()->death(),
|
||||
});
|
||||
session->locationPickers().emplace(action, picker);
|
||||
}
|
||||
|
||||
std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
|
||||
|
@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "storage/storage_account.h"
|
||||
#include "storage/storage_facade.h"
|
||||
#include "data/components/factchecks.h"
|
||||
#include "data/components/location_pickers.h"
|
||||
#include "data/components/recent_peers.h"
|
||||
#include "data/components/scheduled_messages.h"
|
||||
#include "data/components/sponsored_messages.h"
|
||||
@ -111,6 +112,7 @@ Session::Session(
|
||||
, _sponsoredMessages(std::make_unique<Data::SponsoredMessages>(this))
|
||||
, _topPeers(std::make_unique<Data::TopPeers>(this))
|
||||
, _factchecks(std::make_unique<Data::Factchecks>(this))
|
||||
, _locationPickers(std::make_unique<Data::LocationPickers>())
|
||||
, _cachedReactionIconFactory(std::make_unique<ReactionIconFactory>())
|
||||
, _supportHelper(Support::Helper::Create(this))
|
||||
, _saveSettingsTimer([=] { saveSettings(); }) {
|
||||
|
@ -36,6 +36,7 @@ class ScheduledMessages;
|
||||
class SponsoredMessages;
|
||||
class TopPeers;
|
||||
class Factchecks;
|
||||
class LocationPickers;
|
||||
} // namespace Data
|
||||
|
||||
namespace HistoryView::Reactions {
|
||||
@ -131,6 +132,9 @@ public:
|
||||
[[nodiscard]] Data::Factchecks &factchecks() const {
|
||||
return *_factchecks;
|
||||
}
|
||||
[[nodiscard]] Data::LocationPickers &locationPickers() const {
|
||||
return *_locationPickers;
|
||||
}
|
||||
[[nodiscard]] Api::Updates &updates() const {
|
||||
return *_updates;
|
||||
}
|
||||
@ -259,6 +263,7 @@ private:
|
||||
const std::unique_ptr<Data::SponsoredMessages> _sponsoredMessages;
|
||||
const std::unique_ptr<Data::TopPeers> _topPeers;
|
||||
const std::unique_ptr<Data::Factchecks> _factchecks;
|
||||
const std::unique_ptr<Data::LocationPickers> _locationPickers;
|
||||
|
||||
using ReactionIconFactory = HistoryView::Reactions::CachedIconFactory;
|
||||
const std::unique_ptr<ReactionIconFactory> _cachedReactionIconFactory;
|
||||
|
@ -63,6 +63,7 @@ private:
|
||||
const Ui::LocationPickerConfig _config;
|
||||
rpl::variable<Data::BusinessLocation> _data;
|
||||
rpl::variable<Data::CloudImage*> _map = nullptr;
|
||||
base::weak_ptr<Ui::LocationPicker> _picker;
|
||||
std::shared_ptr<QImage> _view;
|
||||
Ui::RoundRect _bottomSkipRounding;
|
||||
|
||||
@ -232,6 +233,10 @@ void Location::setupPicker(not_null<Ui::VerticalLayout*> content) {
|
||||
}
|
||||
|
||||
void Location::chooseOnMap() {
|
||||
if (const auto strong = _picker.get()) {
|
||||
strong->activate();
|
||||
return;
|
||||
}
|
||||
const auto callback = [=](Data::InputVenue venue) {
|
||||
auto copy = _data.current();
|
||||
copy.point = Data::LocationPoint(
|
||||
@ -249,7 +254,7 @@ void Location::chooseOnMap() {
|
||||
.accuracy = Core::GeoLocationAccuracy::Exact,
|
||||
}
|
||||
: Core::GeoLocation();
|
||||
Ui::LocationPicker::Show({
|
||||
_picker = Ui::LocationPicker::Show({
|
||||
.parent = controller()->widget(),
|
||||
.config = _config,
|
||||
.chooseLabel = tr::lng_maps_point_set(),
|
||||
@ -258,7 +263,7 @@ void Location::chooseOnMap() {
|
||||
.callback = crl::guard(this, callback),
|
||||
.quit = [] { Shortcuts::Launch(Shortcuts::Command::Quit); },
|
||||
.storageId = session->local().resolveStorageIdBots(),
|
||||
.closeRequests = controller()->content()->death(),
|
||||
.closeRequests = death(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "dialogs/ui/chat_search_empty.h" // Dialogs::SearchEmpty.
|
||||
#include "lang/lang_instance.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "lottie/lottie_icon.h"
|
||||
#include "main/session/session_show.h"
|
||||
#include "main/main_session.h"
|
||||
#include "mtproto/mtproto_config.h"
|
||||
@ -41,6 +42,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_settings.h" // settingsCloudPasswordIconSize
|
||||
#include "styles/style_layers.h" // boxDividerHeight
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QJsonDocument>
|
||||
@ -185,11 +188,12 @@ private:
|
||||
|
||||
[[nodiscard]] object_ptr<RpWidget> MakeFoursquarePromo() {
|
||||
auto result = object_ptr<RpWidget>((QWidget*)nullptr);
|
||||
const auto skip = st::defaultVerticalListSkip;
|
||||
const auto raw = result.data();
|
||||
raw->resize(0, st::pickLocationPromoHeight);
|
||||
raw->resize(0, skip + st::pickLocationPromoHeight);
|
||||
const auto shadow = CreateChild<PlainShadow>(raw);
|
||||
raw->widthValue() | rpl::start_with_next([=](int width) {
|
||||
shadow->setGeometry(0, 0, width, st::lineWidth);
|
||||
shadow->setGeometry(0, skip, width, st::lineWidth);
|
||||
}, raw->lifetime());
|
||||
raw->paintRequest() | rpl::start_with_next([=](QRect clip) {
|
||||
auto p = QPainter(raw);
|
||||
@ -197,7 +201,7 @@ private:
|
||||
p.setPen(st::windowSubTextFg);
|
||||
p.setFont(st::normalFont);
|
||||
p.drawText(
|
||||
raw->rect(),
|
||||
raw->rect().marginsRemoved({ 0, skip, 0, 0 }),
|
||||
tr::lng_maps_venues_source(tr::now),
|
||||
style::al_center);
|
||||
}, raw->lifetime());
|
||||
@ -544,7 +548,7 @@ void SetupEmptyView(
|
||||
(query ? Icon::NoResults : Icon::Search),
|
||||
(query
|
||||
? tr::lng_maps_no_places
|
||||
: tr::lng_maps_choose_to_search)(Ui::Text::WithEntities));
|
||||
: tr::lng_maps_choose_to_search)(Text::WithEntities));
|
||||
view->setMinimalHeight(st::recentPeersEmptyHeightMin);
|
||||
view->show();
|
||||
|
||||
@ -636,6 +640,96 @@ void SetupVenues(
|
||||
return result;
|
||||
}
|
||||
|
||||
not_null<RpWidget*> SetupMapPlaceholder(
|
||||
not_null<RpWidget*> parent,
|
||||
int minHeight,
|
||||
int maxHeight,
|
||||
Fn<void()> choose) {
|
||||
const auto result = CreateChild<RpWidget>(parent);
|
||||
|
||||
const auto top = CreateChild<BoxContentDivider>(result);
|
||||
const auto bottom = CreateChild<BoxContentDivider>(result);
|
||||
|
||||
const auto icon = CreateChild<RpWidget>(result);
|
||||
const auto iconSize = st::settingsCloudPasswordIconSize;
|
||||
auto ownedLottie = Lottie::MakeIcon({
|
||||
.name = u"location"_q,
|
||||
.sizeOverride = { iconSize, iconSize },
|
||||
.limitFps = true,
|
||||
});
|
||||
const auto lottie = ownedLottie.get();
|
||||
icon->lifetime().add([kept = std::move(ownedLottie)] {});
|
||||
|
||||
icon->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
auto p = QPainter(icon);
|
||||
const auto left = (icon->width() - iconSize) / 2;
|
||||
const auto scale = icon->height() / float64(iconSize);
|
||||
auto hq = std::optional<PainterHighQualityEnabler>();
|
||||
if (scale < 1.) {
|
||||
const auto center = QPointF(
|
||||
icon->width() / 2.,
|
||||
icon->height() / 2.);
|
||||
hq.emplace(p);
|
||||
p.translate(center);
|
||||
p.scale(scale, scale);
|
||||
p.translate(-center);
|
||||
p.setOpacity(scale);
|
||||
}
|
||||
lottie->paint(p, left, 0);
|
||||
}, icon->lifetime());
|
||||
|
||||
InvokeQueued(icon, [=] {
|
||||
const auto till = lottie->framesCount() - 1;
|
||||
lottie->animate([=] { icon->update(); }, 0, till);
|
||||
});
|
||||
|
||||
const auto button = CreateChild<RoundButton>(
|
||||
result,
|
||||
tr::lng_maps_select_on_map(),
|
||||
st::pickLocationChooseOnMap);
|
||||
button->setFullRadius(true);
|
||||
button->setTextTransform(RoundButton::TextTransform::NoTransform);
|
||||
button->setClickedCallback(choose);
|
||||
|
||||
parent->sizeValue() | rpl::start_with_next([=](QSize size) {
|
||||
result->setGeometry(QRect(QPoint(), size));
|
||||
|
||||
const auto width = size.width();
|
||||
top->setGeometry(0, 0, width, top->height());
|
||||
bottom->setGeometry(QRect(
|
||||
QPoint(0, size.height() - bottom->height()),
|
||||
QSize(width, bottom->height())));
|
||||
const auto dividers = top->height() + bottom->height();
|
||||
|
||||
const auto ratio = (size.height() - minHeight)
|
||||
/ float64(maxHeight - minHeight);
|
||||
const auto iconHeight = int(base::SafeRound(ratio * iconSize));
|
||||
|
||||
const auto available = size.height() - dividers;
|
||||
const auto maxDelta = (maxHeight
|
||||
- dividers
|
||||
- iconSize
|
||||
- button->height()) / 2;
|
||||
const auto minDelta = (minHeight - dividers - button->height()) / 2;
|
||||
|
||||
const auto delta = anim::interpolate(minDelta, maxDelta, ratio);
|
||||
button->move(
|
||||
(width - button->width()) / 2,
|
||||
size.height() - bottom->height() - delta - button->height());
|
||||
const auto wide = available - delta - button->height();
|
||||
const auto skip = (wide - iconHeight) / 2;
|
||||
icon->setGeometry(0, top->height() + skip, width, iconHeight);
|
||||
}, result->lifetime());
|
||||
|
||||
top->show();
|
||||
icon->show();
|
||||
bottom->show();
|
||||
result->show();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
LocationPicker::LocationPicker(Descriptor &&descriptor)
|
||||
@ -646,6 +740,8 @@ LocationPicker::LocationPicker(Descriptor &&descriptor)
|
||||
, _body((_window->setInnerSize(st::pickLocationWindow)
|
||||
, _window->showInner(base::make_unique_q<RpWidget>(_window.get()))
|
||||
, _window->inner()))
|
||||
, _chooseButtonLabel(std::move(descriptor.chooseLabel))
|
||||
, _webviewStorageId(descriptor.storageId)
|
||||
, _updateStyles([=] {
|
||||
const auto str = EscapeForScriptString(ComputeStyles());
|
||||
if (_webview) {
|
||||
@ -684,7 +780,6 @@ bool LocationPicker::Available(const LocationPickerConfig &config) {
|
||||
|
||||
void LocationPicker::setup(const Descriptor &descriptor) {
|
||||
setupWindow(descriptor);
|
||||
setupWebview(descriptor);
|
||||
|
||||
_initialProvided = descriptor.initial;
|
||||
const auto initial = _initialProvided.exact()
|
||||
@ -695,6 +790,9 @@ void LocationPicker::setup(const Descriptor &descriptor) {
|
||||
resolveAddress(initial);
|
||||
venuesSearchEnableAt(initial);
|
||||
}
|
||||
if (!_initialProvided) {
|
||||
resolveCurrentLocation();
|
||||
}
|
||||
}
|
||||
|
||||
void LocationPicker::setupWindow(const Descriptor &descriptor) {
|
||||
@ -714,6 +812,15 @@ void LocationPicker::setupWindow(const Descriptor &descriptor) {
|
||||
parent.y() + (parent.height() - window->height()) / 2);
|
||||
|
||||
_container = CreateChild<RpWidget>(_body.get());
|
||||
_mapPlaceholderAdded = st::pickLocationButtonSkip
|
||||
+ st::pickLocationButton.height
|
||||
+ st::pickLocationButtonSkip
|
||||
+ st::boxDividerHeight;
|
||||
const auto min = st::pickLocationCollapsedHeight + _mapPlaceholderAdded;
|
||||
const auto max = st::pickLocationMapHeight + _mapPlaceholderAdded;
|
||||
_mapPlaceholder = SetupMapPlaceholder(_container, min, max, [=] {
|
||||
setupWebview();
|
||||
});
|
||||
_scroll = CreateChild<ScrollArea>(_body.get());
|
||||
const auto controls = _scroll->setOwnedWidget(
|
||||
object_ptr<VerticalLayout>(_scroll));
|
||||
@ -727,17 +834,6 @@ void LocationPicker::setupWindow(const Descriptor &descriptor) {
|
||||
|
||||
const auto toppad = mapControls->add(object_ptr<RpWidget>(controls));
|
||||
|
||||
const auto button = mapControls->add(
|
||||
MakeChooseLocationButton(
|
||||
mapControls,
|
||||
std::move(descriptor.chooseLabel),
|
||||
_geocoderAddress.value()),
|
||||
{ 0, st::pickLocationButtonSkip, 0, st::pickLocationButtonSkip });
|
||||
button->setClickedCallback([=] {
|
||||
_webview->eval("LocationPicker.send();");
|
||||
});
|
||||
|
||||
AddDivider(mapControls);
|
||||
AddSkip(mapControls);
|
||||
AddSubsectionTitle(mapControls, tr::lng_maps_or_choose());
|
||||
|
||||
@ -757,7 +853,9 @@ void LocationPicker::setupWindow(const Descriptor &descriptor) {
|
||||
const auto sub = std::min(
|
||||
(st::pickLocationMapHeight - st::pickLocationCollapsedHeight),
|
||||
scrollTop);
|
||||
const auto mapHeight = st::pickLocationMapHeight - sub;
|
||||
const auto mapHeight = st::pickLocationMapHeight
|
||||
- sub
|
||||
+ (_mapPlaceholder ? _mapPlaceholderAdded : 0);
|
||||
_container->setGeometry(0, 0, width, mapHeight);
|
||||
const auto scrollWidgetTop = search ? 0 : mapHeight;
|
||||
const auto scrollHeight = height - scrollWidgetTop;
|
||||
@ -771,21 +869,52 @@ void LocationPicker::setupWindow(const Descriptor &descriptor) {
|
||||
}, _container->lifetime());
|
||||
|
||||
_container->show();
|
||||
_scroll->hide();
|
||||
_scroll->show();
|
||||
controls->show();
|
||||
button->show();
|
||||
window->show();
|
||||
}
|
||||
|
||||
void LocationPicker::setupWebview(const Descriptor &descriptor) {
|
||||
void LocationPicker::setupWebview() {
|
||||
Expects(!_webview);
|
||||
|
||||
delete base::take(_mapPlaceholder);
|
||||
|
||||
const auto mapControls = _mapControlsWrap->entity();
|
||||
mapControls->insert(
|
||||
1,
|
||||
object_ptr<BoxContentDivider>(mapControls)
|
||||
)->show();
|
||||
|
||||
_mapButton = mapControls->insert(
|
||||
1,
|
||||
MakeChooseLocationButton(
|
||||
mapControls,
|
||||
_chooseButtonLabel.value(),
|
||||
_geocoderAddress.value()),
|
||||
{ 0, st::pickLocationButtonSkip, 0, st::pickLocationButtonSkip });
|
||||
_mapButton->setClickedCallback([=] {
|
||||
_webview->eval("LocationPicker.send();");
|
||||
});
|
||||
_mapButton->hide();
|
||||
|
||||
_scroll->scrollToY(0);
|
||||
_venuesSearchShown.force_assign(_venuesSearchShown.current());
|
||||
|
||||
_mapLoading = CreateChild<RpWidget>(_body.get());
|
||||
|
||||
_container->geometryValue() | rpl::start_with_next([=](QRect rect) {
|
||||
_mapLoading->setGeometry(rect);
|
||||
}, _mapLoading->lifetime());
|
||||
|
||||
SetupLoadingView(_mapLoading);
|
||||
_mapLoading->show();
|
||||
|
||||
const auto window = _window.get();
|
||||
_webview = std::make_unique<Webview::Window>(
|
||||
_container,
|
||||
Webview::WindowConfig{
|
||||
.opaqueBg = st::windowBg->c,
|
||||
.storageId = descriptor.storageId,
|
||||
.storageId = _webviewStorageId,
|
||||
.dataProtocolOverride = kProtocolOverride,
|
||||
});
|
||||
const auto raw = _webview.get();
|
||||
@ -823,12 +952,6 @@ void LocationPicker::setupWebview(const Descriptor &descriptor) {
|
||||
const auto event = object.value("event").toString();
|
||||
if (event == u"ready"_q) {
|
||||
mapReady();
|
||||
if (!_initialProvided) {
|
||||
resolveCurrentLocation();
|
||||
}
|
||||
if (_webview) {
|
||||
_webview->focus();
|
||||
}
|
||||
} else if (event == u"keydown"_q) {
|
||||
const auto key = object.value("key").toString();
|
||||
const auto modifier = object.value("modifier").toString();
|
||||
@ -968,6 +1091,8 @@ void LocationPicker::resolveAddress(Core::GeoLocation location) {
|
||||
void LocationPicker::mapReady() {
|
||||
Expects(_scroll != nullptr);
|
||||
|
||||
delete base::take(_mapLoading);
|
||||
|
||||
const auto token = _config.mapsToken.toUtf8();
|
||||
const auto center = DefaultCenter(_initialProvided);
|
||||
const auto bounds = DefaultBounds();
|
||||
@ -980,7 +1105,11 @@ void LocationPicker::mapReady() {
|
||||
+ ", protocol: " + protocol;
|
||||
_webview->eval("LocationPicker.init({ " + params + " });");
|
||||
|
||||
_scroll->show();
|
||||
const auto handle = _window->window()->windowHandle();
|
||||
if (handle && QGuiApplication::focusWindow() == handle) {
|
||||
_webview->focus();
|
||||
}
|
||||
_mapButton->show();
|
||||
}
|
||||
|
||||
bool LocationPicker::venuesFromCache(
|
||||
@ -1163,6 +1292,12 @@ void LocationPicker::processKey(
|
||||
}
|
||||
}
|
||||
|
||||
void LocationPicker::activate() {
|
||||
if (_window) {
|
||||
_window->activateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
void LocationPicker::close() {
|
||||
crl::on_main(this, [=] {
|
||||
_window = nullptr;
|
||||
|
@ -29,6 +29,7 @@ class Window;
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class AbstractButton;
|
||||
class SeparatePanel;
|
||||
class RpWidget;
|
||||
class ScrollArea;
|
||||
@ -93,6 +94,7 @@ public:
|
||||
[[nodiscard]] static bool Available(const LocationPickerConfig &config);
|
||||
static not_null<LocationPicker*> Show(Descriptor &&descriptor);
|
||||
|
||||
void activate();
|
||||
void close();
|
||||
void minimize();
|
||||
void quit();
|
||||
@ -109,7 +111,7 @@ private:
|
||||
|
||||
void setup(const Descriptor &descriptor);
|
||||
void setupWindow(const Descriptor &descriptor);
|
||||
void setupWebview(const Descriptor &descriptor);
|
||||
void setupWebview();
|
||||
void processKey(const QString &key, const QString &modifier);
|
||||
void resolveCurrentLocation();
|
||||
void resolveAddressByTimer();
|
||||
@ -129,11 +131,17 @@ private:
|
||||
std::unique_ptr<SeparatePanel> _window;
|
||||
not_null<RpWidget*> _body;
|
||||
RpWidget *_container = nullptr;
|
||||
RpWidget *_mapPlaceholder = nullptr;
|
||||
RpWidget *_mapLoading = nullptr;
|
||||
AbstractButton *_mapButton = nullptr;
|
||||
SlideWrap<VerticalLayout> *_mapControlsWrap = nullptr;
|
||||
rpl::variable<QString> _chooseButtonLabel;
|
||||
ScrollArea *_scroll = nullptr;
|
||||
Webview::StorageId _webviewStorageId;
|
||||
std::unique_ptr<Webview::Window> _webview;
|
||||
SingleQueuedInvokation _updateStyles;
|
||||
Core::GeoLocation _initialProvided;
|
||||
int _mapPlaceholderAdded = 0;
|
||||
bool _subscribedToColors = false;
|
||||
|
||||
base::Timer _geocoderResolveTimer;
|
||||
|
Loading…
Reference in New Issue
Block a user