**Section toggles left-aligned** - Replace QToolButton with flat QPushButton for all section headers; QPushButton properly respects text-align: left in stylesheets **Pagination via "Load More" button** - QTreeWidget expands to fit all items so the scrollbar-based infinite scroll never triggered; replaced with an explicit "Load more…" button that appears when has_more is true and emits loadMoreRequested **Favourite button reflects actual state** - MainWindow preloads fav artist IDs on session restore (getFavArtists) and caches them in m_favArtistIds - ArtistView receives the full set via setFavArtistIds() and checks it on every setArtist() call so the button starts gold if already faved - Toggling updates the local cache immediately for back/forward nav **Playback error → queue advances** - player_loop now sets track_finished on Err (was only set on Ok(None)), so the toolbar's onTrackFinished handler advances to the next track instead of stalling on an unplayable track Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
120 lines
3.7 KiB
C++
120 lines
3.7 KiB
C++
#include "maincontent.hpp"
|
|
|
|
#include <QVBoxLayout>
|
|
#include <QPushButton>
|
|
|
|
MainContent::MainContent(QobuzBackend *backend, PlayQueue *queue, QWidget *parent)
|
|
: QWidget(parent)
|
|
, m_backend(backend)
|
|
{
|
|
auto *layout = new QVBoxLayout(this);
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
m_stack = new QStackedWidget(this);
|
|
layout->addWidget(m_stack);
|
|
|
|
m_welcome = new QLabel(
|
|
tr("<h2>Welcome to Qobuz</h2>"
|
|
"<p>Select something from the library on the left to get started,<br>"
|
|
"or use the search panel (🔍) to find music.</p>"),
|
|
this);
|
|
m_welcome->setAlignment(Qt::AlignCenter);
|
|
|
|
// Tracks page: context header + track list
|
|
auto *tracksPage = new QWidget(this);
|
|
auto *tracksLayout = new QVBoxLayout(tracksPage);
|
|
tracksLayout->setContentsMargins(0, 0, 0, 0);
|
|
tracksLayout->setSpacing(0);
|
|
|
|
m_header = new TrackContextHeader(tracksPage);
|
|
m_header->hide();
|
|
m_tracks = new List::Tracks(m_backend, queue, tracksPage);
|
|
tracksLayout->addWidget(m_header);
|
|
tracksLayout->addWidget(m_tracks, 1);
|
|
|
|
QObject::connect(m_header->playButton(), &QPushButton::clicked,
|
|
[this] { m_tracks->playAll(false); });
|
|
QObject::connect(m_header->shuffleButton(), &QPushButton::clicked,
|
|
[this] { m_tracks->playAll(true); });
|
|
QObject::connect(m_header->subtitleButton(), &QPushButton::clicked,
|
|
[this] {
|
|
const qint64 id = m_header->artistId();
|
|
if (id > 0) emit artistRequested(id);
|
|
});
|
|
|
|
m_albumList = new AlbumListView(this);
|
|
m_artistList = new ArtistListView(this);
|
|
m_artistView = new ArtistView(backend, queue, this);
|
|
|
|
m_stack->addWidget(m_welcome); // 0
|
|
m_stack->addWidget(tracksPage); // 1
|
|
m_stack->addWidget(m_albumList); // 2
|
|
m_stack->addWidget(m_artistList); // 3
|
|
m_stack->addWidget(m_artistView); // 4
|
|
|
|
m_stack->setCurrentIndex(0);
|
|
|
|
connect(m_albumList, &AlbumListView::albumSelected, this, &MainContent::albumRequested);
|
|
connect(m_artistList, &ArtistListView::artistSelected, this, &MainContent::artistRequested);
|
|
connect(m_artistView, &ArtistView::albumSelected, this, &MainContent::albumRequested);
|
|
connect(m_artistView, &ArtistView::playTrackRequested, this, &MainContent::playTrackRequested);
|
|
}
|
|
|
|
void MainContent::showWelcome() { m_stack->setCurrentIndex(0); }
|
|
|
|
void MainContent::showAlbum(const QJsonObject &album)
|
|
{
|
|
m_header->setAlbum(album);
|
|
m_tracks->loadAlbum(album);
|
|
m_stack->setCurrentIndex(1);
|
|
}
|
|
|
|
void MainContent::showPlaylist(const QJsonObject &playlist)
|
|
{
|
|
m_header->setPlaylist(playlist);
|
|
m_tracks->loadPlaylist(playlist);
|
|
m_stack->setCurrentIndex(1);
|
|
}
|
|
|
|
void MainContent::showFavTracks(const QJsonObject &result)
|
|
{
|
|
m_header->hide();
|
|
m_tracks->loadTracks(result["items"].toArray());
|
|
m_stack->setCurrentIndex(1);
|
|
}
|
|
|
|
void MainContent::showSearchTracks(const QJsonArray &tracks)
|
|
{
|
|
m_header->hide();
|
|
m_tracks->loadSearchTracks(tracks);
|
|
m_stack->setCurrentIndex(1);
|
|
}
|
|
|
|
void MainContent::showFavAlbums(const QJsonObject &result)
|
|
{
|
|
m_albumList->setAlbums(result["items"].toArray());
|
|
m_stack->setCurrentIndex(2);
|
|
}
|
|
|
|
void MainContent::showFavArtists(const QJsonObject &result)
|
|
{
|
|
m_artistList->setArtists(result["items"].toArray());
|
|
m_stack->setCurrentIndex(3);
|
|
}
|
|
|
|
void MainContent::showArtist(const QJsonObject &artist)
|
|
{
|
|
m_artistView->setArtist(artist);
|
|
m_stack->setCurrentIndex(4);
|
|
}
|
|
|
|
void MainContent::updateArtistReleases(const QString &releaseType, const QJsonArray &items, bool hasMore, int offset)
|
|
{
|
|
m_artistView->setReleases(releaseType, items, hasMore, offset);
|
|
}
|
|
|
|
void MainContent::setFavArtistIds(const QSet<qint64> &ids)
|
|
{
|
|
m_artistView->setFavArtistIds(ids);
|
|
}
|