mirror of https://github.com/procxx/kepka.git
Request full feed channels list before messages.
This commit is contained in:
parent
20889d7003
commit
280ddb4629
|
@ -2637,12 +2637,81 @@ void ApiWrap::userPhotosDone(
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApiWrap::requestFeedChannels(not_null<Data::Feed*> feed) {
|
||||||
|
if (_feedChannelsRequests.contains(feed)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto hash = feed->channelsHash();
|
||||||
|
request(MTPchannels_GetFeedSources(
|
||||||
|
MTP_flags(MTPchannels_GetFeedSources::Flag::f_feed_id),
|
||||||
|
MTP_int(feed->id()),
|
||||||
|
MTP_int(hash)
|
||||||
|
)).done([=](const MTPchannels_FeedSources &result) {
|
||||||
|
_feedChannelsRequests.remove(feed);
|
||||||
|
|
||||||
|
switch (result.type()) {
|
||||||
|
case mtpc_channels_feedSourcesNotModified:
|
||||||
|
if (feed->channelsHash() == hash) {
|
||||||
|
feedChannelsDone(feed);
|
||||||
|
} else {
|
||||||
|
requestFeedChannels(feed);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case mtpc_channels_feedSources: {
|
||||||
|
const auto &data = result.c_channels_feedSources();
|
||||||
|
App::feedUsers(data.vusers);
|
||||||
|
App::feedChats(data.vchats);
|
||||||
|
for (const auto &broadcasts : data.vfeeds.v) {
|
||||||
|
if (broadcasts.type() == mtpc_feedBroadcasts) {
|
||||||
|
const auto &list = broadcasts.c_feedBroadcasts();
|
||||||
|
const auto feedId = list.vfeed_id.v;
|
||||||
|
const auto feed = _session->data().feed(feedId);
|
||||||
|
auto channels = std::vector<not_null<ChannelData*>>();
|
||||||
|
for (const auto &channelId : list.vchannels.v) {
|
||||||
|
channels.push_back(App::channel(channelId.v));
|
||||||
|
}
|
||||||
|
feed->setChannels(std::move(channels));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (feed->channelsLoaded()) {
|
||||||
|
feedChannelsDone(feed);
|
||||||
|
} else {
|
||||||
|
LOG(("API Error: feed channels not received for "
|
||||||
|
).arg(feed->id()));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: Unexpected("Type in channels.getFeedSources response.");
|
||||||
|
}
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
_feedChannelsRequests.remove(feed);
|
||||||
|
}).send();
|
||||||
|
_feedChannelsRequests.emplace(feed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApiWrap::feedChannelsDone(not_null<Data::Feed*> feed) {
|
||||||
|
feed->setChannelsLoaded(true);
|
||||||
|
for (const auto key : base::take(_feedMessagesRequestsPending)) {
|
||||||
|
std::apply(
|
||||||
|
[=](auto&&...args) { requestFeedMessages(args...); },
|
||||||
|
key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ApiWrap::requestFeedMessages(
|
void ApiWrap::requestFeedMessages(
|
||||||
not_null<Data::Feed*> feed,
|
not_null<Data::Feed*> feed,
|
||||||
Data::MessagePosition messageId,
|
Data::MessagePosition messageId,
|
||||||
SliceType slice) {
|
SliceType slice) {
|
||||||
const auto key = std::make_tuple(feed, messageId, slice);
|
const auto key = std::make_tuple(feed, messageId, slice);
|
||||||
if (_feedMessagesRequests.contains(key)) {
|
if (_feedMessagesRequests.contains(key)
|
||||||
|
|| _feedMessagesRequestsPending.contains(key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!feed->channelsLoaded()) {
|
||||||
|
_feedMessagesRequestsPending.emplace(key);
|
||||||
|
requestFeedChannels(feed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2656,7 +2725,7 @@ void ApiWrap::requestFeedMessages(
|
||||||
}
|
}
|
||||||
Unexpected("Direction in PrepareSearchRequest");
|
Unexpected("Direction in PrepareSearchRequest");
|
||||||
}();
|
}();
|
||||||
const auto sourcesHash = int32(0);// feed->channelsHash(); // #TODO
|
const auto sourcesHash = feed->channelsHash();
|
||||||
const auto hash = int32(0);
|
const auto hash = int32(0);
|
||||||
const auto flags = (messageId && messageId.fullId.channel)
|
const auto flags = (messageId && messageId.fullId.channel)
|
||||||
? MTPchannels_GetFeed::Flag::f_offset_position
|
? MTPchannels_GetFeed::Flag::f_offset_position
|
||||||
|
@ -2681,7 +2750,7 @@ void ApiWrap::requestFeedMessages(
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
_feedMessagesRequests.remove(key);
|
_feedMessagesRequests.remove(key);
|
||||||
}).send();
|
}).send();
|
||||||
_feedMessagesRequests.emplace(key, requestId);
|
_feedMessagesRequests.emplace(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApiWrap::feedMessagesDone(
|
void ApiWrap::feedMessagesDone(
|
||||||
|
|
|
@ -161,6 +161,8 @@ public:
|
||||||
not_null<UserData*> user,
|
not_null<UserData*> user,
|
||||||
PhotoId afterId);
|
PhotoId afterId);
|
||||||
|
|
||||||
|
void requestFeedChannels(
|
||||||
|
not_null<Data::Feed*> feed);
|
||||||
void requestFeedMessages(
|
void requestFeedMessages(
|
||||||
not_null<Data::Feed*> feed,
|
not_null<Data::Feed*> feed,
|
||||||
Data::MessagePosition messageId,
|
Data::MessagePosition messageId,
|
||||||
|
@ -323,6 +325,7 @@ private:
|
||||||
PhotoId photoId,
|
PhotoId photoId,
|
||||||
const MTPphotos_Photos &result);
|
const MTPphotos_Photos &result);
|
||||||
|
|
||||||
|
void feedChannelsDone(not_null<Data::Feed*> feed);
|
||||||
void feedMessagesDone(
|
void feedMessagesDone(
|
||||||
not_null<Data::Feed*> feed,
|
not_null<Data::Feed*> feed,
|
||||||
Data::MessagePosition messageId,
|
Data::MessagePosition messageId,
|
||||||
|
@ -450,10 +453,15 @@ private:
|
||||||
|
|
||||||
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;
|
base::flat_map<not_null<UserData*>, mtpRequestId> _userPhotosRequests;
|
||||||
|
|
||||||
base::flat_map<std::tuple<
|
base::flat_set<not_null<Data::Feed*>> _feedChannelsRequests;
|
||||||
|
base::flat_set<std::tuple<
|
||||||
not_null<Data::Feed*>,
|
not_null<Data::Feed*>,
|
||||||
Data::MessagePosition,
|
Data::MessagePosition,
|
||||||
SliceType>, mtpRequestId> _feedMessagesRequests;
|
SliceType>> _feedMessagesRequests;
|
||||||
|
base::flat_set<std::tuple<
|
||||||
|
not_null<Data::Feed*>,
|
||||||
|
Data::MessagePosition,
|
||||||
|
SliceType>> _feedMessagesRequestsPending;
|
||||||
|
|
||||||
rpl::event_stream<SendOptions> _sendActions;
|
rpl::event_stream<SendOptions> _sendActions;
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,49 @@ int32 Feed::channelsHash() const {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Feed::channelsLoaded() const {
|
||||||
|
return _channelsLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Feed::setChannelsLoaded(bool loaded) {
|
||||||
|
_channelsLoaded = loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Feed::setChannels(std::vector<not_null<ChannelData*>> channels) {
|
||||||
|
const auto remove = ranges::view::all(
|
||||||
|
_channels
|
||||||
|
) | ranges::view::transform([](not_null<History*> history) {
|
||||||
|
return history->peer->asChannel();
|
||||||
|
}) | ranges::view::filter([&](not_null<ChannelData*> channel) {
|
||||||
|
return !base::contains(channels, channel);
|
||||||
|
}) | ranges::to_vector;
|
||||||
|
|
||||||
|
const auto add = ranges::view::all(
|
||||||
|
channels
|
||||||
|
) | ranges::view::filter([&](not_null<ChannelData*> channel) {
|
||||||
|
return ranges::find(
|
||||||
|
_channels,
|
||||||
|
channel.get(),
|
||||||
|
[](auto history) { return history->peer->asChannel(); }
|
||||||
|
) != end(_channels);
|
||||||
|
}) | ranges::to_vector;
|
||||||
|
|
||||||
|
for (const auto channel : remove) {
|
||||||
|
channel->clearFeed();
|
||||||
|
}
|
||||||
|
for (const auto channel : add) {
|
||||||
|
channel->setFeed(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
_channels.clear();
|
||||||
|
for (const auto channel : channels) {
|
||||||
|
Assert(channel->feed() == this);
|
||||||
|
|
||||||
|
_channels.push_back(App::history(channel));
|
||||||
|
}
|
||||||
|
_channelsLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Feed::justSetLastMessage(not_null<HistoryItem*> item) {
|
bool Feed::justSetLastMessage(not_null<HistoryItem*> item) {
|
||||||
if (_lastMessage && item->position() <= _lastMessage->position()) {
|
if (_lastMessage && item->position() <= _lastMessage->position()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -66,6 +66,9 @@ public:
|
||||||
|
|
||||||
const std::vector<not_null<History*>> &channels() const;
|
const std::vector<not_null<History*>> &channels() const;
|
||||||
int32 channelsHash() const;
|
int32 channelsHash() const;
|
||||||
|
bool channelsLoaded() const;
|
||||||
|
void setChannelsLoaded(bool loaded);
|
||||||
|
void setChannels(std::vector<not_null<ChannelData*>> channels);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void indexNameParts();
|
void indexNameParts();
|
||||||
|
@ -75,6 +78,7 @@ private:
|
||||||
FeedId _id = 0;
|
FeedId _id = 0;
|
||||||
not_null<Data::Session*> _parent;
|
not_null<Data::Session*> _parent;
|
||||||
std::vector<not_null<History*>> _channels;
|
std::vector<not_null<History*>> _channels;
|
||||||
|
bool _channelsLoaded = false;
|
||||||
|
|
||||||
QString _name;
|
QString _name;
|
||||||
base::flat_set<QString> _nameWords;
|
base::flat_set<QString> _nameWords;
|
||||||
|
|
|
@ -185,23 +185,39 @@ void paintRow(
|
||||||
icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth);
|
icon.paint(p, fullWidth - st::dialogsPadding.x() - icon.width(), texttop, fullWidth);
|
||||||
availableWidth -= icon.width() + st::dialogsUnreadPadding;
|
availableWidth -= icon.width() + st::dialogsUnreadPadding;
|
||||||
}
|
}
|
||||||
auto sendStateIcon = ([draft, item, active, selected]() -> const style::icon* {
|
auto sendStateIcon = [&]() -> const style::icon* {
|
||||||
if (draft) {
|
if (draft) {
|
||||||
if (draft->saveRequestId) {
|
if (draft->saveRequestId) {
|
||||||
return &(active ? st::dialogsSendingIconActive : (selected ? st::dialogsSendingIconOver : st::dialogsSendingIcon));
|
return &(active
|
||||||
|
? st::dialogsSendingIconActive
|
||||||
|
: (selected
|
||||||
|
? st::dialogsSendingIconOver
|
||||||
|
: st::dialogsSendingIcon));
|
||||||
}
|
}
|
||||||
} else if (item && !item->isEmpty() && item->needCheck()) {
|
} else if (item && !item->isEmpty() && item->needCheck()) {
|
||||||
if (item->id > 0) {
|
if (item->id > 0) {
|
||||||
if (item->unread()) {
|
if (item->unread()) {
|
||||||
return &(active ? st::dialogsSentIconActive : (selected ? st::dialogsSentIconOver : st::dialogsSentIcon));
|
return &(active
|
||||||
|
? st::dialogsSentIconActive
|
||||||
|
: (selected
|
||||||
|
? st::dialogsSentIconOver
|
||||||
|
: st::dialogsSentIcon));
|
||||||
}
|
}
|
||||||
return &(active ? st::dialogsReceivedIconActive : (selected ? st::dialogsReceivedIconOver : st::dialogsReceivedIcon));
|
return &(active
|
||||||
|
? st::dialogsReceivedIconActive
|
||||||
|
: (selected
|
||||||
|
? st::dialogsReceivedIconOver
|
||||||
|
: st::dialogsReceivedIcon));
|
||||||
}
|
}
|
||||||
return &(active ? st::dialogsSendingIconActive : (selected ? st::dialogsSendingIconOver : st::dialogsSendingIcon));
|
return &(active
|
||||||
|
? st::dialogsSendingIconActive
|
||||||
|
: (selected
|
||||||
|
? st::dialogsSendingIconOver
|
||||||
|
: st::dialogsSendingIcon));
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
})();
|
}();
|
||||||
if (sendStateIcon) {
|
if (sendStateIcon && history) {
|
||||||
rectForName.setWidth(rectForName.width() - st::dialogsSendStateSkip);
|
rectForName.setWidth(rectForName.width() - st::dialogsSendStateSkip);
|
||||||
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth);
|
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth);
|
||||||
}
|
}
|
||||||
|
|
|
@ -236,6 +236,7 @@ ListWidget::ListWidget(
|
||||||
, _delegate(delegate)
|
, _delegate(delegate)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _context(_delegate->listContext())
|
, _context(_delegate->listContext())
|
||||||
|
, _itemAverageHeight(itemMinimalHeight())
|
||||||
, _scrollDateCheck([this] { scrollDateCheck(); })
|
, _scrollDateCheck([this] { scrollDateCheck(); })
|
||||||
, _selectEnabled(_delegate->listAllowsMultiSelect()) {
|
, _selectEnabled(_delegate->listAllowsMultiSelect()) {
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
|
@ -782,6 +783,12 @@ void ListWidget::setTextSelection(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ListWidget::itemMinimalHeight() const {
|
||||||
|
return st::msgMarginTopAttached
|
||||||
|
+ st::msgPhotoSize
|
||||||
|
+ st::msgMargin.bottom();
|
||||||
|
}
|
||||||
|
|
||||||
void ListWidget::checkMoveToOtherViewer() {
|
void ListWidget::checkMoveToOtherViewer() {
|
||||||
auto visibleHeight = (_visibleBottom - _visibleTop);
|
auto visibleHeight = (_visibleBottom - _visibleTop);
|
||||||
if (width() <= 0
|
if (width() <= 0
|
||||||
|
@ -795,13 +802,10 @@ void ListWidget::checkMoveToOtherViewer() {
|
||||||
auto topItem = findItemByY(_visibleTop);
|
auto topItem = findItemByY(_visibleTop);
|
||||||
auto bottomItem = findItemByY(_visibleBottom);
|
auto bottomItem = findItemByY(_visibleBottom);
|
||||||
auto preloadedHeight = kPreloadedScreensCountFull * visibleHeight;
|
auto preloadedHeight = kPreloadedScreensCountFull * visibleHeight;
|
||||||
auto minItemHeight = st::msgMarginTopAttached
|
auto preloadedCount = preloadedHeight / _itemAverageHeight;
|
||||||
+ st::msgPhotoSize
|
|
||||||
+ st::msgMargin.bottom();
|
|
||||||
auto preloadedCount = preloadedHeight / minItemHeight;
|
|
||||||
auto preloadIdsLimitMin = (preloadedCount / 2) + 1;
|
auto preloadIdsLimitMin = (preloadedCount / 2) + 1;
|
||||||
auto preloadIdsLimit = preloadIdsLimitMin
|
auto preloadIdsLimit = preloadIdsLimitMin
|
||||||
+ (visibleHeight / minItemHeight);
|
+ (visibleHeight / _itemAverageHeight);
|
||||||
|
|
||||||
auto preloadBefore = kPreloadIfLessThanScreens * visibleHeight;
|
auto preloadBefore = kPreloadIfLessThanScreens * visibleHeight;
|
||||||
auto before = _slice.skippedBefore;
|
auto before = _slice.skippedBefore;
|
||||||
|
@ -814,7 +818,7 @@ void ListWidget::checkMoveToOtherViewer() {
|
||||||
auto minScreenDelta = kPreloadedScreensCount
|
auto minScreenDelta = kPreloadedScreensCount
|
||||||
- kPreloadIfLessThanScreens;
|
- kPreloadIfLessThanScreens;
|
||||||
auto minUniversalIdDelta = (minScreenDelta * visibleHeight)
|
auto minUniversalIdDelta = (minScreenDelta * visibleHeight)
|
||||||
/ minItemHeight;
|
/ _itemAverageHeight;
|
||||||
auto preloadAroundMessage = [&](not_null<Element*> view) {
|
auto preloadAroundMessage = [&](not_null<Element*> view) {
|
||||||
auto preloadRequired = false;
|
auto preloadRequired = false;
|
||||||
auto itemPosition = view->data()->position();
|
auto itemPosition = view->data()->position();
|
||||||
|
@ -952,6 +956,11 @@ int ListWidget::resizeGetHeight(int newWidth) {
|
||||||
newHeight += view->height();
|
newHeight += view->height();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (newHeight > 0) {
|
||||||
|
_itemAverageHeight = std::max(
|
||||||
|
itemMinimalHeight(),
|
||||||
|
newHeight / int(_items.size()));
|
||||||
|
}
|
||||||
_itemsWidth = newWidth;
|
_itemsWidth = newWidth;
|
||||||
_itemsHeight = newHeight;
|
_itemsHeight = newHeight;
|
||||||
_itemsTop = (_minHeight > _itemsHeight + st::historyPaddingBottom) ? (_minHeight - _itemsHeight - st::historyPaddingBottom) : 0;
|
_itemsTop = (_minHeight > _itemsHeight + st::historyPaddingBottom) ? (_minHeight - _itemsHeight - st::historyPaddingBottom) : 0;
|
||||||
|
|
|
@ -295,6 +295,7 @@ private:
|
||||||
void setTextSelection(
|
void setTextSelection(
|
||||||
not_null<Element*> view,
|
not_null<Element*> view,
|
||||||
TextSelection selection);
|
TextSelection selection);
|
||||||
|
int itemMinimalHeight() const;
|
||||||
|
|
||||||
bool isGoodForSelection(not_null<HistoryItem*> item) const;
|
bool isGoodForSelection(not_null<HistoryItem*> item) const;
|
||||||
bool isGoodForSelection(
|
bool isGoodForSelection(
|
||||||
|
@ -393,6 +394,7 @@ private:
|
||||||
int _itemsTop = 0;
|
int _itemsTop = 0;
|
||||||
int _itemsWidth = 0;
|
int _itemsWidth = 0;
|
||||||
int _itemsHeight = 0;
|
int _itemsHeight = 0;
|
||||||
|
int _itemAverageHeight = 0;
|
||||||
|
|
||||||
int _minHeight = 0;
|
int _minHeight = 0;
|
||||||
int _visibleTop = 0;
|
int _visibleTop = 0;
|
||||||
|
|
Loading…
Reference in New Issue