mirror of https://github.com/procxx/kepka.git
Read feed while scrolling.
This commit is contained in:
parent
a7f67c4bc9
commit
0c5efb935d
|
@ -1024,6 +1024,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_user_action_upload_file" = "{user} is sending a file";
|
||||
"lng_unread_bar#one" = "{count} unread message";
|
||||
"lng_unread_bar#other" = "{count} unread messages";
|
||||
"lng_unread_bar_some" = "Unread messages";
|
||||
|
||||
"lng_maps_point" = "Location";
|
||||
"lng_save_photo" = "Save image";
|
||||
|
|
|
@ -55,6 +55,7 @@ constexpr auto kSharedMediaLimit = 100;
|
|||
constexpr auto kFeedMessagesLimit = 50;
|
||||
constexpr auto kReadFeaturedSetsTimeout = TimeMs(1000);
|
||||
constexpr auto kFileLoaderQueueStopTimeout = TimeMs(5000);
|
||||
constexpr auto kFeedReadTimeout = TimeMs(1000);
|
||||
|
||||
bool IsSilentPost(not_null<HistoryItem*> item, bool silent) {
|
||||
const auto history = item->history();
|
||||
|
@ -133,7 +134,8 @@ ApiWrap::ApiWrap(not_null<AuthSession*> session)
|
|||
, _webPagesTimer([this] { resolveWebPages(); })
|
||||
, _draftsSaveTimer([this] { saveDraftsToCloud(); })
|
||||
, _featuredSetsReadTimer([this] { readFeaturedSets(); })
|
||||
, _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout)) {
|
||||
, _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout))
|
||||
, _feedReadTimer([this] { readFeeds(); }) {
|
||||
}
|
||||
|
||||
void ApiWrap::requestChangelog(
|
||||
|
@ -3076,9 +3078,12 @@ void ApiWrap::feedMessagesDone(
|
|||
if (data.has_read_max_position()) {
|
||||
return Data::FeedPositionFromMTP(data.vread_max_position);
|
||||
} else if (!messageId) {
|
||||
return ids.empty()
|
||||
const auto result = ids.empty()
|
||||
? noSkipRange.till
|
||||
: ids.back();
|
||||
return Data::MessagePosition(
|
||||
result.date,
|
||||
FullMsgId(result.fullId.channel, result.fullId.msg - 1));
|
||||
}
|
||||
return Data::MessagePosition();
|
||||
}();
|
||||
|
@ -3712,6 +3717,56 @@ void ApiWrap::readServerHistoryForce(not_null<History*> history) {
|
|||
}
|
||||
}
|
||||
|
||||
void ApiWrap::readFeed(
|
||||
not_null<Data::Feed*> feed,
|
||||
Data::MessagePosition position) {
|
||||
const auto already = feed->unreadPosition();
|
||||
if (already && already >= position) {
|
||||
return;
|
||||
}
|
||||
feed->setUnreadPosition(position);
|
||||
if (!_feedReadsDelayed.contains(feed)) {
|
||||
if (_feedReadsDelayed.empty()) {
|
||||
_feedReadTimer.callOnce(kFeedReadTimeout);
|
||||
}
|
||||
_feedReadsDelayed.emplace(feed, getms(true) + kFeedReadTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::readFeeds() {
|
||||
auto delay = kFeedReadTimeout;
|
||||
const auto now = getms(true);
|
||||
for (auto i = begin(_feedReadsDelayed); i != end(_feedReadsDelayed);) {
|
||||
const auto [feed, time] = *i;
|
||||
if (time > now) {
|
||||
accumulate_min(delay, time - now);
|
||||
++i;
|
||||
} else if (_feedReadRequests.contains(feed)) {
|
||||
++i;
|
||||
} else {
|
||||
const auto position = feed->unreadPosition();
|
||||
const auto requestId = request(MTPchannels_ReadFeed(
|
||||
MTP_int(feed->id()),
|
||||
MTP_feedPosition(
|
||||
MTP_int(position.date),
|
||||
MTP_peerChannel(MTP_int(position.fullId.channel)),
|
||||
MTP_int(position.fullId.msg))
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
applyUpdates(result);
|
||||
_feedReadRequests.remove(feed);
|
||||
}).fail([=](const RPCError &error) {
|
||||
_feedReadRequests.remove(feed);
|
||||
}).send();
|
||||
_feedReadRequests.emplace(feed, requestId);
|
||||
|
||||
i = _feedReadsDelayed.erase(i);
|
||||
}
|
||||
}
|
||||
if (!_feedReadRequests.empty()) {
|
||||
_feedReadTimer.callOnce(delay);
|
||||
}
|
||||
}
|
||||
|
||||
void ApiWrap::sendReadRequest(not_null<PeerData*> peer, MsgId upTo) {
|
||||
const auto requestId = [&] {
|
||||
const auto finished = [=] {
|
||||
|
|
|
@ -226,6 +226,9 @@ public:
|
|||
void shareContact(not_null<UserData*> user, const SendOptions &options);
|
||||
void readServerHistory(not_null<History*> history);
|
||||
void readServerHistoryForce(not_null<History*> history);
|
||||
void readFeed(
|
||||
not_null<Data::Feed*> feed,
|
||||
Data::MessagePosition position);
|
||||
|
||||
void sendVoiceMessage(
|
||||
QByteArray result,
|
||||
|
@ -399,6 +402,8 @@ private:
|
|||
bool silent,
|
||||
uint64 randomId);
|
||||
|
||||
void readFeeds();
|
||||
|
||||
not_null<AuthSession*> _session;
|
||||
|
||||
MessageDataRequests _messageDataRequests;
|
||||
|
@ -511,6 +516,7 @@ private:
|
|||
};
|
||||
base::flat_map<not_null<PeerData*>, ReadRequest> _readRequests;
|
||||
base::flat_map<not_null<PeerData*>, MsgId> _readRequestsPending;
|
||||
|
||||
std::unique_ptr<TaskQueue> _fileLoader;
|
||||
base::flat_map<uint64, std::shared_ptr<SendingAlbum>> _sendingAlbums;
|
||||
|
||||
|
@ -518,4 +524,8 @@ private:
|
|||
|
||||
rpl::event_stream<uint64> _stickerSetInstalled;
|
||||
|
||||
base::flat_map<not_null<Data::Feed*>, TimeMs> _feedReadsDelayed;
|
||||
base::flat_map<not_null<Data::Feed*>, mtpRequestId> _feedReadRequests;
|
||||
base::Timer _feedReadTimer;
|
||||
|
||||
};
|
||||
|
|
|
@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "storage/storage_feed_messages.h"
|
||||
#include "mainwidget.h"
|
||||
#include "apiwrap.h"
|
||||
#include "auth_session.h"
|
||||
#include "styles/style_widgets.h"
|
||||
#include "styles/style_history.h"
|
||||
|
@ -241,6 +242,40 @@ void Widget::listSelectionChanged(HistoryView::SelectedItems &&items) {
|
|||
_topBar->showSelected(state);
|
||||
}
|
||||
|
||||
void Widget::listVisibleItemsChanged(HistoryItemsList &&items) {
|
||||
const auto reversed = ranges::view::reverse(items);
|
||||
const auto good = ranges::find_if(reversed, [](auto item) {
|
||||
return IsServerMsgId(item->id);
|
||||
});
|
||||
if (good != end(reversed)) {
|
||||
Auth().api().readFeed(_feed, (*good)->position());
|
||||
}
|
||||
}
|
||||
|
||||
base::optional<int> Widget::listUnreadBarView(
|
||||
const std::vector<not_null<Element*>> &elements) {
|
||||
const auto position = _feed->unreadPosition();
|
||||
if (!position || elements.empty()) {
|
||||
return base::none;
|
||||
}
|
||||
const auto minimal = ranges::upper_bound(
|
||||
elements,
|
||||
position,
|
||||
std::less<>(),
|
||||
[](auto view) { return view->data()->position(); });
|
||||
if (minimal == end(elements)) {
|
||||
return base::none;
|
||||
}
|
||||
const auto view = *minimal;
|
||||
const auto unreadMessagesHeight = elements.back()->y()
|
||||
+ elements.back()->height()
|
||||
- view->y();
|
||||
if (unreadMessagesHeight < _scroll->height()) {
|
||||
return base::none;
|
||||
}
|
||||
return base::make_optional(int(minimal - begin(elements)));
|
||||
}
|
||||
|
||||
std::unique_ptr<Window::SectionMemento> Widget::createMemento() {
|
||||
auto result = std::make_unique<Memento>(_feed);
|
||||
saveState(result.get());
|
||||
|
@ -272,7 +307,9 @@ void Widget::resizeEvent(QResizeEvent *e) {
|
|||
void Widget::updateControlsGeometry() {
|
||||
const auto contentWidth = width();
|
||||
|
||||
const auto newScrollTop = _scroll->scrollTop() + topDelta();
|
||||
const auto newScrollTop = _scroll->isHidden()
|
||||
? base::none
|
||||
: base::make_optional(_scroll->scrollTop() + topDelta());
|
||||
_topBar->resizeToWidth(contentWidth);
|
||||
_topBarShadow->resize(contentWidth, st::lineWidth);
|
||||
|
||||
|
@ -282,14 +319,14 @@ void Widget::updateControlsGeometry() {
|
|||
- _showNext->height();
|
||||
const auto scrollSize = QSize(contentWidth, scrollHeight);
|
||||
if (_scroll->size() != scrollSize) {
|
||||
_skipScrollEvent = true;
|
||||
_scroll->resize(scrollSize);
|
||||
_inner->resizeToWidth(scrollSize.width(), _scroll->height());
|
||||
//_inner->restoreScrollPosition();
|
||||
_skipScrollEvent = false;
|
||||
}
|
||||
|
||||
if (!_scroll->isHidden()) {
|
||||
if (topDelta()) {
|
||||
_scroll->scrollToY(newScrollTop);
|
||||
if (newScrollTop) {
|
||||
_scroll->scrollToY(*newScrollTop);
|
||||
}
|
||||
updateInnerVisibleArea();
|
||||
}
|
||||
|
@ -320,12 +357,16 @@ void Widget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
void Widget::onScroll() {
|
||||
if (_skipScrollEvent) {
|
||||
return;
|
||||
}
|
||||
updateInnerVisibleArea();
|
||||
}
|
||||
|
||||
void Widget::updateInnerVisibleArea() {
|
||||
const auto scrollTop = _scroll->scrollTop();
|
||||
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
|
||||
|
||||
}
|
||||
|
||||
void Widget::showAnimatedHook(
|
||||
|
|
|
@ -21,6 +21,7 @@ class FlatButton;
|
|||
namespace HistoryView {
|
||||
class ListWidget;
|
||||
class TopBarWidget;
|
||||
class Element;
|
||||
} // namespace HistoryView
|
||||
|
||||
namespace HistoryFeed {
|
||||
|
@ -31,6 +32,8 @@ class Widget final
|
|||
: public Window::SectionWidget
|
||||
, public HistoryView::ListDelegate {
|
||||
public:
|
||||
using Element = HistoryView::Element;
|
||||
|
||||
Widget(
|
||||
QWidget *parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
|
@ -75,6 +78,9 @@ public:
|
|||
not_null<HistoryItem*> second) override;
|
||||
void listSelectionChanged(
|
||||
HistoryView::SelectedItems &&items) override;
|
||||
void listVisibleItemsChanged(HistoryItemsList &&items) override;
|
||||
base::optional<int> listUnreadBarView(
|
||||
const std::vector<not_null<Element*>> &elements) override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
@ -104,6 +110,7 @@ private:
|
|||
object_ptr<HistoryView::TopBarWidget> _topBar;
|
||||
object_ptr<Ui::PlainShadow> _topBarShadow;
|
||||
object_ptr<Ui::FlatButton> _showNext;
|
||||
bool _skipScrollEvent = false;
|
||||
bool _undefinedAroundPosition = false;
|
||||
|
||||
};
|
||||
|
|
|
@ -57,11 +57,14 @@ TextSelection ShiftItemSelection(
|
|||
return ShiftItemSelection(selection, byText.length());
|
||||
}
|
||||
|
||||
void UnreadBar::init(int count) {
|
||||
void UnreadBar::init(int newCount) {
|
||||
if (freezed) {
|
||||
return;
|
||||
}
|
||||
text = lng_unread_bar(lt_count, count);
|
||||
count = newCount;
|
||||
text = (count == kCountUnknown)
|
||||
? lang(lng_unread_bar_some)
|
||||
: lng_unread_bar(lt_count, count);
|
||||
width = st::semiboldFont->width(text);
|
||||
}
|
||||
|
||||
|
@ -311,8 +314,6 @@ void Element::destroyUnreadBar() {
|
|||
}
|
||||
|
||||
void Element::setUnreadBarCount(int count) {
|
||||
Expects(count > 0);
|
||||
|
||||
const auto changed = AddComponents(UnreadBar::Bit());
|
||||
const auto bar = Get<UnreadBar>();
|
||||
if (bar->freezed) {
|
||||
|
|
|
@ -61,15 +61,18 @@ TextSelection ShiftItemSelection(
|
|||
// Any HistoryView::Element can have this Component for
|
||||
// displaying the unread messages bar above the message.
|
||||
struct UnreadBar : public RuntimeComponent<UnreadBar, Element> {
|
||||
void init(int count);
|
||||
void init(int newCount);
|
||||
|
||||
static int height();
|
||||
static int marginTop();
|
||||
|
||||
void paint(Painter &p, int y, int w) const;
|
||||
|
||||
static constexpr auto kCountUnknown = std::numeric_limits<int>::max();
|
||||
|
||||
QString text;
|
||||
int width = 0;
|
||||
int count = 0;
|
||||
|
||||
// If unread bar is freezed the new messages do not
|
||||
// increment the counter displayed by this bar.
|
||||
|
@ -150,8 +153,6 @@ public:
|
|||
|
||||
bool computeIsAttachToPrevious(not_null<Element*> previous);
|
||||
|
||||
// count > 0 - creates the unread bar if necessary and
|
||||
// sets unread messages count if bar is not freezed yet
|
||||
void setUnreadBarCount(int count);
|
||||
void destroyUnreadBar();
|
||||
|
||||
|
|
|
@ -238,6 +238,7 @@ ListWidget::ListWidget(
|
|||
, _context(_delegate->listContext())
|
||||
, _itemAverageHeight(itemMinimalHeight())
|
||||
, _scrollDateCheck([this] { scrollDateCheck(); })
|
||||
, _applyUpdatedScrollState([this] { applyUpdatedScrollState(); })
|
||||
, _selectEnabled(_delegate->listAllowsMultiSelect()) {
|
||||
setMouseTracking(true);
|
||||
_scrollDateHideTimer.setCallback([this] { scrollDateHideByTimer(); });
|
||||
|
@ -320,10 +321,21 @@ void ListWidget::refreshRows() {
|
|||
updateAroundPositionFromRows();
|
||||
|
||||
updateItemsGeometry();
|
||||
checkUnreadBarCreation();
|
||||
restoreScrollState();
|
||||
mouseActionUpdate(QCursor::pos());
|
||||
}
|
||||
|
||||
void ListWidget::checkUnreadBarCreation() {
|
||||
if (!_unreadBarElement) {
|
||||
if (const auto index = _delegate->listUnreadBarView(_items)) {
|
||||
_unreadBarElement = _items[*index].get();
|
||||
_unreadBarElement->setUnreadBarCount(UnreadBar::kCountUnknown);
|
||||
refreshAttachmentsAtIndex(*index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::saveScrollState() {
|
||||
if (!_scrollTopState.item) {
|
||||
_scrollTopState = countScrollState();
|
||||
|
@ -331,9 +343,16 @@ void ListWidget::saveScrollState() {
|
|||
}
|
||||
|
||||
void ListWidget::restoreScrollState() {
|
||||
if (_items.empty() || !_scrollTopState.item) {
|
||||
if (_items.empty()) {
|
||||
return;
|
||||
}
|
||||
if (!_scrollTopState.item) {
|
||||
if (!_unreadBarElement) {
|
||||
return;
|
||||
}
|
||||
_scrollTopState.item = _unreadBarElement->data()->position();
|
||||
_scrollTopState.shift = st::lineWidth + st::historyUnreadBarMargin;
|
||||
}
|
||||
const auto index = findNearestItem(_scrollTopState.item);
|
||||
if (index >= 0) {
|
||||
const auto view = _items[index];
|
||||
|
@ -393,21 +412,57 @@ int ListWidget::findNearestItem(Data::MessagePosition position) const {
|
|||
: int(after - begin(_items));
|
||||
}
|
||||
|
||||
HistoryItemsList ListWidget::collectVisibleItems() const {
|
||||
auto result = HistoryItemsList();
|
||||
const auto from = std::lower_bound(
|
||||
begin(_items),
|
||||
end(_items),
|
||||
_visibleTop,
|
||||
[this](auto &elem, int top) {
|
||||
return this->itemTop(elem) + elem->height() <= top;
|
||||
});
|
||||
const auto to = std::lower_bound(
|
||||
begin(_items),
|
||||
end(_items),
|
||||
_visibleBottom,
|
||||
[this](auto &elem, int bottom) {
|
||||
return this->itemTop(elem) < bottom;
|
||||
});
|
||||
result.reserve(to - from);
|
||||
for (auto i = from; i != to; ++i) {
|
||||
result.push_back((*i)->data());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void ListWidget::visibleTopBottomUpdated(
|
||||
int visibleTop,
|
||||
int visibleBottom) {
|
||||
auto scrolledUp = (visibleTop < _visibleTop);
|
||||
if (!(visibleTop < visibleBottom)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto initializing = !(_visibleTop < _visibleBottom);
|
||||
const auto scrolledUp = (visibleTop < _visibleTop);
|
||||
_visibleTop = visibleTop;
|
||||
_visibleBottom = visibleBottom;
|
||||
|
||||
if (initializing) {
|
||||
checkUnreadBarCreation();
|
||||
}
|
||||
updateVisibleTopItem();
|
||||
checkMoveToOtherViewer();
|
||||
if (scrolledUp) {
|
||||
_scrollDateCheck.call();
|
||||
} else {
|
||||
scrollDateHideByTimer();
|
||||
}
|
||||
_controller->floatPlayerAreaUpdated().notify(true);
|
||||
_applyUpdatedScrollState.call();
|
||||
}
|
||||
|
||||
void ListWidget::applyUpdatedScrollState() {
|
||||
checkMoveToOtherViewer();
|
||||
_delegate->listVisibleItemsChanged(collectVisibleItems());
|
||||
}
|
||||
|
||||
void ListWidget::updateVisibleTopItem() {
|
||||
|
@ -938,11 +993,16 @@ void ListWidget::updateItemsGeometry() {
|
|||
}
|
||||
|
||||
void ListWidget::updateSize() {
|
||||
TWidget::resizeToWidth(width());
|
||||
restoreScrollPosition();
|
||||
resizeToWidth(width(), _minHeight);
|
||||
updateVisibleTopItem();
|
||||
}
|
||||
|
||||
void ListWidget::resizeToWidth(int newWidth, int minHeight) {
|
||||
_minHeight = minHeight;
|
||||
TWidget::resizeToWidth(newWidth);
|
||||
restoreScrollPosition();
|
||||
}
|
||||
|
||||
int ListWidget::resizeGetHeight(int newWidth) {
|
||||
update();
|
||||
|
||||
|
@ -963,7 +1023,9 @@ int ListWidget::resizeGetHeight(int newWidth) {
|
|||
}
|
||||
_itemsWidth = newWidth;
|
||||
_itemsHeight = newHeight;
|
||||
_itemsTop = (_minHeight > _itemsHeight + st::historyPaddingBottom) ? (_minHeight - _itemsHeight - st::historyPaddingBottom) : 0;
|
||||
_itemsTop = (_minHeight > _itemsHeight + st::historyPaddingBottom)
|
||||
? (_minHeight - _itemsHeight - st::historyPaddingBottom)
|
||||
: 0;
|
||||
return _itemsTop + _itemsHeight + st::historyPaddingBottom;
|
||||
}
|
||||
|
||||
|
@ -2131,6 +2193,18 @@ void ListWidget::viewReplaced(not_null<const Element*> was, Element *now) {
|
|||
if (_visibleTopItem == was) _visibleTopItem = now;
|
||||
if (_scrollDateLastItem == was) _scrollDateLastItem = now;
|
||||
if (_overElement == was) _overElement = now;
|
||||
if (_unreadBarElement == was) {
|
||||
const auto bar = _unreadBarElement->Get<UnreadBar>();
|
||||
const auto count = bar ? bar->count : 0;
|
||||
const auto freezed = bar ? bar->freezed : false;
|
||||
_unreadBarElement = now;
|
||||
if (now && count) {
|
||||
_unreadBarElement->setUnreadBarCount(count);
|
||||
if (freezed) {
|
||||
_unreadBarElement->setUnreadBarFreezed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::itemRemoved(not_null<const HistoryItem*> item) {
|
||||
|
|
|
@ -61,6 +61,9 @@ public:
|
|||
not_null<HistoryItem*> first,
|
||||
not_null<HistoryItem*> second) = 0;
|
||||
virtual void listSelectionChanged(SelectedItems &&items) = 0;
|
||||
virtual void listVisibleItemsChanged(HistoryItemsList &&items) = 0;
|
||||
virtual base::optional<int> listUnreadBarView(
|
||||
const std::vector<not_null<Element*>> &elements) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -127,10 +130,7 @@ public:
|
|||
// Set the correct scroll position after being resized.
|
||||
void restoreScrollPosition();
|
||||
|
||||
void resizeToWidth(int newWidth, int minHeight) {
|
||||
_minHeight = minHeight;
|
||||
return TWidget::resizeToWidth(newWidth);
|
||||
}
|
||||
void resizeToWidth(int newWidth, int minHeight);
|
||||
|
||||
void saveState(not_null<ListMemento*> memento);
|
||||
void restoreState(not_null<ListMemento*> memento);
|
||||
|
@ -264,6 +264,7 @@ private:
|
|||
Element *strictFindItemByY(int y) const;
|
||||
int findNearestItem(Data::MessagePosition position) const;
|
||||
void viewReplaced(not_null<const Element*> was, Element *now);
|
||||
HistoryItemsList collectVisibleItems() const;
|
||||
|
||||
void checkMoveToOtherViewer();
|
||||
void updateVisibleTopItem();
|
||||
|
@ -352,6 +353,8 @@ private:
|
|||
TextSelection computeRenderSelection(
|
||||
not_null<const SelectedMap*> selected,
|
||||
not_null<const Element*> view) const;
|
||||
void checkUnreadBarCreation();
|
||||
void applyUpdatedScrollState();
|
||||
|
||||
// This function finds all history items that are displayed and calls template method
|
||||
// for each found message (in given direction) in the passed history with passed top offset.
|
||||
|
@ -409,6 +412,9 @@ private:
|
|||
base::Timer _scrollDateHideTimer;
|
||||
Element *_scrollDateLastItem = nullptr;
|
||||
int _scrollDateLastItemTop = 0;
|
||||
SingleQueuedInvokation _applyUpdatedScrollState;
|
||||
|
||||
Element *_unreadBarElement = nullptr;
|
||||
|
||||
MouseAction _mouseAction = MouseAction::None;
|
||||
TextSelectType _mouseSelectType = TextSelectType::Letters;
|
||||
|
|
|
@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_drafts.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_feed.h"
|
||||
#include "ui/special_buttons.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
|
@ -4676,7 +4677,17 @@ void MainWidget::feedUpdate(const MTPUpdate &update) {
|
|||
case mtpc_updateReadFeed: {
|
||||
const auto &d = update.c_updateReadFeed();
|
||||
const auto feedId = d.vfeed_id.v;
|
||||
// #TODO feeds
|
||||
if (const auto feed = Auth().data().feedLoaded(feedId)) {
|
||||
feed->setUnreadPosition(
|
||||
Data::FeedPositionFromMTP(d.vmax_position));
|
||||
if (d.has_unread_count() && d.has_unread_muted_count()) {
|
||||
feed->setUnreadCounts(
|
||||
d.vunread_count.v,
|
||||
d.vunread_muted_count.v);
|
||||
} else {
|
||||
Auth().api().requestDialogEntry(feed);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
// Deleted messages.
|
||||
|
|
Loading…
Reference in New Issue