2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 14:38:15 +00:00

Update API scheme to layer 164.

This commit is contained in:
John Preston
2023-08-31 12:58:34 +04:00
parent 1bde096417
commit d5b429e910
37 changed files with 586 additions and 358 deletions

View File

@@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "core/application.h"
#include "data/data_changes.h"
#include "data/data_channel.h"
#include "data/data_document.h"
#include "data/data_folder.h"
#include "data/data_photo.h"
@@ -78,11 +79,11 @@ using UpdateFlag = StoryUpdate::Flag;
StoriesSourceInfo StoriesSource::info() const {
return {
.id = user->id,
.id = peer->id,
.last = ids.empty() ? 0 : ids.back().date,
.count = uint32(std::min(int(ids.size()), kMaxSegmentsCount)),
.unreadCount = uint32(std::min(unreadCount(), kMaxSegmentsCount)),
.premium = user->isPremium() ? 1U : 0U,
.premium = (peer->isUser() && peer->asUser()->isPremium()) ? 1U : 0,
};
}
@@ -122,10 +123,10 @@ Main::Session &Stories::session() const {
}
void Stories::apply(const MTPDupdateStory &data) {
const auto peerId = peerFromUser(data.vuser_id());
const auto user = not_null(_owner->peer(peerId)->asUser());
const auto peerId = peerFromMTP(data.vpeer());
const auto peer = _owner->peer(peerId);
const auto now = base::unixtime::now();
const auto idDates = parseAndApply(user, data.vstory(), now);
const auto idDates = parseAndApply(peer, data.vstory(), now);
if (!idDates) {
return;
}
@@ -136,7 +137,7 @@ void Stories::apply(const MTPDupdateStory &data) {
}
const auto i = _all.find(peerId);
if (i == end(_all)) {
requestUserStories(user);
requestPeerStories(peer);
return;
} else if (i->second.ids.contains(idDates)) {
return;
@@ -144,8 +145,8 @@ void Stories::apply(const MTPDupdateStory &data) {
const auto wasInfo = i->second.info();
i->second.ids.emplace(idDates);
const auto nowInfo = i->second.info();
if (user->isSelf() && i->second.readTill < idDates.id) {
_readTill[user->id] = i->second.readTill = idDates.id;
if (peer->isSelf() && i->second.readTill < idDates.id) {
_readTill[peerId] = i->second.readTill = idDates.id;
}
if (wasInfo == nowInfo) {
return;
@@ -161,17 +162,17 @@ void Stories::apply(const MTPDupdateStory &data) {
sort(list);
}
};
if (user->hasStoriesHidden()) {
if (peer->hasStoriesHidden()) {
refreshInList(StorySourcesList::Hidden);
} else {
refreshInList(StorySourcesList::NotHidden);
}
_sourceChanged.fire_copy(peerId);
updateUserStoriesState(user);
updatePeerStoriesState(peer);
}
void Stories::apply(const MTPDupdateReadStories &data) {
bumpReadTill(peerFromUser(data.vuser_id()), data.vmax_id().v);
bumpReadTill(peerFromMTP(data.vpeer()), data.vmax_id().v);
}
void Stories::apply(const MTPStoriesStealthMode &stealthMode) {
@@ -182,13 +183,13 @@ void Stories::apply(const MTPStoriesStealthMode &stealthMode) {
};
}
void Stories::apply(not_null<PeerData*> peer, const MTPUserStories *data) {
void Stories::apply(not_null<PeerData*> peer, const MTPPeerStories *data) {
if (!data) {
applyDeletedFromSources(peer->id, StorySourcesList::NotHidden);
applyDeletedFromSources(peer->id, StorySourcesList::Hidden);
_all.erase(peer->id);
_sourceChanged.fire_copy(peer->id);
updateUserStoriesState(peer);
updatePeerStoriesState(peer);
} else {
parseAndApply(*data);
}
@@ -205,10 +206,10 @@ Story *Stories::applyFromWebpage(PeerId peerId, const MTPstoryItem &story) {
return value ? value->get() : nullptr;
}
void Stories::requestUserStories(
not_null<UserData*> user,
void Stories::requestPeerStories(
not_null<PeerData*> peer,
Fn<void()> done) {
const auto [i, ok] = _requestingUserStories.emplace(user);
const auto [i, ok] = _requestingPeerStories.emplace(peer);
if (done) {
i->second.push_back(std::move(done));
}
@@ -216,22 +217,23 @@ void Stories::requestUserStories(
return;
}
const auto finish = [=] {
if (const auto callbacks = _requestingUserStories.take(user)) {
if (const auto callbacks = _requestingPeerStories.take(peer)) {
for (const auto &callback : *callbacks) {
callback();
}
}
};
_owner->session().api().request(MTPstories_GetUserStories(
user->inputUser
)).done([=](const MTPstories_UserStories &result) {
_owner->session().api().request(MTPstories_GetPeerStories(
peer->input
)).done([=](const MTPstories_PeerStories &result) {
const auto &data = result.data();
_owner->processUsers(data.vusers());
_owner->processChats(data.vchats());
parseAndApply(data.vstories());
finish();
}).fail([=] {
applyDeletedFromSources(user->id, StorySourcesList::NotHidden);
applyDeletedFromSources(user->id, StorySourcesList::Hidden);
applyDeletedFromSources(peer->id, StorySourcesList::NotHidden);
applyDeletedFromSources(peer->id, StorySourcesList::Hidden);
finish();
}).send();
}
@@ -291,33 +293,33 @@ void Stories::processExpired() {
}
}
void Stories::parseAndApply(const MTPUserStories &stories) {
void Stories::parseAndApply(const MTPPeerStories &stories) {
const auto &data = stories.data();
const auto peerId = peerFromUser(data.vuser_id());
const auto peerId = peerFromMTP(data.vpeer());
const auto already = _readTill.find(peerId);
const auto readTill = std::max(
data.vmax_read_id().value_or_empty(),
(already != end(_readTill) ? already->second : 0));
const auto user = _owner->peer(peerId)->asUser();
const auto peer = _owner->peer(peerId);
auto result = StoriesSource{
.user = user,
.peer = peer,
.readTill = readTill,
.hidden = user->hasStoriesHidden(),
.hidden = peer->hasStoriesHidden(),
};
const auto &list = data.vstories().v;
const auto now = base::unixtime::now();
result.ids.reserve(list.size());
for (const auto &story : list) {
if (const auto id = parseAndApply(result.user, story, now)) {
if (const auto id = parseAndApply(result.peer, story, now)) {
result.ids.emplace(id);
}
}
if (result.ids.empty()) {
applyDeletedFromSources(peerId, StorySourcesList::NotHidden);
applyDeletedFromSources(peerId, StorySourcesList::Hidden);
user->setStoriesState(UserData::StoriesState::None);
peer->setStoriesState(PeerData::StoriesState::None);
return;
} else if (user->isSelf()) {
} else if (peer->isSelf()) {
result.readTill = result.ids.back().id;
}
_readTill[peerId] = result.readTill;
@@ -345,11 +347,13 @@ void Stories::parseAndApply(const MTPUserStories &stories) {
}
sort(list);
};
if (result.user->isSelf()
|| result.user->isBot()
|| result.user->isServiceUser()
|| result.user->isContact()) {
const auto hidden = result.user->hasStoriesHidden();
if (result.peer->isSelf()
|| (result.peer->isChannel() && result.peer->asChannel()->amIn())
|| (result.peer->isUser()
&& (result.peer->asUser()->isBot()
|| result.peer->asUser()->isContact()))
|| result.peer->isServiceUser()) {
const auto hidden = result.peer->hasStoriesHidden();
using List = StorySourcesList;
add(hidden ? List::Hidden : List::NotHidden);
applyDeletedFromSources(
@@ -360,7 +364,7 @@ void Stories::parseAndApply(const MTPUserStories &stories) {
applyDeletedFromSources(peerId, StorySourcesList::Hidden);
}
_sourceChanged.fire_copy(peerId);
updateUserStoriesState(result.user);
updatePeerStoriesState(result.peer);
}
Story *Stories::parseAndApply(
@@ -539,9 +543,10 @@ void Stories::loadMore(StorySourcesList list) {
result.match([&](const MTPDstories_allStories &data) {
_owner->processUsers(data.vusers());
_owner->processChats(data.vchats());
_sourcesStates[index] = qs(data.vstate());
_sourcesLoaded[index] = !data.is_has_more();
for (const auto &single : data.vuser_stories().v) {
for (const auto &single : data.vpeer_stories().v) {
parseAndApply(single);
}
}, [](const MTPDstories_allStoriesNotModified &) {
@@ -654,18 +659,15 @@ void Stories::sendResolveRequests() {
crl::on_main(&session(), [=] { sendResolveRequests(); });
}
};
const auto user = _owner->session().data().peer(peerId)->asUser();
if (!user) {
finish(peerId);
continue;
}
const auto peer = _owner->session().data().peer(peerId);
api->request(MTPstories_GetStoriesByID(
user->inputUser,
peer->input,
MTP_vector<MTPint>(prepared)
)).done([=](const MTPstories_Stories &result) {
owner().processUsers(result.data().vusers());
processResolvedStories(user, result.data().vstories().v);
finish(user->id);
owner().processChats(result.data().vchats());
processResolvedStories(peer, result.data().vstories().v);
finish(peer->id);
}).fail([=] {
finish(peerId);
}).send();
@@ -786,14 +788,14 @@ void Stories::applyRemovedFromActive(FullStoryId id) {
const auto j = i->second.ids.lower_bound(StoryIdDates{ id.story });
if (j != end(i->second.ids) && j->id == id.story) {
i->second.ids.erase(j);
const auto user = i->second.user;
const auto peer = i->second.peer;
if (i->second.ids.empty()) {
_all.erase(i);
removeFromList(StorySourcesList::NotHidden);
removeFromList(StorySourcesList::Hidden);
}
_sourceChanged.fire_copy(id.peer);
updateUserStoriesState(user);
updatePeerStoriesState(peer);
}
}
}
@@ -881,7 +883,7 @@ void Stories::sendReaction(FullStoryId id, Data::ReactionId reaction) {
const auto api = &session().api();
api->request(MTPstories_SendReaction(
MTP_flags(0),
story->peer()->asUser()->inputUser,
story->peer()->input,
MTP_int(id.story),
ReactionToMTP(reaction)
)).send();
@@ -1054,7 +1056,7 @@ bool Stories::bumpReadTill(PeerId peerId, StoryId maxReadTill) {
if (till < maxReadTill) {
const auto from = till;
till = maxReadTill;
updateUserStoriesState(_owner->peer(peerId));
updatePeerStoriesState(_owner->peer(peerId));
const auto i = _stories.find(peerId);
if (i != end(_stories)) {
refreshItems = ranges::make_subrange(
@@ -1097,19 +1099,16 @@ void Stories::toggleHidden(
PeerId peerId,
bool hidden,
std::shared_ptr<Ui::Show> show) {
const auto user = _owner->peer(peerId)->asUser();
Assert(user != nullptr);
if (user->hasStoriesHidden() != hidden) {
user->setFlags(hidden
? (user->flags() | UserDataFlag::StoriesHidden)
: (user->flags() & ~UserDataFlag::StoriesHidden));
session().api().request(MTPcontacts_ToggleStoriesHidden(
user->inputUser,
const auto peer = _owner->peer(peerId);
if (peer->hasStoriesHidden() != hidden) {
peer->setStoriesHidden(hidden);
session().api().request(MTPstories_TogglePeerStoriesHidden(
peer->input,
MTP_bool(hidden)
)).send();
}
const auto name = user->shortName();
const auto name = peer->shortName();
const auto guard = gsl::finally([&] {
if (show) {
const auto phrase = hidden
@@ -1166,8 +1165,6 @@ void Stories::toggleHidden(
void Stories::sendMarkAsReadRequest(
not_null<PeerData*> peer,
StoryId tillId) {
Expects(peer->isUser());
const auto peerId = peer->id;
_markReadRequests.emplace(peerId);
const auto finish = [=] {
@@ -1181,7 +1178,7 @@ void Stories::sendMarkAsReadRequest(
const auto api = &_owner->session().api();
api->request(MTPstories_ReadStories(
peer->asUser()->inputUser,
peer->input,
MTP_int(tillId)
)).done(finish).fail(finish).send();
}
@@ -1205,7 +1202,7 @@ void Stories::sendMarkAsReadRequests() {
}
const auto j = _all.find(peerId);
if (j != end(_all)) {
sendMarkAsReadRequest(j->second.user, j->second.readTill);
sendMarkAsReadRequest(j->second.peer, j->second.readTill);
}
i = _markReadPending.erase(i);
}
@@ -1243,7 +1240,7 @@ void Stories::sendIncrementViewsRequests() {
checkQuitPreventFinished();
};
api->request(MTPstories_IncrementStoryViews(
_owner->peer(peer)->asUser()->inputUser,
_owner->peer(peer)->input,
MTP_vector<MTPint>(std::move(ids))
)).done(finish).fail(finish).send();
_incrementViewsPending.remove(peer);
@@ -1272,6 +1269,7 @@ void Stories::loadViewsSlice(
using Flag = MTPstories_GetStoryViewsList::Flag;
_viewsRequestId = api->request(MTPstories_GetStoryViewsList(
MTP_flags(Flag::f_reactions_first),
MTP_inputPeerSelf(),
MTPstring(), // q
MTP_int(id),
MTP_string(offset),
@@ -1364,6 +1362,7 @@ void Stories::archiveLoadMore() {
}
const auto api = &_owner->session().api();
_archiveRequestId = api->request(MTPstories_GetStoriesArchive(
MTP_inputPeerSelf(),
MTP_int(_archiveLastId),
MTP_int(_archiveLastId ? kArchivePerPage : kArchiveFirstPerPage)
)).done([=](const MTPstories_Stories &result) {
@@ -1399,8 +1398,6 @@ void Stories::archiveLoadMore() {
}
void Stories::savedLoadMore(PeerId peerId) {
Expects(peerIsUser(peerId));
auto &saved = _saved[peerId];
if (saved.requestId || saved.loaded) {
return;
@@ -1408,7 +1405,7 @@ void Stories::savedLoadMore(PeerId peerId) {
const auto api = &_owner->session().api();
const auto peer = _owner->peer(peerId);
saved.requestId = api->request(MTPstories_GetPinnedStories(
peer->asUser()->inputUser,
peer->input,
MTP_int(saved.lastId),
MTP_int(saved.lastId ? kSavedPerPage : kSavedFirstPerPage)
)).done([=](const MTPstories_Stories &result) {
@@ -1456,6 +1453,7 @@ void Stories::deleteList(const std::vector<FullStoryId> &ids) {
if (!list.empty()) {
const auto api = &_owner->session().api();
api->request(MTPstories_DeleteStories(
MTP_inputPeerSelf(),
MTP_vector<MTPint>(list)
)).done([=](const MTPVector<MTPint> &result) {
for (const auto &id : result.v) {
@@ -1481,6 +1479,7 @@ void Stories::togglePinnedList(
}
const auto api = &_owner->session().api();
api->request(MTPstories_TogglePinned(
MTP_inputPeerSelf(),
MTP_vector<MTPint>(list),
MTP_bool(pinned)
)).done([=](const MTPVector<MTPint> &result) {
@@ -1608,7 +1607,7 @@ std::optional<Stories::PeerSourceState> Stories::peerSourceState(
};
}
requestReadTills();
_pendingUserStateMaxId[peer] = storyMaxId;
_pendingPeerStateMaxId[peer] = storyMaxId;
return std::nullopt;
}
@@ -1617,12 +1616,12 @@ void Stories::requestReadTills() {
return;
}
const auto api = &_owner->session().api();
_readTillsRequestId = api->request(MTPstories_GetAllReadUserStories(
_readTillsRequestId = api->request(MTPstories_GetAllReadPeerStories(
)).done([=](const MTPUpdates &result) {
_readTillReceived = true;
api->applyUpdates(result);
for (auto &[peer, maxId] : base::take(_pendingUserStateMaxId)) {
updateUserStoriesState(peer);
for (auto &[peer, maxId] : base::take(_pendingPeerStateMaxId)) {
updatePeerStoriesState(peer);
}
for (const auto &storyId : base::take(_pendingReadTillItems)) {
_owner->refreshStoryItemViews(storyId);
@@ -1745,24 +1744,22 @@ void Stories::sendPollingViewsRequests() {
_pollingViewsTimer.callOnce(kPollViewsInterval);
}
void Stories::updateUserStoriesState(not_null<PeerData*> peer) {
void Stories::updatePeerStoriesState(not_null<PeerData*> peer) {
const auto till = _readTill.find(peer->id);
const auto readTill = (till != end(_readTill)) ? till->second : 0;
const auto pendingMaxId = [&] {
const auto j = _pendingUserStateMaxId.find(peer);
return (j != end(_pendingUserStateMaxId)) ? j->second : 0;
const auto j = _pendingPeerStateMaxId.find(peer);
return (j != end(_pendingPeerStateMaxId)) ? j->second : 0;
};
const auto i = _all.find(peer->id);
const auto max = (i != end(_all))
? (i->second.ids.empty() ? 0 : i->second.ids.back().id)
: pendingMaxId();
if (const auto user = peer->asUser()) {
user->setStoriesState(!max
? UserData::StoriesState::None
: (max <= readTill)
? UserData::StoriesState::HasRead
: UserData::StoriesState::HasUnread);
}
peer->setStoriesState(!max
? PeerData::StoriesState::None
: (max <= readTill)
? PeerData::StoriesState::HasRead
: PeerData::StoriesState::HasUnread);
}
void Stories::preloadSourcesChanged(StorySourcesList list) {