From ebe2088561878a03ef9050366f531950a1528b69 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 4 Aug 2023 18:33:31 +0200 Subject: [PATCH] Parse story location marks. --- Telegram/SourceFiles/data/data_story.cpp | 60 +++++++++++++++++++++++- Telegram/SourceFiles/data/data_story.h | 27 +++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) diff --git a/Telegram/SourceFiles/data/data_story.cpp b/Telegram/SourceFiles/data/data_story.cpp index 30596269f..719c8a13c 100644 --- a/Telegram/SourceFiles/data/data_story.cpp +++ b/Telegram/SourceFiles/data/data_story.cpp @@ -31,6 +31,44 @@ namespace { using UpdateFlag = StoryUpdate::Flag; +[[nodiscard]] StoryArea ParseArea(const MTPMediaAreaCoordinates &area) { + const auto &data = area.data(); + return { + .geometry = { data.vx().v, data.vy().v, data.vw().v, data.vh().v }, + .rotation = data.vrotation().v, + }; +} + +[[nodiscard]] auto ParseLocation(const MTPMediaArea &area) +-> std::optional { + auto result = std::optional(); + area.match([&](const MTPDmediaAreaVenue &data) { + data.vgeo().match([&](const MTPDgeoPoint &geo) { + result.emplace(StoryLocation{ + .area = ParseArea(data.vcoordinates()), + .point = Data::LocationPoint(geo), + .title = qs(data.vtitle()), + .address = qs(data.vaddress()), + .provider = qs(data.vprovider()), + .venueId = qs(data.vvenue_id()), + .venueType = qs(data.vvenue_type()), + }); + }, [](const MTPDgeoPointEmpty &) { + }); + }, [&](const MTPDmediaAreaGeoPoint &data) { + data.vgeo().match([&](const MTPDgeoPoint &geo) { + result.emplace(StoryLocation{ + .area = ParseArea(data.vcoordinates()), + .point = Data::LocationPoint(geo), + }); + }, [](const MTPDgeoPointEmpty &) { + }); + }, [&](const MTPDinputMediaAreaVenue &data) { + LOG(("API Error: Unexpected inputMediaAreaVenue in API data.")); + }); + return result; +} + } // namespace class StoryPreload::LoadTask final : private Storage::DownloadMtprotoTask { @@ -399,6 +437,10 @@ void Story::applyViewsSlice( } } +const std::vector &Story::locations() const { + return _locations; +} + void Story::applyChanges( StoryMedia media, const MTPDstoryItem &data, @@ -449,6 +491,15 @@ void Story::applyFields( } } } + auto locations = std::vector(); + if (const auto areas = data.vmedia_areas()) { + locations.reserve(areas->v.size()); + for (const auto &area : areas->v) { + if (const auto parsed = ParseLocation(area)) { + locations.push_back(*parsed); + } + } + } const auto pinnedChanged = (_pinned != pinned); const auto editedChanged = (_edited != edited); @@ -457,6 +508,7 @@ void Story::applyFields( const auto viewsChanged = (_views.total != views) || (_views.reactions != reactions) || (_recentViewers != viewers); + const auto locationsChanged = (_locations != locations); _privacyPublic = (privacy == StoryPrivacy::Public); _privacyCloseFriends = (privacy == StoryPrivacy::CloseFriends); @@ -478,8 +530,14 @@ void Story::applyFields( if (captionChanged) { _caption = std::move(caption); } + if (locationsChanged) { + _locations = std::move(locations); + } - const auto changed = (editedChanged || captionChanged || mediaChanged); + const auto changed = editedChanged + || captionChanged + || mediaChanged + || locationsChanged; if (!initial && (changed || viewsChanged)) { _peer->session().changes().storyUpdated(this, UpdateFlag() | (changed ? UpdateFlag::Edited : UpdateFlag()) diff --git a/Telegram/SourceFiles/data/data_story.h b/Telegram/SourceFiles/data/data_story.h index 50d1dbff8..d288ee293 100644 --- a/Telegram/SourceFiles/data/data_story.h +++ b/Telegram/SourceFiles/data/data_story.h @@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #pragma once #include "base/weak_ptr.h" +#include "data/data_location.h" #include "data/data_message_reaction_id.h" class Image; @@ -72,6 +73,29 @@ struct StoryViews { int total = 0; }; +struct StoryArea { + QRectF geometry; + float64 rotation = 0; + + friend inline bool operator==( + const StoryArea &, + const StoryArea &) = default; +}; + +struct StoryLocation { + StoryArea area; + Data::LocationPoint point; + QString title; + QString address; + QString provider; + QString venueId; + QString venueType; + + friend inline bool operator==( + const StoryLocation &, + const StoryLocation &) = default; +}; + class Story final { public: Story( @@ -129,6 +153,8 @@ public: [[nodiscard]] int reactions() const; void applyViewsSlice(const QString &offset, const StoryViews &slice); + [[nodiscard]] const std::vector &locations() const; + void applyChanges( StoryMedia media, const MTPDstoryItem &data, @@ -147,6 +173,7 @@ private: StoryMedia _media; TextWithEntities _caption; std::vector> _recentViewers; + std::vector _locations; StoryViews _views; const TimeId _date = 0; const TimeId _expires = 0;