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

32
src/util/icon.hpp Normal file
View File

@@ -0,0 +1,32 @@
#pragma once
#include <QIcon>
#include <QString>
namespace Icon
{
inline QIcon get(const QString &name)
{
// Try theme icon first, fall back to resource
if (QIcon::hasThemeIcon(name))
return QIcon::fromTheme(name);
return QIcon(QStringLiteral(":/icons/%1.svg").arg(name));
}
// Convenient aliases for common icons used throughout the app
inline QIcon play() { return get("media-playback-start"); }
inline QIcon pause() { return get("media-playback-pause"); }
inline QIcon stop() { return get("media-playback-stop"); }
inline QIcon next() { return get("media-skip-forward"); }
inline QIcon previous() { return get("media-skip-backward"); }
inline QIcon shuffle() { return get("media-playlist-shuffle"); }
inline QIcon repeat() { return get("media-playlist-repeat"); }
inline QIcon volumeHigh() { return get("audio-volume-high"); }
inline QIcon volumeMid() { return get("audio-volume-medium"); }
inline QIcon volumeMute() { return get("audio-volume-muted"); }
inline QIcon search() { return get("edit-find"); }
inline QIcon heart() { return get("emblem-favorite"); }
inline QIcon album() { return get("media-optical"); }
inline QIcon artist() { return get("system-users"); }
inline QIcon playlist() { return get("view-list-symbolic"); }
}