diff --git a/lib/include/lib/spotify/api.hpp b/lib/include/lib/spotify/api.hpp index e7d36d73..967d9a3e 100644 --- a/lib/include/lib/spotify/api.hpp +++ b/lib/include/lib/spotify/api.hpp @@ -102,6 +102,15 @@ namespace lib void saved_albums(const paged_callback &callback) const; + void add_saved_albums(const std::vector &album_ids, + lib::callback &callback); + + void remove_saved_albums(const std::vector &album_ids, + lib::callback &callback); + + void is_saved_album(const std::vector &album_ids, + lib::callback> &callback); + /** * @deprecated Use with pagination instead */ diff --git a/lib/src/spotifyapi/library.cpp b/lib/src/spotifyapi/library.cpp index c2d2ca33..e9da8bda 100644 --- a/lib/src/spotifyapi/library.cpp +++ b/lib/src/spotifyapi/library.cpp @@ -1,7 +1,6 @@ #include "lib/spotify/api.hpp" // Currently unavailable: -// me/albums/contains // me/shows // me/shows/contains @@ -10,6 +9,29 @@ void lib::spt::api::saved_albums(const paged_callback &callback) co request.get_page("me/albums", {}, callback); } +void lib::spt::api::add_saved_albums(const std::vector &album_ids, + lib::callback &callback) +{ + put("me/albums", { + {"ids", album_ids}, + }, callback); +} + +void lib::spt::api::remove_saved_albums(const std::vector &album_ids, + lib::callback &callback) +{ + del("me/albums", { + {"ids", album_ids}, + }, callback); +} + +void lib::spt::api::is_saved_album(const std::vector &album_ids, + lib::callback> &callback) +{ + get(lib::fmt::format("me/albums/contains?ids={}", + lib::strings::join(album_ids, ",")), callback); +} + void lib::spt::api::saved_tracks(lib::callback> &callback) { get_items("me/tracks?limit=50", callback); diff --git a/src/menu/album.cpp b/src/menu/album.cpp index 9d9092b0..ec090372 100644 --- a/src/menu/album.cpp +++ b/src/menu/album.cpp @@ -13,12 +13,18 @@ Menu::Album::Album(lib::spt::api &spotify, lib::cache &cache, trackCount = addAction("..."); trackCount->setEnabled(false); addSeparator(); - + auto *playShuffle = addAction(Icon::get("media-playlist-shuffle"), "Shuffle play"); QAction::connect(playShuffle, &QAction::triggered, this, &Menu::Album::onShuffle); + toggleLikedAlbum = addAction("Add to liked albums"); + toggleLikedAlbum->setEnabled(false); + + QAction::connect(toggleLikedAlbum, &QAction::triggered, + this, &Menu::Album::onLikeAlbum); + auto *share = addMenu(Icon::get("document-share"), "Share"); auto *copyLink = share->addAction("Copy album link"); @@ -38,6 +44,13 @@ Menu::Album::Album(lib::spt::api &spotify, lib::cache &cache, addToPlaylist->setEnabled(false); addMenu(addToPlaylist); + spotify.is_saved_album({albumId}, [this](const std::vector &likes) + { + auto liked = !likes.empty() && likes.front(); + this->setLikedAlbum(liked); + this->toggleLikedAlbum->setEnabled(true); + }); + album = cache.get_album(albumId); if (album.is_valid()) { @@ -103,6 +116,31 @@ void Menu::Album::onShuffle(bool /*checked*/) }); } +void Menu::Album::onLikeAlbum(bool /*checked*/) +{ + auto callback = [this](const std::string &status) + { + if (status.empty()) + { + return; + } + + StatusMessage::error(QString("Failed to %1 album: %2") + .arg(isLiked ? "unlike" : "like") + .arg(QString::fromStdString(status))); + }; + + std::vector albumIds = { album.id }; + + if (isLiked) + { + spotify.remove_saved_albums(albumIds, callback); + } else + { + spotify.add_saved_albums(albumIds, callback); + } +} + void Menu::Album::onCopyLink(bool /*checked*/) { QApplication::clipboard()->setText(QString("https://open.spotify.com/album/%1") @@ -123,6 +161,19 @@ void Menu::Album::onOpenInSpotify(bool /*checked*/) MainWindow::find(parentWidget())); } +void Menu::Album::setLikedAlbum(bool liked) +{ + isLiked = liked; + + toggleLikedAlbum->setIcon(Icon::get(liked + ? QStringLiteral("list-remove") + : QStringLiteral("list-add"))); + + toggleLikedAlbum->setText(liked + ? QStringLiteral("Remove from liked albums") + : QStringLiteral("Add to liked albums")); +} + void Menu::Album::tracksLoaded() { if (addToPlaylist != nullptr) diff --git a/src/menu/album.hpp b/src/menu/album.hpp index 0dfde8b3..94a5b45e 100644 --- a/src/menu/album.hpp +++ b/src/menu/album.hpp @@ -19,18 +19,23 @@ namespace Menu const std::string &albumId, QWidget *parent); private: + bool isLiked = false; + std::vector tracks; lib::spt::album album; lib::spt::api &spotify; lib::cache &cache; + QAction *toggleLikedAlbum = nullptr; QAction *trackCount = nullptr; AddToPlaylist *addToPlaylist = nullptr; + void setLikedAlbum(bool liked); void tracksLoaded(); auto getTrackIds() const -> std::vector; void onShuffle(bool checked); + void onLikeAlbum(bool checked); void onCopyLink(bool checked); void onCopyName(bool checked); void onOpenInSpotify(bool checked);