/* 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/invoke_queued.h" #include "base/timer.h" #include "base/weak_ptr.h" #include "core/current_geo_location.h" #include "mtproto/sender.h" #include "webview/webview_common.h" namespace Data { struct InputVenue; } // namespace Data namespace Main { class Session; class SessionShow; } // namespace Main namespace Webview { class Window; } // namespace Webview namespace Ui { class AbstractButton; class SeparatePanel; class RpWidget; class ScrollArea; class VerticalLayout; template class SlideWrap; struct PickerVenueLoading { friend inline bool operator==( PickerVenueLoading, PickerVenueLoading) = default; }; struct PickerVenueNothingFound { QString query; friend inline bool operator==( const PickerVenueNothingFound&, const PickerVenueNothingFound&) = default; }; struct PickerVenueWaitingForLocation { friend inline bool operator==( PickerVenueWaitingForLocation, PickerVenueWaitingForLocation) = default; }; struct PickerVenueList { std::vector list; friend inline bool operator==( const PickerVenueList&, const PickerVenueList&) = default; }; using PickerVenueState = std::variant< PickerVenueLoading, PickerVenueNothingFound, PickerVenueWaitingForLocation, PickerVenueList>; struct LocationPickerConfig { QString mapsToken; QString geoToken; }; class LocationPicker final : public base::has_weak_ptr { public: struct Descriptor { RpWidget *parent = nullptr; LocationPickerConfig config; rpl::producer chooseLabel; PeerData *recipient = nullptr; not_null session; Core::GeoLocation initial; Fn callback; Fn quit; Webview::StorageId storageId; rpl::producer<> closeRequests; }; [[nodiscard]] static bool Available(const LocationPickerConfig &config); static not_null Show(Descriptor &&descriptor); void activate(); void close(); void minimize(); void quit(); private: struct VenuesCacheEntry { Core::GeoLocation location; PickerVenueList result; }; explicit LocationPicker(Descriptor &&descriptor); [[nodiscard]] std::shared_ptr uiShow(); void setup(const Descriptor &descriptor); void setupWindow(const Descriptor &descriptor); void setupWebview(); void processKey(const QString &key, const QString &modifier); void resolveCurrentLocation(); void resolveAddressByTimer(); void resolveAddress(Core::GeoLocation location); void mapReady(); bool venuesFromCache(Core::GeoLocation location, QString query = {}); void venuesRequest(Core::GeoLocation location, QString query = {}); void venuesSendRequest(); void venuesApplyResults(PickerVenueList venues); void venuesSearchEnableAt(Core::GeoLocation location); void venuesSearchChanged(const std::optional &query); LocationPickerConfig _config; Fn _callback; Fn _quit; std::unique_ptr _window; not_null _body; RpWidget *_container = nullptr; RpWidget *_mapPlaceholder = nullptr; RpWidget *_mapLoading = nullptr; AbstractButton *_mapButton = nullptr; SlideWrap *_mapControlsWrap = nullptr; rpl::variable _chooseButtonLabel; ScrollArea *_scroll = nullptr; Webview::StorageId _webviewStorageId; std::unique_ptr _webview; SingleQueuedInvokation _updateStyles; Core::GeoLocation _initialProvided; int _mapPlaceholderAdded = 0; bool _subscribedToColors = false; base::Timer _geocoderResolveTimer; Core::GeoLocation _geocoderResolvePostponed; Core::GeoLocation _geocoderResolvingFor; QString _geocoderSavedAddress; rpl::variable _geocoderAddress; rpl::variable _venueState; const not_null _session; std::optional _venuesSearchLocation; std::optional _venuesSearchQuery; base::Timer _venuesSearchDebounceTimer; MTP::Sender _api; PeerData *_venueRecipient = nullptr; UserData *_venuesBot = nullptr; mtpRequestId _venuesBotRequestId = 0; mtpRequestId _venuesRequestId = 0; Core::GeoLocation _venuesRequestLocation; QString _venuesRequestQuery; QString _venuesInitialQuery; base::flat_map> _venuesCache; Core::GeoLocation _venuesNoSearchLocation; rpl::variable _venuesSearchShown = false; rpl::lifetime _lifetime; }; } // namespace Ui