mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 15:13:57 +02:00
Support unread mentions / reactions in topics.
This commit is contained in:
parent
6a7f030ee7
commit
3999bca823
15 changed files with 229 additions and 175 deletions
|
@ -128,12 +128,12 @@ void UnreadThings::requestMentions(
|
||||||
MTP_int(maxId),
|
MTP_int(maxId),
|
||||||
MTP_int(minId)
|
MTP_int(minId)
|
||||||
)).done([=](const MTPmessages_Messages &result) {
|
)).done([=](const MTPmessages_Messages &result) {
|
||||||
_mentionsRequests.remove(history);
|
_mentionsRequests.remove(entry);
|
||||||
history->unreadMentions().addSlice(result, loaded);
|
entry->unreadMentions().addSlice(result, loaded);
|
||||||
}).fail([=] {
|
}).fail([=] {
|
||||||
_mentionsRequests.remove(history);
|
_mentionsRequests.remove(entry);
|
||||||
}).send();
|
}).send();
|
||||||
_mentionsRequests.emplace(history, requestId);
|
_mentionsRequests.emplace(entry, requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnreadThings::requestReactions(
|
void UnreadThings::requestReactions(
|
||||||
|
@ -162,12 +162,12 @@ void UnreadThings::requestReactions(
|
||||||
MTP_int(maxId),
|
MTP_int(maxId),
|
||||||
MTP_int(minId)
|
MTP_int(minId)
|
||||||
)).done([=](const MTPmessages_Messages &result) {
|
)).done([=](const MTPmessages_Messages &result) {
|
||||||
_reactionsRequests.remove(history);
|
_reactionsRequests.remove(entry);
|
||||||
history->unreadReactions().addSlice(result, loaded);
|
entry->unreadReactions().addSlice(result, loaded);
|
||||||
}).fail([=] {
|
}).fail([=] {
|
||||||
_reactionsRequests.remove(history);
|
_reactionsRequests.remove(entry);
|
||||||
}).send();
|
}).send();
|
||||||
_reactionsRequests.emplace(history, requestId);
|
_reactionsRequests.emplace(entry, requestId);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace UnreadThings
|
} // namespace UnreadThings
|
||||||
|
|
|
@ -271,6 +271,7 @@ void Changes::sendNotifications() {
|
||||||
_historyChanges.sendNotifications();
|
_historyChanges.sendNotifications();
|
||||||
_messageChanges.sendNotifications();
|
_messageChanges.sendNotifications();
|
||||||
_entryChanges.sendNotifications();
|
_entryChanges.sendNotifications();
|
||||||
|
_topicChanges.sendNotifications();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
|
@ -914,7 +914,6 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
width(),
|
width(),
|
||||||
std::min(st::msgMaxWidth / 2, width() / 2));
|
std::min(st::msgMaxWidth / 2, width() / 2));
|
||||||
|
|
||||||
const auto now = crl::now();
|
|
||||||
const auto historyDisplayedEmpty = _history->isDisplayedEmpty()
|
const auto historyDisplayedEmpty = _history->isDisplayedEmpty()
|
||||||
&& (!_migrated || _migrated->isDisplayedEmpty());
|
&& (!_migrated || _migrated->isDisplayedEmpty());
|
||||||
if (_botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) {
|
if (_botAbout && !_botAbout->info->text.isEmpty() && _botAbout->height > 0) {
|
||||||
|
@ -1015,7 +1014,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
_widget->enqueueMessageHighlight(view);
|
_widget->enqueueMessageHighlight(view);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
session().data().reactions().poll(item, now);
|
session().data().reactions().poll(item, context.now);
|
||||||
if (item->hasExtendedMediaPreview()) {
|
if (item->hasExtendedMediaPreview()) {
|
||||||
session().api().views().pollExtendedMedia(item);
|
session().api().views().pollExtendedMedia(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5769,7 +5769,7 @@ bool HistoryWidget::cornerButtonsIgnoreVisibility() {
|
||||||
return _a_show.animating();
|
return _a_show.animating();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HistoryWidget::cornerButtonsDownShown() {
|
std::optional<bool> HistoryWidget::cornerButtonsDownShown() {
|
||||||
if (!_list || _firstLoadRequest) {
|
if (!_list || _firstLoadRequest) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -328,7 +328,7 @@ private:
|
||||||
Dialogs::Entry *cornerButtonsEntry() override;
|
Dialogs::Entry *cornerButtonsEntry() override;
|
||||||
FullMsgId cornerButtonsCurrentId() override;
|
FullMsgId cornerButtonsCurrentId() override;
|
||||||
bool cornerButtonsIgnoreVisibility() override;
|
bool cornerButtonsIgnoreVisibility() override;
|
||||||
bool cornerButtonsDownShown() override;
|
std::optional<bool> cornerButtonsDownShown() override;
|
||||||
bool cornerButtonsUnreadMayBeShown() override;
|
bool cornerButtonsUnreadMayBeShown() override;
|
||||||
|
|
||||||
void checkSuggestToGigagroup();
|
void checkSuggestToGigagroup();
|
||||||
|
|
|
@ -251,8 +251,9 @@ void CornerButtons::updateUnreadThingsVisibility() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CornerButtons::updateJumpDownVisibility(std::optional<int> counter) {
|
void CornerButtons::updateJumpDownVisibility(std::optional<int> counter) {
|
||||||
const auto shown = _delegate->cornerButtonsDownShown();
|
if (const auto shown = _delegate->cornerButtonsDownShown()) {
|
||||||
updateVisibility(CornerButtonType::Down, shown);
|
updateVisibility(CornerButtonType::Down, *shown);
|
||||||
|
}
|
||||||
if (counter) {
|
if (counter) {
|
||||||
down.widget->setUnreadCount(*counter);
|
down.widget->setUnreadCount(*counter);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ public:
|
||||||
[[nodiscard]] virtual Dialogs::Entry *cornerButtonsEntry() = 0;
|
[[nodiscard]] virtual Dialogs::Entry *cornerButtonsEntry() = 0;
|
||||||
[[nodiscard]] virtual FullMsgId cornerButtonsCurrentId() = 0;
|
[[nodiscard]] virtual FullMsgId cornerButtonsCurrentId() = 0;
|
||||||
[[nodiscard]] virtual bool cornerButtonsIgnoreVisibility() = 0;
|
[[nodiscard]] virtual bool cornerButtonsIgnoreVisibility() = 0;
|
||||||
[[nodiscard]] virtual bool cornerButtonsDownShown() = 0;
|
[[nodiscard]] virtual std::optional<bool> cornerButtonsDownShown() = 0;
|
||||||
[[nodiscard]] virtual bool cornerButtonsUnreadMayBeShown() = 0;
|
[[nodiscard]] virtual bool cornerButtonsUnreadMayBeShown() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/core_settings.h"
|
#include "core/core_settings.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "api/api_who_reacted.h"
|
#include "api/api_who_reacted.h"
|
||||||
|
#include "api/api_views.h"
|
||||||
#include "layout/layout_selection.h"
|
#include "layout/layout_selection.h"
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
#include "window/window_adaptive.h"
|
#include "window/window_adaptive.h"
|
||||||
|
@ -54,6 +55,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/premium_preview_box.h"
|
#include "boxes/premium_preview_box.h"
|
||||||
#include "boxes/peers/edit_participant_box.h"
|
#include "boxes/peers/edit_participant_box.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_sponsored_messages.h"
|
||||||
|
#include "data/data_changes.h"
|
||||||
#include "data/data_folder.h"
|
#include "data/data_folder.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
@ -350,6 +353,13 @@ ListWidget::ListWidget(
|
||||||
itemRemoved(item);
|
itemRemoved(item);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
using MessageUpdateFlag = Data::MessageUpdate::Flag;
|
||||||
|
session().changes().realtimeMessageUpdates(
|
||||||
|
MessageUpdateFlag::NewUnreadReaction
|
||||||
|
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
||||||
|
maybeMarkReactionsRead(update.item);
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
session().data().itemVisibilityQueries(
|
session().data().itemVisibilityQueries(
|
||||||
) | rpl::start_with_next([=](
|
) | rpl::start_with_next([=](
|
||||||
const Data::Session::ItemVisibilityQuery &query) {
|
const Data::Session::ItemVisibilityQuery &query) {
|
||||||
|
@ -787,7 +797,6 @@ void ListWidget::visibleTopBottomUpdated(
|
||||||
|
|
||||||
void ListWidget::applyUpdatedScrollState() {
|
void ListWidget::applyUpdatedScrollState() {
|
||||||
checkMoveToOtherViewer();
|
checkMoveToOtherViewer();
|
||||||
_delegate->listVisibleItemsChanged(collectVisibleItems());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::updateVisibleTopItem() {
|
void ListWidget::updateVisibleTopItem() {
|
||||||
|
@ -1764,7 +1773,15 @@ void ListWidget::paintEvent(QPaintEvent *e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto readTill = (HistoryItem*)nullptr;
|
||||||
|
auto readContents = base::flat_set<not_null<HistoryItem*>>();
|
||||||
const auto guard = gsl::finally([&] {
|
const auto guard = gsl::finally([&] {
|
||||||
|
if (readTill) {
|
||||||
|
_delegate->listMarkReadTill(readTill);
|
||||||
|
}
|
||||||
|
if (!readContents.empty()) {
|
||||||
|
_delegate->listMarkContentsRead(readContents);
|
||||||
|
}
|
||||||
_userpicsCache.clear();
|
_userpicsCache.clear();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1787,23 +1804,61 @@ void ListWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (from != end(_items)) {
|
if (from != end(_items)) {
|
||||||
_reactionsManager->startEffectsCollection();
|
_reactionsManager->startEffectsCollection();
|
||||||
|
|
||||||
|
const auto session = &controller()->session();
|
||||||
auto top = itemTop(from->get());
|
auto top = itemTop(from->get());
|
||||||
auto context = preparePaintContext(clip).translated(0, -top);
|
auto context = preparePaintContext(clip).translated(0, -top);
|
||||||
p.translate(0, top);
|
p.translate(0, top);
|
||||||
const auto &sendingAnimation = _controller->sendingAnimation();
|
const auto &sendingAnimation = _controller->sendingAnimation();
|
||||||
for (auto i = from; i != to; ++i) {
|
for (auto i = from; i != to; ++i) {
|
||||||
const auto view = *i;
|
const auto view = *i;
|
||||||
if (!sendingAnimation.hasAnimatedMessage(view->data())) {
|
const auto item = view->data();
|
||||||
|
const auto height = view->height();
|
||||||
|
if (!sendingAnimation.hasAnimatedMessage(item)) {
|
||||||
context.reactionInfo
|
context.reactionInfo
|
||||||
= _reactionsManager->currentReactionPaintInfo();
|
= _reactionsManager->currentReactionPaintInfo();
|
||||||
context.outbg = view->hasOutLayout();
|
context.outbg = view->hasOutLayout();
|
||||||
context.selection = itemRenderSelection(view);
|
context.selection = itemRenderSelection(view);
|
||||||
view->draw(p, context);
|
view->draw(p, context);
|
||||||
}
|
}
|
||||||
|
const auto isSponsored = item->isSponsored();
|
||||||
|
const auto isUnread = _delegate->listElementShownUnread(view)
|
||||||
|
&& item->isRegular();
|
||||||
|
const auto withReaction = item->hasUnreadReaction();
|
||||||
|
const auto yShown = [&](int y) {
|
||||||
|
return (_visibleBottom >= y && _visibleTop <= y);
|
||||||
|
};
|
||||||
|
const auto markShown = isSponsored
|
||||||
|
? view->markSponsoredViewed(_visibleBottom - top)
|
||||||
|
: withReaction
|
||||||
|
? yShown(top + context.reactionInfo->position.y())
|
||||||
|
: isUnread
|
||||||
|
? yShown(top + height)
|
||||||
|
: yShown(top + height / 2);
|
||||||
|
if (markShown) {
|
||||||
|
if (isSponsored) {
|
||||||
|
session->data().sponsoredMessages().view(
|
||||||
|
item->fullId());
|
||||||
|
} else if (isUnread) {
|
||||||
|
readTill = item;
|
||||||
|
}
|
||||||
|
if (item->hasViews()) {
|
||||||
|
session->api().views().scheduleIncrement(item);
|
||||||
|
}
|
||||||
|
if (withReaction) {
|
||||||
|
readContents.insert(item);
|
||||||
|
} else if (item->isUnreadMention()
|
||||||
|
&& !item->isUnreadMedia()) {
|
||||||
|
readContents.insert(item);
|
||||||
|
_highlighter.enqueue(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
session->data().reactions().poll(item, context.now);
|
||||||
|
if (item->hasExtendedMediaPreview()) {
|
||||||
|
session->api().views().pollExtendedMedia(item);
|
||||||
|
}
|
||||||
_reactionsManager->recordCurrentReactionEffect(
|
_reactionsManager->recordCurrentReactionEffect(
|
||||||
view->data()->fullId(),
|
item->fullId(),
|
||||||
QPoint(0, top));
|
QPoint(0, top));
|
||||||
const auto height = view->height();
|
|
||||||
top += height;
|
top += height;
|
||||||
context.translate(0, -height);
|
context.translate(0, -height);
|
||||||
p.translate(0, height);
|
p.translate(0, height);
|
||||||
|
@ -1847,7 +1902,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
|
||||||
auto &v = _sponsoredUserpics[itemId.msg];
|
auto &v = _sponsoredUserpics[itemId.msg];
|
||||||
if (!info->customUserpic.isCurrentView(v)) {
|
if (!info->customUserpic.isCurrentView(v)) {
|
||||||
v = info->customUserpic.createView();
|
v = info->customUserpic.createView();
|
||||||
info->customUserpic.load(&session(), itemId);
|
info->customUserpic.load(session, itemId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1909,6 +1964,21 @@ void ListWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ListWidget::maybeMarkReactionsRead(not_null<HistoryItem*> item) {
|
||||||
|
const auto view = viewForItem(item);
|
||||||
|
if (!view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto top = itemTop(view);
|
||||||
|
const auto reactionCenter
|
||||||
|
= view->reactionButtonParameters({}, {}).center.y();
|
||||||
|
if (top + reactionCenter < _visibleTop
|
||||||
|
|| top + view->height() > _visibleBottom) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_delegate->listMarkContentsRead({ item });
|
||||||
|
}
|
||||||
|
|
||||||
bool ListWidget::eventHook(QEvent *e) {
|
bool ListWidget::eventHook(QEvent *e) {
|
||||||
if (e->type() == QEvent::TouchBegin
|
if (e->type() == QEvent::TouchBegin
|
||||||
|| e->type() == QEvent::TouchUpdate
|
|| e->type() == QEvent::TouchUpdate
|
||||||
|
|
|
@ -100,7 +100,9 @@ public:
|
||||||
not_null<HistoryItem*> first,
|
not_null<HistoryItem*> first,
|
||||||
not_null<HistoryItem*> second) = 0;
|
not_null<HistoryItem*> second) = 0;
|
||||||
virtual void listSelectionChanged(SelectedItems &&items) = 0;
|
virtual void listSelectionChanged(SelectedItems &&items) = 0;
|
||||||
virtual void listVisibleItemsChanged(HistoryItemsList &&items) = 0;
|
virtual void listMarkReadTill(not_null<HistoryItem*> item) = 0;
|
||||||
|
virtual void listMarkContentsRead(
|
||||||
|
const base::flat_set<not_null<HistoryItem*>> &items) = 0;
|
||||||
virtual MessagesBarData listMessagesBar(
|
virtual MessagesBarData listMessagesBar(
|
||||||
const std::vector<not_null<Element*>> &elements) = 0;
|
const std::vector<not_null<Element*>> &elements) = 0;
|
||||||
virtual void listContentRefreshed() = 0;
|
virtual void listContentRefreshed() = 0;
|
||||||
|
@ -529,6 +531,7 @@ private:
|
||||||
void scrollToAnimationCallback(FullMsgId attachToId, int relativeTo);
|
void scrollToAnimationCallback(FullMsgId attachToId, int relativeTo);
|
||||||
void startItemRevealAnimations();
|
void startItemRevealAnimations();
|
||||||
void revealItemsCallback();
|
void revealItemsCallback();
|
||||||
|
void maybeMarkReactionsRead(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
void startMessageSendingAnimation(not_null<HistoryItem*> item);
|
void startMessageSendingAnimation(not_null<HistoryItem*> item);
|
||||||
void showPremiumStickerTooltip(
|
void showPremiumStickerTooltip(
|
||||||
|
|
|
@ -636,7 +636,11 @@ void PinnedWidget::listSelectionChanged(SelectedItems &&items) {
|
||||||
_topBar->showSelected(state);
|
_topBar->showSelected(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PinnedWidget::listVisibleItemsChanged(HistoryItemsList &&items) {
|
void PinnedWidget::listMarkReadTill(not_null<HistoryItem*> item) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void PinnedWidget::listMarkContentsRead(
|
||||||
|
const base::flat_set<not_null<HistoryItem*>> &items) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MessagesBarData PinnedWidget::listMessagesBar(
|
MessagesBarData PinnedWidget::listMessagesBar(
|
||||||
|
|
|
@ -90,7 +90,9 @@ public:
|
||||||
not_null<HistoryItem*> first,
|
not_null<HistoryItem*> first,
|
||||||
not_null<HistoryItem*> second) override;
|
not_null<HistoryItem*> second) override;
|
||||||
void listSelectionChanged(SelectedItems &&items) override;
|
void listSelectionChanged(SelectedItems &&items) override;
|
||||||
void listVisibleItemsChanged(HistoryItemsList &&items) override;
|
void listMarkReadTill(not_null<HistoryItem*> item) override;
|
||||||
|
void listMarkContentsRead(
|
||||||
|
const base::flat_set<not_null<HistoryItem*>> &items) override;
|
||||||
MessagesBarData listMessagesBar(
|
MessagesBarData listMessagesBar(
|
||||||
const std::vector<not_null<Element*>> &elements) override;
|
const std::vector<not_null<Element*>> &elements) override;
|
||||||
void listContentRefreshed() override;
|
void listContentRefreshed() override;
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/view/history_view_schedule_box.h"
|
#include "history/view/history_view_schedule_box.h"
|
||||||
#include "history/view/history_view_pinned_bar.h"
|
#include "history/view/history_view_pinned_bar.h"
|
||||||
#include "history/view/history_view_sticker_toast.h"
|
#include "history/view/history_view_sticker_toast.h"
|
||||||
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_drag_area.h"
|
#include "history/history_drag_area.h"
|
||||||
#include "history/history_item_components.h"
|
#include "history/history_item_components.h"
|
||||||
|
@ -212,9 +213,10 @@ RepliesWidget::RepliesWidget(
|
||||||
this,
|
this,
|
||||||
controller->chatStyle()->value(lifetime(), st::historyScroll),
|
controller->chatStyle()->value(lifetime(), st::historyScroll),
|
||||||
false))
|
false))
|
||||||
, _scrollDown(
|
, _cornerButtons(
|
||||||
_scroll.get(),
|
_scroll.get(),
|
||||||
controller->chatStyle()->value(lifetime(), st::historyToDown))
|
controller->chatStyle(),
|
||||||
|
static_cast<HistoryView::CornerButtonsDelegate*>(this))
|
||||||
, _readRequestTimer([=] { sendReadTillRequest(); }) {
|
, _readRequestTimer([=] { sendReadTillRequest(); }) {
|
||||||
controller->chatStyle()->paletteChanged(
|
controller->chatStyle()->paletteChanged(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
|
@ -335,8 +337,8 @@ RepliesWidget::RepliesWidget(
|
||||||
controller->showBackFromStack();
|
controller->showBackFromStack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (update.item == _replyReturn) {
|
while (update.item == _cornerButtons.replyReturn()) {
|
||||||
calculateNextReplyReturn();
|
_cornerButtons.calculateNextReplyReturn();
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
@ -347,7 +349,6 @@ RepliesWidget::RepliesWidget(
|
||||||
_inner->update();
|
_inner->update();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
setupScrollDownButton();
|
|
||||||
setupComposeControls();
|
setupComposeControls();
|
||||||
orderWidgets();
|
orderWidgets();
|
||||||
}
|
}
|
||||||
|
@ -469,14 +470,34 @@ void RepliesWidget::setupTopicViewer() {
|
||||||
_inner->update();
|
_inner->update();
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
if (_topic) {
|
||||||
|
subscribeToTopic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RepliesWidget::subscribeToTopic() {
|
||||||
|
using TopicUpdateFlag = Data::TopicUpdate::Flag;
|
||||||
|
session().changes().topicUpdates(
|
||||||
|
_topic,
|
||||||
|
(TopicUpdateFlag::UnreadMentions
|
||||||
|
| TopicUpdateFlag::UnreadReactions)
|
||||||
|
) | rpl::start_with_next([=](const Data::TopicUpdate &update) {
|
||||||
|
_cornerButtons.updateUnreadThingsVisibility();
|
||||||
|
}, _topicLifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::setTopic(Data::ForumTopic *topic) {
|
void RepliesWidget::setTopic(Data::ForumTopic *topic) {
|
||||||
if (_topic != topic) {
|
if (_topic == topic) {
|
||||||
_topic = topic;
|
return;
|
||||||
refreshReplies();
|
}
|
||||||
refreshTopBarActiveChat();
|
_topicLifetime.destroy();
|
||||||
if (_topic && _rootView) {
|
_topic = topic;
|
||||||
|
refreshReplies();
|
||||||
|
refreshTopBarActiveChat();
|
||||||
|
if (_topic) {
|
||||||
|
subscribeToTopic();
|
||||||
|
if (_rootView) {
|
||||||
_rootView = nullptr;
|
_rootView = nullptr;
|
||||||
_rootViewHeight = 0;
|
_rootViewHeight = 0;
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
@ -684,7 +705,8 @@ void RepliesWidget::setupComposeControls() {
|
||||||
|
|
||||||
_composeControls->lockShowStarts(
|
_composeControls->lockShowStarts(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
updateScrollDownVisibility();
|
_cornerButtons.updateJumpDownVisibility();
|
||||||
|
_cornerButtons.updateUnreadThingsVisibility();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
_composeControls->viewportEvents(
|
_composeControls->viewportEvents(
|
||||||
|
@ -919,48 +941,21 @@ std::optional<QString> RepliesWidget::writeRestriction() const {
|
||||||
|
|
||||||
void RepliesWidget::pushReplyReturn(not_null<HistoryItem*> item) {
|
void RepliesWidget::pushReplyReturn(not_null<HistoryItem*> item) {
|
||||||
if (item->history() == _history && item->inThread(_rootId)) {
|
if (item->history() == _history && item->inThread(_rootId)) {
|
||||||
_replyReturns.push_back(item->id);
|
_cornerButtons.pushReplyReturn(item);
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_replyReturn = item;
|
|
||||||
updateScrollDownVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepliesWidget::restoreReplyReturns(const std::vector<MsgId> &list) {
|
|
||||||
_replyReturns = list;
|
|
||||||
computeCurrentReplyReturn();
|
|
||||||
if (!_replyReturn) {
|
|
||||||
calculateNextReplyReturn();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepliesWidget::computeCurrentReplyReturn() {
|
|
||||||
_replyReturn = _replyReturns.empty()
|
|
||||||
? nullptr
|
|
||||||
: _history->owner().message(_history->peer, _replyReturns.back());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepliesWidget::calculateNextReplyReturn() {
|
|
||||||
_replyReturn = nullptr;
|
|
||||||
while (!_replyReturns.empty() && !_replyReturn) {
|
|
||||||
_replyReturns.pop_back();
|
|
||||||
computeCurrentReplyReturn();
|
|
||||||
}
|
|
||||||
if (!_replyReturn) {
|
|
||||||
updateScrollDownVisibility();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::checkReplyReturns() {
|
void RepliesWidget::checkReplyReturns() {
|
||||||
const auto currentTop = _scroll->scrollTop();
|
const auto currentTop = _scroll->scrollTop();
|
||||||
for (; _replyReturn != nullptr; calculateNextReplyReturn()) {
|
while (const auto replyReturn = _cornerButtons.replyReturn()) {
|
||||||
const auto position = _replyReturn->position();
|
const auto position = replyReturn->position();
|
||||||
const auto scrollTop = _inner->scrollTopForPosition(position);
|
const auto scrollTop = _inner->scrollTopForPosition(position);
|
||||||
const auto scrolledBelow = scrollTop
|
const auto below = scrollTop
|
||||||
? (currentTop >= std::min(*scrollTop, _scroll->scrollTopMax()))
|
? (currentTop >= std::min(*scrollTop, _scroll->scrollTopMax()))
|
||||||
: _inner->isBelowPosition(position);
|
: _inner->isBelowPosition(position);
|
||||||
if (!scrolledBelow) {
|
if (below) {
|
||||||
|
_cornerButtons.calculateNextReplyReturn();
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1057,6 +1052,10 @@ void RepliesWidget::send(Api::SendOptions options) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!options.scheduled) {
|
||||||
|
_cornerButtons.clearReplyReturns();
|
||||||
|
}
|
||||||
|
|
||||||
const auto webPageId = _composeControls->webPageId();
|
const auto webPageId = _composeControls->webPageId();
|
||||||
|
|
||||||
auto message = ApiWrap::MessageToSend(prepareSendAction(options));
|
auto message = ApiWrap::MessageToSend(prepareSendAction(options));
|
||||||
|
@ -1355,24 +1354,9 @@ MsgId RepliesWidget::replyToId() const {
|
||||||
: _rootId;
|
: _rootId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::setupScrollDownButton() {
|
|
||||||
_scrollDown->setClickedCallback([=] {
|
|
||||||
scrollDownClicked();
|
|
||||||
});
|
|
||||||
base::install_event_filter(_scrollDown, [=](not_null<QEvent*> event) {
|
|
||||||
if (event->type() != QEvent::Wheel) {
|
|
||||||
return base::EventFilterResult::Continue;
|
|
||||||
}
|
|
||||||
return _scroll->viewportEvent(event)
|
|
||||||
? base::EventFilterResult::Cancel
|
|
||||||
: base::EventFilterResult::Continue;
|
|
||||||
});
|
|
||||||
updateScrollDownVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepliesWidget::refreshUnreadCountBadge(std::optional<int> count) {
|
void RepliesWidget::refreshUnreadCountBadge(std::optional<int> count) {
|
||||||
if (count.has_value()) {
|
if (count.has_value()) {
|
||||||
_scrollDown->setUnreadCount(*count);
|
_cornerButtons.updateJumpDownVisibility(count);
|
||||||
} else if (!_readRequestTimer.isActive() && !_readRequestId) {
|
} else if (!_readRequestTimer.isActive() && !_readRequestId) {
|
||||||
reloadUnreadCountIfNeeded();
|
reloadUnreadCountIfNeeded();
|
||||||
}
|
}
|
||||||
|
@ -1389,14 +1373,39 @@ void RepliesWidget::reloadUnreadCountIfNeeded() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::scrollDownClicked() {
|
void RepliesWidget::cornerButtonsShowAtPosition(
|
||||||
if (base::IsCtrlPressed()) {
|
Data::MessagePosition position) {
|
||||||
showAtEnd();
|
showAtPosition(position);
|
||||||
} else if (_replyReturn) {
|
}
|
||||||
showAtPosition(_replyReturn->position());
|
|
||||||
} else {
|
Dialogs::Entry *RepliesWidget::cornerButtonsEntry() {
|
||||||
showAtEnd();
|
return _topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
FullMsgId RepliesWidget::cornerButtonsCurrentId() {
|
||||||
|
return _lastShownAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RepliesWidget::cornerButtonsIgnoreVisibility() {
|
||||||
|
return animatingShow();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<bool> RepliesWidget::cornerButtonsDownShown() {
|
||||||
|
if (_composeControls->isLockPresent()) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
const auto top = _scroll->scrollTop() + st::historyToDownShownAfter;
|
||||||
|
if (top < _scroll->scrollTopMax() || _cornerButtons.replyReturn()) {
|
||||||
|
return true;
|
||||||
|
} else if (_inner->loadedAtBottomKnown()) {
|
||||||
|
return !_inner->loadedAtBottom();
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RepliesWidget::cornerButtonsUnreadMayBeShown() {
|
||||||
|
return _inner->loadedAtBottomKnown()
|
||||||
|
&& !_composeControls->isLockPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::showAtStart() {
|
void RepliesWidget::showAtStart() {
|
||||||
|
@ -1435,9 +1444,7 @@ bool RepliesWidget::showAtPositionNow(
|
||||||
: nullptr;
|
: nullptr;
|
||||||
const auto use = item ? item->position() : position;
|
const auto use = item ? item->position() : position;
|
||||||
if (const auto scrollTop = _inner->scrollTopForPosition(use)) {
|
if (const auto scrollTop = _inner->scrollTopForPosition(use)) {
|
||||||
while (_replyReturn && use.fullId.msg == _replyReturn->id) {
|
_cornerButtons.skipReplyReturn(use.fullId);
|
||||||
calculateNextReplyReturn();
|
|
||||||
}
|
|
||||||
const auto currentScrollTop = _scroll->scrollTop();
|
const auto currentScrollTop = _scroll->scrollTop();
|
||||||
const auto wanted = std::clamp(
|
const auto wanted = std::clamp(
|
||||||
*scrollTop,
|
*scrollTop,
|
||||||
|
@ -1452,6 +1459,7 @@ bool RepliesWidget::showAtPositionNow(
|
||||||
? AnimatedScroll::Part
|
? AnimatedScroll::Part
|
||||||
: AnimatedScroll::Full;
|
: AnimatedScroll::Full;
|
||||||
_inner->scrollTo(wanted, use, scrollDelta, type);
|
_inner->scrollTo(wanted, use, scrollDelta, type);
|
||||||
|
_lastShownAt = use.fullId;
|
||||||
if (use != Data::MaxMessagePosition
|
if (use != Data::MaxMessagePosition
|
||||||
&& use != Data::UnreadMessagePosition) {
|
&& use != Data::UnreadMessagePosition) {
|
||||||
_inner->highlightMessage(use.fullId);
|
_inner->highlightMessage(use.fullId);
|
||||||
|
@ -1464,57 +1472,6 @@ bool RepliesWidget::showAtPositionNow(
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::updateScrollDownVisibility() {
|
|
||||||
if (animatingShow()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto scrollDownIsVisible = [&]() -> std::optional<bool> {
|
|
||||||
if (_composeControls->isLockPresent()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const auto top = _scroll->scrollTop() + st::historyToDownShownAfter;
|
|
||||||
if (top < _scroll->scrollTopMax() || _replyReturn) {
|
|
||||||
return true;
|
|
||||||
} else if (_inner->loadedAtBottomKnown()) {
|
|
||||||
return !_inner->loadedAtBottom();
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
};
|
|
||||||
const auto scrollDownIsShown = scrollDownIsVisible();
|
|
||||||
if (!scrollDownIsShown) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_scrollDownIsShown != *scrollDownIsShown) {
|
|
||||||
_scrollDownIsShown = *scrollDownIsShown;
|
|
||||||
_scrollDownShown.start(
|
|
||||||
[=] { updateScrollDownPosition(); },
|
|
||||||
_scrollDownIsShown ? 0. : 1.,
|
|
||||||
_scrollDownIsShown ? 1. : 0.,
|
|
||||||
st::historyToDownDuration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepliesWidget::updateScrollDownPosition() {
|
|
||||||
// _scrollDown is a child widget of _scroll, not me.
|
|
||||||
auto top = anim::interpolate(
|
|
||||||
0,
|
|
||||||
_scrollDown->height() + st::historyToDownPosition.y(),
|
|
||||||
_scrollDownShown.value(_scrollDownIsShown ? 1. : 0.));
|
|
||||||
_scrollDown->moveToRight(
|
|
||||||
st::historyToDownPosition.x(),
|
|
||||||
_scroll->height() - top);
|
|
||||||
auto shouldBeHidden = !_scrollDownIsShown && !_scrollDownShown.animating();
|
|
||||||
if (shouldBeHidden != _scrollDown->isHidden()) {
|
|
||||||
_scrollDown->setVisible(!shouldBeHidden);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepliesWidget::scrollDownAnimationFinish() {
|
|
||||||
_scrollDownShown.stop();
|
|
||||||
updateScrollDownPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RepliesWidget::updateAdaptiveLayout() {
|
void RepliesWidget::updateAdaptiveLayout() {
|
||||||
_topBarShadow->moveToLeft(
|
_topBarShadow->moveToLeft(
|
||||||
controller()->adaptive().isOneColumn() ? 0 : st::lineWidth,
|
controller()->adaptive().isOneColumn() ? 0 : st::lineWidth,
|
||||||
|
@ -1662,7 +1619,8 @@ bool RepliesWidget::showMessage(
|
||||||
if (!originMessage) {
|
if (!originMessage) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto originItem = (!originMessage || _replyReturn == originMessage)
|
const auto originItem = (!originMessage
|
||||||
|
|| _cornerButtons.replyReturn() == originMessage)
|
||||||
? nullptr
|
? nullptr
|
||||||
: originMessage;
|
: originMessage;
|
||||||
showAtPosition(message->position(), originItem);
|
showAtPosition(message->position(), originItem);
|
||||||
|
@ -1685,7 +1643,7 @@ void RepliesWidget::replyToMessage(FullMsgId itemId) {
|
||||||
|
|
||||||
void RepliesWidget::saveState(not_null<RepliesMemento*> memento) {
|
void RepliesWidget::saveState(not_null<RepliesMemento*> memento) {
|
||||||
memento->setReplies(_replies);
|
memento->setReplies(_replies);
|
||||||
memento->setReplyReturns(_replyReturns);
|
memento->setReplyReturns(_cornerButtons.replyReturns());
|
||||||
_inner->saveState(memento->list());
|
_inner->saveState(memento->list());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1740,7 +1698,7 @@ void RepliesWidget::restoreState(not_null<RepliesMemento*> memento) {
|
||||||
} else if (!_replies) {
|
} else if (!_replies) {
|
||||||
refreshReplies();
|
refreshReplies();
|
||||||
}
|
}
|
||||||
restoreReplyReturns(memento->replyReturns());
|
_cornerButtons.setReplyReturns(memento->replyReturns());
|
||||||
_inner->restoreState(memento->list());
|
_inner->restoreState(memento->list());
|
||||||
if (const auto highlight = memento->getHighlightId()) {
|
if (const auto highlight = memento->getHighlightId()) {
|
||||||
const auto position = Data::MessagePosition{
|
const auto position = Data::MessagePosition{
|
||||||
|
@ -1811,7 +1769,7 @@ void RepliesWidget::updateControlsGeometry() {
|
||||||
_composeControls->move(0, bottom - controlsHeight);
|
_composeControls->move(0, bottom - controlsHeight);
|
||||||
_composeControls->setAutocompleteBoundingRect(_scroll->geometry());
|
_composeControls->setAutocompleteBoundingRect(_scroll->geometry());
|
||||||
|
|
||||||
updateScrollDownPosition();
|
_cornerButtons.updatePositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::paintEvent(QPaintEvent *e) {
|
void RepliesWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -1842,7 +1800,8 @@ void RepliesWidget::updateInnerVisibleArea() {
|
||||||
const auto scrollTop = _scroll->scrollTop();
|
const auto scrollTop = _scroll->scrollTop();
|
||||||
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
|
_inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height());
|
||||||
updatePinnedVisibility();
|
updatePinnedVisibility();
|
||||||
updateScrollDownVisibility();
|
_cornerButtons.updateJumpDownVisibility();
|
||||||
|
_cornerButtons.updateUnreadThingsVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::updatePinnedVisibility() {
|
void RepliesWidget::updatePinnedVisibility() {
|
||||||
|
@ -2024,11 +1983,16 @@ void RepliesWidget::readTill(not_null<HistoryItem*> item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RepliesWidget::listVisibleItemsChanged(HistoryItemsList &&items) {
|
void RepliesWidget::listMarkReadTill(not_null<HistoryItem*> item) {
|
||||||
const auto reversed = ranges::views::reverse(items);
|
if (true/*doWeReadServerHistory()*/) { // #TODO forum active
|
||||||
const auto good = ranges::find_if(reversed, &HistoryItem::isRegular);
|
readTill(item);
|
||||||
if (good != end(reversed)) {
|
}
|
||||||
readTill(*good);
|
}
|
||||||
|
|
||||||
|
void RepliesWidget::listMarkContentsRead(
|
||||||
|
const base::flat_set<not_null<HistoryItem*>> &items) {
|
||||||
|
if (true/*doWeReadMentions()*/) { // #TODO forum active
|
||||||
|
session().api().markContentsRead(items);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "window/section_widget.h"
|
#include "window/section_widget.h"
|
||||||
#include "window/section_memento.h"
|
#include "window/section_memento.h"
|
||||||
|
#include "history/view/history_view_corner_buttons.h"
|
||||||
#include "history/view/history_view_list_widget.h"
|
#include "history/view/history_view_list_widget.h"
|
||||||
#include "data/data_messages.h"
|
#include "data/data_messages.h"
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
@ -67,7 +68,8 @@ class StickerToast;
|
||||||
|
|
||||||
class RepliesWidget final
|
class RepliesWidget final
|
||||||
: public Window::SectionWidget
|
: public Window::SectionWidget
|
||||||
, private ListDelegate {
|
, private ListDelegate
|
||||||
|
, private CornerButtonsDelegate {
|
||||||
public:
|
public:
|
||||||
RepliesWidget(
|
RepliesWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
|
@ -128,7 +130,9 @@ public:
|
||||||
not_null<HistoryItem*> first,
|
not_null<HistoryItem*> first,
|
||||||
not_null<HistoryItem*> second) override;
|
not_null<HistoryItem*> second) override;
|
||||||
void listSelectionChanged(SelectedItems &&items) override;
|
void listSelectionChanged(SelectedItems &&items) override;
|
||||||
void listVisibleItemsChanged(HistoryItemsList &&items) override;
|
void listMarkReadTill(not_null<HistoryItem*> item) override;
|
||||||
|
void listMarkContentsRead(
|
||||||
|
const base::flat_set<not_null<HistoryItem*>> &items) override;
|
||||||
MessagesBarData listMessagesBar(
|
MessagesBarData listMessagesBar(
|
||||||
const std::vector<not_null<Element*>> &elements) override;
|
const std::vector<not_null<Element*>> &elements) override;
|
||||||
void listContentRefreshed() override;
|
void listContentRefreshed() override;
|
||||||
|
@ -147,6 +151,15 @@ public:
|
||||||
->rpl::producer<Data::AllowedReactions> override;
|
->rpl::producer<Data::AllowedReactions> override;
|
||||||
void listShowPremiumToast(not_null<DocumentData*> document) override;
|
void listShowPremiumToast(not_null<DocumentData*> document) override;
|
||||||
|
|
||||||
|
// CornerButtonsDelegate delegate.
|
||||||
|
void cornerButtonsShowAtPosition(
|
||||||
|
Data::MessagePosition position) override;
|
||||||
|
Dialogs::Entry *cornerButtonsEntry() override;
|
||||||
|
FullMsgId cornerButtonsCurrentId() override;
|
||||||
|
bool cornerButtonsIgnoreVisibility() override;
|
||||||
|
std::optional<bool> cornerButtonsDownShown() override;
|
||||||
|
bool cornerButtonsUnreadMayBeShown() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
@ -181,16 +194,13 @@ private:
|
||||||
void setupRoot();
|
void setupRoot();
|
||||||
void setupRootView();
|
void setupRootView();
|
||||||
void setupTopicViewer();
|
void setupTopicViewer();
|
||||||
|
void subscribeToTopic();
|
||||||
void setTopic(Data::ForumTopic *topic);
|
void setTopic(Data::ForumTopic *topic);
|
||||||
void setupDragArea();
|
void setupDragArea();
|
||||||
void sendReadTillRequest();
|
void sendReadTillRequest();
|
||||||
void readTill(not_null<HistoryItem*> item);
|
void readTill(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
void setupScrollDownButton();
|
|
||||||
void scrollDownClicked();
|
|
||||||
void scrollDownAnimationFinish();
|
void scrollDownAnimationFinish();
|
||||||
void updateScrollDownVisibility();
|
|
||||||
void updateScrollDownPosition();
|
|
||||||
void updatePinnedVisibility();
|
void updatePinnedVisibility();
|
||||||
|
|
||||||
void confirmDeleteSelected();
|
void confirmDeleteSelected();
|
||||||
|
@ -216,9 +226,6 @@ private:
|
||||||
void orderWidgets();
|
void orderWidgets();
|
||||||
|
|
||||||
void pushReplyReturn(not_null<HistoryItem*> item);
|
void pushReplyReturn(not_null<HistoryItem*> item);
|
||||||
void computeCurrentReplyReturn();
|
|
||||||
void calculateNextReplyReturn();
|
|
||||||
void restoreReplyReturns(const std::vector<MsgId> &list);
|
|
||||||
void checkReplyReturns();
|
void checkReplyReturns();
|
||||||
void recountChatWidth();
|
void recountChatWidth();
|
||||||
void replyToMessage(FullMsgId itemId);
|
void replyToMessage(FullMsgId itemId);
|
||||||
|
@ -295,12 +302,9 @@ private:
|
||||||
std::unique_ptr<Ui::ScrollArea> _scroll;
|
std::unique_ptr<Ui::ScrollArea> _scroll;
|
||||||
std::unique_ptr<HistoryView::StickerToast> _stickerToast;
|
std::unique_ptr<HistoryView::StickerToast> _stickerToast;
|
||||||
|
|
||||||
std::vector<MsgId> _replyReturns;
|
FullMsgId _lastShownAt;
|
||||||
HistoryItem *_replyReturn = nullptr;
|
HistoryView::CornerButtons _cornerButtons;
|
||||||
|
rpl::lifetime _topicLifetime;
|
||||||
Ui::Animations::Simple _scrollDownShown;
|
|
||||||
bool _scrollDownIsShown = false;
|
|
||||||
object_ptr<Ui::HistoryDownButton> _scrollDown;
|
|
||||||
|
|
||||||
bool _choosingAttach = false;
|
bool _choosingAttach = false;
|
||||||
|
|
||||||
|
@ -351,10 +355,10 @@ public:
|
||||||
return _replies;
|
return _replies;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setReplyReturns(const std::vector<MsgId> &list) {
|
void setReplyReturns(const QVector<FullMsgId> &list) {
|
||||||
_replyReturns = list;
|
_replyReturns = list;
|
||||||
}
|
}
|
||||||
const std::vector<MsgId> &replyReturns() const {
|
const QVector<FullMsgId> &replyReturns() const {
|
||||||
return _replyReturns;
|
return _replyReturns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +377,7 @@ private:
|
||||||
const MsgId _highlightId = 0;
|
const MsgId _highlightId = 0;
|
||||||
ListMemento _list;
|
ListMemento _list;
|
||||||
std::shared_ptr<Data::RepliesList> _replies;
|
std::shared_ptr<Data::RepliesList> _replies;
|
||||||
std::vector<MsgId> _replyReturns;
|
QVector<FullMsgId> _replyReturns;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
|
|
@ -1258,7 +1258,11 @@ void ScheduledWidget::listSelectionChanged(SelectedItems &&items) {
|
||||||
_topBar->showSelected(state);
|
_topBar->showSelected(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScheduledWidget::listVisibleItemsChanged(HistoryItemsList &&items) {
|
void ScheduledWidget::listMarkReadTill(not_null<HistoryItem*> item) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScheduledWidget::listMarkContentsRead(
|
||||||
|
const base::flat_set<not_null<HistoryItem*>> &items) {
|
||||||
}
|
}
|
||||||
|
|
||||||
MessagesBarData ScheduledWidget::listMessagesBar(
|
MessagesBarData ScheduledWidget::listMessagesBar(
|
||||||
|
|
|
@ -112,7 +112,9 @@ public:
|
||||||
not_null<HistoryItem*> first,
|
not_null<HistoryItem*> first,
|
||||||
not_null<HistoryItem*> second) override;
|
not_null<HistoryItem*> second) override;
|
||||||
void listSelectionChanged(SelectedItems &&items) override;
|
void listSelectionChanged(SelectedItems &&items) override;
|
||||||
void listVisibleItemsChanged(HistoryItemsList &&items) override;
|
void listMarkReadTill(not_null<HistoryItem*> item) override;
|
||||||
|
void listMarkContentsRead(
|
||||||
|
const base::flat_set<not_null<HistoryItem*>> &items) override;
|
||||||
MessagesBarData listMessagesBar(
|
MessagesBarData listMessagesBar(
|
||||||
const std::vector<not_null<Element*>> &elements) override;
|
const std::vector<not_null<Element*>> &elements) override;
|
||||||
void listContentRefreshed() override;
|
void listContentRefreshed() override;
|
||||||
|
|
Loading…
Add table
Reference in a new issue