mirror of https://github.com/procxx/kepka.git
Highlight found messages in feed.
This commit is contained in:
parent
07528be1e6
commit
351a423337
|
@ -508,6 +508,10 @@ void InnerWidget::elementAnimationAutoplayAsync(
|
|||
});
|
||||
}
|
||||
|
||||
TimeMs InnerWidget::elementHighlightTime(
|
||||
not_null<const HistoryView::Element*> element) {
|
||||
return TimeMs(0);
|
||||
}
|
||||
|
||||
void InnerWidget::saveState(not_null<SectionMemento*> memento) {
|
||||
memento->setFilter(std::move(_filter));
|
||||
|
|
|
@ -85,6 +85,8 @@ public:
|
|||
not_null<const HistoryView::Element*> view) override;
|
||||
void elementAnimationAutoplayAsync(
|
||||
not_null<const HistoryView::Element*> view) override;
|
||||
TimeMs elementHighlightTime(
|
||||
not_null<const HistoryView::Element*> element) override;
|
||||
|
||||
~InnerWidget();
|
||||
|
||||
|
|
|
@ -159,7 +159,11 @@ void Widget::scrollDownClicked() {
|
|||
}
|
||||
|
||||
void Widget::showAtPosition(Data::MessagePosition position) {
|
||||
if (!showAtPositionNow(position)) {
|
||||
if (showAtPositionNow(position)) {
|
||||
if (const auto highlight = base::take(_highlightMessageId)) {
|
||||
_inner->highlightMessage(highlight);
|
||||
}
|
||||
} else {
|
||||
_nextAnimatedScrollPosition = position;
|
||||
_nextAnimatedScrollDelta = _inner->isBelowPosition(position)
|
||||
? -_scroll->height()
|
||||
|
@ -424,6 +428,9 @@ void Widget::listContentRefreshed() {
|
|||
position,
|
||||
_nextAnimatedScrollDelta,
|
||||
HistoryView::ListWidget::AnimatedScroll::Part);
|
||||
if (const auto highlight = base::take(_highlightMessageId)) {
|
||||
_inner->highlightMessage(highlight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,7 +454,7 @@ void Widget::restoreState(not_null<Memento*> memento) {
|
|||
_undefinedAroundPosition = !list->aroundPosition();
|
||||
_inner->restoreState(memento->list());
|
||||
if (const auto position = memento->position()) {
|
||||
_currentMessageId = position.fullId;
|
||||
_currentMessageId = _highlightMessageId = position.fullId;
|
||||
showAtPosition(position);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ private:
|
|||
std::unique_ptr<HistoryView::Element> _emptyTextView;
|
||||
|
||||
FullMsgId _currentMessageId;
|
||||
FullMsgId _highlightMessageId;
|
||||
base::optional<Data::MessagePosition> _nextAnimatedScrollPosition;
|
||||
int _nextAnimatedScrollDelta = 0;
|
||||
|
||||
|
|
|
@ -3006,6 +3006,18 @@ not_null<HistoryView::ElementDelegate*> HistoryInner::ElementDelegate() {
|
|||
}
|
||||
});
|
||||
}
|
||||
TimeMs elementHighlightTime(
|
||||
not_null<const HistoryView::Element*> view) override {
|
||||
const auto fullAnimMs = App::main()->highlightStartTime(
|
||||
view->data());
|
||||
if (fullAnimMs > 0) {
|
||||
const auto now = getms();
|
||||
if (fullAnimMs < now) {
|
||||
return now - fullAnimMs;
|
||||
}
|
||||
}
|
||||
return TimeMs(0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -174,26 +174,34 @@ void Element::setY(int y) {
|
|||
_y = y;
|
||||
}
|
||||
|
||||
int Element::marginTop() const {
|
||||
const auto item = data();
|
||||
auto result = 0;
|
||||
if (!isHidden()) {
|
||||
if (isAttachedToPrevious()) {
|
||||
result += st::msgMarginTopAttached;
|
||||
} else {
|
||||
result += st::msgMargin.top();
|
||||
}
|
||||
void Element::paintHighlight(
|
||||
Painter &p,
|
||||
int geometryHeight) const {
|
||||
const auto animms = delegate()->elementHighlightTime(this);
|
||||
if (!animms
|
||||
|| animms >= st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||
return;
|
||||
}
|
||||
result += displayedDateHeight();
|
||||
if (const auto bar = Get<UnreadBar>()) {
|
||||
result += bar->height();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int Element::marginBottom() const {
|
||||
const auto item = data();
|
||||
return isHidden() ? 0 : st::msgMargin.bottom();
|
||||
const auto top = marginTop();
|
||||
const auto bottom = marginBottom();
|
||||
const auto fill = qMin(top, bottom);
|
||||
const auto skiptop = top - fill;
|
||||
const auto fillheight = fill + geometryHeight + fill;
|
||||
|
||||
const auto dt = (animms > st::activeFadeInDuration)
|
||||
? (1. - (animms - st::activeFadeInDuration)
|
||||
/ float64(st::activeFadeOutDuration))
|
||||
: (animms / float64(st::activeFadeInDuration));
|
||||
const auto o = p.opacity();
|
||||
p.setOpacity(o * dt);
|
||||
p.fillRect(
|
||||
0,
|
||||
skiptop,
|
||||
width(),
|
||||
fillheight,
|
||||
st::defaultTextPalette.selectOverlay);
|
||||
p.setOpacity(o);
|
||||
}
|
||||
|
||||
bool Element::isUnderCursor() const {
|
||||
|
|
|
@ -42,6 +42,8 @@ public:
|
|||
virtual bool elementUnderCursor(not_null<const Element*> view) = 0;
|
||||
virtual void elementAnimationAutoplayAsync(
|
||||
not_null<const Element*> element) = 0;
|
||||
virtual TimeMs elementHighlightTime(
|
||||
not_null<const Element*> element) = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -126,8 +128,9 @@ public:
|
|||
int y() const;
|
||||
void setY(int y);
|
||||
|
||||
int marginTop() const;
|
||||
int marginBottom() const;
|
||||
virtual int marginTop() const = 0;
|
||||
virtual int marginBottom() const = 0;
|
||||
|
||||
void setPendingResize();
|
||||
bool pendingResize() const;
|
||||
bool isUnderCursor() const;
|
||||
|
@ -242,8 +245,9 @@ public:
|
|||
virtual ~Element();
|
||||
|
||||
protected:
|
||||
void setInitialSize(int maxWidth, int minHeight);
|
||||
void setCurrentSize(int width, int height);
|
||||
void paintHighlight(
|
||||
Painter &p,
|
||||
int geometryHeight) const;
|
||||
|
||||
private:
|
||||
// This should be called only from previousInBlocksChanged()
|
||||
|
|
|
@ -239,7 +239,8 @@ ListWidget::ListWidget(
|
|||
, _itemAverageHeight(itemMinimalHeight())
|
||||
, _scrollDateCheck([this] { scrollDateCheck(); })
|
||||
, _applyUpdatedScrollState([this] { applyUpdatedScrollState(); })
|
||||
, _selectEnabled(_delegate->listAllowsMultiSelect()) {
|
||||
, _selectEnabled(_delegate->listAllowsMultiSelect())
|
||||
, _highlightTimer([this] { updateHighlightedMessage(); }) {
|
||||
setMouseTracking(true);
|
||||
_scrollDateHideTimer.setCallback([this] { scrollDateHideByTimer(); });
|
||||
Auth().data().viewRepaintRequest(
|
||||
|
@ -417,6 +418,32 @@ bool ListWidget::isBelowPosition(Data::MessagePosition position) const {
|
|||
return _items.front()->data()->position() > position;
|
||||
}
|
||||
|
||||
void ListWidget::highlightMessage(FullMsgId itemId) {
|
||||
if (const auto item = App::histItemById(itemId)) {
|
||||
if (const auto view = viewForItem(item)) {
|
||||
_highlightStart = getms();
|
||||
_highlightedMessageId = itemId;
|
||||
_highlightTimer.callEach(AnimationTimerDelta);
|
||||
|
||||
repaintItem(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ListWidget::updateHighlightedMessage() {
|
||||
if (const auto item = App::histItemById(_highlightedMessageId)) {
|
||||
if (const auto view = viewForItem(item)) {
|
||||
repaintItem(view);
|
||||
auto duration = st::activeFadeInDuration + st::activeFadeOutDuration;
|
||||
if (getms() - _highlightStart <= duration) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
_highlightTimer.cancel();
|
||||
_highlightedMessageId = FullMsgId();
|
||||
}
|
||||
|
||||
void ListWidget::checkUnreadBarCreation() {
|
||||
if (!_unreadBarElement) {
|
||||
if (const auto index = _delegate->listUnreadBarView(_items)) {
|
||||
|
@ -1071,6 +1098,16 @@ void ListWidget::elementAnimationAutoplayAsync(
|
|||
});
|
||||
}
|
||||
|
||||
TimeMs ListWidget::elementHighlightTime(
|
||||
not_null<const HistoryView::Element*> element) {
|
||||
if (element->data()->fullId() == _highlightedMessageId) {
|
||||
if (_highlightTimer.isActive()) {
|
||||
return getms() - _highlightStart;
|
||||
}
|
||||
}
|
||||
return TimeMs(0);
|
||||
}
|
||||
|
||||
void ListWidget::saveState(not_null<ListMemento*> memento) {
|
||||
memento->setAroundPosition(_aroundPosition);
|
||||
auto state = countScrollState();
|
||||
|
|
|
@ -149,6 +149,7 @@ public:
|
|||
AnimatedScroll type);
|
||||
bool isAbovePosition(Data::MessagePosition position) const;
|
||||
bool isBelowPosition(Data::MessagePosition position) const;
|
||||
void highlightMessage(FullMsgId itemId);
|
||||
|
||||
TextWithEntities getSelectedText() const;
|
||||
MessageIdsList getSelectedItems() const;
|
||||
|
@ -175,6 +176,7 @@ public:
|
|||
bool elementUnderCursor(not_null<const Element*> view) override;
|
||||
void elementAnimationAutoplayAsync(
|
||||
not_null<const Element*> view) override;
|
||||
TimeMs elementHighlightTime(not_null<const Element*> element) override;
|
||||
|
||||
~ListWidget();
|
||||
|
||||
|
@ -378,6 +380,8 @@ private:
|
|||
void applyUpdatedScrollState();
|
||||
void scrollToAnimationCallback(FullMsgId attachToId);
|
||||
|
||||
void updateHighlightedMessage();
|
||||
|
||||
// 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.
|
||||
//
|
||||
|
@ -469,6 +473,10 @@ private:
|
|||
QPoint _trippleClickPoint;
|
||||
TimeMs _trippleClickStartTime = 0;
|
||||
|
||||
TimeMs _highlightStart = 0;
|
||||
FullMsgId _highlightedMessageId;
|
||||
base::Timer _highlightTimer;
|
||||
|
||||
rpl::lifetime _viewerLifetime;
|
||||
|
||||
};
|
||||
|
|
|
@ -342,6 +342,26 @@ QSize Message::performCountOptimalSize() {
|
|||
return QSize(maxWidth, minHeight);
|
||||
}
|
||||
|
||||
int Message::marginTop() const {
|
||||
auto result = 0;
|
||||
if (!isHidden()) {
|
||||
if (isAttachedToPrevious()) {
|
||||
result += st::msgMarginTopAttached;
|
||||
} else {
|
||||
result += st::msgMargin.top();
|
||||
}
|
||||
}
|
||||
result += displayedDateHeight();
|
||||
if (const auto bar = Get<UnreadBar>()) {
|
||||
result += bar->height();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int Message::marginBottom() const {
|
||||
return isHidden() ? 0 : st::msgMargin.bottom();
|
||||
}
|
||||
|
||||
void Message::draw(
|
||||
Painter &p,
|
||||
QRect clip,
|
||||
|
@ -376,25 +396,11 @@ void Message::draw(
|
|||
return;
|
||||
}
|
||||
|
||||
auto fullAnimMs = App::main() ? App::main()->highlightStartTime(item) : 0LL;
|
||||
if (fullAnimMs > 0 && fullAnimMs <= ms) {
|
||||
auto animms = ms - fullAnimMs;
|
||||
if (animms < st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||
auto top = marginTop();
|
||||
auto bottom = marginBottom();
|
||||
auto fill = qMin(top, bottom);
|
||||
auto skiptop = top - fill;
|
||||
auto fillheight = fill + g.height() + fill;
|
||||
paintHighlight(p, g.height());
|
||||
|
||||
auto dt = (animms > st::activeFadeInDuration) ? (1. - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration));
|
||||
auto o = p.opacity();
|
||||
p.setOpacity(o * dt);
|
||||
p.fillRect(0, skiptop, width(), fillheight, st::defaultTextPalette.selectOverlay);
|
||||
p.setOpacity(o);
|
||||
}
|
||||
}
|
||||
|
||||
p.setTextPalette(selected ? (outbg ? st::outTextPaletteSelected : st::inTextPaletteSelected) : (outbg ? st::outTextPalette : st::inTextPalette));
|
||||
p.setTextPalette(selected
|
||||
? (outbg ? st::outTextPaletteSelected : st::inTextPaletteSelected)
|
||||
: (outbg ? st::outTextPalette : st::inTextPalette));
|
||||
|
||||
auto keyboard = item->inlineReplyKeyboard();
|
||||
if (keyboard) {
|
||||
|
|
|
@ -32,6 +32,8 @@ public:
|
|||
not_null<ElementDelegate*> delegate,
|
||||
not_null<HistoryMessage*> data);
|
||||
|
||||
int marginTop() const override;
|
||||
int marginBottom() const override;
|
||||
void draw(
|
||||
Painter &p,
|
||||
QRect clip,
|
||||
|
|
|
@ -373,6 +373,14 @@ bool Service::isHidden() const {
|
|||
return Element::isHidden();
|
||||
}
|
||||
|
||||
int Service::marginTop() const {
|
||||
return st::msgServiceMargin.top();
|
||||
}
|
||||
|
||||
int Service::marginBottom() const {
|
||||
return st::msgServiceMargin.bottom();
|
||||
}
|
||||
|
||||
void Service::draw(
|
||||
Painter &p,
|
||||
QRect clip,
|
||||
|
@ -410,23 +418,7 @@ void Service::draw(
|
|||
return;
|
||||
}
|
||||
|
||||
auto fullAnimMs = App::main() ? App::main()->highlightStartTime(item) : 0LL;
|
||||
if (fullAnimMs > 0 && fullAnimMs <= ms) {
|
||||
auto animms = ms - fullAnimMs;
|
||||
if (animms < st::activeFadeInDuration + st::activeFadeOutDuration) {
|
||||
auto top = st::msgServiceMargin.top();
|
||||
auto bottom = st::msgServiceMargin.bottom();
|
||||
auto fill = qMin(top, bottom);
|
||||
auto skiptop = top - fill;
|
||||
auto fillheight = fill + height + fill;
|
||||
|
||||
auto dt = (animms > st::activeFadeInDuration) ? (1. - (animms - st::activeFadeInDuration) / float64(st::activeFadeOutDuration)) : (animms / float64(st::activeFadeInDuration));
|
||||
auto o = p.opacity();
|
||||
p.setOpacity(o * dt);
|
||||
p.fillRect(0, skiptop, width(), fillheight, st::defaultTextPalette.selectOverlay);
|
||||
p.setOpacity(o);
|
||||
}
|
||||
}
|
||||
paintHighlight(p, height);
|
||||
|
||||
p.setTextPalette(st::serviceTextPalette);
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ public:
|
|||
not_null<ElementDelegate*> delegate,
|
||||
not_null<HistoryService*> data);
|
||||
|
||||
int marginTop() const override;
|
||||
int marginBottom() const override;
|
||||
bool isHidden() const override;
|
||||
void draw(
|
||||
Painter &p,
|
||||
|
|
Loading…
Reference in New Issue