mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-22 17:17:15 +02:00
Moved items highlighting to separate management module.
This commit is contained in:
parent
924780d8d8
commit
ba7422805b
8 changed files with 198 additions and 164 deletions
|
@ -728,6 +728,8 @@ PRIVATE
|
|||
history/history_service.h
|
||||
history/history_unread_things.cpp
|
||||
history/history_unread_things.h
|
||||
history/history_view_highlight_manager.cpp
|
||||
history/history_view_highlight_manager.h
|
||||
history/history_widget.cpp
|
||||
history/history_widget.h
|
||||
info/info_content_widget.cpp
|
||||
|
|
|
@ -3158,14 +3158,7 @@ void HistoryInner::elementStartStickerLoop(
|
|||
|
||||
crl::time HistoryInner::elementHighlightTime(
|
||||
not_null<const HistoryItem*> item) {
|
||||
const auto fullAnimMs = _widget->highlightStartTime(item);
|
||||
if (fullAnimMs > 0) {
|
||||
const auto now = crl::now();
|
||||
if (fullAnimMs < now) {
|
||||
return now - fullAnimMs;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return _widget->highlightStartTime(item);
|
||||
}
|
||||
|
||||
void HistoryInner::elementShowPollResults(
|
||||
|
|
118
Telegram/SourceFiles/history/history_view_highlight_manager.cpp
Normal file
118
Telegram/SourceFiles/history/history_view_highlight_manager.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#include "history/history_view_highlight_manager.h"
|
||||
|
||||
#include "data/data_session.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/view/history_view_element.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
ElementHighlighter::ElementHighlighter(
|
||||
not_null<Data::Session*> data,
|
||||
ViewForItem viewForItem,
|
||||
RepaintView repaintView)
|
||||
: _data(data)
|
||||
, _viewForItem(std::move(viewForItem))
|
||||
, _repaintView(std::move(repaintView))
|
||||
, _timer([=] { updateMessage(); }) {
|
||||
}
|
||||
|
||||
void ElementHighlighter::enqueue(not_null<Element*> view) {
|
||||
const auto item = view->data();
|
||||
const auto fullId = item->fullId();
|
||||
if (_queue.empty() && !_timer.isActive()) {
|
||||
highlight(fullId);
|
||||
} else if (_highlightedMessageId != fullId
|
||||
&& !base::contains(_queue, fullId)) {
|
||||
_queue.push_back(fullId);
|
||||
checkNextHighlight();
|
||||
}
|
||||
}
|
||||
|
||||
void ElementHighlighter::checkNextHighlight() {
|
||||
if (_timer.isActive()) {
|
||||
return;
|
||||
}
|
||||
const auto nextHighlight = [&] {
|
||||
while (!_queue.empty()) {
|
||||
const auto fullId = _queue.front();
|
||||
_queue.pop_front();
|
||||
if (const auto item = _data->message(fullId)) {
|
||||
if (_viewForItem(item)) {
|
||||
return fullId;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FullMsgId();
|
||||
}();
|
||||
if (!nextHighlight) {
|
||||
return;
|
||||
}
|
||||
highlight(nextHighlight);
|
||||
}
|
||||
|
||||
crl::time ElementHighlighter::elementTime(
|
||||
not_null<const HistoryItem*> item) const {
|
||||
if (item->fullId() == _highlightedMessageId) {
|
||||
if (_timer.isActive()) {
|
||||
return crl::now() - _highlightStart;
|
||||
}
|
||||
}
|
||||
return crl::time(0);
|
||||
}
|
||||
|
||||
void ElementHighlighter::highlight(FullMsgId itemId) {
|
||||
if (const auto item = _data->message(itemId)) {
|
||||
if (const auto view = _viewForItem(item)) {
|
||||
_highlightStart = crl::now();
|
||||
_highlightedMessageId = itemId;
|
||||
_timer.callEach(AnimationTimerDelta);
|
||||
|
||||
repaintHighlightedItem(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ElementHighlighter::repaintHighlightedItem(
|
||||
not_null<const Element*> view) {
|
||||
if (view->isHiddenByGroup()) {
|
||||
if (const auto group = _data->groups().find(view->data())) {
|
||||
if (const auto leader = _viewForItem(group->items.front())) {
|
||||
if (!leader->isHiddenByGroup()) {
|
||||
_repaintView(leader);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_repaintView(view);
|
||||
}
|
||||
|
||||
void ElementHighlighter::updateMessage() {
|
||||
if (const auto item = _data->message(_highlightedMessageId)) {
|
||||
if (const auto view = _viewForItem(item)) {
|
||||
repaintHighlightedItem(view);
|
||||
const auto duration = st::activeFadeInDuration
|
||||
+ st::activeFadeOutDuration;
|
||||
if (crl::now() - _highlightStart <= duration) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_timer.cancel();
|
||||
_highlightedMessageId = FullMsgId();
|
||||
checkNextHighlight();
|
||||
}
|
||||
|
||||
void ElementHighlighter::clear() {
|
||||
_highlightedMessageId = FullMsgId();
|
||||
updateMessage();
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop application for the Telegram messaging service.
|
||||
|
||||
For license and copyright information please follow this link:
|
||||
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/timer.h"
|
||||
|
||||
class HistoryItem;
|
||||
|
||||
namespace Data {
|
||||
class Session;
|
||||
} // namespace Data
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
class Element;
|
||||
|
||||
class ElementHighlighter final {
|
||||
public:
|
||||
using ViewForItem = Fn<Element*(const HistoryItem*)>;
|
||||
using RepaintView = Fn<void(const Element*)>;
|
||||
ElementHighlighter(
|
||||
not_null<Data::Session*> data,
|
||||
ViewForItem viewForItem,
|
||||
RepaintView repaintView);
|
||||
|
||||
void enqueue(not_null<Element*> view);
|
||||
void highlight(FullMsgId itemId);
|
||||
void clear();
|
||||
|
||||
[[nodiscard]] crl::time elementTime(
|
||||
not_null<const HistoryItem*> item) const;
|
||||
|
||||
private:
|
||||
void checkNextHighlight();
|
||||
void repaintHighlightedItem(not_null<const Element*> view);
|
||||
void updateMessage();
|
||||
|
||||
const not_null<Data::Session*> _data;
|
||||
const ViewForItem _viewForItem;
|
||||
const RepaintView _repaintView;
|
||||
|
||||
FullMsgId _highlightedMessageId;
|
||||
std::deque<FullMsgId> _queue;
|
||||
base::Timer _timer;
|
||||
crl::time _highlightStart = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace HistoryView
|
|
@ -277,6 +277,12 @@ HistoryWidget::HistoryWidget(
|
|||
controller,
|
||||
this)))
|
||||
, _membersDropdownShowTimer([=] { showMembersDropdown(); })
|
||||
, _highlighter(
|
||||
&session().data(),
|
||||
[=](const HistoryItem *item) { return item->mainView(); },
|
||||
[=](const HistoryView::Element *view) {
|
||||
session().data().requestViewRepaint(view);
|
||||
})
|
||||
, _saveDraftTimer([=] { saveDraft(); })
|
||||
, _saveCloudDraftTimer([=] { saveCloudDraft(); })
|
||||
, _topShadow(this) {
|
||||
|
@ -357,8 +363,6 @@ HistoryWidget::HistoryWidget(
|
|||
this,
|
||||
[=] { chooseAttach(); }));
|
||||
|
||||
_highlightTimer.setCallback([this] { updateHighlightedMessage(); });
|
||||
|
||||
const auto rawTextEdit = _field->rawTextEdit().get();
|
||||
rpl::merge(
|
||||
_field->scrollTop().changes() | rpl::to_empty,
|
||||
|
@ -1259,92 +1263,12 @@ void HistoryWidget::scrollToAnimationCallback(
|
|||
|
||||
void HistoryWidget::enqueueMessageHighlight(
|
||||
not_null<HistoryView::Element*> view) {
|
||||
auto enqueueMessageId = [this](MsgId universalId) {
|
||||
if (_highlightQueue.empty() && !_highlightTimer.isActive()) {
|
||||
highlightMessage(universalId);
|
||||
} else if (_highlightedMessageId != universalId
|
||||
&& !base::contains(_highlightQueue, universalId)) {
|
||||
_highlightQueue.push_back(universalId);
|
||||
checkNextHighlight();
|
||||
}
|
||||
};
|
||||
const auto item = view->data();
|
||||
if (item->history() == _history) {
|
||||
enqueueMessageId(item->id);
|
||||
} else if (item->history() == _migrated) {
|
||||
enqueueMessageId(-item->id);
|
||||
}
|
||||
_highlighter.enqueue(view);
|
||||
}
|
||||
|
||||
void HistoryWidget::highlightMessage(MsgId universalMessageId) {
|
||||
_highlightStart = crl::now();
|
||||
_highlightedMessageId = universalMessageId;
|
||||
_highlightTimer.callEach(AnimationTimerDelta);
|
||||
}
|
||||
|
||||
void HistoryWidget::checkNextHighlight() {
|
||||
if (_highlightTimer.isActive()) {
|
||||
return;
|
||||
}
|
||||
auto nextHighlight = [this] {
|
||||
while (!_highlightQueue.empty()) {
|
||||
auto msgId = _highlightQueue.front();
|
||||
_highlightQueue.pop_front();
|
||||
auto item = getItemFromHistoryOrMigrated(msgId);
|
||||
if (item && item->mainView()) {
|
||||
return msgId;
|
||||
}
|
||||
}
|
||||
return MsgId();
|
||||
}();
|
||||
if (!nextHighlight) {
|
||||
return;
|
||||
}
|
||||
highlightMessage(nextHighlight);
|
||||
}
|
||||
|
||||
void HistoryWidget::updateHighlightedMessage() {
|
||||
const auto item = getItemFromHistoryOrMigrated(_highlightedMessageId);
|
||||
auto view = item ? item->mainView() : nullptr;
|
||||
if (!view) {
|
||||
return stopMessageHighlight();
|
||||
}
|
||||
auto duration = st::activeFadeInDuration + st::activeFadeOutDuration;
|
||||
if (crl::now() - _highlightStart > duration) {
|
||||
return stopMessageHighlight();
|
||||
}
|
||||
|
||||
if (const auto group = session().data().groups().find(view->data())) {
|
||||
if (const auto leader = group->items.front()->mainView()) {
|
||||
view = leader;
|
||||
}
|
||||
}
|
||||
session().data().requestViewRepaint(view);
|
||||
}
|
||||
|
||||
crl::time HistoryWidget::highlightStartTime(not_null<const HistoryItem*> item) const {
|
||||
auto isHighlighted = [this](not_null<const HistoryItem*> item) {
|
||||
if (item->id == _highlightedMessageId) {
|
||||
return (item->history() == _history);
|
||||
} else if (item->id == -_highlightedMessageId) {
|
||||
return (item->history() == _migrated);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
return (isHighlighted(item) && _highlightTimer.isActive())
|
||||
? _highlightStart
|
||||
: 0;
|
||||
}
|
||||
|
||||
void HistoryWidget::stopMessageHighlight() {
|
||||
_highlightTimer.cancel();
|
||||
_highlightedMessageId = 0;
|
||||
checkNextHighlight();
|
||||
}
|
||||
|
||||
void HistoryWidget::clearHighlightMessages() {
|
||||
_highlightQueue.clear();
|
||||
stopMessageHighlight();
|
||||
crl::time HistoryWidget::highlightStartTime(
|
||||
not_null<const HistoryItem*> item) const {
|
||||
return _highlighter.elementTime(item);
|
||||
}
|
||||
|
||||
int HistoryWidget::itemTopForHighlight(
|
||||
|
@ -2048,7 +1972,7 @@ void HistoryWidget::showHistory(
|
|||
showAtMsgId = ShowAtTheEndMsgId;
|
||||
}
|
||||
|
||||
clearHighlightMessages();
|
||||
_highlighter.clear();
|
||||
controller()->sendingAnimation().clear();
|
||||
hideInfoTooltip(anim::type::instant);
|
||||
if (_history) {
|
||||
|
@ -6233,7 +6157,7 @@ bool HistoryWidget::replyToNextMessage() {
|
|||
controller()->showPeerHistoryAtItem(next);
|
||||
replyToMessage(next);
|
||||
} else {
|
||||
clearHighlightMessages();
|
||||
_highlighter.clear();
|
||||
cancelReply(false);
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "history/history_drag_area.h"
|
||||
#include "history/history_view_highlight_manager.h"
|
||||
#include "history/history.h"
|
||||
#include "ui/widgets/tooltip.h"
|
||||
#include "mainwidget.h"
|
||||
|
@ -115,7 +116,6 @@ class TTLButton;
|
|||
} // namespace Controls
|
||||
} // namespace HistoryView
|
||||
|
||||
class DragArea;
|
||||
class SendFilesBox;
|
||||
class BotKeyboard;
|
||||
class MessageField;
|
||||
|
@ -420,12 +420,6 @@ private:
|
|||
void supportInsertText(const QString &text);
|
||||
void supportShareContact(Support::Contact contact);
|
||||
|
||||
void highlightMessage(MsgId universalMessageId);
|
||||
void checkNextHighlight();
|
||||
void updateHighlightedMessage();
|
||||
void clearHighlightMessages();
|
||||
void stopMessageHighlight();
|
||||
|
||||
auto computeSendButtonType() const;
|
||||
|
||||
void animationCallback();
|
||||
|
@ -792,10 +786,7 @@ private:
|
|||
Window::SlideDirection _showDirection;
|
||||
QPixmap _cacheUnder, _cacheOver;
|
||||
|
||||
MsgId _highlightedMessageId = 0;
|
||||
std::deque<MsgId> _highlightQueue;
|
||||
base::Timer _highlightTimer;
|
||||
crl::time _highlightStart = 0;
|
||||
HistoryView::ElementHighlighter _highlighter;
|
||||
|
||||
crl::time _saveDraftStart = 0;
|
||||
bool _saveDraftText = false;
|
||||
|
|
|
@ -283,7 +283,10 @@ ListWidget::ListWidget(
|
|||
, _scrollDateCheck([this] { scrollDateCheck(); })
|
||||
, _applyUpdatedScrollState([this] { applyUpdatedScrollState(); })
|
||||
, _selectEnabled(_delegate->listAllowsMultiSelect())
|
||||
, _highlightTimer([this] { updateHighlightedMessage(); }) {
|
||||
, _highlighter(
|
||||
&session().data(),
|
||||
[=](const HistoryItem *item) { return viewForItem(item); },
|
||||
[=](const Element *view) { repaintItem(view); }) {
|
||||
setMouseTracking(true);
|
||||
_scrollDateHideTimer.setCallback([this] { scrollDateHideByTimer(); });
|
||||
session().data().viewRepaintRequest(
|
||||
|
@ -578,15 +581,7 @@ bool ListWidget::isBelowPosition(Data::MessagePosition position) const {
|
|||
}
|
||||
|
||||
void ListWidget::highlightMessage(FullMsgId itemId) {
|
||||
if (const auto item = session().data().message(itemId)) {
|
||||
if (const auto view = viewForItem(item)) {
|
||||
_highlightStart = crl::now();
|
||||
_highlightedMessageId = itemId;
|
||||
_highlightTimer.callEach(AnimationTimerDelta);
|
||||
|
||||
repaintHighlightedItem(view);
|
||||
}
|
||||
}
|
||||
_highlighter.highlight(itemId);
|
||||
}
|
||||
|
||||
void ListWidget::showAroundPosition(
|
||||
|
@ -598,39 +593,6 @@ void ListWidget::showAroundPosition(
|
|||
refreshViewer();
|
||||
}
|
||||
|
||||
void ListWidget::repaintHighlightedItem(not_null<const Element*> view) {
|
||||
if (view->isHiddenByGroup()) {
|
||||
if (const auto group = session().data().groups().find(view->data())) {
|
||||
if (const auto leader = viewForItem(group->items.front())) {
|
||||
if (!leader->isHiddenByGroup()) {
|
||||
repaintItem(leader);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
repaintItem(view);
|
||||
}
|
||||
|
||||
void ListWidget::updateHighlightedMessage() {
|
||||
if (const auto item = session().data().message(_highlightedMessageId)) {
|
||||
if (const auto view = viewForItem(item)) {
|
||||
repaintHighlightedItem(view);
|
||||
auto duration = st::activeFadeInDuration + st::activeFadeOutDuration;
|
||||
if (crl::now() - _highlightStart <= duration) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_highlightTimer.cancel();
|
||||
_highlightedMessageId = FullMsgId();
|
||||
}
|
||||
|
||||
void ListWidget::clearHighlightedMessage() {
|
||||
_highlightedMessageId = FullMsgId();
|
||||
updateHighlightedMessage();
|
||||
}
|
||||
|
||||
void ListWidget::checkUnreadBarCreation() {
|
||||
if (!_bar.element) {
|
||||
if (auto data = _delegate->listMessagesBar(_items); data.bar.element) {
|
||||
|
@ -1437,12 +1399,7 @@ bool ListWidget::elementUnderCursor(
|
|||
|
||||
crl::time ListWidget::elementHighlightTime(
|
||||
not_null<const HistoryItem*> item) {
|
||||
if (item->fullId() == _highlightedMessageId) {
|
||||
if (_highlightTimer.isActive()) {
|
||||
return crl::now() - _highlightStart;
|
||||
}
|
||||
}
|
||||
return crl::time(0);
|
||||
return _highlighter.elementTime(item);
|
||||
}
|
||||
|
||||
bool ListWidget::elementInSelectionMode() {
|
||||
|
@ -3266,7 +3223,7 @@ void ListWidget::replyNextMessage(FullMsgId fullId, bool next) {
|
|||
_requestedToShowMessage.fire_copy(newFullId);
|
||||
} else {
|
||||
replyToMessageRequestNotify(FullMsgId());
|
||||
clearHighlightedMessage();
|
||||
_highlighter.clear();
|
||||
}
|
||||
};
|
||||
const auto replyFirst = [&] {
|
||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "mtproto/sender.h"
|
||||
#include "data/data_messages.h"
|
||||
#include "history/view/history_view_element.h"
|
||||
#include "history/history_view_highlight_manager.h"
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
|
@ -405,7 +406,6 @@ private:
|
|||
int itemTop(not_null<const Element*> view) const;
|
||||
void repaintItem(FullMsgId itemId);
|
||||
void repaintItem(const Element *view);
|
||||
void repaintHighlightedItem(not_null<const Element*> view);
|
||||
void resizeItem(not_null<Element*> view);
|
||||
void refreshItem(not_null<const Element*> view);
|
||||
void itemRemoved(not_null<const HistoryItem*> item);
|
||||
|
@ -516,9 +516,6 @@ private:
|
|||
|
||||
void startMessageSendingAnimation(not_null<HistoryItem*> item);
|
||||
|
||||
void updateHighlightedMessage();
|
||||
void clearHighlightedMessage();
|
||||
|
||||
// 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.
|
||||
//
|
||||
|
@ -638,9 +635,7 @@ private:
|
|||
QPoint _trippleClickPoint;
|
||||
crl::time _trippleClickStartTime = 0;
|
||||
|
||||
crl::time _highlightStart = 0;
|
||||
FullMsgId _highlightedMessageId;
|
||||
base::Timer _highlightTimer;
|
||||
ElementHighlighter _highlighter;
|
||||
|
||||
Ui::Animations::Simple _spoilerOpacity;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue