mirror of
https://github.com/vale981/tdesktop
synced 2025-03-06 02:01:40 -05:00
Highlight all mentions when marking them read.
This commit is contained in:
parent
20efa47126
commit
5a20014b1a
11 changed files with 150 additions and 86 deletions
|
@ -432,6 +432,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
if (item->mentionsMe() && item->isMediaUnread()) {
|
||||
readMentions.insert(item);
|
||||
_widget->enqueueMessageHighlight(item);
|
||||
}
|
||||
|
||||
int32 h = item->height();
|
||||
|
@ -482,6 +483,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
if (item->mentionsMe() && item->isMediaUnread()) {
|
||||
readMentions.insert(item);
|
||||
_widget->enqueueMessageHighlight(item);
|
||||
}
|
||||
}
|
||||
p.translate(0, h);
|
||||
|
|
|
@ -600,9 +600,14 @@ TextSelection shiftSelection(TextSelection selection, uint16 byLength) {
|
|||
|
||||
} // namespace internal
|
||||
|
||||
HistoryItem::HistoryItem(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime msgDate, int32 from) : HistoryElement()
|
||||
, id(msgId)
|
||||
, date(msgDate)
|
||||
HistoryItem::HistoryItem(
|
||||
not_null<History*> history,
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
QDateTime date,
|
||||
UserId from) : HistoryElement()
|
||||
, id(id)
|
||||
, date(date)
|
||||
, _history(history)
|
||||
, _from(from ? App::user(from) : history->peer)
|
||||
, _flags(flags | MTPDmessage_ClientFlag::f_pending_init_dimensions | MTPDmessage_ClientFlag::f_pending_resize)
|
||||
|
|
|
@ -526,7 +526,7 @@ public:
|
|||
}
|
||||
void addLogEntryOriginal(WebPageId localId, const QString &label, const TextWithEntities &content);
|
||||
|
||||
History *history() const {
|
||||
not_null<History*> history() const {
|
||||
return _history;
|
||||
}
|
||||
PeerData *from() const {
|
||||
|
@ -921,7 +921,12 @@ public:
|
|||
~HistoryItem();
|
||||
|
||||
protected:
|
||||
HistoryItem(History *history, MsgId msgId, MTPDmessage::Flags flags, QDateTime msgDate, int32 from);
|
||||
HistoryItem(
|
||||
not_null<History*> history,
|
||||
MsgId id,
|
||||
MTPDmessage::Flags flags,
|
||||
QDateTime date,
|
||||
UserId from);
|
||||
|
||||
// To completely create history item we need to call
|
||||
// a virtual method, it can not be done from constructor.
|
||||
|
@ -938,7 +943,7 @@ protected:
|
|||
void finishEdition(int oldKeyboardTop);
|
||||
void finishEditionToEmpty();
|
||||
|
||||
not_null<History*> _history;
|
||||
const not_null<History*> _history;
|
||||
not_null<PeerData*> _from;
|
||||
HistoryBlock *_block = nullptr;
|
||||
int _indexInBlock = -1;
|
||||
|
|
|
@ -1613,12 +1613,10 @@ void HistoryMessage::draw(Painter &p, QRect clip, TextSelection selection, TimeM
|
|||
}
|
||||
}
|
||||
|
||||
auto fullAnimMs = App::main() ? App::main()->animActiveTimeStart(this) : 0LL;
|
||||
auto fullAnimMs = App::main() ? App::main()->highlightStartTime(this) : 0LL;
|
||||
if (fullAnimMs > 0 && fullAnimMs <= ms) {
|
||||
int animms = ms - fullAnimMs;
|
||||
if (animms > st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||
App::main()->stopAnimActive();
|
||||
} else {
|
||||
auto animms = ms - fullAnimMs;
|
||||
if (animms < st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||
auto top = marginTop();
|
||||
auto bottom = marginBottom();
|
||||
auto fill = qMin(top, bottom);
|
||||
|
|
|
@ -188,16 +188,18 @@ int WideChatWidth() {
|
|||
return st::msgMaxWidth + 2 * st::msgPhotoSkip + 2 * st::msgMargin.left();
|
||||
}
|
||||
|
||||
void ServiceMessagePainter::paint(Painter &p, const HistoryService *message, const PaintContext &context, int height) {
|
||||
void ServiceMessagePainter::paint(
|
||||
Painter &p,
|
||||
not_null<const HistoryService*> message,
|
||||
const PaintContext &context,
|
||||
int height) {
|
||||
auto g = message->countGeometry();
|
||||
if (g.width() < 1) return;
|
||||
|
||||
auto fullAnimMs = App::main() ? App::main()->animActiveTimeStart(message) : 0LL;
|
||||
auto fullAnimMs = App::main() ? App::main()->highlightStartTime(message) : 0LL;
|
||||
if (fullAnimMs > 0 && fullAnimMs <= context.ms) {
|
||||
int animms = context.ms - fullAnimMs;
|
||||
if (animms > st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||
App::main()->stopAnimActive();
|
||||
} else {
|
||||
auto animms = context.ms - fullAnimMs;
|
||||
if (animms < st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||
auto top = st::msgServiceMargin.top();
|
||||
auto bottom = st::msgServiceMargin.bottom();
|
||||
auto fill = qMin(top, bottom);
|
||||
|
|
|
@ -39,7 +39,11 @@ struct PaintContext {
|
|||
|
||||
class ServiceMessagePainter {
|
||||
public:
|
||||
static void paint(Painter &p, const HistoryService *message, const PaintContext &context, int height);
|
||||
static void paint(
|
||||
Painter &p,
|
||||
not_null<const HistoryService*> message,
|
||||
const PaintContext &context,
|
||||
int height);
|
||||
|
||||
static void paintDate(Painter &p, const QDateTime &date, int y, int w);
|
||||
static void paintDate(Painter &p, const QString &dateText, int dateTextWidth, int y, int w);
|
||||
|
|
|
@ -680,8 +680,7 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
|
|||
|
||||
_sendActionStopTimer.setSingleShot(true);
|
||||
|
||||
_animActiveTimer.setSingleShot(false);
|
||||
connect(&_animActiveTimer, SIGNAL(timeout()), this, SLOT(onAnimActiveStep()));
|
||||
_highlightTimer.setCallback([this] { updateHighlightedMessage(); });
|
||||
|
||||
_membersDropdownShowTimer.setSingleShot(true);
|
||||
connect(&_membersDropdownShowTimer, SIGNAL(timeout()), this, SLOT(onMembersDropdownShow()));
|
||||
|
@ -948,24 +947,108 @@ void HistoryWidget::scrollToAnimationCallback(FullMsgId attachToId) {
|
|||
}
|
||||
}
|
||||
|
||||
void HistoryWidget::highlightMessage(HistoryItem *context) {
|
||||
Expects(_list != nullptr);
|
||||
void HistoryWidget::enqueueMessageHighlight(not_null<HistoryItem*> item) {
|
||||
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();
|
||||
}
|
||||
};
|
||||
if (item->history() == _history) {
|
||||
enqueueMessageId(item->id);
|
||||
} else if (item->history() == _migrated) {
|
||||
enqueueMessageId(-item->id);
|
||||
}
|
||||
}
|
||||
|
||||
_animActiveStart = getms();
|
||||
_animActiveTimer.start(AnimationTimerDelta);
|
||||
_activeAnimMsgId = _showAtMsgId;
|
||||
if (context
|
||||
&& context->history() == _history
|
||||
&& context->isGroupMigrate()
|
||||
void HistoryWidget::highlightMessage(MsgId universalMessageId) {
|
||||
_highlightStart = getms();
|
||||
_highlightedMessageId = universalMessageId;
|
||||
_highlightTimer.callEach(AnimationTimerDelta);
|
||||
|
||||
adjustHighlightedMessageToMigrated();
|
||||
}
|
||||
|
||||
void HistoryWidget::adjustHighlightedMessageToMigrated() {
|
||||
if (_history
|
||||
&& _highlightTimer.isActive()
|
||||
&& _highlightedMessageId > 0
|
||||
&& _migrated
|
||||
&& !_migrated->isEmpty()
|
||||
&& _migrated->loadedAtBottom()
|
||||
&& _migrated->blocks.back()->items.back()->isGroupMigrate()
|
||||
&& _list->historyTop() != _list->historyDrawTop()) {
|
||||
_activeAnimMsgId = -_migrated->blocks.back()->items.back()->id;
|
||||
auto highlighted = App::histItemById(
|
||||
_history->channelId(),
|
||||
_highlightedMessageId);
|
||||
if (highlighted && highlighted->isGroupMigrate()) {
|
||||
_highlightedMessageId = -_migrated->blocks.back()->items.back()->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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->detached()) {
|
||||
return msgId;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}();
|
||||
if (!nextHighlight) {
|
||||
return;
|
||||
}
|
||||
highlightMessage(nextHighlight);
|
||||
}
|
||||
|
||||
void HistoryWidget::updateHighlightedMessage() {
|
||||
auto item = getItemFromHistoryOrMigrated(_highlightedMessageId);
|
||||
if (!item || item->detached()) {
|
||||
return stopMessageHighlight();
|
||||
}
|
||||
auto duration = st::activeFadeInDuration + st::activeFadeOutDuration;
|
||||
if (getms() - _highlightStart > duration) {
|
||||
return stopMessageHighlight();
|
||||
}
|
||||
|
||||
Ui::repaintHistoryItem(item);
|
||||
}
|
||||
|
||||
TimeMs 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();
|
||||
}
|
||||
|
||||
int HistoryWidget::itemTopForHighlight(not_null<HistoryItem*> item) const {
|
||||
auto itemTop = _list->itemTop(item);
|
||||
Assert(itemTop >= 0);
|
||||
|
@ -1644,6 +1727,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
|||
showAtMsgId = ShowAtTheEndMsgId;
|
||||
}
|
||||
|
||||
clearHighlightMessages();
|
||||
if (_history) {
|
||||
if (_peer->id == peerId && !reload) {
|
||||
updateForwarding();
|
||||
|
@ -1676,7 +1760,6 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
|||
|
||||
auto item = getItemFromHistoryOrMigrated(_showAtMsgId);
|
||||
animatedScrollToY(countInitialScrollTop(), item);
|
||||
highlightMessage(item);
|
||||
} else {
|
||||
historyLoaded();
|
||||
}
|
||||
|
@ -4808,7 +4891,7 @@ int HistoryWidget::countInitialScrollTop() {
|
|||
return countInitialScrollTop();
|
||||
} else {
|
||||
result = itemTopForHighlight(item);
|
||||
highlightMessage(item);
|
||||
enqueueMessageHighlight(item);
|
||||
}
|
||||
} else if (_history->unreadBar || (_migrated && _migrated->unreadBar)) {
|
||||
result = unreadBarTop();
|
||||
|
@ -4974,12 +5057,7 @@ void HistoryWidget::addMessagesToFront(PeerData *peer, const QVector<MTPMessage>
|
|||
_list->messagesReceived(peer, messages);
|
||||
if (!_firstLoadRequest) {
|
||||
updateHistoryGeometry();
|
||||
if (_animActiveTimer.isActive() && _activeAnimMsgId > 0 && _migrated && !_migrated->isEmpty() && _migrated->loadedAtBottom() && _migrated->blocks.back()->items.back()->isGroupMigrate() && _list->historyTop() != _list->historyDrawTop() && _history) {
|
||||
auto animActiveItem = App::histItemById(_history->channelId(), _activeAnimMsgId);
|
||||
if (animActiveItem && animActiveItem->isGroupMigrate()) {
|
||||
_activeAnimMsgId = -_migrated->blocks.back()->items.back()->id;
|
||||
}
|
||||
}
|
||||
adjustHighlightedMessageToMigrated();
|
||||
updateBotKeyboard();
|
||||
}
|
||||
}
|
||||
|
@ -6147,36 +6225,6 @@ HistoryItem *HistoryWidget::getItemFromHistoryOrMigrated(MsgId genericMsgId) con
|
|||
return App::histItemById(_channel, genericMsgId);
|
||||
}
|
||||
|
||||
void HistoryWidget::onAnimActiveStep() {
|
||||
if (!_history || !_activeAnimMsgId || (_activeAnimMsgId < 0 && (!_migrated || -_activeAnimMsgId >= ServerMaxMsgId))) {
|
||||
return _animActiveTimer.stop();
|
||||
}
|
||||
|
||||
auto item = getItemFromHistoryOrMigrated(_activeAnimMsgId);
|
||||
if (!item || item->detached()) {
|
||||
return _animActiveTimer.stop();
|
||||
}
|
||||
|
||||
if (getms() - _animActiveStart > st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||
stopAnimActive();
|
||||
} else {
|
||||
Ui::repaintHistoryItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
uint64 HistoryWidget::animActiveTimeStart(const HistoryItem *msg) const {
|
||||
if (!msg) return 0;
|
||||
if ((msg->history() == _history && msg->id == _activeAnimMsgId) || (_migrated && msg->history() == _migrated && msg->id == -_activeAnimMsgId)) {
|
||||
return _animActiveTimer.isActive() ? _animActiveStart : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void HistoryWidget::stopAnimActive() {
|
||||
_animActiveTimer.stop();
|
||||
_activeAnimMsgId = 0;
|
||||
}
|
||||
|
||||
SelectedItemSet HistoryWidget::getSelectedItems() const {
|
||||
return _list ? _list->getSelectedItems() : SelectedItemSet();
|
||||
}
|
||||
|
|
|
@ -262,8 +262,8 @@ public:
|
|||
|
||||
bool touchScroll(const QPoint &delta);
|
||||
|
||||
uint64 animActiveTimeStart(const HistoryItem *msg) const;
|
||||
void stopAnimActive();
|
||||
void enqueueMessageHighlight(not_null<HistoryItem*> item);
|
||||
TimeMs highlightStartTime(not_null<const HistoryItem*> item) const;
|
||||
|
||||
SelectedItemSet getSelectedItems() const;
|
||||
void itemEdited(HistoryItem *item);
|
||||
|
@ -445,8 +445,6 @@ public slots:
|
|||
void onForwardSelected();
|
||||
void onClearSelected();
|
||||
|
||||
void onAnimActiveStep();
|
||||
|
||||
void onDraftSaveDelayed();
|
||||
void onDraftSave(bool delayed = false);
|
||||
void onCloudDraftSave();
|
||||
|
@ -492,6 +490,13 @@ private:
|
|||
void showNextUnreadMention();
|
||||
void handlePeerUpdate();
|
||||
|
||||
void highlightMessage(MsgId universalMessageId);
|
||||
void adjustHighlightedMessageToMigrated();
|
||||
void checkNextHighlight();
|
||||
void updateHighlightedMessage();
|
||||
void clearHighlightMessages();
|
||||
void stopMessageHighlight();
|
||||
|
||||
void animationCallback();
|
||||
void updateOverStates(QPoint pos);
|
||||
void recordStartCallback();
|
||||
|
@ -701,7 +706,7 @@ private:
|
|||
HistoryItem *getItemFromHistoryOrMigrated(MsgId genericMsgId) const;
|
||||
void animatedScrollToItem(MsgId msgId);
|
||||
void animatedScrollToY(int scrollTo, HistoryItem *attachTo = nullptr);
|
||||
void highlightMessage(HistoryItem *context);
|
||||
|
||||
void updateDragAreas();
|
||||
|
||||
// when scroll position or scroll area size changed this method
|
||||
|
@ -729,8 +734,6 @@ private:
|
|||
MsgId _delayedShowAtMsgId = -1; // wtf?
|
||||
mtpRequestId _delayedShowAtRequest = 0;
|
||||
|
||||
MsgId _activeAnimMsgId = 0;
|
||||
|
||||
object_ptr<Ui::AbstractButton> _backAnimationButton = { nullptr };
|
||||
object_ptr<Window::TopBarWidget> _topBar;
|
||||
object_ptr<Ui::ScrollArea> _scroll;
|
||||
|
@ -846,8 +849,10 @@ private:
|
|||
QTimer _scrollTimer;
|
||||
int32 _scrollDelta = 0;
|
||||
|
||||
QTimer _animActiveTimer;
|
||||
float64 _animActiveStart = 0;
|
||||
MsgId _highlightedMessageId = 0;
|
||||
std::deque<MsgId> _highlightQueue;
|
||||
base::Timer _highlightTimer;
|
||||
TimeMs _highlightStart = 0;
|
||||
|
||||
QMap<QPair<History*, SendAction::Type>, mtpRequestId> _sendActionRequests;
|
||||
QTimer _sendActionStopTimer;
|
||||
|
|
|
@ -1529,12 +1529,8 @@ void MainWidget::unreadCountChanged(History *history) {
|
|||
_history->unreadCountChanged(history);
|
||||
}
|
||||
|
||||
TimeMs MainWidget::animActiveTimeStart(const HistoryItem *msg) const {
|
||||
return _history->animActiveTimeStart(msg);
|
||||
}
|
||||
|
||||
void MainWidget::stopAnimActive() {
|
||||
_history->stopAnimActive();
|
||||
TimeMs MainWidget::highlightStartTime(not_null<const HistoryItem*> item) const {
|
||||
return _history->highlightStartTime(item);
|
||||
}
|
||||
|
||||
void MainWidget::sendBotCommand(PeerData *peer, UserData *bot, const QString &cmd, MsgId replyTo) {
|
||||
|
|
|
@ -309,8 +309,7 @@ public:
|
|||
void readServerHistory(History *history, ReadServerHistoryChecks checks = ReadServerHistoryChecks::OnlyIfUnread);
|
||||
void unreadCountChanged(History *history);
|
||||
|
||||
TimeMs animActiveTimeStart(const HistoryItem *msg) const;
|
||||
void stopAnimActive();
|
||||
TimeMs highlightStartTime(not_null<const HistoryItem*> item) const;
|
||||
|
||||
void sendBotCommand(PeerData *peer, UserData *bot, const QString &cmd, MsgId replyTo);
|
||||
void hideSingleUseKeyboard(PeerData *peer, MsgId replyTo);
|
||||
|
|
|
@ -1026,7 +1026,7 @@ void MediaView::onCopy() {
|
|||
}
|
||||
|
||||
void MediaView::showPhoto(PhotoData *photo, HistoryItem *context) {
|
||||
_history = context ? context->history() : nullptr;
|
||||
_history = context ? context->history().get() : nullptr;
|
||||
_migrated = nullptr;
|
||||
if (_history) {
|
||||
if (_history->peer->migrateFrom()) {
|
||||
|
@ -1144,7 +1144,7 @@ void MediaView::showPhoto(PhotoData *photo, PeerData *context) {
|
|||
|
||||
void MediaView::showDocument(DocumentData *doc, HistoryItem *context) {
|
||||
_photo = 0;
|
||||
_history = context ? context->history() : nullptr;
|
||||
_history = context ? context->history().get() : nullptr;
|
||||
_migrated = nullptr;
|
||||
if (_history) {
|
||||
if (_history->peer->migrateFrom()) {
|
||||
|
|
Loading…
Add table
Reference in a new issue