Initial implementation of qobuz-qt

- Rust backend (qobuz-backend static lib): Qobuz API client (reqwest/tokio),
  Symphonia audio decoder, CPAL audio output, extern "C" FFI bridge
- Qt 6 frontend mirroring spotify-qt layout: toolbar with playback controls,
  left library dock, central track list, right search panel
- Auth: email/password login with MD5-signed requests; session token persisted
  via QSettings
- Playback: double-click a track → Rust fetches stream URL → Symphonia decodes
  → CPAL outputs to default audio device
- Dark Fusion palette matching spotify-qt feel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
joren
2026-03-23 23:34:23 +01:00
commit 9402dca7ed
40 changed files with 3963 additions and 0 deletions

58
src/view/maincontent.cpp Normal file
View File

@@ -0,0 +1,58 @@
#include "maincontent.hpp"
#include <QVBoxLayout>
#include <QJsonArray>
MainContent::MainContent(QobuzBackend *backend, 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.</p>"),
this);
m_welcome->setAlignment(Qt::AlignCenter);
m_tracks = new List::Tracks(m_backend, this);
m_stack->addWidget(m_welcome); // index 0
m_stack->addWidget(m_tracks); // index 1
m_stack->setCurrentIndex(0);
}
void MainContent::showWelcome()
{
m_stack->setCurrentIndex(0);
}
void MainContent::showAlbum(const QJsonObject &album)
{
m_tracks->loadAlbum(album);
m_stack->setCurrentIndex(1);
}
void MainContent::showPlaylist(const QJsonObject &playlist)
{
m_tracks->loadPlaylist(playlist);
m_stack->setCurrentIndex(1);
}
void MainContent::showFavTracks(const QJsonObject &result)
{
const QJsonArray items = result["items"].toArray();
m_tracks->loadTracks(items);
m_stack->setCurrentIndex(1);
}
void MainContent::showSearchTracks(const QJsonArray &tracks)
{
m_tracks->loadSearchTracks(tracks);
m_stack->setCurrentIndex(1);
}