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