mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Send chosen venues.
This commit is contained in:
parent
a130bb1be6
commit
8ce10d5503
6 changed files with 73 additions and 64 deletions
|
@ -54,6 +54,10 @@ struct InputVenue {
|
||||||
QString id;
|
QString id;
|
||||||
QString venueType;
|
QString venueType;
|
||||||
|
|
||||||
|
[[nodiscard]] bool justLocation() const {
|
||||||
|
return id.isEmpty() && title.isEmpty() && address.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
friend inline bool operator==(
|
friend inline bool operator==(
|
||||||
const InputVenue &,
|
const InputVenue &,
|
||||||
const InputVenue &) = default;
|
const InputVenue &) = default;
|
||||||
|
|
|
@ -158,12 +158,16 @@ constexpr auto kRefreshBotsTimeout = 60 * 60 * crl::time(1000);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] QString ResolveMapsToken(not_null<Main::Session*> session) {
|
[[nodiscard]] Ui::LocationPickerConfig ResolveMapsConfig(
|
||||||
return u""_q;
|
not_null<Main::Session*> session) {
|
||||||
}
|
const auto &appConfig = session->appConfig();
|
||||||
|
auto map = appConfig.get<base::flat_map<QString, QString>>(
|
||||||
[[nodiscard]] QString ResolveGeocodingToken(not_null<Main::Session*> session) {
|
u"tdesktop_config_map"_q,
|
||||||
return u""_q;
|
base::flat_map<QString, QString>());
|
||||||
|
return {
|
||||||
|
.mapsToken = map[u"maps"_q],
|
||||||
|
.geoToken = map[u"geo"_q],
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowChooseBox(
|
void ShowChooseBox(
|
||||||
|
@ -1806,12 +1810,18 @@ void AttachWebView::toggleInMenu(
|
||||||
|
|
||||||
void ChooseAndSendLocation(
|
void ChooseAndSendLocation(
|
||||||
not_null<Window::SessionController*> controller,
|
not_null<Window::SessionController*> controller,
|
||||||
|
const Ui::LocationPickerConfig &config,
|
||||||
Api::SendAction action) {
|
Api::SendAction action) {
|
||||||
const auto callback = [=](Ui::LocationInfo info) {
|
const auto callback = [=](Data::InputVenue venue) {
|
||||||
Api::SendLocation(action, info.lat, info.lon);
|
if (venue.justLocation()) {
|
||||||
|
Api::SendLocation(action, venue.lat, venue.lon);
|
||||||
|
} else {
|
||||||
|
Api::SendVenue(action, venue);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ui::LocationPicker::Show({
|
Ui::LocationPicker::Show({
|
||||||
.parent = controller->widget(),
|
.parent = controller->widget(),
|
||||||
|
.config = config,
|
||||||
.session = &controller->session(),
|
.session = &controller->session(),
|
||||||
.callback = crl::guard(controller, callback),
|
.callback = crl::guard(controller, callback),
|
||||||
.quit = [] { Shortcuts::Launch(Shortcuts::Command::Quit); },
|
.quit = [] { Shortcuts::Launch(Shortcuts::Command::Quit); },
|
||||||
|
@ -1876,12 +1886,11 @@ std::unique_ptr<Ui::DropdownMenu> MakeAttachBotsMenu(
|
||||||
}
|
}
|
||||||
const auto session = &controller->session();
|
const auto session = &controller->session();
|
||||||
const auto locationType = ChatRestriction::SendOther;
|
const auto locationType = ChatRestriction::SendOther;
|
||||||
|
const auto config = ResolveMapsConfig(session);
|
||||||
if (Data::CanSendAnyOf(peer, locationType)
|
if (Data::CanSendAnyOf(peer, locationType)
|
||||||
&& Ui::LocationPicker::Available(
|
&& Ui::LocationPicker::Available(config)) {
|
||||||
ResolveMapsToken(session),
|
|
||||||
ResolveGeocodingToken(session))) {
|
|
||||||
raw->addAction(tr::lng_maps_point(tr::now), [=] {
|
raw->addAction(tr::lng_maps_point(tr::now), [=] {
|
||||||
ChooseAndSendLocation(controller, actionFactory());
|
ChooseAndSendLocation(controller, config, actionFactory());
|
||||||
}, &st::menuIconAddress);
|
}, &st::menuIconAddress);
|
||||||
}
|
}
|
||||||
for (const auto &bot : bots->attachBots()) {
|
for (const auto &bot : bots->attachBots()) {
|
||||||
|
|
|
@ -144,28 +144,22 @@ std::vector<QString> AppConfig::getStringArray(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::map<QString, QString>> AppConfig::getStringMapArray(
|
base::flat_map<QString, QString> AppConfig::getStringMap(
|
||||||
const QString &key,
|
const QString &key,
|
||||||
std::vector<std::map<QString, QString>> &&fallback) const {
|
base::flat_map<QString, QString> &&fallback) const {
|
||||||
return getValue(key, [&](const MTPJSONValue &value) {
|
return getValue(key, [&](const MTPJSONValue &value) {
|
||||||
return value.match([&](const MTPDjsonArray &data) {
|
return value.match([&](const MTPDjsonObject &data) {
|
||||||
auto result = std::vector<std::map<QString, QString>>();
|
auto result = base::flat_map<QString, QString>();
|
||||||
result.reserve(data.vvalue().v.size());
|
result.reserve(data.vvalue().v.size());
|
||||||
for (const auto &entry : data.vvalue().v) {
|
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);
|
return std::move(fallback);
|
||||||
}
|
}
|
||||||
auto element = std::map<QString, QString>();
|
result.emplace(
|
||||||
for (const auto &field : entry.c_jsonObject().vvalue().v) {
|
qs(data.vkey()),
|
||||||
const auto &data = field.c_jsonObjectValue();
|
qs(value.c_jsonString().vvalue()));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}, [&](const auto &data) {
|
}, [&](const auto &data) {
|
||||||
|
|
|
@ -35,12 +35,11 @@ public:
|
||||||
return getString(key, fallback);
|
return getString(key, fallback);
|
||||||
} else if constexpr (std::is_same_v<Type, std::vector<QString>>) {
|
} else if constexpr (std::is_same_v<Type, std::vector<QString>>) {
|
||||||
return getStringArray(key, std::move(fallback));
|
return getStringArray(key, std::move(fallback));
|
||||||
|
} else if constexpr (
|
||||||
|
std::is_same_v<Type, base::flat_map<QString, QString>>) {
|
||||||
|
return getStringMap(key, std::move(fallback));
|
||||||
} else if constexpr (std::is_same_v<Type, std::vector<int>>) {
|
} else if constexpr (std::is_same_v<Type, std::vector<int>>) {
|
||||||
return getIntArray(key, std::move(fallback));
|
return getIntArray(key, std::move(fallback));
|
||||||
} else if constexpr (std::is_same_v<
|
|
||||||
Type,
|
|
||||||
std::vector<std::map<QString, QString>>>) {
|
|
||||||
return getStringMapArray(key, std::move(fallback));
|
|
||||||
} else if constexpr (std::is_same_v<Type, bool>) {
|
} else if constexpr (std::is_same_v<Type, bool>) {
|
||||||
return getBool(key, fallback);
|
return getBool(key, fallback);
|
||||||
}
|
}
|
||||||
|
@ -78,9 +77,9 @@ private:
|
||||||
[[nodiscard]] std::vector<QString> getStringArray(
|
[[nodiscard]] std::vector<QString> getStringArray(
|
||||||
const QString &key,
|
const QString &key,
|
||||||
std::vector<QString> &&fallback) const;
|
std::vector<QString> &&fallback) const;
|
||||||
[[nodiscard]] std::vector<std::map<QString, QString>> getStringMapArray(
|
[[nodiscard]] base::flat_map<QString, QString> getStringMap(
|
||||||
const QString &key,
|
const QString &key,
|
||||||
std::vector<std::map<QString, QString>> &&fallback) const;
|
base::flat_map<QString, QString> &&fallback) const;
|
||||||
[[nodiscard]] std::vector<int> getIntArray(
|
[[nodiscard]] std::vector<int> getIntArray(
|
||||||
const QString &key,
|
const QString &key,
|
||||||
std::vector<int> &&fallback) const;
|
std::vector<int> &&fallback) const;
|
||||||
|
|
|
@ -56,8 +56,6 @@ const auto kProtocolOverride = "";
|
||||||
#endif // Q_OS_MAC
|
#endif // Q_OS_MAC
|
||||||
|
|
||||||
Core::GeoLocation LastExactLocation;
|
Core::GeoLocation LastExactLocation;
|
||||||
QString MapsProviderToken;
|
|
||||||
QString GeocodingProviderToken;
|
|
||||||
|
|
||||||
using VenueData = Data::InputVenue;
|
using VenueData = Data::InputVenue;
|
||||||
|
|
||||||
|
@ -136,7 +134,8 @@ class VenuesController final
|
||||||
public:
|
public:
|
||||||
VenuesController(
|
VenuesController(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
rpl::producer<std::vector<VenueData>> content);
|
rpl::producer<std::vector<VenueData>> content,
|
||||||
|
Fn<void(VenueData)> callback);
|
||||||
|
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
|
@ -165,6 +164,7 @@ private:
|
||||||
void rebuild(const std::vector<VenueData> &rows);
|
void rebuild(const std::vector<VenueData> &rows);
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Main::Session*> _session;
|
||||||
|
const Fn<void(VenueData)> _callback;
|
||||||
rpl::variable<std::vector<VenueData>> _rows;
|
rpl::variable<std::vector<VenueData>> _rows;
|
||||||
|
|
||||||
base::flat_map<QString, VenueIcon> _icons;
|
base::flat_map<QString, VenueIcon> _icons;
|
||||||
|
@ -179,8 +179,10 @@ private:
|
||||||
|
|
||||||
VenuesController::VenuesController(
|
VenuesController::VenuesController(
|
||||||
not_null<Main::Session*> session,
|
not_null<Main::Session*> session,
|
||||||
rpl::producer<std::vector<VenueData>> content)
|
rpl::producer<std::vector<VenueData>> content,
|
||||||
|
Fn<void(VenueData)> callback)
|
||||||
: _session(session)
|
: _session(session)
|
||||||
|
, _callback(std::move(callback))
|
||||||
, _rows(std::move(content)) {
|
, _rows(std::move(content)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,8 +213,7 @@ void VenuesController::rebuild(const std::vector<VenueData> &rows) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VenuesController::rowClicked(not_null<PeerListRow*> row) {
|
void VenuesController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
const auto venue = static_cast<VenueRow*>(row.get())->data();
|
_callback(static_cast<VenueRow*>(row.get())->data());
|
||||||
venue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VenuesController::rowRightActionClicked(not_null<PeerListRow*> row) {
|
void VenuesController::rowRightActionClicked(not_null<PeerListRow*> row) {
|
||||||
|
@ -468,13 +469,15 @@ void VenuesController::rowPaintIcon(
|
||||||
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<std::vector<VenueData>> value,
|
||||||
|
Fn<void(VenueData)> callback) {
|
||||||
auto &lifetime = container->lifetime();
|
auto &lifetime = container->lifetime();
|
||||||
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(value),
|
||||||
|
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>(
|
||||||
container,
|
container,
|
||||||
|
@ -520,7 +523,8 @@ void SetupVenues(
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
LocationPicker::LocationPicker(Descriptor &&descriptor)
|
LocationPicker::LocationPicker(Descriptor &&descriptor)
|
||||||
: _callback(std::move(descriptor.callback))
|
: _config(std::move(descriptor.config))
|
||||||
|
, _callback(std::move(descriptor.callback))
|
||||||
, _quit(std::move(descriptor.quit))
|
, _quit(std::move(descriptor.quit))
|
||||||
, _window(std::make_unique<SeparatePanel>())
|
, _window(std::make_unique<SeparatePanel>())
|
||||||
, _body((_window->setInnerSize(st::pickLocationWindow)
|
, _body((_window->setInnerSize(st::pickLocationWindow)
|
||||||
|
@ -550,13 +554,9 @@ std::shared_ptr<Main::SessionShow> LocationPicker::uiShow() {
|
||||||
return Main::MakeSessionShow(nullptr, _session);
|
return Main::MakeSessionShow(nullptr, _session);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LocationPicker::Available(
|
bool LocationPicker::Available(const LocationPickerConfig &config) {
|
||||||
const QString &mapsToken,
|
|
||||||
const QString &geocodingToken) {
|
|
||||||
static const auto Supported = Webview::NavigateToDataSupported();
|
static const auto Supported = Webview::NavigateToDataSupported();
|
||||||
MapsProviderToken = mapsToken;
|
return Supported && !config.mapsToken.isEmpty();
|
||||||
GeocodingProviderToken = geocodingToken;
|
|
||||||
return Supported && !MapsProviderToken.isEmpty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationPicker::setup(const Descriptor &descriptor) {
|
void LocationPicker::setup(const Descriptor &descriptor) {
|
||||||
|
@ -606,7 +606,10 @@ void LocationPicker::setupWindow(const Descriptor &descriptor) {
|
||||||
return v::is<PickerVenueList>(state);
|
return v::is<PickerVenueList>(state);
|
||||||
}) | rpl::map([=](PickerVenueState &&state) {
|
}) | rpl::map([=](PickerVenueState &&state) {
|
||||||
return std::move(v::get<PickerVenueList>(state).list);
|
return std::move(v::get<PickerVenueList>(state).list);
|
||||||
}));
|
}), [=](VenueData info) {
|
||||||
|
_callback(std::move(info));
|
||||||
|
close();
|
||||||
|
});
|
||||||
|
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
_body->sizeValue(),
|
_body->sizeValue(),
|
||||||
|
@ -810,14 +813,14 @@ void LocationPicker::resolveAddress(Core::GeoLocation location) {
|
||||||
Core::ResolveLocationAddress(
|
Core::ResolveLocationAddress(
|
||||||
location,
|
location,
|
||||||
langId,
|
langId,
|
||||||
GeocodingProviderToken,
|
_config.geoToken,
|
||||||
crl::guard(this, done));
|
crl::guard(this, done));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocationPicker::mapReady() {
|
void LocationPicker::mapReady() {
|
||||||
Expects(_scroll != nullptr);
|
Expects(_scroll != nullptr);
|
||||||
|
|
||||||
const auto token = MapsProviderToken.toUtf8();
|
const auto token = _config.mapsToken.toUtf8();
|
||||||
const auto center = DefaultCenter();
|
const auto center = DefaultCenter();
|
||||||
const auto bounds = DefaultBounds();
|
const auto bounds = DefaultBounds();
|
||||||
const auto protocol = *kProtocolOverride
|
const auto protocol = *kProtocolOverride
|
||||||
|
|
|
@ -33,11 +33,6 @@ class SeparatePanel;
|
||||||
class RpWidget;
|
class RpWidget;
|
||||||
class ScrollArea;
|
class ScrollArea;
|
||||||
|
|
||||||
struct LocationInfo {
|
|
||||||
float64 lat = 0.;
|
|
||||||
float64 lon = 0.;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PickerVenueLoading {
|
struct PickerVenueLoading {
|
||||||
friend inline bool operator==(
|
friend inline bool operator==(
|
||||||
PickerVenueLoading,
|
PickerVenueLoading,
|
||||||
|
@ -72,20 +67,24 @@ using PickerVenueState = std::variant<
|
||||||
PickerVenueWaitingForLocation,
|
PickerVenueWaitingForLocation,
|
||||||
PickerVenueList>;
|
PickerVenueList>;
|
||||||
|
|
||||||
|
struct LocationPickerConfig {
|
||||||
|
QString mapsToken;
|
||||||
|
QString geoToken;
|
||||||
|
};
|
||||||
|
|
||||||
class LocationPicker final : public base::has_weak_ptr {
|
class LocationPicker final : public base::has_weak_ptr {
|
||||||
public:
|
public:
|
||||||
struct Descriptor {
|
struct Descriptor {
|
||||||
RpWidget *parent = nullptr;
|
RpWidget *parent = nullptr;
|
||||||
|
LocationPickerConfig config;
|
||||||
not_null<Main::Session*> session;
|
not_null<Main::Session*> session;
|
||||||
Fn<void(LocationInfo)> callback;
|
Fn<void(Data::InputVenue)> callback;
|
||||||
Fn<void()> quit;
|
Fn<void()> quit;
|
||||||
Webview::StorageId storageId;
|
Webview::StorageId storageId;
|
||||||
rpl::producer<> closeRequests;
|
rpl::producer<> closeRequests;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[nodiscard]] static bool Available(
|
[[nodiscard]] static bool Available(const LocationPickerConfig &config);
|
||||||
const QString &mapsToken,
|
|
||||||
const QString &geocodingToken);
|
|
||||||
static not_null<LocationPicker*> Show(Descriptor &&descriptor);
|
static not_null<LocationPicker*> Show(Descriptor &&descriptor);
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
@ -114,9 +113,8 @@ private:
|
||||||
void venuesRequest(Core::GeoLocation location, QString query = {});
|
void venuesRequest(Core::GeoLocation location, QString query = {});
|
||||||
void venuesSendRequest();
|
void venuesSendRequest();
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
LocationPickerConfig _config;
|
||||||
|
Fn<void(Data::InputVenue)> _callback;
|
||||||
Fn<void(LocationInfo)> _callback;
|
|
||||||
Fn<void()> _quit;
|
Fn<void()> _quit;
|
||||||
std::unique_ptr<SeparatePanel> _window;
|
std::unique_ptr<SeparatePanel> _window;
|
||||||
not_null<RpWidget*> _body;
|
not_null<RpWidget*> _body;
|
||||||
|
@ -143,6 +141,8 @@ private:
|
||||||
QString _venuesRequestQuery;
|
QString _venuesRequestQuery;
|
||||||
base::flat_map<QString, std::vector<VenuesCacheEntry>> _venuesCache;
|
base::flat_map<QString, std::vector<VenuesCacheEntry>> _venuesCache;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
Loading…
Add table
Reference in a new issue