mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add basic new messages animation.
This commit is contained in:
parent
551732738b
commit
7bbc4b7191
8 changed files with 189 additions and 80 deletions
|
@ -1441,12 +1441,12 @@ rpl::producer<not_null<const ViewElement*>> Session::viewLayoutChanged() const {
|
||||||
return _viewLayoutChanges.events();
|
return _viewLayoutChanges.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::notifyUnreadItemAdded(not_null<HistoryItem*> item) {
|
void Session::notifyNewItemAdded(not_null<HistoryItem*> item) {
|
||||||
_unreadItemAdded.fire_copy(item);
|
_newItemAdded.fire_copy(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<not_null<HistoryItem*>> Session::unreadItemAdded() const {
|
rpl::producer<not_null<HistoryItem*>> Session::newItemAdded() const {
|
||||||
return _unreadItemAdded.events();
|
return _newItemAdded.events();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::changeMessageId(ChannelId channel, MsgId wasId, MsgId nowId) {
|
void Session::changeMessageId(ChannelId channel, MsgId wasId, MsgId nowId) {
|
||||||
|
|
|
@ -235,8 +235,8 @@ public:
|
||||||
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemLayoutChanged() const;
|
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemLayoutChanged() const;
|
||||||
void notifyViewLayoutChange(not_null<const ViewElement*> view);
|
void notifyViewLayoutChange(not_null<const ViewElement*> view);
|
||||||
[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewLayoutChanged() const;
|
[[nodiscard]] rpl::producer<not_null<const ViewElement*>> viewLayoutChanged() const;
|
||||||
void notifyUnreadItemAdded(not_null<HistoryItem*> item);
|
void notifyNewItemAdded(not_null<HistoryItem*> item);
|
||||||
[[nodiscard]] rpl::producer<not_null<HistoryItem*>> unreadItemAdded() const;
|
[[nodiscard]] rpl::producer<not_null<HistoryItem*>> newItemAdded() const;
|
||||||
void requestItemRepaint(not_null<const HistoryItem*> item);
|
void requestItemRepaint(not_null<const HistoryItem*> item);
|
||||||
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
|
[[nodiscard]] rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
|
||||||
void requestViewRepaint(not_null<const ViewElement*> view);
|
void requestViewRepaint(not_null<const ViewElement*> view);
|
||||||
|
@ -836,7 +836,7 @@ private:
|
||||||
rpl::event_stream<IdChange> _itemIdChanges;
|
rpl::event_stream<IdChange> _itemIdChanges;
|
||||||
rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanges;
|
rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanges;
|
||||||
rpl::event_stream<not_null<const ViewElement*>> _viewLayoutChanges;
|
rpl::event_stream<not_null<const ViewElement*>> _viewLayoutChanges;
|
||||||
rpl::event_stream<not_null<HistoryItem*>> _unreadItemAdded;
|
rpl::event_stream<not_null<HistoryItem*>> _newItemAdded;
|
||||||
rpl::event_stream<not_null<const HistoryItem*>> _itemRepaintRequest;
|
rpl::event_stream<not_null<const HistoryItem*>> _itemRepaintRequest;
|
||||||
rpl::event_stream<not_null<const ViewElement*>> _viewRepaintRequest;
|
rpl::event_stream<not_null<const ViewElement*>> _viewRepaintRequest;
|
||||||
rpl::event_stream<not_null<const HistoryItem*>> _itemResizeRequest;
|
rpl::event_stream<not_null<const HistoryItem*>> _itemResizeRequest;
|
||||||
|
|
|
@ -1072,16 +1072,16 @@ void History::newItemAdded(not_null<HistoryItem*> item) {
|
||||||
item->contributeToSlowmode();
|
item->contributeToSlowmode();
|
||||||
if (item->showNotification()) {
|
if (item->showNotification()) {
|
||||||
_notifications.push_back(item);
|
_notifications.push_back(item);
|
||||||
owner().notifyUnreadItemAdded(item);
|
}
|
||||||
const auto stillShow = item->showNotification();
|
owner().notifyNewItemAdded(item);
|
||||||
if (stillShow) {
|
const auto stillShow = item->showNotification(); // Could be read already.
|
||||||
Core::App().notifications().schedule(item);
|
if (stillShow) {
|
||||||
if (!item->out() && item->unread()) {
|
Core::App().notifications().schedule(item);
|
||||||
if (unreadCountKnown()) {
|
if (!item->out() && item->unread()) {
|
||||||
setUnreadCount(unreadCount() + 1);
|
if (unreadCountKnown()) {
|
||||||
} else {
|
setUnreadCount(unreadCount() + 1);
|
||||||
owner().histories().requestDialogEntry(this);
|
} else {
|
||||||
}
|
owner().histories().requestDialogEntry(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (item->out()) {
|
} else if (item->out()) {
|
||||||
|
|
|
@ -2369,6 +2369,21 @@ void HistoryInner::repaintScrollDateCallback() {
|
||||||
update(0, updateTop, width(), updateHeight);
|
update(0, updateTop, width(), updateHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryInner::setItemsRevealHeight(int revealHeight) {
|
||||||
|
_revealHeight = revealHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HistoryInner::changeItemsRevealHeight(int revealHeight) {
|
||||||
|
if (_revealHeight == revealHeight) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto old = std::exchange(_revealHeight, revealHeight);
|
||||||
|
resize(_scroll->width(), height() + old - _revealHeight);
|
||||||
|
if (!_revealHeight) {
|
||||||
|
mouseActionUpdate(QCursor::pos());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryInner::updateSize() {
|
void HistoryInner::updateSize() {
|
||||||
int visibleHeight = _scroll->height();
|
int visibleHeight = _scroll->height();
|
||||||
int newHistoryPaddingTop = qMax(visibleHeight - historyHeight() - st::historyPaddingBottom, 0);
|
int newHistoryPaddingTop = qMax(visibleHeight - historyHeight() - st::historyPaddingBottom, 0);
|
||||||
|
@ -2393,11 +2408,13 @@ void HistoryInner::updateSize() {
|
||||||
|
|
||||||
_historyPaddingTop = newHistoryPaddingTop;
|
_historyPaddingTop = newHistoryPaddingTop;
|
||||||
|
|
||||||
int newHeight = _historyPaddingTop + historyHeight() + st::historyPaddingBottom;
|
int newHeight = _historyPaddingTop + historyHeight() + st::historyPaddingBottom - _revealHeight;
|
||||||
if (width() != _scroll->width() || height() != newHeight) {
|
if (width() != _scroll->width() || height() != newHeight) {
|
||||||
resize(_scroll->width(), newHeight);
|
resize(_scroll->width(), newHeight);
|
||||||
|
|
||||||
mouseActionUpdate(QCursor::pos());
|
if (!_revealHeight) {
|
||||||
|
mouseActionUpdate(QCursor::pos());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,8 @@ public:
|
||||||
|
|
||||||
void touchScrollUpdated(const QPoint &screenPos);
|
void touchScrollUpdated(const QPoint &screenPos);
|
||||||
|
|
||||||
|
void setItemsRevealHeight(int revealHeight);
|
||||||
|
void changeItemsRevealHeight(int revealHeight);
|
||||||
void checkHistoryActivation();
|
void checkHistoryActivation();
|
||||||
void recountHistoryGeometry();
|
void recountHistoryGeometry();
|
||||||
void updateSize();
|
void updateSize();
|
||||||
|
@ -345,6 +347,7 @@ private:
|
||||||
History *_migrated = nullptr;
|
History *_migrated = nullptr;
|
||||||
int _contentWidth = 0;
|
int _contentWidth = 0;
|
||||||
int _historyPaddingTop = 0;
|
int _historyPaddingTop = 0;
|
||||||
|
int _revealHeight = 0;
|
||||||
|
|
||||||
// Save visible area coords for painting / pressing userpics.
|
// Save visible area coords for painting / pressing userpics.
|
||||||
int _visibleAreaTop = 0;
|
int _visibleAreaTop = 0;
|
||||||
|
|
|
@ -154,6 +154,7 @@ constexpr auto kSaveDraftTimeout = 1000;
|
||||||
constexpr auto kSaveDraftAnywayTimeout = 5000;
|
constexpr auto kSaveDraftAnywayTimeout = 5000;
|
||||||
constexpr auto kSaveCloudDraftIdleTimeout = 14000;
|
constexpr auto kSaveCloudDraftIdleTimeout = 14000;
|
||||||
constexpr auto kRefreshSlowmodeLabelTimeout = crl::time(200);
|
constexpr auto kRefreshSlowmodeLabelTimeout = crl::time(200);
|
||||||
|
constexpr auto kItemRevealDuration = crl::time(200);
|
||||||
constexpr auto kCommonModifiers = 0
|
constexpr auto kCommonModifiers = 0
|
||||||
| Qt::ShiftModifier
|
| Qt::ShiftModifier
|
||||||
| Qt::MetaModifier
|
| Qt::MetaModifier
|
||||||
|
@ -425,14 +426,9 @@ HistoryWidget::HistoryWidget(
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
session().data().unreadItemAdded(
|
session().data().newItemAdded(
|
||||||
) | rpl::start_with_next([=](not_null<HistoryItem*> item) {
|
) | rpl::start_with_next([=](not_null<HistoryItem*> item) {
|
||||||
unreadMessageAdded(item);
|
newItemAdded(item);
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
session().data().itemRemoved(
|
|
||||||
) | rpl::start_with_next([=](not_null<const HistoryItem*> item) {
|
|
||||||
itemRemoved(item);
|
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
session().data().historyChanged(
|
session().data().historyChanged(
|
||||||
|
@ -539,43 +535,25 @@ HistoryWidget::HistoryWidget(
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
session().changes().messageUpdates(
|
session().changes().messageUpdates(
|
||||||
Data::MessageUpdate::Flag::Edited
|
Data::MessageUpdate::Flag::Destroyed
|
||||||
|
| Data::MessageUpdate::Flag::Edited
|
||||||
|
| Data::MessageUpdate::Flag::ReplyMarkup
|
||||||
|
| Data::MessageUpdate::Flag::BotCallbackSent
|
||||||
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
||||||
itemEdited(update.item);
|
if (update.flags & Data::MessageUpdate::Flag::Destroyed) {
|
||||||
}, lifetime());
|
itemRemoved(update.item);
|
||||||
|
|
||||||
session().changes().messageUpdates(
|
|
||||||
Data::MessageUpdate::Flag::ReplyMarkup
|
|
||||||
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
|
||||||
if (_keyboard->forMsgId() == update.item->fullId()) {
|
|
||||||
updateBotKeyboard(update.item->history(), true);
|
|
||||||
}
|
|
||||||
}, lifetime());
|
|
||||||
|
|
||||||
session().changes().messageUpdates(
|
|
||||||
Data::MessageUpdate::Flag::BotCallbackSent
|
|
||||||
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
|
||||||
const auto item = update.item;
|
|
||||||
if (item->id < 0 || _peer != item->history()->peer) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (update.flags & Data::MessageUpdate::Flag::Edited) {
|
||||||
const auto keyId = _keyboard->forMsgId();
|
itemEdited(update.item);
|
||||||
const auto lastKeyboardUsed = (keyId == FullMsgId(_channel, item->id))
|
|
||||||
&& (keyId == FullMsgId(_channel, _history->lastKeyboardId));
|
|
||||||
|
|
||||||
session().data().requestItemRepaint(item);
|
|
||||||
|
|
||||||
if (_replyToId == item->id) {
|
|
||||||
cancelReply();
|
|
||||||
}
|
}
|
||||||
if (_keyboard->singleUse()
|
if (update.flags & Data::MessageUpdate::Flag::ReplyMarkup) {
|
||||||
&& _keyboard->hasMarkup()
|
if (_keyboard->forMsgId() == update.item->fullId()) {
|
||||||
&& lastKeyboardUsed) {
|
updateBotKeyboard(update.item->history(), true);
|
||||||
if (_kbShown) {
|
|
||||||
toggleKeyboard(false);
|
|
||||||
}
|
}
|
||||||
_history->lastKeyboardUsed = true;
|
}
|
||||||
|
if (update.flags & Data::MessageUpdate::Flag::BotCallbackSent) {
|
||||||
|
botCallbackSent(update.item);
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
@ -1887,7 +1865,6 @@ void HistoryWidget::showHistory(
|
||||||
|
|
||||||
App::clearMousedItems();
|
App::clearMousedItems();
|
||||||
|
|
||||||
_addToScroll = 0;
|
|
||||||
_saveEditMsgRequestId = 0;
|
_saveEditMsgRequestId = 0;
|
||||||
_replyEditMsg = nullptr;
|
_replyEditMsg = nullptr;
|
||||||
_editMsgId = _replyToId = 0;
|
_editMsgId = _replyToId = 0;
|
||||||
|
@ -1939,6 +1916,7 @@ void HistoryWidget::showHistory(
|
||||||
|
|
||||||
noSelectingScroll();
|
noSelectingScroll();
|
||||||
_nonEmptySelection = false;
|
_nonEmptySelection = false;
|
||||||
|
_itemRevealPending.clear();
|
||||||
|
|
||||||
if (_peer) {
|
if (_peer) {
|
||||||
_history = _peer->owner().history(_peer);
|
_history = _peer->owner().history(_peer);
|
||||||
|
@ -2447,8 +2425,10 @@ void HistoryWidget::destroyUnreadBarOnClose() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::unreadMessageAdded(not_null<HistoryItem*> item) {
|
void HistoryWidget::newItemAdded(not_null<HistoryItem*> item) {
|
||||||
if (_history != item->history() || !_historyInited) {
|
if (_history != item->history()
|
||||||
|
|| !_historyInited
|
||||||
|
|| item->isScheduled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2459,21 +2439,28 @@ void HistoryWidget::unreadMessageAdded(not_null<HistoryItem*> item) {
|
||||||
// - on second we get wrong doWeReadServerHistory() and read both.
|
// - on second we get wrong doWeReadServerHistory() and read both.
|
||||||
session().data().sendHistoryChangeNotifications();
|
session().data().sendHistoryChangeNotifications();
|
||||||
|
|
||||||
const auto atBottom = (_scroll->scrollTop() >= _scroll->scrollTopMax());
|
if (item->isSending()) {
|
||||||
if (!atBottom) {
|
synteticScrollToY(_scroll->scrollTopMax());
|
||||||
|
} else if (_scroll->scrollTop() < _scroll->scrollTopMax()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
destroyUnreadBar();
|
if (item->showNotification()) {
|
||||||
if (!doWeReadServerHistory()) {
|
destroyUnreadBar();
|
||||||
return;
|
if (doWeReadServerHistory()) {
|
||||||
}
|
if (item->isUnreadMention() && !item->isUnreadMedia()) {
|
||||||
if (item->isUnreadMention() && !item->isUnreadMedia()) {
|
session().api().markMediaRead(item);
|
||||||
session().api().markMediaRead(item);
|
}
|
||||||
}
|
session().data().histories().readInboxOnNewMessage(item);
|
||||||
session().data().histories().readInboxOnNewMessage(item);
|
|
||||||
|
|
||||||
// Also clear possible scheduled messages notifications.
|
// Also clear possible scheduled messages notifications.
|
||||||
Core::App().notifications().clearFromHistory(_history);
|
Core::App().notifications().clearFromHistory(_history);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const auto view = item->mainView();
|
||||||
|
if (anim::Disabled() || !view) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_itemRevealPending.emplace(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::unreadCountUpdated() {
|
void HistoryWidget::unreadCountUpdated() {
|
||||||
|
@ -2904,9 +2891,13 @@ void HistoryWidget::delayedShowAt(MsgId showAtMsgId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::handleScroll() {
|
void HistoryWidget::handleScroll() {
|
||||||
preloadHistoryIfNeeded();
|
if (!_itemsRevealHeight) {
|
||||||
|
preloadHistoryIfNeeded();
|
||||||
|
}
|
||||||
visibleAreaUpdated();
|
visibleAreaUpdated();
|
||||||
updatePinnedViewer();
|
if (!_itemsRevealHeight) {
|
||||||
|
updatePinnedViewer();
|
||||||
|
}
|
||||||
if (!_synteticScrollEvent) {
|
if (!_synteticScrollEvent) {
|
||||||
_lastUserScrolled = crl::now();
|
_lastUserScrolled = crl::now();
|
||||||
}
|
}
|
||||||
|
@ -4692,6 +4683,11 @@ void HistoryWidget::itemRemoved(not_null<const HistoryItem*> item) {
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const auto i = _itemRevealAnimations.find(item);
|
||||||
|
if (i != end(_itemRevealAnimations)) {
|
||||||
|
_itemRevealAnimations.erase(i);
|
||||||
|
revealItemsCallback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::itemEdited(not_null<HistoryItem*> item) {
|
void HistoryWidget::itemEdited(not_null<HistoryItem*> item) {
|
||||||
|
@ -4784,6 +4780,9 @@ void HistoryWidget::updateHistoryGeometry(
|
||||||
bool initial,
|
bool initial,
|
||||||
bool loadedDown,
|
bool loadedDown,
|
||||||
const ScrollChange &change) {
|
const ScrollChange &change) {
|
||||||
|
const auto guard = gsl::finally([&] {
|
||||||
|
_itemRevealPending.clear();
|
||||||
|
});
|
||||||
if (!_history || (initial && _historyInited) || (!initial && !_historyInited)) {
|
if (!_history || (initial && _historyInited) || (!initial && !_historyInited)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4867,20 +4866,74 @@ void HistoryWidget::updateHistoryGeometry(
|
||||||
newScrollTop += change.value;
|
newScrollTop += change.value;
|
||||||
} else if (change.type == ScrollChangeNoJumpToBottom) {
|
} else if (change.type == ScrollChangeNoJumpToBottom) {
|
||||||
newScrollTop = wasScrollTop;
|
newScrollTop = wasScrollTop;
|
||||||
} else if (const auto add = base::take(_addToScroll)) {
|
|
||||||
newScrollTop += add;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const auto toY = std::clamp(newScrollTop, 0, _scroll->scrollTopMax());
|
const auto toY = std::clamp(newScrollTop, 0, _scroll->scrollTopMax());
|
||||||
synteticScrollToY(toY);
|
synteticScrollToY(toY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::revealItemsCallback() {
|
||||||
|
auto height = 0;
|
||||||
|
if (!_historyInited) {
|
||||||
|
_itemRevealAnimations.clear();
|
||||||
|
}
|
||||||
|
for (auto i = begin(_itemRevealAnimations)
|
||||||
|
; i != end(_itemRevealAnimations);) {
|
||||||
|
if (!i->second.animation.animating()) {
|
||||||
|
i = _itemRevealAnimations.erase(i);
|
||||||
|
} else {
|
||||||
|
height += anim::interpolate(
|
||||||
|
i->second.startHeight,
|
||||||
|
0,
|
||||||
|
i->second.animation.value(1.));
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_itemsRevealHeight != height) {
|
||||||
|
const auto wasScrollTop = _scroll->scrollTop();
|
||||||
|
const auto wasAtBottom = (wasScrollTop == _scroll->scrollTopMax());
|
||||||
|
|
||||||
|
_itemsRevealHeight = height;
|
||||||
|
_list->changeItemsRevealHeight(_itemsRevealHeight);
|
||||||
|
|
||||||
|
const auto newScrollTop = (wasAtBottom && !_history->unreadBar())
|
||||||
|
? countAutomaticScrollTop()
|
||||||
|
: _list->historyScrollTop();
|
||||||
|
const auto toY = std::clamp(newScrollTop, 0, _scroll->scrollTopMax());
|
||||||
|
synteticScrollToY(toY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void HistoryWidget::updateListSize() {
|
void HistoryWidget::updateListSize() {
|
||||||
_list->recountHistoryGeometry();
|
_list->recountHistoryGeometry();
|
||||||
auto washidden = _scroll->isHidden();
|
auto washidden = _scroll->isHidden();
|
||||||
if (washidden) {
|
if (washidden) {
|
||||||
_scroll->show();
|
_scroll->show();
|
||||||
}
|
}
|
||||||
|
for (const auto item : base::take(_itemRevealPending)) {
|
||||||
|
if (const auto view = item->mainView()) {
|
||||||
|
if (const auto top = _list->itemTop(view); top >= 0) {
|
||||||
|
if (const auto height = view->height()) {
|
||||||
|
if (!_itemRevealAnimations.contains(item)) {
|
||||||
|
auto &animation = _itemRevealAnimations[item];
|
||||||
|
if (!animation.animation.animating()) {
|
||||||
|
animation.startHeight
|
||||||
|
= animation.currentHeight
|
||||||
|
= height;
|
||||||
|
_itemsRevealHeight += height;
|
||||||
|
animation.animation.start(
|
||||||
|
[=] { revealItemsCallback(); },
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
kItemRevealDuration,
|
||||||
|
anim::easeOutCirc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_list->setItemsRevealHeight(_itemsRevealHeight);
|
||||||
_list->updateSize();
|
_list->updateSize();
|
||||||
if (washidden) {
|
if (washidden) {
|
||||||
_scroll->hide();
|
_scroll->hide();
|
||||||
|
@ -5029,6 +5082,30 @@ void HistoryWidget::updateBotKeyboard(History *h, bool force) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistoryWidget::botCallbackSent(not_null<HistoryItem*> item) {
|
||||||
|
if (item->id < 0 || _peer != item->history()->peer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto keyId = _keyboard->forMsgId();
|
||||||
|
const auto lastKeyboardUsed = (keyId == FullMsgId(_channel, item->id))
|
||||||
|
&& (keyId == FullMsgId(_channel, _history->lastKeyboardId));
|
||||||
|
|
||||||
|
session().data().requestItemRepaint(item);
|
||||||
|
|
||||||
|
if (_replyToId == item->id) {
|
||||||
|
cancelReply();
|
||||||
|
}
|
||||||
|
if (_keyboard->singleUse()
|
||||||
|
&& _keyboard->hasMarkup()
|
||||||
|
&& lastKeyboardUsed) {
|
||||||
|
if (_kbShown) {
|
||||||
|
toggleKeyboard(false);
|
||||||
|
}
|
||||||
|
_history->lastKeyboardUsed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int HistoryWidget::computeMaxFieldHeight() const {
|
int HistoryWidget::computeMaxFieldHeight() const {
|
||||||
const auto available = height()
|
const auto available = height()
|
||||||
- _topBar->height()
|
- _topBar->height()
|
||||||
|
|
|
@ -225,6 +225,7 @@ public:
|
||||||
// With force=true the markup is updated even if it is
|
// With force=true the markup is updated even if it is
|
||||||
// already shown for the passed history item.
|
// already shown for the passed history item.
|
||||||
void updateBotKeyboard(History *h = nullptr, bool force = false);
|
void updateBotKeyboard(History *h = nullptr, bool force = false);
|
||||||
|
void botCallbackSent(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
void fastShowAtEnd(not_null<History*> history);
|
void fastShowAtEnd(not_null<History*> history);
|
||||||
void applyDraft(
|
void applyDraft(
|
||||||
|
@ -321,6 +322,11 @@ private:
|
||||||
Fn<void(MessageIdsList)> callback;
|
Fn<void(MessageIdsList)> callback;
|
||||||
bool active = false;
|
bool active = false;
|
||||||
};
|
};
|
||||||
|
struct ItemRevealAnimation {
|
||||||
|
int startHeight = 0;
|
||||||
|
int currentHeight = 0;
|
||||||
|
Ui::Animations::Simple animation;
|
||||||
|
};
|
||||||
enum class TextUpdateEvent {
|
enum class TextUpdateEvent {
|
||||||
SaveDraft = (1 << 0),
|
SaveDraft = (1 << 0),
|
||||||
SendTyping = (1 << 1),
|
SendTyping = (1 << 1),
|
||||||
|
@ -414,7 +420,7 @@ private:
|
||||||
void historyDownAnimationFinish();
|
void historyDownAnimationFinish();
|
||||||
void unreadMentionsAnimationFinish();
|
void unreadMentionsAnimationFinish();
|
||||||
void sendButtonClicked();
|
void sendButtonClicked();
|
||||||
void unreadMessageAdded(not_null<HistoryItem*> item);
|
void newItemAdded(not_null<HistoryItem*> item);
|
||||||
|
|
||||||
bool canSendFiles(not_null<const QMimeData*> data) const;
|
bool canSendFiles(not_null<const QMimeData*> data) const;
|
||||||
bool confirmSendingFiles(
|
bool confirmSendingFiles(
|
||||||
|
@ -530,6 +536,7 @@ private:
|
||||||
|
|
||||||
void updateHistoryGeometry(bool initial = false, bool loadedDown = false, const ScrollChange &change = { ScrollChangeNone, 0 });
|
void updateHistoryGeometry(bool initial = false, bool loadedDown = false, const ScrollChange &change = { ScrollChangeNone, 0 });
|
||||||
void updateListSize();
|
void updateListSize();
|
||||||
|
void revealItemsCallback();
|
||||||
|
|
||||||
// Does any of the shown histories has this flag set.
|
// Does any of the shown histories has this flag set.
|
||||||
bool hasPendingResizedItems() const;
|
bool hasPendingResizedItems() const;
|
||||||
|
@ -664,7 +671,6 @@ private:
|
||||||
bool _historyInited = false;
|
bool _historyInited = false;
|
||||||
// If updateListSize() was called without updateHistoryGeometry().
|
// If updateListSize() was called without updateHistoryGeometry().
|
||||||
bool _updateHistoryGeometryRequired = false;
|
bool _updateHistoryGeometryRequired = false;
|
||||||
int _addToScroll = 0;
|
|
||||||
|
|
||||||
int _lastScrollTop = 0; // gifs optimization
|
int _lastScrollTop = 0; // gifs optimization
|
||||||
crl::time _lastScrolled = 0;
|
crl::time _lastScrolled = 0;
|
||||||
|
@ -755,6 +761,12 @@ private:
|
||||||
base::weak_ptr<Ui::Toast::Instance> _topToast;
|
base::weak_ptr<Ui::Toast::Instance> _topToast;
|
||||||
std::unique_ptr<ChooseMessagesForReport> _chooseForReport;
|
std::unique_ptr<ChooseMessagesForReport> _chooseForReport;
|
||||||
|
|
||||||
|
base::flat_set<not_null<HistoryItem*>> _itemRevealPending;
|
||||||
|
base::flat_map<
|
||||||
|
not_null<HistoryItem*>,
|
||||||
|
ItemRevealAnimation> _itemRevealAnimations;
|
||||||
|
int _itemsRevealHeight = 0;
|
||||||
|
|
||||||
object_ptr<Ui::PlainShadow> _topShadow;
|
object_ptr<Ui::PlainShadow> _topShadow;
|
||||||
bool _inGrab = false;
|
bool _inGrab = false;
|
||||||
|
|
||||||
|
|
|
@ -1124,7 +1124,7 @@ bool ListWidget::loadedAtBottom() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::isEmpty() const {
|
bool ListWidget::isEmpty() const {
|
||||||
return loadedAtTop() && loadedAtBottom() && (_itemsHeight == 0);
|
return loadedAtTop() && loadedAtBottom();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ListWidget::itemMinimalHeight() const {
|
int ListWidget::itemMinimalHeight() const {
|
||||||
|
|
Loading…
Add table
Reference in a new issue