mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-08-06 11:52:58 +00:00
Improve initial visible scroll handling.
This commit is contained in:
@@ -458,6 +458,14 @@ HistoryInner::HistoryInner(
|
||||
) | rpl::on_next(
|
||||
[this](auto item) { itemRemoved(item); },
|
||||
lifetime());
|
||||
session().data().newItemAdded(
|
||||
) | rpl::filter([=](not_null<HistoryItem*> item) {
|
||||
const auto history = item->history();
|
||||
return (history == _history)
|
||||
|| (_migrated && history == _migrated);
|
||||
}) | rpl::on_next([=] {
|
||||
checkAnnounceFirstMessages();
|
||||
}, lifetime());
|
||||
setupThanosEffect();
|
||||
session().data().viewRemoved(
|
||||
) | rpl::on_next(
|
||||
@@ -840,13 +848,7 @@ void HistoryInner::messagesReceived(
|
||||
_migrated->addNewerSlice(QVector<MTPMessage>());
|
||||
}
|
||||
}
|
||||
if (_announceFirstMessages && hasFocus()) {
|
||||
InvokeQueued(this, [=] {
|
||||
if (_announceFirstMessages && hasFocus()) {
|
||||
announceAccessibilityFocusedChild();
|
||||
}
|
||||
});
|
||||
}
|
||||
checkAnnounceFirstMessages();
|
||||
}
|
||||
|
||||
void HistoryInner::messagesReceivedDown(
|
||||
@@ -6626,17 +6628,30 @@ auto HistoryInner::computeActiveColumns(int row) const
|
||||
return _activeColumns;
|
||||
}
|
||||
|
||||
void HistoryInner::checkAnnounceFirstMessages() {
|
||||
if (_announceFirstMessages && hasFocus()) {
|
||||
InvokeQueued(this, [=] {
|
||||
if (_announceFirstMessages && hasFocus()) {
|
||||
announceAccessibilityFocusedChild();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryInner::announceAccessibilityFocusedChild() {
|
||||
const auto count = accessibilityChildCount();
|
||||
if (count <= 0) {
|
||||
// One-shot for chats focused before their first page arrived:
|
||||
// One-shot for chats focused before their first messages arrived:
|
||||
// while the empty list holds focus, remember that the first
|
||||
// received slice should announce the focused message. Fired
|
||||
// (queued) from messagesReceived and disarmed by any real
|
||||
// announcement below or in a later focus-in.
|
||||
if (Ui::ScreenReaderModeActive()) {
|
||||
_announceFirstMessages = true;
|
||||
}
|
||||
// received slice (or the first live-added message in a genuinely
|
||||
// empty chat) should announce the focused message. Fired (queued)
|
||||
// from checkAnnounceFirstMessages and disarmed by any real
|
||||
// announcement below or in a later focus-in. Deliberately not
|
||||
// gated by the screen-reader-mode detector: it may still be false
|
||||
// during startup or for valid clients that are not on its
|
||||
// allowlist, while the deferred announcement is a no-op without
|
||||
// an accessibility client and never moves ordinary keyboard focus.
|
||||
_announceFirstMessages = true;
|
||||
return;
|
||||
}
|
||||
_announceFirstMessages = false;
|
||||
|
||||
@@ -323,6 +323,7 @@ private:
|
||||
void playPauseFocusedMedia();
|
||||
void setAccessibilityFocusedItem(int index, HistoryItem *item);
|
||||
void announceAccessibilityFocus(int index);
|
||||
void checkAnnounceFirstMessages();
|
||||
void announceAccessibilityFocusedChild();
|
||||
void applyAccessibilityFocus(int index, bool announceAlways);
|
||||
[[nodiscard]] auto computeActiveColumns(int row) const
|
||||
|
||||
@@ -393,7 +393,9 @@ HistoryWidget::HistoryWidget(
|
||||
}), lifetime());
|
||||
|
||||
_scroll->setBottomContentRequest([=] {
|
||||
if (!_history || !_history->loadedAtBottom()) {
|
||||
if (!_history
|
||||
|| _firstLoadRequest
|
||||
|| !_history->loadedAtBottom()) {
|
||||
return false;
|
||||
}
|
||||
using Result = Data::SponsoredMessages::AppendResult;
|
||||
@@ -4797,6 +4799,8 @@ void HistoryWidget::loadMessages() {
|
||||
bool HistoryWidget::historyLoadedAtTop() const {
|
||||
if (!_history) {
|
||||
return true;
|
||||
} else if (_firstLoadRequest) {
|
||||
return false;
|
||||
}
|
||||
const auto loadMigrated = _migrated
|
||||
&& (_history->isEmpty()
|
||||
@@ -4807,8 +4811,16 @@ bool HistoryWidget::historyLoadedAtTop() const {
|
||||
}
|
||||
|
||||
bool HistoryWidget::historyLoadedAtBottom() const {
|
||||
// While the first load request is pending the (visible) scroll area
|
||||
// shows a blank list, but getReadyFor() may have already marked the
|
||||
// history as loaded at bottom before any server page arrived. Report
|
||||
// unloaded edges for that interval: it keeps the elastic overscroll
|
||||
// (and the pull-to-next-channel gesture riding on it) away from the
|
||||
// blank list until the requested messages are actually shown.
|
||||
if (!_history) {
|
||||
return true;
|
||||
} else if (_firstLoadRequest) {
|
||||
return false;
|
||||
}
|
||||
const auto loadMigrated = _migrated
|
||||
&& !(_migrated->isEmpty()
|
||||
@@ -8109,12 +8121,11 @@ void HistoryWidget::updateHistoryGeometry(
|
||||
});
|
||||
if (!_history
|
||||
|| (initial && _historyInited)
|
||||
|| (!initial && !_historyInited)) {
|
||||
|| (!initial && !_historyInited && !_firstLoadRequest)) {
|
||||
return;
|
||||
}
|
||||
if (_firstLoadRequest || _showAnimation) {
|
||||
if (_showAnimation) {
|
||||
_updateHistoryGeometryRequired = true;
|
||||
// scrollTopMax etc are not working after recountHistoryGeometry()
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8211,6 +8222,16 @@ void HistoryWidget::updateHistoryGeometry(
|
||||
_subsectionTabs->setBoundingRect(
|
||||
{ 0, subsectionTabsTop, width(), areaHeight });
|
||||
}
|
||||
if (_firstLoadRequest) {
|
||||
// The scroll area stays visible (and possibly focused) while the
|
||||
// first messages are being loaded, so its viewport geometry above
|
||||
// is maintained even now. The list layout and the scroll position
|
||||
// are still deferred until the requested messages arrive:
|
||||
// scrollTopMax etc are not working after recountHistoryGeometry()
|
||||
// and the initial scroll position can not be counted yet.
|
||||
_updateHistoryGeometryRequired = true;
|
||||
return;
|
||||
}
|
||||
|
||||
updateListSize();
|
||||
_updateHistoryGeometryRequired = false;
|
||||
|
||||
Reference in New Issue
Block a user