From 8ce10d55038e2d025e5008c4d84e2cb3210b1acc Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 12 Jul 2024 12:23:47 +0200 Subject: [PATCH] Send chosen venues. --- Telegram/SourceFiles/data/data_location.h | 4 ++ .../inline_bots/bot_attach_web_view.cpp | 33 ++++++++++------ Telegram/SourceFiles/main/main_app_config.cpp | 26 +++++-------- Telegram/SourceFiles/main/main_app_config.h | 11 +++--- .../ui/controls/location_picker.cpp | 39 ++++++++++--------- .../SourceFiles/ui/controls/location_picker.h | 24 ++++++------ 6 files changed, 73 insertions(+), 64 deletions(-) diff --git a/Telegram/SourceFiles/data/data_location.h b/Telegram/SourceFiles/data/data_location.h index 10f05adfb..5157f79a1 100644 --- a/Telegram/SourceFiles/data/data_location.h +++ b/Telegram/SourceFiles/data/data_location.h @@ -54,6 +54,10 @@ struct InputVenue { QString id; QString venueType; + [[nodiscard]] bool justLocation() const { + return id.isEmpty() && title.isEmpty() && address.isEmpty(); + } + friend inline bool operator==( const InputVenue &, const InputVenue &) = default; diff --git a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp index b9233313c..d52e13b82 100644 --- a/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp +++ b/Telegram/SourceFiles/inline_bots/bot_attach_web_view.cpp @@ -158,12 +158,16 @@ constexpr auto kRefreshBotsTimeout = 60 * 60 * crl::time(1000); return result; } -[[nodiscard]] QString ResolveMapsToken(not_null session) { - return u""_q; -} - -[[nodiscard]] QString ResolveGeocodingToken(not_null session) { - return u""_q; +[[nodiscard]] Ui::LocationPickerConfig ResolveMapsConfig( + not_null session) { + const auto &appConfig = session->appConfig(); + auto map = appConfig.get>( + u"tdesktop_config_map"_q, + base::flat_map()); + return { + .mapsToken = map[u"maps"_q], + .geoToken = map[u"geo"_q], + }; } void ShowChooseBox( @@ -1806,12 +1810,18 @@ void AttachWebView::toggleInMenu( void ChooseAndSendLocation( not_null controller, + const Ui::LocationPickerConfig &config, Api::SendAction action) { - const auto callback = [=](Ui::LocationInfo info) { - Api::SendLocation(action, info.lat, info.lon); + const auto callback = [=](Data::InputVenue venue) { + if (venue.justLocation()) { + Api::SendLocation(action, venue.lat, venue.lon); + } else { + Api::SendVenue(action, venue); + } }; Ui::LocationPicker::Show({ .parent = controller->widget(), + .config = config, .session = &controller->session(), .callback = crl::guard(controller, callback), .quit = [] { Shortcuts::Launch(Shortcuts::Command::Quit); }, @@ -1876,12 +1886,11 @@ std::unique_ptr MakeAttachBotsMenu( } const auto session = &controller->session(); const auto locationType = ChatRestriction::SendOther; + const auto config = ResolveMapsConfig(session); if (Data::CanSendAnyOf(peer, locationType) - && Ui::LocationPicker::Available( - ResolveMapsToken(session), - ResolveGeocodingToken(session))) { + && Ui::LocationPicker::Available(config)) { raw->addAction(tr::lng_maps_point(tr::now), [=] { - ChooseAndSendLocation(controller, actionFactory()); + ChooseAndSendLocation(controller, config, actionFactory()); }, &st::menuIconAddress); } for (const auto &bot : bots->attachBots()) { diff --git a/Telegram/SourceFiles/main/main_app_config.cpp b/Telegram/SourceFiles/main/main_app_config.cpp index 2507dc8f1..6a4c63c35 100644 --- a/Telegram/SourceFiles/main/main_app_config.cpp +++ b/Telegram/SourceFiles/main/main_app_config.cpp @@ -144,28 +144,22 @@ std::vector AppConfig::getStringArray( }); } -std::vector> AppConfig::getStringMapArray( +base::flat_map AppConfig::getStringMap( const QString &key, - std::vector> &&fallback) const { + base::flat_map &&fallback) const { return getValue(key, [&](const MTPJSONValue &value) { - return value.match([&](const MTPDjsonArray &data) { - auto result = std::vector>(); + return value.match([&](const MTPDjsonObject &data) { + auto result = base::flat_map(); result.reserve(data.vvalue().v.size()); for (const auto &entry : data.vvalue().v) { - if (entry.type() != mtpc_jsonObject) { + const auto &data = entry.data(); + const auto &value = data.vvalue(); + if (value.type() != mtpc_jsonString) { return std::move(fallback); } - auto element = std::map(); - for (const auto &field : entry.c_jsonObject().vvalue().v) { - const auto &data = field.c_jsonObjectValue(); - if (data.vvalue().type() != mtpc_jsonString) { - return std::move(fallback); - } - element.emplace( - qs(data.vkey()), - qs(data.vvalue().c_jsonString().vvalue())); - } - result.push_back(std::move(element)); + result.emplace( + qs(data.vkey()), + qs(value.c_jsonString().vvalue())); } return result; }, [&](const auto &data) { diff --git a/Telegram/SourceFiles/main/main_app_config.h b/Telegram/SourceFiles/main/main_app_config.h index 67b985348..f09d5f120 100644 --- a/Telegram/SourceFiles/main/main_app_config.h +++ b/Telegram/SourceFiles/main/main_app_config.h @@ -35,12 +35,11 @@ public: return getString(key, fallback); } else if constexpr (std::is_same_v>) { return getStringArray(key, std::move(fallback)); + } else if constexpr ( + std::is_same_v>) { + return getStringMap(key, std::move(fallback)); } else if constexpr (std::is_same_v>) { return getIntArray(key, std::move(fallback)); - } else if constexpr (std::is_same_v< - Type, - std::vector>>) { - return getStringMapArray(key, std::move(fallback)); } else if constexpr (std::is_same_v) { return getBool(key, fallback); } @@ -78,9 +77,9 @@ private: [[nodiscard]] std::vector getStringArray( const QString &key, std::vector &&fallback) const; - [[nodiscard]] std::vector> getStringMapArray( + [[nodiscard]] base::flat_map getStringMap( const QString &key, - std::vector> &&fallback) const; + base::flat_map &&fallback) const; [[nodiscard]] std::vector getIntArray( const QString &key, std::vector &&fallback) const; diff --git a/Telegram/SourceFiles/ui/controls/location_picker.cpp b/Telegram/SourceFiles/ui/controls/location_picker.cpp index b5920e131..9d926f980 100644 --- a/Telegram/SourceFiles/ui/controls/location_picker.cpp +++ b/Telegram/SourceFiles/ui/controls/location_picker.cpp @@ -56,8 +56,6 @@ const auto kProtocolOverride = ""; #endif // Q_OS_MAC Core::GeoLocation LastExactLocation; -QString MapsProviderToken; -QString GeocodingProviderToken; using VenueData = Data::InputVenue; @@ -136,7 +134,8 @@ class VenuesController final public: VenuesController( not_null session, - rpl::producer> content); + rpl::producer> content, + Fn callback); void prepare() override; void rowClicked(not_null row) override; @@ -165,6 +164,7 @@ private: void rebuild(const std::vector &rows); const not_null _session; + const Fn _callback; rpl::variable> _rows; base::flat_map _icons; @@ -179,8 +179,10 @@ private: VenuesController::VenuesController( not_null session, - rpl::producer> content) + rpl::producer> content, + Fn callback) : _session(session) +, _callback(std::move(callback)) , _rows(std::move(content)) { } @@ -211,8 +213,7 @@ void VenuesController::rebuild(const std::vector &rows) { } void VenuesController::rowClicked(not_null row) { - const auto venue = static_cast(row.get())->data(); - venue; + _callback(static_cast(row.get())->data()); } void VenuesController::rowRightActionClicked(not_null row) { @@ -468,13 +469,15 @@ void VenuesController::rowPaintIcon( void SetupVenues( not_null container, std::shared_ptr show, - rpl::producer> value) { + rpl::producer> value, + Fn callback) { auto &lifetime = container->lifetime(); const auto delegate = lifetime.make_state( show); const auto controller = lifetime.make_state( &show->session(), - std::move(value)); + std::move(value), + std::move(callback)); controller->setStyleOverrides(&st::pickLocationVenueList); const auto content = container->add(object_ptr( container, @@ -520,7 +523,8 @@ void SetupVenues( } // namespace LocationPicker::LocationPicker(Descriptor &&descriptor) -: _callback(std::move(descriptor.callback)) +: _config(std::move(descriptor.config)) +, _callback(std::move(descriptor.callback)) , _quit(std::move(descriptor.quit)) , _window(std::make_unique()) , _body((_window->setInnerSize(st::pickLocationWindow) @@ -550,13 +554,9 @@ std::shared_ptr LocationPicker::uiShow() { return Main::MakeSessionShow(nullptr, _session); } -bool LocationPicker::Available( - const QString &mapsToken, - const QString &geocodingToken) { +bool LocationPicker::Available(const LocationPickerConfig &config) { static const auto Supported = Webview::NavigateToDataSupported(); - MapsProviderToken = mapsToken; - GeocodingProviderToken = geocodingToken; - return Supported && !MapsProviderToken.isEmpty(); + return Supported && !config.mapsToken.isEmpty(); } void LocationPicker::setup(const Descriptor &descriptor) { @@ -606,7 +606,10 @@ void LocationPicker::setupWindow(const Descriptor &descriptor) { return v::is(state); }) | rpl::map([=](PickerVenueState &&state) { return std::move(v::get(state).list); - })); + }), [=](VenueData info) { + _callback(std::move(info)); + close(); + }); rpl::combine( _body->sizeValue(), @@ -810,14 +813,14 @@ void LocationPicker::resolveAddress(Core::GeoLocation location) { Core::ResolveLocationAddress( location, langId, - GeocodingProviderToken, + _config.geoToken, crl::guard(this, done)); } void LocationPicker::mapReady() { Expects(_scroll != nullptr); - const auto token = MapsProviderToken.toUtf8(); + const auto token = _config.mapsToken.toUtf8(); const auto center = DefaultCenter(); const auto bounds = DefaultBounds(); const auto protocol = *kProtocolOverride diff --git a/Telegram/SourceFiles/ui/controls/location_picker.h b/Telegram/SourceFiles/ui/controls/location_picker.h index 0adfc166f..b7996ee50 100644 --- a/Telegram/SourceFiles/ui/controls/location_picker.h +++ b/Telegram/SourceFiles/ui/controls/location_picker.h @@ -33,11 +33,6 @@ class SeparatePanel; class RpWidget; class ScrollArea; -struct LocationInfo { - float64 lat = 0.; - float64 lon = 0.; -}; - struct PickerVenueLoading { friend inline bool operator==( PickerVenueLoading, @@ -72,20 +67,24 @@ using PickerVenueState = std::variant< PickerVenueWaitingForLocation, PickerVenueList>; +struct LocationPickerConfig { + QString mapsToken; + QString geoToken; +}; + class LocationPicker final : public base::has_weak_ptr { public: struct Descriptor { RpWidget *parent = nullptr; + LocationPickerConfig config; not_null session; - Fn callback; + Fn callback; Fn quit; Webview::StorageId storageId; rpl::producer<> closeRequests; }; - [[nodiscard]] static bool Available( - const QString &mapsToken, - const QString &geocodingToken); + [[nodiscard]] static bool Available(const LocationPickerConfig &config); static not_null Show(Descriptor &&descriptor); void close(); @@ -114,9 +113,8 @@ private: void venuesRequest(Core::GeoLocation location, QString query = {}); void venuesSendRequest(); - rpl::lifetime _lifetime; - - Fn _callback; + LocationPickerConfig _config; + Fn _callback; Fn _quit; std::unique_ptr _window; not_null _body; @@ -143,6 +141,8 @@ private: QString _venuesRequestQuery; base::flat_map> _venuesCache; + rpl::lifetime _lifetime; + }; } // namespace Ui