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:
@@ -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) {
|
||||
|
Reference in New Issue
Block a user