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

Track unread mentions and unread reactions the same way.

This commit is contained in:
John Preston
2022-01-26 19:01:40 +03:00
parent 6207770120
commit e9c79886d2
31 changed files with 885 additions and 347 deletions

View File

@@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_sending.h"
#include "api/api_text_entities.h"
#include "api/api_send_progress.h"
#include "api/api_unread_things.h"
#include "ui/boxes/confirm_box.h"
#include "boxes/delete_messages_box.h"
#include "boxes/send_files_box.h"
@@ -73,6 +74,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history_drag_area.h"
#include "history/history_inner_widget.h"
#include "history/history_item_components.h"
#include "history/history_unread_things.h"
#include "history/view/controls/history_view_voice_record_bar.h"
#include "history/view/controls/history_view_ttl_button.h"
#include "history/view/history_view_service_message.h"
@@ -215,6 +217,9 @@ HistoryWidget::HistoryWidget(
, _unreadMentions(
_scroll,
controller->chatStyle()->value(lifetime(), st::historyUnreadMentions))
, _unreadReactions(
_scroll,
controller->chatStyle()->value(lifetime(), st::historyUnreadReactions))
, _fieldAutocomplete(this, controller)
, _supportAutocomplete(session().supportMode()
? object_ptr<Support::Autocomplete>(this, &session())
@@ -278,8 +283,13 @@ HistoryWidget::HistoryWidget(
}
}, lifetime());
_historyDown->addClickHandler([=] { historyDownClicked(); });
_unreadMentions->addClickHandler([=] { showNextUnreadMention(); });
_historyDown.widget->addClickHandler([=] { historyDownClicked(); });
_unreadMentions.widget->addClickHandler([=] {
showNextUnreadMention();
});
_unreadReactions.widget->addClickHandler([=] {
showNextUnreadReaction();
});
_fieldBarCancel->addClickHandler([=] { cancelFieldAreaState(); });
_send->addClickHandler([=] { sendButtonClicked(); });
@@ -353,9 +363,13 @@ HistoryWidget::HistoryWidget(
_scroll->updateBars();
}, lifetime());
_historyDown->installEventFilter(this);
_unreadMentions->installEventFilter(this);
SendMenu::SetupUnreadMentionsMenu(_unreadMentions.data(), [=] {
_historyDown.widget->installEventFilter(this);
_unreadMentions.widget->installEventFilter(this);
_unreadReactions.widget->installEventFilter(this);
SendMenu::SetupUnreadMentionsMenu(_unreadMentions.widget.data(), [=] {
return _history ? _history->peer.get() : nullptr;
});
SendMenu::SetupUnreadReactionsMenu(_unreadReactions.widget.data(), [=] {
return _history ? _history->peer.get() : nullptr;
});
@@ -562,6 +576,7 @@ HistoryWidget::HistoryWidget(
| HistoryUpdateFlag::BotKeyboard
| HistoryUpdateFlag::CloudDraft
| HistoryUpdateFlag::UnreadMentions
| HistoryUpdateFlag::UnreadReactions
| HistoryUpdateFlag::UnreadView
| HistoryUpdateFlag::TopPromoted
| HistoryUpdateFlag::ClientSideMessages
@@ -591,8 +606,9 @@ HistoryWidget::HistoryWidget(
if (flags & HistoryUpdateFlag::ClientSideMessages) {
updateSendButtonType();
}
if (flags & HistoryUpdateFlag::UnreadMentions) {
updateUnreadMentionsVisibility();
if ((flags & HistoryUpdateFlag::UnreadMentions)
|| (flags & HistoryUpdateFlag::UnreadReactions)) {
updateUnreadThingsVisibility();
}
if (flags & HistoryUpdateFlag::UnreadView) {
unreadCountUpdated();
@@ -907,7 +923,7 @@ void HistoryWidget::initVoiceRecordBar() {
_voiceRecordBar->lockShowStarts(
) | rpl::start_with_next([=] {
updateHistoryDownVisibility();
updateUnreadMentionsVisibility();
updateUnreadThingsVisibility();
}, lifetime());
_voiceRecordBar->updateSendButtonTypeRequests(
@@ -2459,7 +2475,7 @@ void HistoryWidget::updateControlsVisibility() {
_topBar->setVisible(_peer != nullptr);
}
updateHistoryDownVisibility();
updateUnreadMentionsVisibility();
updateUnreadThingsVisibility();
if (!_history || _a_show.animating()) {
hideChildWidgets();
return;
@@ -2744,7 +2760,7 @@ void HistoryWidget::newItemAdded(not_null<HistoryItem*> item) {
destroyUnreadBar();
if (doWeReadServerHistory()) {
if (item->isUnreadMention() && !item->isUnreadMedia()) {
session().api().markMediaRead(item);
session().api().markContentsRead(item);
}
session().data().histories().readInboxOnNewMessage(item);
@@ -2769,7 +2785,7 @@ void HistoryWidget::unreadCountUpdated() {
});
} else {
updateHistoryDownVisibility();
_historyDown->setUnreadCount(_history->chatListUnreadCount());
_historyDown.widget->setUnreadCount(_history->chatListUnreadCount());
}
}
@@ -3243,7 +3259,7 @@ void HistoryWidget::preloadHistoryIfNeeded() {
}
updateHistoryDownVisibility();
updateUnreadMentionsVisibility();
updateUnreadThingsVisibility();
if (!_scrollToAnimation.animating()) {
preloadHistoryByScroll();
checkReplyReturns();
@@ -3332,7 +3348,7 @@ void HistoryWidget::historyDownClicked() {
}
void HistoryWidget::showNextUnreadMention() {
const auto msgId = _history->getMinLoadedUnreadMention();
const auto msgId = _history->unreadMentions().minLoaded();
const auto already = (_showAtMsgId == msgId);
// Mark mention voice/video message as read.
@@ -3354,6 +3370,12 @@ void HistoryWidget::showNextUnreadMention() {
showHistory(_peer->id, msgId);
}
void HistoryWidget::showNextUnreadReaction() {
const auto msgId = _history->unreadReactions().minLoaded();
const auto already = (_showAtMsgId == msgId);
showHistory(_peer->id, msgId);
}
void HistoryWidget::saveEditMsg() {
Expects(_history != nullptr);
@@ -3698,8 +3720,7 @@ void HistoryWidget::showAnimated(
_preserveScrollTop = true;
show();
_topBar->finishAnimating();
historyDownAnimationFinish();
unreadMentionsAnimationFinish();
cornerButtonsAnimationFinish();
if (_pinnedBar) {
_pinnedBar->finishAnimating();
}
@@ -3732,8 +3753,7 @@ void HistoryWidget::showAnimated(
void HistoryWidget::animationCallback() {
update();
if (!_a_show.animating()) {
historyDownAnimationFinish();
unreadMentionsAnimationFinish();
cornerButtonsAnimationFinish();
if (_pinnedBar) {
_pinnedBar->finishAnimating();
}
@@ -3808,22 +3828,20 @@ void HistoryWidget::checkSuggestToGigagroup() {
}
void HistoryWidget::finishAnimating() {
if (!_a_show.animating()) return;
if (!_a_show.animating()) {
return;
}
_a_show.stop();
_topShadow->setVisible(_peer != nullptr);
_topBar->setVisible(_peer != nullptr);
historyDownAnimationFinish();
unreadMentionsAnimationFinish();
cornerButtonsAnimationFinish();
}
void HistoryWidget::historyDownAnimationFinish() {
_historyDownShown.stop();
updateHistoryDownPosition();
}
void HistoryWidget::unreadMentionsAnimationFinish() {
_unreadMentionsShown.stop();
updateUnreadMentionsPosition();
void HistoryWidget::cornerButtonsAnimationFinish() {
_historyDown.animation.stop();
_unreadMentions.animation.stop();
_unreadReactions.animation.stop();
updateCornerButtonsPositions();
}
void HistoryWidget::chooseAttach() {
@@ -4047,7 +4065,10 @@ bool HistoryWidget::eventFilter(QObject *obj, QEvent *e) {
}
}
}
if ((obj == _historyDown || obj == _unreadMentions) && e->type() == QEvent::Wheel) {
if (e->type() == QEvent::Wheel
&& (obj == _historyDown.widget
|| obj == _unreadMentions.widget
|| obj == _unreadReactions.widget)) {
return _scroll->viewportEvent(e);
}
return TWidget::eventFilter(obj, e);
@@ -4946,7 +4967,7 @@ void HistoryWidget::updateControlsGeometry() {
updateFieldSize();
updateHistoryDownPosition();
updateCornerButtonsPositions();
if (_membersDropdown) {
_membersDropdown->setMaxHeight(countMembersDropdownHeightMax());
@@ -5156,16 +5177,7 @@ void HistoryWidget::updateHistoryGeometry(
if (_supportAutocomplete) {
_supportAutocomplete->setBoundings(_scroll->geometry());
}
if (!_historyDownShown.animating()) {
// _historyDown is a child widget of _scroll, not me.
_historyDown->moveToRight(st::historyToDownPosition.x(), _scroll->height() - _historyDown->height() - st::historyToDownPosition.y());
if (!_unreadMentionsShown.animating()) {
// _unreadMentions is a child widget of _scroll, not me.
auto additionalSkip = _historyDownIsShown ? (_historyDown->height() + st::historyUnreadMentionsSkip) : 0;
_unreadMentions->moveToRight(st::historyToDownPosition.x(), _scroll->height() - _unreadMentions->height() - additionalSkip - st::historyToDownPosition.y());
}
}
updateCornerButtonsPositions();
controller()->floatPlayerAreaUpdated();
}
@@ -5470,15 +5482,71 @@ int HistoryWidget::computeMaxFieldHeight() const {
return std::min(st::historyComposeFieldMaxHeight, available);
}
void HistoryWidget::updateHistoryDownPosition() {
// _historyDown is a child widget of _scroll, not me.
auto top = anim::interpolate(0, _historyDown->height() + st::historyToDownPosition.y(), _historyDownShown.value(_historyDownIsShown ? 1. : 0.));
_historyDown->moveToRight(st::historyToDownPosition.x(), _scroll->height() - top);
auto shouldBeHidden = !_historyDownIsShown && !_historyDownShown.animating();
if (shouldBeHidden != _historyDown->isHidden()) {
_historyDown->setVisible(!shouldBeHidden);
void HistoryWidget::updateCornerButtonsPositions() {
const auto checkVisibility = [](CornerButton &button) {
const auto shouldBeHidden = !button.shown
&& !button.animation.animating();
if (shouldBeHidden != button.widget->isHidden()) {
button.widget->setVisible(!shouldBeHidden);
}
};
const auto shown = [](CornerButton &button) {
return button.animation.value(button.shown ? 1. : 0.);
};
// All corner buttons is a child widgets of _scroll, not me.
const auto historyDownShown = shown(_historyDown);
const auto unreadMentionsShown = shown(_unreadMentions);
const auto unreadReactionsShown = shown(_unreadReactions);
const auto skip = st::historyUnreadThingsSkip;
{
const auto top = anim::interpolate(
0,
_historyDown.widget->height() + st::historyToDownPosition.y(),
historyDownShown);
_historyDown.widget->moveToRight(
st::historyToDownPosition.x(),
_scroll->height() - top);
}
updateUnreadMentionsPosition();
{
const auto right = anim::interpolate(
-_unreadMentions.widget->width(),
st::historyToDownPosition.x(),
unreadMentionsShown);
const auto shift = anim::interpolate(
0,
_historyDown.widget->height() + skip,
historyDownShown);
const auto top = _scroll->height()
- _unreadMentions.widget->height()
- st::historyToDownPosition.y()
- shift;
_unreadMentions.widget->moveToRight(right, top);
}
{
const auto right = anim::interpolate(
-_unreadReactions.widget->width(),
st::historyToDownPosition.x(),
unreadReactionsShown);
const auto shift = anim::interpolate(
0,
_historyDown.widget->height() + skip,
historyDownShown
) + anim::interpolate(
0,
_unreadMentions.widget->height() + skip,
unreadMentionsShown);
const auto top = _scroll->height()
- _unreadReactions.widget->height()
- st::historyToDownPosition.y()
- shift;
_unreadReactions.widget->moveToRight(right, top);
}
checkVisibility(_historyDown);
checkVisibility(_unreadMentions);
checkVisibility(_unreadReactions);
}
void HistoryWidget::updateHistoryDownVisibility() {
@@ -5495,7 +5563,7 @@ void HistoryWidget::updateHistoryDownVisibility() {
const auto top = _list->itemTop(unread);
return (top >= _scroll->scrollTop() + _scroll->height());
};
const auto historyDownIsVisible = [&] {
updateCornerButtonVisibility(_historyDown, [&] {
if (!_list || _firstLoadRequest) {
return false;
}
@@ -5514,60 +5582,69 @@ void HistoryWidget::updateHistoryDownVisibility() {
return true;
}
return false;
};
auto historyDownIsShown = historyDownIsVisible();
if (_historyDownIsShown != historyDownIsShown) {
_historyDownIsShown = historyDownIsShown;
_historyDownShown.start([=] { updateHistoryDownPosition(); }, _historyDownIsShown ? 0. : 1., _historyDownIsShown ? 1. : 0., st::historyToDownDuration);
}());
}
void HistoryWidget::updateCornerButtonVisibility(
CornerButton &button,
bool shown) {
if (button.shown != shown) {
button.shown = shown;
button.animation.start(
[=] { updateCornerButtonsPositions(); },
shown ? 0. : 1.,
shown ? 1. : 0.,
st::historyToDownDuration);
}
}
void HistoryWidget::updateUnreadMentionsPosition() {
// _unreadMentions is a child widget of _scroll, not me.
auto right = anim::interpolate(-_unreadMentions->width(), st::historyToDownPosition.x(), _unreadMentionsShown.value(_unreadMentionsIsShown ? 1. : 0.));
auto shift = anim::interpolate(0, _historyDown->height() + st::historyUnreadMentionsSkip, _historyDownShown.value(_historyDownIsShown ? 1. : 0.));
auto top = _scroll->height() - _unreadMentions->height() - st::historyToDownPosition.y() - shift;
_unreadMentions->moveToRight(right, top);
auto shouldBeHidden = !_unreadMentionsIsShown && !_unreadMentionsShown.animating();
if (shouldBeHidden != _unreadMentions->isHidden()) {
_unreadMentions->setVisible(!shouldBeHidden);
void HistoryWidget::updateUnreadThingsVisibility() {
if (_a_show.animating()) {
return;
}
}
void HistoryWidget::updateUnreadMentionsVisibility() {
if (_a_show.animating()) return;
auto &unreadThings = session().api().unreadThings();
unreadThings.preloadEnough(_history);
auto showUnreadMentions = _peer && (_peer->isChat() || _peer->isMegagroup());
if (showUnreadMentions) {
session().api().preloadEnoughUnreadMentions(_history);
}
const auto unreadMentionsIsShown = [&] {
if (!showUnreadMentions || _firstLoadRequest) {
return false;
}
if (_voiceRecordBar->isLockPresent()) {
return false;
}
if (!_history->getUnreadMentionsLoadedCount()) {
return false;
}
// If we have an unheard voice message with the mention
// and our message is the last one, we can't see the status
// (delivered/read) of this message.
// (Except for MacBooks with the TouchPad.)
if (_scroll->scrollTop() == _scroll->scrollTopMax()) {
if (const auto lastMessage = _history->lastMessage()) {
return !lastMessage->from()->isSelf();
const auto updateWithLoadedCount = [&](CornerButton &button, int count) {
updateCornerButtonVisibility(button, [&] {
if (!count
|| _firstLoadRequest
|| _voiceRecordBar->isLockPresent()) {
return false;
}
// If we have an unheard voice message with the mention
// and our message is the last one, we can't see the status
// (delivered/read) of this message.
// (Except for MacBooks with the TouchPad.)
if (_scroll->scrollTop() == _scroll->scrollTopMax()) {
if (const auto lastMessage = _history->lastMessage()) {
return !lastMessage->from()->isSelf();
}
}
return true;
}());
};
if (unreadThings.trackMentions(_peer)) {
if (const auto count = _history->unreadMentions().count(0)) {
_unreadMentions.widget->setUnreadCount(count);
}
return true;
}();
if (unreadMentionsIsShown) {
_unreadMentions->setUnreadCount(_history->getUnreadMentionsCount());
updateWithLoadedCount(
_unreadMentions,
_history->unreadMentions().loadedCount());
} else {
updateCornerButtonVisibility(_unreadMentions, false);
}
if (_unreadMentionsIsShown != unreadMentionsIsShown) {
_unreadMentionsIsShown = unreadMentionsIsShown;
_unreadMentionsShown.start([=] { updateUnreadMentionsPosition(); }, _unreadMentionsIsShown ? 0. : 1., _unreadMentionsIsShown ? 1. : 0., st::historyToDownDuration);
if (unreadThings.trackReactions(_peer)) {
if (const auto count = _history->unreadReactions().count(0)) {
_unreadReactions.widget->setUnreadCount(count);
}
updateWithLoadedCount(
_unreadReactions,
_history->unreadReactions().loadedCount());
} else {
updateCornerButtonVisibility(_unreadReactions, false);
}
}