feat: restore most-popular search and top results badges
Some checks failed
Build for Windows / build-windows (push) Has been cancelled

This commit is contained in:
joren
2026-03-30 22:53:41 +02:00
parent 3346b424b3
commit 2da934f3f6
7 changed files with 134 additions and 1 deletions

View File

@@ -51,6 +51,11 @@ void QobuzBackend::search(const QString &query, quint32 offset, quint32 limit)
qobuz_backend_search(m_backend, query.toUtf8().constData(), offset, limit);
}
void QobuzBackend::mostPopularSearch(const QString &query, quint32 limit)
{
qobuz_backend_most_popular_search(m_backend, query.toUtf8().constData(), limit);
}
void QobuzBackend::getAlbum(const QString &albumId)
{
qobuz_backend_get_album(m_backend, albumId.toUtf8().constData());
@@ -251,6 +256,9 @@ void QobuzBackend::onEvent(int eventType, const QString &json)
case EV_SEARCH_OK:
emit searchResult(obj);
break;
case 26: // EV_MOST_POPULAR_OK
emit mostPopularResult(obj);
break;
case EV_SEARCH_ERR:
emit error(obj["error"].toString());
break;

View File

@@ -28,6 +28,7 @@ public:
// --- catalog ---
void search(const QString &query, quint32 offset = 0, quint32 limit = 20);
void mostPopularSearch(const QString &query, quint32 limit = 8);
void getAlbum(const QString &albumId);
void getArtist(qint64 artistId);
void getArtistReleases(qint64 artistId, const QString &releaseType, quint32 limit = 50, quint32 offset = 0);
@@ -83,6 +84,7 @@ signals:
// catalog
void searchResult(const QJsonObject &result);
void mostPopularResult(const QJsonObject &result);
void albumLoaded(const QJsonObject &album);
void artistLoaded(const QJsonObject &artist);
void artistReleasesLoaded(const QString &releaseType, const QJsonArray &items, bool hasMore, int offset);

View File

@@ -39,6 +39,14 @@ SearchTab::SearchTab(QobuzBackend *backend, PlayQueue *queue, QWidget *parent)
// Result tabs
m_resultTabs = new QTabWidget(this);
m_topResults = new QTreeWidget(this);
m_topResults->setHeaderLabels({tr(""), tr("Top Result"), tr("Info")});
m_topResults->setRootIsDecorated(false);
m_topResults->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
m_topResults->header()->setSectionResizeMode(1, QHeaderView::Stretch);
m_topResults->header()->setSectionResizeMode(2, QHeaderView::Stretch);
m_topResults->header()->setStretchLastSection(false);
m_trackResults = new QTreeWidget(this);
m_trackResults->setHeaderLabels({tr("Title"), tr("Artist"), tr("Album")});
m_trackResults->setRootIsDecorated(false);
@@ -57,6 +65,7 @@ SearchTab::SearchTab(QobuzBackend *backend, PlayQueue *queue, QWidget *parent)
m_artistResults->setHeaderLabels({tr("Artist")});
m_artistResults->setRootIsDecorated(false);
m_resultTabs->addTab(m_topResults, tr("Top Results"));
m_resultTabs->addTab(m_trackResults, tr("Tracks"));
m_resultTabs->addTab(m_albumResults, tr("Albums"));
m_resultTabs->addTab(m_artistResults, tr("Artists"));
@@ -66,7 +75,9 @@ SearchTab::SearchTab(QobuzBackend *backend, PlayQueue *queue, QWidget *parent)
connect(m_searchBox, &QLineEdit::returnPressed, this, &SearchTab::onSearchSubmit);
connect(m_backend, &QobuzBackend::searchResult, this, &SearchTab::onSearchResult);
connect(m_backend, &QobuzBackend::mostPopularResult, this, &SearchTab::onMostPopularResult);
connect(m_topResults, &QTreeWidget::itemDoubleClicked, this, &SearchTab::onItemDoubleClicked);
connect(m_trackResults, &QTreeWidget::itemDoubleClicked, this, &SearchTab::onItemDoubleClicked);
connect(m_albumResults, &QTreeWidget::itemDoubleClicked, this, &SearchTab::onItemDoubleClicked);
connect(m_artistResults, &QTreeWidget::itemDoubleClicked, this, &SearchTab::onItemDoubleClicked);
@@ -86,8 +97,67 @@ void SearchTab::setUserPlaylists(const QVector<QPair<qint64, QString>> &playlist
void SearchTab::onSearchSubmit()
{
const QString q = m_searchBox->text().trimmed();
if (!q.isEmpty())
if (!q.isEmpty()) {
m_backend->mostPopularSearch(q, 8);
m_backend->search(q, 0, 20);
m_resultTabs->setCurrentIndex(0);
}
}
void SearchTab::onMostPopularResult(const QJsonObject &result)
{
m_topResults->clear();
QFont badgeFont;
badgeFont.setBold(true);
const QJsonArray items = result["most_popular"].toObject()["items"].toArray();
for (const auto &value : items) {
const QJsonObject itemObj = value.toObject();
const QString type = itemObj["type"].toString();
const QJsonObject content = itemObj["content"].toObject();
auto *item = new QTreeWidgetItem(m_topResults);
item->setData(0, JsonRole, content);
if (type == QStringLiteral("tracks")) {
const QString title = content["title"].toString();
const QString artist = content["performer"].toObject()["name"].toString();
const QString album = content["album"].toObject()["title"].toString();
item->setText(0, QStringLiteral("T"));
item->setForeground(0, QColor(QStringLiteral("#2FA84F")));
item->setFont(0, badgeFont);
item->setTextAlignment(0, Qt::AlignCenter);
item->setText(1, title);
item->setText(2, artist.isEmpty() ? album : QStringLiteral("%1 - %2").arg(artist, album));
item->setData(0, TypeRole, QStringLiteral("track"));
item->setData(0, IdRole, static_cast<qint64>(content["id"].toDouble()));
} else if (type == QStringLiteral("albums")) {
const QString title = content["title"].toString();
const QString artist = content["artist"].toObject()["name"].toString();
const bool hiRes = content["hires_streamable"].toBool()
|| content["rights"].toObject()["hires_streamable"].toBool();
item->setText(0, hiRes ? QStringLiteral("H") : QStringLiteral("A"));
item->setForeground(0, hiRes
? QColor(QStringLiteral("#FFB232"))
: QColor(QStringLiteral("#8E8E93")));
item->setFont(0, badgeFont);
item->setTextAlignment(0, Qt::AlignCenter);
item->setText(1, title);
item->setText(2, artist);
item->setData(0, TypeRole, QStringLiteral("album"));
item->setData(1, IdRole, content["id"].toString());
} else if (type == QStringLiteral("artists")) {
item->setText(0, QStringLiteral("A"));
item->setForeground(0, QColor(QStringLiteral("#2B7CD3")));
item->setFont(0, badgeFont);
item->setTextAlignment(0, Qt::AlignCenter);
item->setText(1, content["name"].toString());
item->setText(2, tr("Artist"));
item->setData(0, TypeRole, QStringLiteral("artist"));
item->setData(0, IdRole, static_cast<qint64>(content["id"].toDouble()));
}
}
}
void SearchTab::onSearchResult(const QJsonObject &result)

View File

@@ -30,6 +30,7 @@ namespace SidePanel
private slots:
void onSearchResult(const QJsonObject &result);
void onMostPopularResult(const QJsonObject &result);
void onSearchSubmit();
void onItemDoubleClicked(QTreeWidgetItem *item, int column);
@@ -38,6 +39,7 @@ namespace SidePanel
PlayQueue *m_queue = nullptr;
QLineEdit *m_searchBox = nullptr;
QTabWidget *m_resultTabs = nullptr;
QTreeWidget *m_topResults = nullptr;
QTreeWidget *m_trackResults = nullptr;
QTreeWidget *m_albumResults = nullptr;
QTreeWidget *m_artistResults = nullptr;