fix: detect followed playlists correctly in header
Some checks failed
Build for Windows / build-windows (push) Has been cancelled

Load owner+subscriber playlists, track all playlist IDs for follow-state resolution, and keep audio ring buffer at 32k as requested.
This commit is contained in:
joren
2026-03-31 02:02:31 +02:00
parent 1ad3ba4e69
commit 4ebd5ed3f0
7 changed files with 24 additions and 10 deletions

View File

@@ -609,6 +609,7 @@ impl QobuzClient {
let resp = self let resp = self
.get_request("playlist/getUserPlaylists") .get_request("playlist/getUserPlaylists")
.query(&[ .query(&[
("filter", "owner,subscriber"),
("offset", &offset.to_string()), ("offset", &offset.to_string()),
("limit", &limit.to_string()), ("limit", &limit.to_string()),
]) ])

View File

@@ -10,9 +10,7 @@ use std::sync::{
}; };
use symphonia::core::audio::AudioBufferRef; use symphonia::core::audio::AudioBufferRef;
// Bigger output buffer gives the decoder/network pipeline more headroom, const RING_BUFFER_SIZE: usize = 32 * 1024;
// reducing audible underruns on transient CPU/network stalls.
const RING_BUFFER_SIZE: usize = 256 * 1024;
pub struct AudioOutput { pub struct AudioOutput {
_ring: SpscRb<f32>, _ring: SpscRb<f32>,

View File

@@ -45,7 +45,7 @@ public:
void getFavTracks(quint32 offset = 0, quint32 limit = 500); void getFavTracks(quint32 offset = 0, quint32 limit = 500);
void getFavAlbums(quint32 offset = 0, quint32 limit = 200); void getFavAlbums(quint32 offset = 0, quint32 limit = 200);
void getFavArtists(quint32 offset = 0, quint32 limit = 200); void getFavArtists(quint32 offset = 0, quint32 limit = 200);
void getUserPlaylists(quint32 offset = 0, quint32 limit = 200); void getUserPlaylists(quint32 offset = 0, quint32 limit = 350);
// --- playback options --- // --- playback options ---
void setReplayGain(bool enabled); void setReplayGain(bool enabled);

View File

@@ -99,6 +99,7 @@ void Library::onUserPlaylistsLoaded(const QJsonObject &result)
while (m_playlistsNode->childCount() > 0) while (m_playlistsNode->childCount() > 0)
delete m_playlistsNode->takeChild(0); delete m_playlistsNode->takeChild(0);
QSet<qint64> allPlaylistIds;
QVector<QPair<qint64, QString>> editablePlaylists; QVector<QPair<qint64, QString>> editablePlaylists;
const qint64 myUserId = AppSettings::instance().userId(); const qint64 myUserId = AppSettings::instance().userId();
const QJsonArray items = result["items"].toArray(); const QJsonArray items = result["items"].toArray();
@@ -109,6 +110,9 @@ void Library::onUserPlaylistsLoaded(const QJsonObject &result)
const qint64 ownId = static_cast<qint64>(pl["owner"].toObject()["id"].toDouble()); const qint64 ownId = static_cast<qint64>(pl["owner"].toObject()["id"].toDouble());
const bool isOwner = (myUserId > 0 && ownId == myUserId); const bool isOwner = (myUserId > 0 && ownId == myUserId);
if (id > 0)
allPlaylistIds.insert(id);
auto *item = new QTreeWidgetItem(m_playlistsNode, QStringList{name}); auto *item = new QTreeWidgetItem(m_playlistsNode, QStringList{name});
item->setData(0, TypeRole, NodePlaylist); item->setData(0, TypeRole, NodePlaylist);
item->setData(0, IdRole, id); item->setData(0, IdRole, id);
@@ -120,6 +124,7 @@ void Library::onUserPlaylistsLoaded(const QJsonObject &result)
editablePlaylists.append({id, name}); editablePlaylists.append({id, name});
} }
emit userPlaylistIdsChanged(allPlaylistIds);
emit userPlaylistsChanged(editablePlaylists); emit userPlaylistsChanged(editablePlaylists);
} }

View File

