mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 23:27:09 +02:00
Fix navigation in a message replies section.
This commit is contained in:
parent
1849f01b15
commit
c563df7d9d
5 changed files with 61 additions and 25 deletions
|
@ -20,7 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
namespace Data {
|
||||
namespace {
|
||||
|
||||
constexpr auto kMessagesPerPage = 4; // #TODO replies
|
||||
constexpr auto kMessagesPerPage = 16;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -94,8 +94,8 @@ bool RepliesList::buildFromData(not_null<Viewer*> viewer) {
|
|||
const auto around = viewer->around;
|
||||
if (_list.empty()
|
||||
|| (!around && _skippedAfter != 0)
|
||||
|| (around > 0 && around < _list.back())
|
||||
|| (around > _list.front())) {
|
||||
|| (around > _list.front() && _skippedAfter != 0)
|
||||
|| (around > 0 && around < _list.back() && _skippedBefore != 0)) {
|
||||
loadAround(around);
|
||||
return false;
|
||||
}
|
||||
|
@ -207,6 +207,13 @@ void RepliesList::loadAround(MsgId id) {
|
|||
_list.clear();
|
||||
if (processMessagesIsEmpty(result)) {
|
||||
_fullCount = _skippedBefore = _skippedAfter = 0;
|
||||
} else if (id > 0) {
|
||||
Assert(!_list.empty());
|
||||
if (_list.front() <= id) {
|
||||
_skippedAfter = 0;
|
||||
} else if (_list.back() >= id) {
|
||||
_skippedBefore = 0;
|
||||
}
|
||||
}
|
||||
}).fail([=](const RPCError &error) {
|
||||
_beforeId = 0;
|
||||
|
@ -312,7 +319,8 @@ void RepliesList::loadAfter() {
|
|||
bool RepliesList::processMessagesIsEmpty(const MTPmessages_Messages &result) {
|
||||
const auto guard = gsl::finally([&] { _partLoaded.fire({}); });
|
||||
|
||||
_fullCount = result.match([&](const MTPDmessages_messagesNotModified &) {
|
||||
const auto fullCount = result.match([&](
|
||||
const MTPDmessages_messagesNotModified &) {
|
||||
LOG(("API Error: received messages.messagesNotModified! "
|
||||
"(HistoryWidget::messagesReceived)"));
|
||||
return 0;
|
||||
|
@ -346,7 +354,8 @@ bool RepliesList::processMessagesIsEmpty(const MTPmessages_Messages &result) {
|
|||
}
|
||||
|
||||
const auto id = IdFromMessage(list.front());
|
||||
const auto toFront = !_list.empty() && (id > _list.front());
|
||||
const auto wasSize = int(_list.size());
|
||||
const auto toFront = (wasSize > 0) && (id > _list.front());
|
||||
const auto clientFlags = MTPDmessage_ClientFlags();
|
||||
const auto type = NewMessageType::Existing;
|
||||
auto refreshed = std::vector<MsgId>();
|
||||
|
@ -368,11 +377,31 @@ bool RepliesList::processMessagesIsEmpty(const MTPmessages_Messages &result) {
|
|||
refreshed.insert(refreshed.end(), _list.begin(), _list.end());
|
||||
_list = std::move(refreshed);
|
||||
}
|
||||
if (_fullCount.current() && _skippedBefore && !_skippedAfter) {
|
||||
_skippedAfter = *_fullCount.current() - *_skippedBefore - _list.size();
|
||||
} else if (_fullCount.current() && _skippedAfter && !_skippedBefore) {
|
||||
_skippedBefore = *_fullCount.current() - *_skippedAfter - _list.size();
|
||||
|
||||
const auto nowSize = int(_list.size());
|
||||
auto &decrementFrom = toFront ? _skippedAfter : _skippedBefore;
|
||||
if (decrementFrom.has_value()) {
|
||||
*decrementFrom = std::max(
|
||||
*decrementFrom - (nowSize - wasSize),
|
||||
0);
|
||||
}
|
||||
|
||||
const auto checkedCount = std::max(fullCount, nowSize);
|
||||
if (_skippedBefore && _skippedAfter) {
|
||||
auto &correct = toFront ? _skippedBefore : _skippedAfter;
|
||||
*correct = std::max(
|
||||
checkedCount - *decrementFrom - nowSize,
|
||||
0);
|
||||
*decrementFrom = *_fullCount.current() - *correct - nowSize;
|
||||
Assert(*decrementFrom >= 0);
|
||||
} else if (_skippedBefore) {
|
||||
*_skippedBefore = std::min(*_skippedBefore, checkedCount - nowSize);
|
||||
_skippedAfter = checkedCount - *_skippedBefore - nowSize;
|
||||
} else if (_skippedAfter) {
|
||||
*_skippedAfter = std::min(*_skippedAfter, checkedCount - nowSize);
|
||||
_skippedBefore = checkedCount - *_skippedAfter - nowSize;
|
||||
}
|
||||
_fullCount = checkedCount;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -455,6 +455,15 @@ void ListWidget::highlightMessage(FullMsgId itemId) {
|
|||
}
|
||||
}
|
||||
|
||||
void ListWidget::showAroundPosition(
|
||||
Data::MessagePosition position,
|
||||
Fn<bool()> overrideInitialScroll) {
|
||||
_aroundPosition = position;
|
||||
_aroundIndex = -1;
|
||||
_overrideInitialScroll = std::move(overrideInitialScroll);
|
||||
refreshViewer();
|
||||
}
|
||||
|
||||
void ListWidget::updateHighlightedMessage() {
|
||||
if (const auto item = session().data().message(_highlightedMessageId)) {
|
||||
if (const auto view = viewForItem(item)) {
|
||||
|
@ -486,7 +495,9 @@ void ListWidget::saveScrollState() {
|
|||
}
|
||||
|
||||
void ListWidget::restoreScrollState() {
|
||||
if (_items.empty()) {
|
||||
if (_items.empty()
|
||||
|| (_overrideInitialScroll
|
||||
&& base::take(_overrideInitialScroll)())) {
|
||||
return;
|
||||
}
|
||||
if (!_scrollTopState.item) {
|
||||
|
|
|
@ -164,6 +164,9 @@ public:
|
|||
bool isAbovePosition(Data::MessagePosition position) const;
|
||||
bool isBelowPosition(Data::MessagePosition position) const;
|
||||
void highlightMessage(FullMsgId itemId);
|
||||
void showAroundPosition(
|
||||
Data::MessagePosition position,
|
||||
Fn<bool()> overrideInitialScroll);
|
||||
|
||||
TextForMimeData getSelectedText() const;
|
||||
MessageIdsList getSelectedItems() const;
|
||||
|
@ -472,6 +475,7 @@ private:
|
|||
int _visibleTopFromItem = 0;
|
||||
ScrollTopState _scrollTopState;
|
||||
Ui::Animations::Simple _scrollToAnimation;
|
||||
Fn<bool()> _overrideInitialScroll;
|
||||
|
||||
bool _scrollDateShown = false;
|
||||
Ui::Animations::Simple _scrollDateOpacity;
|
||||
|
|
|
@ -780,19 +780,10 @@ void RepliesWidget::scrollDownClicked() {
|
|||
}
|
||||
|
||||
void RepliesWidget::showAtPosition(Data::MessagePosition position) {
|
||||
if (showAtPositionNow(position)) {
|
||||
if (const auto highlight = base::take(_highlightMessageId)) {
|
||||
_inner->highlightMessage(highlight);
|
||||
}
|
||||
} else {
|
||||
_nextAnimatedScrollPosition = position;
|
||||
_nextAnimatedScrollDelta = _inner->isBelowPosition(position)
|
||||
? -_scroll->height()
|
||||
: _inner->isAbovePosition(position)
|
||||
? _scroll->height()
|
||||
: 0;
|
||||
auto memento = HistoryView::ListMemento(position);
|
||||
_inner->restoreState(&memento);
|
||||
if (!showAtPositionNow(position)) {
|
||||
_inner->showAroundPosition(position, [=] {
|
||||
return showAtPositionNow(position);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -810,6 +801,9 @@ bool RepliesWidget::showAtPositionNow(Data::MessagePosition position) {
|
|||
(std::abs(fullDelta) > limit
|
||||
? HistoryView::ListWidget::AnimatedScroll::Part
|
||||
: HistoryView::ListWidget::AnimatedScroll::Full));
|
||||
if (const auto highlight = base::take(_highlightMessageId)) {
|
||||
_inner->highlightMessage(highlight);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -213,8 +213,6 @@ private:
|
|||
bool _skipScrollEvent = false;
|
||||
|
||||
FullMsgId _highlightMessageId;
|
||||
std::optional<Data::MessagePosition> _nextAnimatedScrollPosition;
|
||||
int _nextAnimatedScrollDelta = 0;
|
||||
|
||||
Ui::Animations::Simple _scrollDownShown;
|
||||
bool _scrollDownIsShown = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue