diff --git a/data/icons.qrc b/data/icons.qrc
index bafe558fb..99068a035 100644
--- a/data/icons.qrc
+++ b/data/icons.qrc
@@ -87,6 +87,7 @@
icons/128x128/scrobble.png
icons/128x128/scrobble-disabled.png
icons/128x128/moodbar.png
+ icons/128x128/love.png
icons/64x64/albums.png
icons/64x64/alsa.png
icons/64x64/application-exit.png
@@ -174,6 +175,7 @@
icons/64x64/scrobble.png
icons/64x64/scrobble-disabled.png
icons/64x64/moodbar.png
+ icons/64x64/love.png
icons/48x48/albums.png
icons/48x48/alsa.png
icons/48x48/application-exit.png
@@ -264,6 +266,7 @@
icons/48x48/scrobble.png
icons/48x48/scrobble-disabled.png
icons/48x48/moodbar.png
+ icons/48x48/love.png
icons/32x32/albums.png
icons/32x32/alsa.png
icons/32x32/application-exit.png
@@ -355,6 +358,7 @@
icons/32x32/scrobble.png
icons/32x32/scrobble-disabled.png
icons/32x32/moodbar.png
+ icons/32x32/love.png
icons/22x22/albums.png
icons/22x22/alsa.png
icons/22x22/application-exit.png
@@ -446,5 +450,6 @@
icons/22x22/scrobble.png
icons/22x22/scrobble-disabled.png
icons/22x22/moodbar.png
+ icons/22x22/love.png
diff --git a/data/icons/128x128/love.png b/data/icons/128x128/love.png
new file mode 100644
index 000000000..4dc1e7d74
Binary files /dev/null and b/data/icons/128x128/love.png differ
diff --git a/data/icons/22x22/love.png b/data/icons/22x22/love.png
new file mode 100644
index 000000000..b6453bf86
Binary files /dev/null and b/data/icons/22x22/love.png differ
diff --git a/data/icons/32x32/love.png b/data/icons/32x32/love.png
new file mode 100644
index 000000000..f8aedc30e
Binary files /dev/null and b/data/icons/32x32/love.png differ
diff --git a/data/icons/48x48/love.png b/data/icons/48x48/love.png
new file mode 100644
index 000000000..f815fabfe
Binary files /dev/null and b/data/icons/48x48/love.png differ
diff --git a/data/icons/64x64/love.png b/data/icons/64x64/love.png
new file mode 100644
index 000000000..bc7456915
Binary files /dev/null and b/data/icons/64x64/love.png differ
diff --git a/src/core/mainwindow.cpp b/src/core/mainwindow.cpp
index f727cca75..80b3a0e0b 100644
--- a/src/core/mainwindow.cpp
+++ b/src/core/mainwindow.cpp
@@ -359,7 +359,8 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
// Scrobble
- ui_->action_toggle_scrobbling->setIcon(IconLoader::Load("scrobble-disabled", 22));
+ ui_->action_toggle_scrobbling->setIcon(IconLoader::Load("scrobble-disabled"));
+ ui_->action_love->setIcon(IconLoader::Load("love"));
// File view connections
connect(file_view_, SIGNAL(AddToPlaylist(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
@@ -419,6 +420,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
#endif
connect(ui_->action_toggle_scrobbling, SIGNAL(triggered()), app_->scrobbler(), SLOT(ToggleScrobbling()));
+ connect(ui_->action_love, SIGNAL(triggered()), SLOT(Love()));
connect(app_->scrobbler(), SIGNAL(ErrorMessage(QString)), SLOT(ShowErrorDialog(QString)));
// Playlist view actions
@@ -435,6 +437,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
ui_->pause_play_button->setDefaultAction(ui_->action_play_pause);
ui_->stop_button->setDefaultAction(ui_->action_stop);
ui_->button_scrobble->setDefaultAction(ui_->action_toggle_scrobbling);
+ ui_->button_love->setDefaultAction(ui_->action_love);
ui_->playlist->SetActions(ui_->action_new_playlist, ui_->action_load_playlist, ui_->action_save_playlist, ui_->action_clear_playlist, ui_->action_next_playlist, /* These two actions aren't associated */ ui_->action_previous_playlist /* to a button but to the main window */ );
@@ -615,13 +618,14 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
connect(app_->scrobbler(), SIGNAL(ScrobblingEnabledChanged(bool)), SLOT(ScrobblingEnabledChanged(bool)));
connect(app_->scrobbler(), SIGNAL(ScrobbleButtonVisibilityChanged(bool)), SLOT(ScrobbleButtonVisibilityChanged(bool)));
+ connect(app_->scrobbler(), SIGNAL(LoveButtonVisibilityChanged(bool)), SLOT(LoveButtonVisibilityChanged(bool)));
#ifdef Q_OS_MACOS
mac::SetApplicationHandler(this);
#endif
// Tray icon
if (tray_icon_) {
- tray_icon_->SetupMenu(ui_->action_previous_track, ui_->action_play_pause, ui_->action_stop, ui_->action_stop_after_this_track, ui_->action_next_track, ui_->action_mute, ui_->action_quit);
+ tray_icon_->SetupMenu(ui_->action_previous_track, ui_->action_play_pause, ui_->action_stop, ui_->action_stop_after_this_track, ui_->action_next_track, ui_->action_mute, ui_->action_love, ui_->action_quit);
connect(tray_icon_, SIGNAL(PlayPause()), app_->player(), SLOT(PlayPause()));
connect(tray_icon_, SIGNAL(SeekForward()), app_->player(), SLOT(SeekForward()));
connect(tray_icon_, SIGNAL(SeekBackward()), app_->player(), SLOT(SeekBackward()));
@@ -632,7 +636,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
}
// Windows 7 thumbbar buttons
- thumbbar_->SetActions(QList() << ui_->action_previous_track << ui_->action_play_pause << ui_->action_stop << ui_->action_next_track << nullptr); // spacer
+ thumbbar_->SetActions(QList() << ui_->action_previous_track << ui_->action_play_pause << ui_->action_stop << ui_->action_next_track << nullptr << ui_->action_love);
#if (defined(Q_OS_MACOS) && defined(HAVE_SPARKLE))
// Add check for updates item to application menu.
@@ -659,6 +663,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
connect(global_shortcuts_, SIGNAL(ShowOSD()), app_->player(), SLOT(ShowOSD()));
connect(global_shortcuts_, SIGNAL(TogglePrettyOSD()), app_->player(), SLOT(TogglePrettyOSD()));
connect(global_shortcuts_, SIGNAL(ToggleScrobbling()), app_->scrobbler(), SLOT(ToggleScrobbling()));
+ connect(global_shortcuts_, SIGNAL(Love()), app_->scrobbler(), SLOT(Love()));
#endif
// Fancy tabs
@@ -725,6 +730,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
connect(app_->playlist_manager()->sequence(), SIGNAL(ShuffleModeChanged(PlaylistSequence::ShuffleMode)), osd_, SLOT(ShuffleModeChanged(PlaylistSequence::ShuffleMode)));
ScrobbleButtonVisibilityChanged(app_->scrobbler()->ScrobbleButton());
+ LoveButtonVisibilityChanged(app_->scrobbler()->LoveButton());
ScrobblingEnabledChanged(app_->scrobbler()->IsEnabled());
// Load settings
@@ -913,6 +919,10 @@ void MainWindow::MediaStopped() {
ui_->action_play_pause->setEnabled(true);
+ ui_->action_love->setEnabled(false);
+ ui_->button_love->setEnabled(false);
+ if (tray_icon_) tray_icon_->LoveStateChanged(false);
+
track_position_timer_->stop();
track_slider_timer_->stop();
ui_->track_slider->SetStopped();
@@ -925,6 +935,8 @@ void MainWindow::MediaStopped() {
song_ = Song();
image_original_ = QImage();
+ app_->scrobbler()->ClearPlaying();
+
}
void MainWindow::MediaPaused() {
@@ -939,7 +951,9 @@ void MainWindow::MediaPaused() {
track_position_timer_->stop();
track_slider_timer_->stop();
- if (tray_icon_) tray_icon_->SetPaused();
+ if (tray_icon_) {
+ tray_icon_->SetPaused();
+ }
}
@@ -971,6 +985,9 @@ void MainWindow::MediaPlaying() {
if (app_->scrobbler()->IsEnabled() && playlist && !playlist->nowplaying() && item->Metadata().is_metadata_good() && item->Metadata().length_nanosec() > 0) {
app_->scrobbler()->UpdateNowPlaying(item->Metadata());
playlist->set_nowplaying(true);
+ ui_->action_love->setEnabled(true);
+ ui_->button_love->setEnabled(true);
+ if (tray_icon_) tray_icon_->LoveStateChanged(true);
}
}
@@ -2409,12 +2426,24 @@ void MainWindow::ScrobblingEnabledChanged(bool value) {
}
void MainWindow::ScrobbleButtonVisibilityChanged(bool value) {
+
ui_->button_scrobble->setVisible(value);
ui_->action_toggle_scrobbling->setVisible(value);
if (value) SetToggleScrobblingIcon(app_->scrobbler()->IsEnabled());
}
+void MainWindow::LoveButtonVisibilityChanged(bool value) {
+
+ if (value)
+ ui_->widget_love->show();
+ else
+ ui_->widget_love->hide();
+
+ if (tray_icon_) tray_icon_->LoveVisibilityChanged(value);
+
+}
+
void MainWindow::SetToggleScrobblingIcon(bool value) {
if (value) {
@@ -2428,3 +2457,12 @@ void MainWindow::SetToggleScrobblingIcon(bool value) {
}
}
+
+void MainWindow::Love() {
+
+ app_->scrobbler()->Love();
+ ui_->button_love->setEnabled(false);
+ ui_->action_love->setEnabled(false);
+ if (tray_icon_) tray_icon_->LoveStateChanged(false);
+
+}
diff --git a/src/core/mainwindow.h b/src/core/mainwindow.h
index efacbbe78..f44b31600 100644
--- a/src/core/mainwindow.h
+++ b/src/core/mainwindow.h
@@ -255,6 +255,8 @@ signals:
void ScrobblingEnabledChanged(bool value);
void ScrobbleButtonVisibilityChanged(bool value);
+ void LoveButtonVisibilityChanged(bool value);
+ void Love();
private:
diff --git a/src/core/mainwindow.ui b/src/core/mainwindow.ui
index 712f19ee6..2dc57359a 100644
--- a/src/core/mainwindow.ui
+++ b/src/core/mainwindow.ui
@@ -178,6 +178,41 @@
+ -
+
+
+
+ 1
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ Qt::Vertical
+
+
+
+ -
+
+
+ true
+
+
+
+
+
+
-
@@ -407,7 +442,7 @@
0
0
1131
- 27
+ 24
@@ -528,6 +564,17 @@
Ctrl+Alt+V
+
+
+ false
+
+
+ Love
+
+
+ Ctrl+L
+
+
&Clear playlist
diff --git a/src/core/qtsystemtrayicon.cpp b/src/core/qtsystemtrayicon.cpp
index ad63188b1..30750300c 100644
--- a/src/core/qtsystemtrayicon.cpp
+++ b/src/core/qtsystemtrayicon.cpp
@@ -131,7 +131,7 @@ bool QtSystemTrayIcon::eventFilter(QObject *object, QEvent *event) {
}
-void QtSystemTrayIcon::SetupMenu(QAction *previous, QAction *play, QAction *stop, QAction *stop_after, QAction *next, QAction *mute, QAction *quit) {
+void QtSystemTrayIcon::SetupMenu(QAction *previous, QAction *play, QAction *stop, QAction *stop_after, QAction *next, QAction *mute, QAction *love, QAction *quit) {
// Creating new actions and connecting them to old ones.
// This allows us to use old actions without displaying shortcuts that can not be used when Strawberry's window is hidden
@@ -147,6 +147,9 @@ void QtSystemTrayIcon::SetupMenu(QAction *previous, QAction *play, QAction *stop
action_mute_->setChecked(mute->isChecked());
menu_->addSeparator();
+ action_love_ = menu_->addAction(love->icon(), love->text(), love, SLOT(trigger()));
+ action_love_->setVisible(love->isVisible());
+ action_love_->setEnabled(love->isEnabled());
menu_->addSeparator();
menu_->addAction(quit->icon(), quit->text(), quit, SLOT(trigger()));
@@ -216,6 +219,8 @@ void QtSystemTrayIcon::SetStopped() {
action_play_pause_->setEnabled(true);
+ action_love_->setEnabled(false);
+
}
void QtSystemTrayIcon::MuteButtonStateChanged(bool value) {
@@ -278,3 +283,11 @@ void QtSystemTrayIcon::SetNowPlaying(const Song &song, const QString &image_path
void QtSystemTrayIcon::ClearNowPlaying() {
tray_->setToolTip(app_name_);
}
+
+void QtSystemTrayIcon::LoveVisibilityChanged(bool value) {
+ action_love_->setVisible(value);
+}
+
+void QtSystemTrayIcon::LoveStateChanged(bool value) {
+ action_love_->setEnabled(value);
+}
diff --git a/src/core/qtsystemtrayicon.h b/src/core/qtsystemtrayicon.h
index b2f914715..c6ab4ce5c 100644
--- a/src/core/qtsystemtrayicon.h
+++ b/src/core/qtsystemtrayicon.h
@@ -46,7 +46,7 @@ class QtSystemTrayIcon : public SystemTrayIcon {
QtSystemTrayIcon(QObject *parent = nullptr);
~QtSystemTrayIcon();
- void SetupMenu(QAction *previous, QAction *play, QAction *stop, QAction *stop_after, QAction *next, QAction *mute, QAction *quit);
+ void SetupMenu(QAction *previous, QAction *play, QAction *stop, QAction *stop_after, QAction *next, QAction *mute, QAction *love, QAction *quit);
bool IsVisible() const;
void SetVisible(bool visible);
@@ -65,6 +65,8 @@ class QtSystemTrayIcon : public SystemTrayIcon {
void SetPlaying(bool enable_play_pause = false);
void SetStopped();
void MuteButtonStateChanged(bool value);
+ void LoveVisibilityChanged(bool value);
+ void LoveStateChanged(bool value);
// QObject
bool eventFilter(QObject *, QEvent *);
@@ -84,6 +86,7 @@ class QtSystemTrayIcon : public SystemTrayIcon {
QAction *action_stop_;
QAction *action_stop_after_this_track_;
QAction *action_mute_;
+ QAction *action_love_;
#ifndef Q_OS_WIN
QString de_;
diff --git a/src/core/systemtrayicon.h b/src/core/systemtrayicon.h
index 1d432daaf..a53a452a8 100644
--- a/src/core/systemtrayicon.h
+++ b/src/core/systemtrayicon.h
@@ -39,7 +39,7 @@ class SystemTrayIcon : public QObject {
SystemTrayIcon(QObject *parent = nullptr);
// Called once to create the icon's context menu
- virtual void SetupMenu(QAction *previous, QAction *play, QAction *stop, QAction *stop_after, QAction *next, QAction *mute, QAction *quit) = 0;
+ virtual void SetupMenu(QAction *previous, QAction *play, QAction *stop, QAction *stop_after, QAction *next, QAction *mute, QAction *love, QAction *quit) = 0;
virtual bool IsVisible() const { return true; }
virtual void SetVisible(bool visible) {}
@@ -60,6 +60,8 @@ class SystemTrayIcon : public QObject {
virtual void SetPaused();
virtual void SetPlaying(bool enable_play_pause = false);
virtual void SetStopped();
+ virtual void LoveVisibilityChanged(bool value) {}
+ virtual void LoveStateChanged(bool value) {}
virtual void MuteButtonStateChanged(bool value) {}
signals:
diff --git a/src/globalshortcuts/globalshortcuts.cpp b/src/globalshortcuts/globalshortcuts.cpp
index 09bcf3cfe..ca83bbadc 100644
--- a/src/globalshortcuts/globalshortcuts.cpp
+++ b/src/globalshortcuts/globalshortcuts.cpp
@@ -80,6 +80,7 @@ GlobalShortcuts::GlobalShortcuts(QWidget *parent)
AddShortcut("shuffle_mode", "Change shuffle mode", SIGNAL(CycleShuffleMode()));
AddShortcut("repeat_mode", "Change repeat mode", SIGNAL(CycleRepeatMode()));
AddShortcut("toggle_scrobbling", "Enable/disable scrobbling", SIGNAL(ToggleScrobbling()));
+ AddShortcut("love", "Love", SIGNAL(Love()));
// Create backends - these do the actual shortcut registration
#ifdef HAVE_DBUS
diff --git a/src/globalshortcuts/globalshortcuts.h b/src/globalshortcuts/globalshortcuts.h
index 104abc45d..aba480d82 100644
--- a/src/globalshortcuts/globalshortcuts.h
+++ b/src/globalshortcuts/globalshortcuts.h
@@ -85,6 +85,7 @@ class GlobalShortcuts : public QWidget {
void CycleRepeatMode();
void RemoveCurrentSong();
void ToggleScrobbling();
+ void Love();
private:
void AddShortcut(const QString &id, const QString &name, const char *signal, const QKeySequence &default_key = QKeySequence(0));
diff --git a/src/scrobbler/audioscrobbler.cpp b/src/scrobbler/audioscrobbler.cpp
index 5a54571a9..99ef30062 100644
--- a/src/scrobbler/audioscrobbler.cpp
+++ b/src/scrobbler/audioscrobbler.cpp
@@ -49,6 +49,7 @@ AudioScrobbler::AudioScrobbler(Application *app, QObject *parent) :
enabled_(false),
offline_(false),
scrobble_button_(false),
+ love_button_(false),
submit_delay_(0)
{
@@ -69,11 +70,13 @@ void AudioScrobbler::ReloadSettings() {
enabled_ = s.value("enabled", false).toBool();
offline_ = s.value("offline", false).toBool();
scrobble_button_ = s.value("scrobble_button", false).toBool();
+ love_button_ = s.value("love_button", false).toBool();
submit_delay_ = s.value("submit", 0).toInt();
s.endGroup();
emit ScrobblingEnabledChanged(enabled_);
emit ScrobbleButtonVisibilityChanged(scrobble_button_);
+ emit LoveButtonVisibilityChanged(love_button_);
for (ScrobblerService *service : scrobbler_services_->List()) {
service->ReloadSettings();
@@ -116,25 +119,32 @@ void AudioScrobbler::ShowConfig() {
}
void AudioScrobbler::UpdateNowPlaying(const Song &song) {
- qLog(Debug) << "Sending now playing for song" << song.title();
+ qLog(Debug) << "Sending now playing for song" << song.artist() << song.album() << song.title();
for (ScrobblerService *service : scrobbler_services_->List()) {
if (!service->IsEnabled()) continue;
service->UpdateNowPlaying(song);
}
}
+void AudioScrobbler::ClearPlaying() {
+ for (ScrobblerService *service : scrobbler_services_->List()) {
+ if (!service->IsEnabled()) continue;
+ service->ClearPlaying();
+ }
+}
+
void AudioScrobbler::Scrobble(const Song &song, const int scrobble_point) {
- qLog(Debug) << "Scrobbling song" << QString("") + song.title() + QString("") << "at" << scrobble_point;
+ qLog(Debug) << "Scrobbling song" << song.artist() << song.album() << song.title() << "at" << scrobble_point;
for (ScrobblerService *service : scrobbler_services_->List()) {
if (!service->IsEnabled()) continue;
service->Scrobble(song);
}
}
-void AudioScrobbler::Love(const Song &song) {
+void AudioScrobbler::Love() {
for (ScrobblerService *service : scrobbler_services_->List()) {
if (!service->IsEnabled() || !service->IsAuthenticated()) continue;
- service->Love(song);
+ service->Love();
}
}
diff --git a/src/scrobbler/audioscrobbler.h b/src/scrobbler/audioscrobbler.h
index 38b691410..ed0c6ef44 100644
--- a/src/scrobbler/audioscrobbler.h
+++ b/src/scrobbler/audioscrobbler.h
@@ -46,11 +46,12 @@ class AudioScrobbler : public QObject {
bool IsEnabled() const { return enabled_; }
bool IsOffline() const { return offline_; }
bool ScrobbleButton() const { return scrobble_button_; }
+ bool LoveButton() const { return love_button_; }
int SubmitDelay() const { return submit_delay_; }
void UpdateNowPlaying(const Song &song);
+ void ClearPlaying();
void Scrobble(const Song &song, const int scrobble_point);
- void Love(const Song &song);
void ShowConfig();
void ConnectError();
@@ -65,6 +66,7 @@ class AudioScrobbler : public QObject {
void ToggleScrobbling();
void ToggleOffline();
void Submit();
+ void Love();
void WriteCache();
void ErrorReceived(QString);
@@ -73,6 +75,7 @@ class AudioScrobbler : public QObject {
void ScrobblingEnabledChanged(bool value);
void ScrobblingOfflineChanged(bool value);
void ScrobbleButtonVisibilityChanged(bool value);
+ void LoveButtonVisibilityChanged(bool value);
private:
@@ -82,6 +85,7 @@ class AudioScrobbler : public QObject {
bool enabled_;
bool offline_;
bool scrobble_button_;
+ bool love_button_;
int submit_delay_;
};
diff --git a/src/scrobbler/listenbrainzscrobbler.cpp b/src/scrobbler/listenbrainzscrobbler.cpp
index e83497f55..3868174a0 100644
--- a/src/scrobbler/listenbrainzscrobbler.cpp
+++ b/src/scrobbler/listenbrainzscrobbler.cpp
@@ -340,7 +340,7 @@ void ListenBrainzScrobbler::UpdateNowPlaying(const Song &song) {
album = album.remove(Song::kAlbumRemoveMisc);
QJsonObject object_track_metadata;
- object_track_metadata.insert("artist_name", QJsonValue::fromVariant(song.artist()));
+ object_track_metadata.insert("artist_name", QJsonValue::fromVariant(song.effective_albumartist()));
object_track_metadata.insert("release_name", QJsonValue::fromVariant(album));
object_track_metadata.insert("track_name", QJsonValue::fromVariant(song.title()));
@@ -394,6 +394,10 @@ void ListenBrainzScrobbler::UpdateNowPlayingRequestFinished(QNetworkReply *reply
}
+void ListenBrainzScrobbler::ClearPlaying() {
+ song_playing_ = Song();
+}
+
void ListenBrainzScrobbler::Scrobble(const Song &song) {
if (song.id() != song_playing_.id() || song.url() != song_playing_.url() || !song.is_metadata_good()) return;
@@ -450,7 +454,8 @@ void ListenBrainzScrobbler::Submit() {
QJsonObject object_listen;
object_listen.insert("listened_at", QJsonValue::fromVariant(item->timestamp_));
QJsonObject object_track_metadata;
- object_track_metadata.insert("artist_name", QJsonValue::fromVariant(item->artist_));
+ if (item->albumartist_.isEmpty()) object_track_metadata.insert("artist_name", QJsonValue::fromVariant(item->artist_));
+ else object_track_metadata.insert("artist_name", QJsonValue::fromVariant(item->albumartist_));
object_track_metadata.insert("release_name", QJsonValue::fromVariant(item->album_));
object_track_metadata.insert("track_name", QJsonValue::fromVariant(item->song_));
object_listen.insert("track_metadata", object_track_metadata);
@@ -508,8 +513,6 @@ void ListenBrainzScrobbler::ScrobbleRequestFinished(QNetworkReply *reply, QList<
}
-void ListenBrainzScrobbler::Love(const Song &song) {}
-
void ListenBrainzScrobbler::AuthError(QString error) {
emit AuthenticationComplete(false, error);
}
diff --git a/src/scrobbler/listenbrainzscrobbler.h b/src/scrobbler/listenbrainzscrobbler.h
index b776dee5c..ee0246126 100644
--- a/src/scrobbler/listenbrainzscrobbler.h
+++ b/src/scrobbler/listenbrainzscrobbler.h
@@ -65,8 +65,8 @@ class ListenBrainzScrobbler : public ScrobblerService {
void ShowConfig();
void Submit();
void UpdateNowPlaying(const Song &song);
+ void ClearPlaying();
void Scrobble(const Song &song);
- void Love(const Song &song);
signals:
void AuthenticationComplete(bool success, QString error = QString());
diff --git a/src/scrobbler/scrobblerservice.cpp b/src/scrobbler/scrobblerservice.cpp
index 482214dd5..6a6a82ef6 100644
--- a/src/scrobbler/scrobblerservice.cpp
+++ b/src/scrobbler/scrobblerservice.cpp
@@ -30,7 +30,7 @@
ScrobblerService::ScrobblerService(const QString &name, Application *app, QObject *parent) : QObject(parent), name_(name) {}
-QJsonObject ScrobblerService::ExtractJsonObj(const QByteArray &data) {
+QJsonObject ScrobblerService::ExtractJsonObj(const QByteArray &data, const bool ignore_empty) {
QJsonParseError error;
QJsonDocument json_doc = QJsonDocument::fromJson(data, &error);
@@ -49,7 +49,8 @@ QJsonObject ScrobblerService::ExtractJsonObj(const QByteArray &data) {
}
QJsonObject json_obj = json_doc.object();
if (json_obj.isEmpty()) {
- Error("Received empty Json object.", json_doc);
+ if (!ignore_empty)
+ Error("Received empty Json object.", json_doc);
return QJsonObject();
}
diff --git a/src/scrobbler/scrobblerservice.h b/src/scrobbler/scrobblerservice.h
index 2b59c31b4..838600859 100644
--- a/src/scrobbler/scrobblerservice.h
+++ b/src/scrobbler/scrobblerservice.h
@@ -49,8 +49,9 @@ class ScrobblerService : public QObject {
virtual bool IsAuthenticated() const { return false; }
virtual void UpdateNowPlaying(const Song &song) = 0;
+ virtual void ClearPlaying() = 0;
virtual void Scrobble(const Song &song) = 0;
- virtual void Love(const Song &song) = 0;
+ virtual void Love() {}
virtual void Error(QString error, QVariant debug = QVariant()) = 0;
virtual void DoSubmit() = 0;
@@ -61,7 +62,7 @@ class ScrobblerService : public QObject {
typedef QPair EncodedParam;
typedef QList ParamList;
- QJsonObject ExtractJsonObj(const QByteArray &data);
+ QJsonObject ExtractJsonObj(const QByteArray &data, const bool ignore_empty = false);
public slots:
virtual void Submit() = 0;
diff --git a/src/scrobbler/scrobblingapi20.cpp b/src/scrobbler/scrobblingapi20.cpp
index 7b74a37d3..1795215e5 100644
--- a/src/scrobbler/scrobblingapi20.cpp
+++ b/src/scrobbler/scrobblingapi20.cpp
@@ -414,6 +414,7 @@ void ScrobblingAPI20::UpdateNowPlaying(const Song &song) {
<< Param("artist", song.artist())
<< Param("track", song.title())
<< Param("album", album);
+ if (!song.albumartist().isEmpty()) params << Param("albumArtist", song.albumartist());
QNetworkReply *reply = CreateRequest(params);
NewClosure(reply, SIGNAL(finished()), this, SLOT(UpdateNowPlayingRequestFinished(QNetworkReply*)), reply);
@@ -449,6 +450,10 @@ void ScrobblingAPI20::UpdateNowPlayingRequestFinished(QNetworkReply *reply) {
}
+void ScrobblingAPI20::ClearPlaying() {
+ song_playing_ = Song();
+}
+
void ScrobblingAPI20::Scrobble(const Song &song) {
if (song.id() != song_playing_.id() || song.url() != song_playing_.url() || !song.is_metadata_good()) return;
@@ -488,14 +493,13 @@ void ScrobblingAPI20::DoSubmit() {
void ScrobblingAPI20::Submit() {
- qLog(Debug) << __PRETTY_FUNCTION__ << name_;
-
submitted_ = false;
if (!IsEnabled() || !IsAuthenticated() || app_->scrobbler()->IsOffline()) return;
- ParamList params = ParamList()
- << Param("method", "track.scrobble");
+ qLog(Debug) << name_ << "Submitting scrobbles.";
+
+ ParamList params = ParamList() << Param("method", "track.scrobble");
int i(0);
QList list;
@@ -820,18 +824,73 @@ void ScrobblingAPI20::SingleScrobbleRequestFinished(QNetworkReply *reply, quint6
}
-void ScrobblingAPI20::Love(const Song &song) {
+void ScrobblingAPI20::Love() {
+
+ if (!song_playing_.is_valid() || !song_playing_.is_metadata_good()) return;
if (!IsAuthenticated()) app_->scrobbler()->ShowConfig();
+ qLog(Debug) << name_ << "Sending love for song" << song_playing_.artist() << song_playing_.album() << song_playing_.title();
+
ParamList params = ParamList()
<< Param("method", "track.love")
- << Param("artist", song.artist())
- << Param("track", song.title())
- << Param("album", song.album());
+ << Param("artist", song_playing_.artist())
+ << Param("track", song_playing_.title())
+ << Param("album", song_playing_.album());
+ if (!song_playing_.albumartist().isEmpty()) params << Param("albumArtist", song_playing_.albumartist());
QNetworkReply *reply = CreateRequest(params);
- NewClosure(reply, SIGNAL(finished()), this, SLOT(RequestFinished(QNetworkReply*)), reply);
+ NewClosure(reply, SIGNAL(finished()), this, SLOT(LoveRequestFinished(QNetworkReply*)), reply);
+
+}
+
+void ScrobblingAPI20::LoveRequestFinished(QNetworkReply *reply) {
+
+ reply->deleteLater();
+
+ QByteArray data = GetReplyData(reply);
+ if (data.isEmpty()) {
+ return;
+ }
+
+ QJsonObject json_obj = ExtractJsonObj(data, true);
+ if (json_obj.isEmpty()) {
+ return;
+ }
+
+ if (json_obj.contains("error")) {
+ QJsonValue json_value = json_obj["error"];
+ if (!json_value.isObject()) {
+ Error("Error is not on object.");
+ return;
+ }
+ QJsonObject json_obj_error = json_value.toObject();
+ if (json_obj_error.isEmpty()) {
+ Error("Received empty json error object.", json_obj);
+ return;
+ }
+ if (json_obj_error.contains("code") && json_obj_error.contains("#text")) {
+ int code = json_obj_error["code"].toInt();
+ QString text = json_obj_error["#text"].toString();
+ QString error_reason = QString("%1 (%2)").arg(text).arg(code);
+ Error(error_reason);
+ return;
+ }
+ }
+
+ if (json_obj.contains("lfm")) {
+ QJsonValue json_value = json_obj["lfm"];
+ if (json_value.isObject()) {
+ QJsonObject json_obj_lfm = json_value.toObject();
+ if (json_obj_lfm.contains("status")) {
+ QString status = json_obj_lfm["status"].toString();
+ qLog(Debug) << name_ << "Received love status:" << status;
+ return;
+ }
+ }
+ }
+
+ qLog(Debug) << name_ << json_obj;
}
diff --git a/src/scrobbler/scrobblingapi20.h b/src/scrobbler/scrobblingapi20.h
index 9748278e5..7ecffbcb1 100644
--- a/src/scrobbler/scrobblingapi20.h
+++ b/src/scrobbler/scrobblingapi20.h
@@ -69,9 +69,10 @@ class ScrobblingAPI20 : public ScrobblerService {
void Authenticate(const bool https = false);
void Logout();
void UpdateNowPlaying(const Song &song);
+ void ClearPlaying();
void Scrobble(const Song &song);
void Submit();
- void Love(const Song &song);
+ void Love();
signals:
void AuthenticationComplete(bool success, QString error = QString());
@@ -85,6 +86,7 @@ class ScrobblingAPI20 : public ScrobblerService {
void UpdateNowPlayingRequestFinished(QNetworkReply *reply);
void ScrobbleRequestFinished(QNetworkReply *reply, QList);
void SingleScrobbleRequestFinished(QNetworkReply *reply, quint64 timestamp);
+ void LoveRequestFinished(QNetworkReply *reply);
private:
diff --git a/src/settings/scrobblersettingspage.cpp b/src/settings/scrobblersettingspage.cpp
index 46a46072d..37911089c 100644
--- a/src/settings/scrobblersettingspage.cpp
+++ b/src/settings/scrobblersettingspage.cpp
@@ -81,6 +81,7 @@ void ScrobblerSettingsPage::Load() {
ui_->checkbox_enable->setChecked(scrobbler_->IsEnabled());
ui_->checkbox_scrobble_button->setChecked(scrobbler_->ScrobbleButton());
+ ui_->checkbox_love_button->setChecked(scrobbler_->LoveButton());
ui_->checkbox_offline->setChecked(scrobbler_->IsOffline());
ui_->spinbox_submit->setValue(scrobbler_->SubmitDelay());
@@ -104,6 +105,7 @@ void ScrobblerSettingsPage::Save() {
s.beginGroup(kSettingsGroup);
s.setValue("enabled", ui_->checkbox_enable->isChecked());
s.setValue("scrobble_button", ui_->checkbox_scrobble_button->isChecked());
+ s.setValue("love_button", ui_->checkbox_love_button->isChecked());
s.setValue("offline", ui_->checkbox_offline->isChecked());
s.setValue("submit", ui_->spinbox_submit->value());
s.endGroup();
diff --git a/src/settings/scrobblersettingspage.ui b/src/settings/scrobblersettingspage.ui
index 24da14013..cb937a416 100644
--- a/src/settings/scrobblersettingspage.ui
+++ b/src/settings/scrobblersettingspage.ui
@@ -51,6 +51,13 @@
+ -
+
+
+ Show love button
+
+
+
-
-