fix: lazy-load genre/playlist views and cap playlist search scrolling
Some checks failed
Build for Windows / build-windows (push) Has been cancelled
Some checks failed
Build for Windows / build-windows (push) Has been cancelled
- Defer eager-load scrollbar checks to next event loop iteration via QTimer::singleShot(0), fixing initial load not filling the viewport - Playlist search: eagerly fill viewport, then show "Load more playlists…" button instead of infinite scroll to avoid loading thousands of results - Increase search page size from 8 to 25 - Featured/discover playlists keep auto-scroll behavior unchanged Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,9 @@
|
||||
#include <QListWidget>
|
||||
#include <QMenu>
|
||||
#include <QPushButton>
|
||||
#include <QScrollBar>
|
||||
#include <QSignalBlocker>
|
||||
#include <QTimer>
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
@@ -120,8 +122,18 @@ GenreBrowserView::GenreBrowserView(QobuzBackend *backend, PlayQueue *queue, QWid
|
||||
m_playlistList->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
m_playlistList->header()->setStretchLastSection(false);
|
||||
|
||||
auto *playlistPage = new QWidget(this);
|
||||
auto *playlistPageLayout = new QVBoxLayout(playlistPage);
|
||||
playlistPageLayout->setContentsMargins(0, 0, 0, 0);
|
||||
playlistPageLayout->setSpacing(0);
|
||||
playlistPageLayout->addWidget(m_playlistList, 1);
|
||||
|
||||
m_loadMorePlaylistsBtn = new QPushButton(tr("Load more playlists…"), this);
|
||||
m_loadMorePlaylistsBtn->hide();
|
||||
playlistPageLayout->addWidget(m_loadMorePlaylistsBtn);
|
||||
|
||||
m_resultsStack->addWidget(m_albumList);
|
||||
m_resultsStack->addWidget(m_playlistList);
|
||||
m_resultsStack->addWidget(playlistPage);
|
||||
layout->addWidget(m_resultsStack, 1);
|
||||
|
||||
connect(m_backend, &QobuzBackend::genresLoaded,
|
||||
@@ -180,6 +192,12 @@ GenreBrowserView::GenreBrowserView(QobuzBackend *backend, PlayQueue *queue, QWid
|
||||
this, &GenreBrowserView::onAlbumScroll);
|
||||
connect(m_playlistList->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
this, &GenreBrowserView::onPlaylistScroll);
|
||||
connect(m_loadMorePlaylistsBtn, &QPushButton::clicked, this, [this] {
|
||||
m_loadMorePlaylistsBtn->hide();
|
||||
requestPlaylistsPage(m_lastPlaylistGenreIds, m_lastPlaylistType,
|
||||
m_lastPlaylistTags, m_lastPlaylistQuery,
|
||||
m_playlistOffset, true);
|
||||
});
|
||||
|
||||
m_kindCombo->setCurrentIndex(0);
|
||||
refreshModeUi();
|
||||
@@ -391,9 +409,12 @@ void GenreBrowserView::onFeaturedAlbumsLoaded(const QJsonObject &result)
|
||||
}
|
||||
|
||||
// If the viewport is not scrollable yet, eagerly fetch more pages.
|
||||
// Deferred: the scrollbar maximum isn't updated until after layout runs.
|
||||
QTimer::singleShot(0, this, [this] {
|
||||
QScrollBar *bar = m_albumList->verticalScrollBar();
|
||||
if (bar && bar->maximum() == 0 && m_albumOffset < m_albumTotal)
|
||||
requestAlbumsPage(m_lastAlbumGenreIds, m_lastAlbumType, m_albumOffset, true);
|
||||
});
|
||||
}
|
||||
|
||||
void GenreBrowserView::onFeaturedPlaylistsLoaded(const QJsonObject &result)
|
||||
@@ -413,9 +434,11 @@ void GenreBrowserView::onFeaturedPlaylistsLoaded(const QJsonObject &result)
|
||||
m_playlistTotal = m_playlistOffset;
|
||||
m_loadingPlaylists = false;
|
||||
|
||||
QTimer::singleShot(0, this, [this] {
|
||||
QScrollBar *bar = m_playlistList->verticalScrollBar();
|
||||
if (bar && bar->maximum() == 0 && m_playlistOffset < m_playlistTotal)
|
||||
requestPlaylistsPage(m_lastPlaylistGenreIds, m_lastPlaylistType, m_lastPlaylistTags, m_lastPlaylistQuery, m_playlistOffset, true);
|
||||
});
|
||||
}
|
||||
|
||||
void GenreBrowserView::onDiscoverPlaylistsLoaded(const QJsonObject &result)
|
||||
@@ -435,9 +458,11 @@ void GenreBrowserView::onDiscoverPlaylistsLoaded(const QJsonObject &result)
|
||||
m_playlistTotal = m_playlistOffset;
|
||||
m_loadingPlaylists = false;
|
||||
|
||||
QTimer::singleShot(0, this, [this] {
|
||||
QScrollBar *bar = m_playlistList->verticalScrollBar();
|
||||
if (bar && bar->maximum() == 0 && m_playlistOffset < m_playlistTotal)
|
||||
requestPlaylistsPage(m_lastPlaylistGenreIds, m_lastPlaylistType, m_lastPlaylistTags, m_lastPlaylistQuery, m_playlistOffset, true);
|
||||
});
|
||||
}
|
||||
|
||||
void GenreBrowserView::onPlaylistSearchLoaded(const QJsonObject &result)
|
||||
@@ -456,9 +481,25 @@ void GenreBrowserView::onPlaylistSearchLoaded(const QJsonObject &result)
|
||||
m_playlistTotal = m_playlistOffset;
|
||||
m_loadingPlaylists = false;
|
||||
|
||||
// Eagerly fill the viewport, then switch to a manual "Load more" button.
|
||||
if (m_playlistOffset >= m_playlistTotal) {
|
||||
m_loadMorePlaylistsBtn->hide();
|
||||
m_searchViewportFilled = true;
|
||||
} else if (!m_searchViewportFilled) {
|
||||
QTimer::singleShot(0, this, [this] {
|
||||
QScrollBar *bar = m_playlistList->verticalScrollBar();
|
||||
if (bar && bar->maximum() == 0 && m_playlistOffset < m_playlistTotal)
|
||||
requestPlaylistsPage(m_lastPlaylistGenreIds, m_lastPlaylistType, m_lastPlaylistTags, m_lastPlaylistQuery, m_playlistOffset, true);
|
||||
if (bar && bar->maximum() == 0 && m_playlistOffset < m_playlistTotal) {
|
||||
requestPlaylistsPage(m_lastPlaylistGenreIds, m_lastPlaylistType,
|
||||
m_lastPlaylistTags, m_lastPlaylistQuery,
|
||||
m_playlistOffset, true);
|
||||
} else {
|
||||
m_searchViewportFilled = true;
|
||||
m_loadMorePlaylistsBtn->setVisible(m_playlistOffset < m_playlistTotal);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
m_loadMorePlaylistsBtn->setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
void GenreBrowserView::onSelectionChanged()
|
||||
@@ -571,6 +612,9 @@ void GenreBrowserView::requestPlaylistsPage(const QString &genreIds, const QStri
|
||||
m_loadingPlaylists = false;
|
||||
m_playlistOffset = 0;
|
||||
m_playlistTotal = 0;
|
||||
m_loadMorePlaylistsBtn->hide();
|
||||
if (type == QStringLiteral("search"))
|
||||
m_searchViewportFilled = false;
|
||||
}
|
||||
|
||||
m_lastPlaylistGenreIds = genreIds;
|
||||
@@ -580,7 +624,7 @@ void GenreBrowserView::requestPlaylistsPage(const QString &genreIds, const QStri
|
||||
m_loadingPlaylists = true;
|
||||
|
||||
if (type == QStringLiteral("search")) {
|
||||
m_backend->searchPlaylists(query, 8, static_cast<quint32>(offset));
|
||||
m_backend->searchPlaylists(query, 25, static_cast<quint32>(offset));
|
||||
} else if (type.startsWith(QStringLiteral("discover-"))) {
|
||||
m_backend->discoverPlaylists(genreIds, tags, 25, static_cast<quint32>(offset));
|
||||
} else {
|
||||
@@ -608,6 +652,9 @@ void GenreBrowserView::onAlbumScroll(int value)
|
||||
|
||||
void GenreBrowserView::onPlaylistScroll(int value)
|
||||
{
|
||||
// Search results use a manual "Load more" button instead of infinite scroll.
|
||||
if (m_lastPlaylistType == QStringLiteral("search"))
|
||||
return;
|
||||
if (m_loadingPlaylists)
|
||||
return;
|
||||
if (m_playlistOffset >= m_playlistTotal)
|
||||
|
||||
@@ -70,6 +70,8 @@ private:
|
||||
QStackedWidget *m_resultsStack = nullptr;
|
||||
AlbumListView *m_albumList = nullptr;
|
||||
QTreeWidget *m_playlistList = nullptr;
|
||||
QPushButton *m_loadMorePlaylistsBtn = nullptr;
|
||||
bool m_searchViewportFilled = false;
|
||||
BrowseMode m_mode = BrowseMode::Genres;
|
||||
bool m_genresLoaded = false;
|
||||
int m_lastGenreComboIndex = 0;
|
||||
|
||||
Reference in New Issue
Block a user