@@ -7,6 +7,7 @@
#include <QVector> #include <QVector>
#include <QPair> #include <QPair>
#include <QString> #include <QString>
#include <QSet>
namespace List namespace List
{ {
@@ -31,6 +32,8 @@ namespace List
void playlistRequested(qint64 playlistId, const QString &name); void playlistRequested(qint64 playlistId, const QString &name);
/// Emitted after playlists are loaded so others can cache the list. /// Emitted after playlists are loaded so others can cache the list.
void userPlaylistsChanged(const QVector<QPair<qint64, QString>> &playlists); void userPlaylistsChanged(const QVector<QPair<qint64, QString>> &playlists);
/// Emitted with all user playlist IDs (owned + subscribed).
void userPlaylistIdsChanged(const QSet<qint64> &playlistIds);
/// Emitted when the currently open playlist was deleted. /// Emitted when the currently open playlist was deleted.
void openPlaylistDeleted(); void openPlaylistDeleted();

View File

@@ -128,12 +128,14 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
statusBar()->showMessage(tr("Track added to playlist"), 3000); statusBar()->showMessage(tr("Track added to playlist"), 3000);
}); });
connect(m_backend, &QobuzBackend::playlistSubscribed, this, [this](qint64 playlistId) { connect(m_backend, &QobuzBackend::playlistSubscribed, this, [this](qint64 playlistId) {
m_userPlaylistIds.insert(playlistId);
m_library->refresh(); m_library->refresh();
if (m_content->tracksList()->playlistId() == playlistId) if (m_content->tracksList()->playlistId() == playlistId)
m_content->setCurrentPlaylistFollowed(true); m_content->setCurrentPlaylistFollowed(true);
statusBar()->showMessage(tr("Playlist followed"), 3000); statusBar()->showMessage(tr("Playlist followed"), 3000);
}); });
connect(m_backend, &QobuzBackend::playlistUnsubscribed, this, [this](qint64 playlistId) { connect(m_backend, &QobuzBackend::playlistUnsubscribed, this, [this](qint64 playlistId) {
m_userPlaylistIds.remove(playlistId);
m_library->refresh(); m_library->refresh();
if (m_content->tracksList()->playlistId() == playlistId) if (m_content->tracksList()->playlistId() == playlistId)
m_content->setCurrentPlaylistFollowed(false); m_content->setCurrentPlaylistFollowed(false);
@@ -145,6 +147,10 @@ MainWindow::MainWindow(QobuzBackend *backend, QWidget *parent)
}); });
// ---- Library signals ---- // ---- Library signals ----
connect(m_library, &List::Library::userPlaylistIdsChanged,
this, [this](const QSet<qint64> &playlistIds) {
m_userPlaylistIds = playlistIds;
});
connect(m_library, &List::Library::userPlaylistsChanged, connect(m_library, &List::Library::userPlaylistsChanged,
this, &MainWindow::onUserPlaylistsChanged); this, &MainWindow::onUserPlaylistsChanged);
connect(m_library, &List::Library::openPlaylistDeleted, connect(m_library, &List::Library::openPlaylistDeleted,
@@ -536,12 +542,12 @@ void MainWindow::onPlaylistLoaded(const QJsonObject &playlist)
const qint64 myId = AppSettings::instance().userId(); const qint64 myId = AppSettings::instance().userId();
const bool isOwned = (myId > 0 && ownerId == myId); const bool isOwned = (myId > 0 && ownerId == myId);
bool isFollowed = false; bool isFollowed = isOwned || m_userPlaylistIds.contains(id);
for (const auto &pl : m_userPlaylists) { if (!isFollowed) {
if (pl.first == id) { if (playlist.contains("is_subscribed"))
isFollowed = true; isFollowed = playlist["is_subscribed"].toBool();
break; else if (playlist.contains("subscribed_at"))
} isFollowed = !playlist["subscribed_at"].isNull();
} }
m_content->showPlaylist(playlist, isFollowed, isOwned); m_content->showPlaylist(playlist, isFollowed, isOwned);

View File

@@ -55,6 +55,7 @@ private:
QobuzBackend *m_backend = nullptr; QobuzBackend *m_backend = nullptr;
PlayQueue *m_queue = nullptr; PlayQueue *m_queue = nullptr;
QVector<QPair<qint64, QString>> m_userPlaylists; QVector<QPair<qint64, QString>> m_userPlaylists;
QSet<qint64> m_userPlaylistIds;
QSet<QString> m_favAlbumIds; QSet<QString> m_favAlbumIds;
QSet<qint64> m_favArtistIds; QSet<qint64> m_favArtistIds;
bool m_showFavAlbumsOnLoad = false; bool m_showFavAlbumsOnLoad = false;