1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-16 19:31:02 +01:00

VkService: added albums support, added ability to fetch music from wall. Fixed

update bug.
This commit is contained in:
Ivan Leontiev 2014-10-29 01:22:07 +03:00
parent 3d124a2dea
commit 45a3f32c86
2 changed files with 272 additions and 66 deletions

View File

@ -60,6 +60,7 @@ const char* VkService::kUrlScheme = "vk";
const char* VkService::kDefCacheFilename = "%artist - %title"; const char* VkService::kDefCacheFilename = "%artist - %title";
const int VkService::kMaxVkSongList = 6000; const int VkService::kMaxVkSongList = 6000;
const int VkService::kMaxVkWallPostList = 100;
const int VkService::kCustomSongCount = 50; const int VkService::kCustomSongCount = 50;
QString VkService::DefaultCacheDir() { QString VkService::DefaultCacheDir() {
@ -198,10 +199,10 @@ VkService::VkService(Application* app, InternetModel* parent)
root_item_(NULL), root_item_(NULL),
recommendations_item_(NULL), recommendations_item_(NULL),
my_music_item_(NULL), my_music_item_(NULL),
my_albums_item_(NULL),
search_result_item_(NULL), search_result_item_(NULL),
context_menu_(NULL), context_menu_(NULL),
update_item_(NULL), update_item_(NULL),
update_recommendations_(NULL),
find_this_artist_(NULL), find_this_artist_(NULL),
add_to_my_music_(NULL), add_to_my_music_(NULL),
remove_from_my_music_(NULL), remove_from_my_music_(NULL),
@ -260,22 +261,26 @@ QStandardItem* VkService::CreateRootItem() {
} }
void VkService::LazyPopulate(QStandardItem* parent) { void VkService::LazyPopulate(QStandardItem* parent) {
qLog(Debug) << "LazyPopulate";
switch (parent->data(InternetModel::Role_Type).toInt()) { switch (parent->data(InternetModel::Role_Type).toInt()) {
case InternetModel::Type_Service: case InternetModel::Type_Service:
UpdateRoot(); UpdateRoot();
break; break;
case Type_MyMusic:
UpdateMyMusic();
break;
case Type_Recommendations: case Type_Recommendations:
UpdateRecommendations(); UpdateRecommendations();
break; break;
case Type_Bookmark: case Type_AlbumList:
UpdateBookmarkSongs(parent); UpdateAlbumList(parent);
break;
case Type_Music:
UpdateMusic(parent);
break; break;
case Type_Album: case Type_Album:
UpdateAlbumSongs(parent); UpdateAlbumSongs(parent);
break; break;
case Type_Wall:
UpdateWallSongs(parent);
break;
default: default:
break; break;
} }
@ -322,10 +327,6 @@ void VkService::EnsureMenuCreated() {
tr("Add user/group to bookmarks"), tr("Add user/group to bookmarks"),
this, SLOT(ShowSearchDialog())); this, SLOT(ShowSearchDialog()));
update_recommendations_ =
context_menu_->addAction(IconLoader::Load("view-refresh"), tr("Update"),
this, SLOT(UpdateRecommendations()));
update_item_ = update_item_ =
context_menu_->addAction(IconLoader::Load("view-refresh"), tr("Update"), context_menu_->addAction(IconLoader::Load("view-refresh"), tr("Update"),
this, SLOT(UpdateItem())); this, SLOT(UpdateItem()));
@ -341,23 +342,32 @@ void VkService::ShowContextMenu(const QPoint& global_pos) {
EnsureMenuCreated(); EnsureMenuCreated();
QModelIndex current(model()->current_index()); QModelIndex current(model()->current_index());
QStandardItem *current_item = model()->itemFromIndex(current);
const int item_type = current.data(InternetModel::Role_Type).toInt(); const int item_type = current.data(InternetModel::Role_Type).toInt();
const int parent_type = const int parent_type =
current.parent().data(InternetModel::Role_Type).toInt(); current.parent().data(InternetModel::Role_Type).toInt();
const bool is_playable = model()->IsPlayable(current); const bool is_playable = model()->IsPlayable(current);
const bool is_my_music_item = const bool is_my_music_item = current_item == my_music_item_ ||
item_type == Type_MyMusic || parent_type == Type_MyMusic; current_item->parent() == my_music_item_;
const bool is_recommend_item =
item_type == Type_Recommendations || parent_type == Type_Recommendations;
const bool is_track = item_type == InternetModel::Type_Track; const bool is_track = item_type == InternetModel::Type_Track;
const bool is_bookmark = item_type == Type_Bookmark; const bool is_bookmark = item_type == Type_Bookmark;
const bool is_updatable = const bool is_updatable =
item_type == InternetModel::Type_Service || item_type == Type_MyMusic || item_type != Type_Bookmark &&
item_type == Type_Album || is_bookmark || is_my_music_item; item_type != Type_Loading &&
item_type != Type_More &&
item_type != Type_Search &&
parent_type != Type_Search;
const bool is_update_enable =
//To prevent call LazyPopulate twice when we try to Update not populated item
!current.data(InternetModel::Role_CanLazyLoad).toBool() &&
!current.parent().data(InternetModel::Role_CanLazyLoad).toBool() &&
//disable update action until all of item's children have finished updating
!isItemBusy(model()->itemFromIndex(current));
bool is_in_mymusic = false; bool is_in_mymusic = false;
bool is_cached = false; bool is_cached = false;
@ -371,7 +381,7 @@ void VkService::ShowContextMenu(const QPoint& global_pos) {
} }
update_item_->setVisible(is_updatable); update_item_->setVisible(is_updatable);
update_recommendations_->setVisible(is_recommend_item); update_item_->setEnabled(is_update_enable);
find_this_artist_->setVisible(is_track); find_this_artist_->setVisible(is_track);
add_song_to_cache_->setVisible(is_track && !is_cached); add_song_to_cache_->setVisible(is_track && !is_cached);
add_to_my_music_->setVisible(is_track && !is_in_mymusic); add_to_my_music_->setVisible(is_track && !is_in_mymusic);
@ -397,6 +407,9 @@ void VkService::ItemDoubleClicked(QStandardItem* item) {
case Type_Search: case Type_Search:
FindMore(); FindMore();
break; break;
case Type_Wall:
MoreWallSongs(item);
break;
default: default:
qLog(Warning) << "Wrong parent for More item:" qLog(Warning) << "Wrong parent for More item:"
<< item->parent()->text(); << item->parent()->text();
@ -460,8 +473,8 @@ void VkService::UpdateRoot() {
if (HasAccount()) { if (HasAccount()) {
CreateAndAppendRow(root_item_, Type_Recommendations); CreateAndAppendRow(root_item_, Type_Recommendations);
CreateAndAppendRow(root_item_, Type_MyMusic); AppendMusic(root_item_, true);
LoadAlbums(); AppendAlbumList(root_item_, true);
LoadBookmarks(); LoadBookmarks();
} else { } else {
ShowConfig(); ShowConfig();
@ -500,14 +513,6 @@ QStandardItem* VkService::CreateAndAppendRow(QStandardItem* parent,
recommendations_item_ = item; recommendations_item_ = item;
break; break;
case Type_MyMusic:
item = new QStandardItem(QIcon(":vk/my_music.png"), tr("My Music"));
item->setData(true, InternetModel::Role_CanLazyLoad);
item->setData(InternetModel::PlayBehaviour_MultipleItems,
InternetModel::Role_PlayBehaviour);
my_music_item_ = item;
break;
case Type_Search: case Type_Search:
item = new QStandardItem(QIcon(":vk/find.png"), tr("Search")); item = new QStandardItem(QIcon(":vk/find.png"), tr("Search"));
item->setData(InternetModel::PlayBehaviour_MultipleItems, item->setData(InternetModel::PlayBehaviour_MultipleItems,
@ -640,12 +645,12 @@ void VkService::Error(Vreen::Client::Error error) {
* My Music * My Music
*/ */
void VkService::UpdateMyMusic() { void VkService::UpdateMusic(QStandardItem *item)
if (!my_music_item_) { {
// Internet services panel still not created. if (item) {
return; MusicOwner owner = item->data(Role_MusicOwnerMetadata).value<MusicOwner>();
LoadAndAppendSongList(item, owner.id());
} }
LoadAndAppendSongList(my_music_item_, 0);
} }
/*** /***
@ -655,9 +660,6 @@ void VkService::UpdateMyMusic() {
void VkService::UpdateRecommendations() { void VkService::UpdateRecommendations() {
ClearStandardItem(recommendations_item_); ClearStandardItem(recommendations_item_);
CreateAndAppendRow(recommendations_item_, Type_Loading); CreateAndAppendRow(recommendations_item_, Type_Loading);
if (update_recommendations_) {
update_recommendations_->setEnabled(false);
}
auto my_audio = auto my_audio =
audio_provider_->getRecommendationsForUser(0, kCustomSongCount, 0); audio_provider_->getRecommendationsForUser(0, kCustomSongCount, 0);
@ -668,9 +670,6 @@ void VkService::UpdateRecommendations() {
void VkService::MoreRecommendations() { void VkService::MoreRecommendations() {
RemoveLastRow(recommendations_item_, Type_More); RemoveLastRow(recommendations_item_, Type_More);
if (update_recommendations_) {
update_recommendations_->setEnabled(false);
}
CreateAndAppendRow(recommendations_item_, Type_Loading); CreateAndAppendRow(recommendations_item_, Type_Loading);
auto my_audio = audio_provider_->getRecommendationsForUser( auto my_audio = audio_provider_->getRecommendationsForUser(
@ -681,9 +680,6 @@ void VkService::MoreRecommendations() {
} }
void VkService::RecommendationsLoaded(Vreen::AudioItemListReply* reply) { void VkService::RecommendationsLoaded(Vreen::AudioItemListReply* reply) {
if (update_recommendations_) {
update_recommendations_->setEnabled(true);
}
SongList songs = FromAudioList(reply->result()); SongList songs = FromAudioList(reply->result());
RemoveLastRow(recommendations_item_, Type_Loading); RemoveLastRow(recommendations_item_, Type_Loading);
AppendSongs(recommendations_item_, songs); AppendSongs(recommendations_item_, songs);
@ -763,35 +759,48 @@ QStandardItem* VkService::AppendBookmark(const MusicOwner& owner) {
item->setData(QVariant::fromValue(owner), Role_MusicOwnerMetadata); item->setData(QVariant::fromValue(owner), Role_MusicOwnerMetadata);
item->setData(Type_Bookmark, InternetModel::Role_Type); item->setData(Type_Bookmark, InternetModel::Role_Type);
item->setData(true, InternetModel::Role_CanLazyLoad);
item->setData(InternetModel::PlayBehaviour_MultipleItems, AppendWall(item);
InternetModel::Role_PlayBehaviour); AppendMusic(item);
AppendAlbumList(item);
root_item_->appendRow(item); root_item_->appendRow(item);
return item; return item;
} }
void VkService::UpdateItem() { void VkService::UpdateItem() {
QModelIndex current(model()->current_index()); QModelIndex current(model()->current_index());
LazyPopulate(model()->itemFromIndex(current)); QStandardItem *item;
if (current.data(InternetModel::Role_Type).toInt() == InternetModel::Type_Track) {
item = model()->itemFromIndex(current.parent());
} else {
item = model()->itemFromIndex(current);
}
LazyPopulate(item);
} }
void VkService::UpdateBookmarkSongs(QStandardItem* item) { void VkService::UpdateAlbumList(QStandardItem* item) {
qLog(Debug) << "Update album list";
MusicOwner owner = item->data(Role_MusicOwnerMetadata).value<MusicOwner>(); MusicOwner owner = item->data(Role_MusicOwnerMetadata).value<MusicOwner>();
LoadAndAppendSongList(item, owner.id()); ClearStandardItem(item);
CreateAndAppendRow(item, Type_Loading);
LoadAlbums(item, owner);
} }
/*** /***
* Albums * Albums
*/ */
void VkService::LoadAlbums() { void VkService::LoadAlbums(QStandardItem* parent, const MusicOwner& owner) {
auto albums_request = audio_provider_->getAlbums(UserID()); auto albums_request = audio_provider_->getAlbums(owner.id());
NewClosure(albums_request, SIGNAL(resultReady(QVariant)), this, NewClosure(albums_request, SIGNAL(resultReady(QVariant)), this,
SLOT(AlbumListReceived(Vreen::AudioAlbumItemListReply*)), SLOT(AlbumListReceived(QStandardItem*, Vreen::AudioAlbumItemListReply*)),
albums_request); parent, albums_request);
} }
QStandardItem* VkService::AppendAlbum(const Vreen::AudioAlbumItem& album) { QStandardItem* VkService::AppendAlbum(QStandardItem* parent, const Vreen::AudioAlbumItem& album) {
QStandardItem* item = QStandardItem* item =
new QStandardItem(QIcon(":vk/playlist.png"), album.title()); new QStandardItem(QIcon(":vk/playlist.png"), album.title());
@ -800,14 +809,38 @@ QStandardItem* VkService::AppendAlbum(const Vreen::AudioAlbumItem& album) {
item->setData(true, InternetModel::Role_CanLazyLoad); item->setData(true, InternetModel::Role_CanLazyLoad);
item->setData(InternetModel::PlayBehaviour_MultipleItems, item->setData(InternetModel::PlayBehaviour_MultipleItems,
InternetModel::Role_PlayBehaviour); InternetModel::Role_PlayBehaviour);
root_item_->appendRow(item);
parent->appendRow(item);
return item; return item;
} }
void VkService::AlbumListReceived(Vreen::AudioAlbumItemListReply* reply) { QStandardItem *VkService::AppendAlbumList(QStandardItem *parent, bool myself)
{
MusicOwner owner;
QStandardItem* item;
if (myself) {
item = new QStandardItem(QIcon(":vk/discography.png"), tr("My Albums"));
owner.setId(UserID()); //TODO: do this better
my_albums_item_ = item;
} else {
owner = parent->data(Role_MusicOwnerMetadata).value<MusicOwner>();
item = new QStandardItem(QIcon(":vk/discography.png"), tr("Albums"));
}
item->setData(QVariant::fromValue(owner), Role_MusicOwnerMetadata);
item->setData(Type_AlbumList, InternetModel::Role_Type);
item->setData(true, InternetModel::Role_CanLazyLoad);
parent->appendRow(item);
return item;
}
void VkService::AlbumListReceived(QStandardItem* parent, Vreen::AudioAlbumItemListReply* reply) {
Vreen::AudioAlbumItemList albums = reply->result(); Vreen::AudioAlbumItemList albums = reply->result();
RemoveLastRow(parent, Type_Loading);
for (const auto& album : albums) { for (const auto& album : albums) {
AppendAlbum(album); AppendAlbum(parent, album);
} }
} }
@ -818,6 +851,106 @@ void VkService::UpdateAlbumSongs(QStandardItem* item) {
LoadAndAppendSongList(item, album.ownerId(), album.id()); LoadAndAppendSongList(item, album.ownerId(), album.id());
} }
/***
* Wall
*/
QStandardItem* VkService::AppendWall(QStandardItem *parent) {
QStandardItem* item =
new QStandardItem(QIcon(":vk/playlist.png"), tr("Wall"));
MusicOwner owner =
parent->data(Role_MusicOwnerMetadata).value<MusicOwner>();
item->setData(QVariant::fromValue(owner), Role_MusicOwnerMetadata);
item->setData(Type_Wall, InternetModel::Role_Type);
item->setData(true, InternetModel::Role_CanLazyLoad);
item->setData(InternetModel::PlayBehaviour_MultipleItems,
InternetModel::Role_PlayBehaviour);
parent->appendRow(item);
return item;
}
QStandardItem *VkService::AppendMusic(QStandardItem *parent, bool myself)
{
MusicOwner owner;
QStandardItem* item;
if (myself) {
item = new QStandardItem(QIcon(":vk/my_music.png"), tr("My Music"));
owner.setId(UserID()); //TODO: do this better
my_music_item_ = item;
} else {
item = new QStandardItem(QIcon(":vk/playlist.png"), tr("Music"));
owner = parent->data(Role_MusicOwnerMetadata).value<MusicOwner>();
}
item->setData(QVariant::fromValue(owner), Role_MusicOwnerMetadata);
item->setData(Type_Music, InternetModel::Role_Type);
item->setData(true, InternetModel::Role_CanLazyLoad);
item->setData(InternetModel::PlayBehaviour_MultipleItems,
InternetModel::Role_PlayBehaviour);
parent->appendRow(item);
return item;
}
void VkService::UpdateWallSongs(QStandardItem *item)
{
MusicOwner owner = item->data(Role_MusicOwnerMetadata).value<MusicOwner>();
ClearStandardItem(item);
LoadAndAppendWallSongList(item, owner);
}
void VkService::MoreWallSongs(QStandardItem *item)
{
QStandardItem *parent = item->parent();
MusicOwner owner = parent->data(Role_MusicOwnerMetadata).value<MusicOwner>();
int offset = item->data(Role_MoreMetadata).value<int>();
RemoveLastRow(parent, Type_More);
LoadAndAppendWallSongList(parent, owner, offset);
}
void VkService::WallPostsLoaded(QStandardItem *item, Vreen::Reply *reply, int offset) {
auto _response = reply->response().toMap();
int count = _response.value("count").toInt();
SongList songs = FromAudioList(handleWallPosts(_response.value("items")));
RemoveLastRow(item, Type_Loading);
AppendSongs(item, songs);
if (count > offset) {
auto m = CreateAndAppendRow(item, Type_More);
m->setData(offset, Role_MoreMetadata);
}
}
void VkService::LoadAndAppendWallSongList(QStandardItem* item, const MusicOwner &owner, int offset) {
if (item) {
CreateAndAppendRow(item, Type_Loading);
QVariantMap args;
QString vk_script =
"var a = API.wall.get({"
" \"owner_id\": Args.q,"
" \"count\": Args.count,"
" \"offset\": Args.offset"
"});"
"return {\"count\": a.count, \"items\": a.items@.attachments};";
args.insert("v", "5.25");
args.insert("q", owner.id());
args.insert("offset", offset);
args.insert("count", kMaxVkWallPostList);
args.insert("code", vk_script);
auto reply = client_->request("execute", args);
NewClosure(reply, SIGNAL(resultReady(QVariant)), this,
SLOT(WallPostsLoaded(QStandardItem*,Vreen::Reply*, int)),
item, reply, offset + kMaxVkWallPostList);
}
}
/*** /***
* Features * Features
*/ */
@ -829,7 +962,7 @@ void VkService::FindThisArtist() {
void VkService::AddToMyMusic() { void VkService::AddToMyMusic() {
SongId id = ExtractIds(selected_song_.url()); SongId id = ExtractIds(selected_song_.url());
auto reply = audio_provider_->addToLibrary(id.audio_id, id.owner_id); auto reply = audio_provider_->addToLibrary(id.audio_id, id.owner_id);
connect(reply, SIGNAL(resultReady(QVariant)), this, SLOT(UpdateMyMusic())); connect(reply, SIGNAL(resultReady(QVariant)), this, SLOT(UpdateMusic(my_music_item_)));
} }
void VkService::AddToMyMusicCurrent() { void VkService::AddToMyMusicCurrent() {
@ -843,7 +976,7 @@ void VkService::RemoveFromMyMusic() {
SongId id = ExtractIds(selected_song_.url()); SongId id = ExtractIds(selected_song_.url());
if (id.owner_id == UserID()) { if (id.owner_id == UserID()) {
auto reply = audio_provider_->removeFromLibrary(id.audio_id, id.owner_id); auto reply = audio_provider_->removeFromLibrary(id.audio_id, id.owner_id);
connect(reply, SIGNAL(resultReady(QVariant)), this, SLOT(UpdateMyMusic())); connect(reply, SIGNAL(resultReady(QVariant)), this, SLOT(UpdateMusic(my_music_item_)));
} else { } else {
qLog(Error) << "Tried to delete song that not owned by user (" << UserID() qLog(Error) << "Tried to delete song that not owned by user (" << UserID()
<< selected_song_.url(); << selected_song_.url();
@ -888,7 +1021,6 @@ void VkService::FindSongs(const QString& query) {
void VkService::FindMore() { void VkService::FindMore() {
RemoveLastRow(search_result_item_, Type_More); RemoveLastRow(search_result_item_, Type_More);
CreateAndAppendRow(recommendations_item_, Type_Loading);
SearchID id(SearchID::MoreLocalSearch); SearchID id(SearchID::MoreLocalSearch);
SongSearch(id, last_query_, kCustomSongCount, SongSearch(id, last_query_, kCustomSongCount,
@ -1277,6 +1409,33 @@ void VkService::UserOrGroupReceived(const SearchID& id, Vreen::Reply* reply) {
* Utils * Utils
*/ */
int VkService::TypeOfItem(QStandardItem *item)
{
return item->data(InternetModel::Role_Type).toInt();
}
bool VkService::isItemBusy(QStandardItem *item)
{
if (TypeOfItem(item) == InternetModel::Type_Track)
item = item->parent();
int r_count = item->rowCount();
bool flag = false;
if (r_count) {
if (TypeOfItem(item->child(r_count - 1)) == Type_Loading)
return true;
int t = TypeOfItem(item);
if (item == root_item_ || t == Type_Bookmark || t == Type_AlbumList) {
for (int i = 0; i < r_count; i++) {
flag |= isItemBusy(item->child(i));
}
}
}
return flag;
}
void VkService::AppendSongs(QStandardItem* parent, const SongList& songs) { void VkService::AppendSongs(QStandardItem* parent, const SongList& songs) {
for (const auto& song : songs) { for (const auto& song : songs) {
parent->appendRow(CreateSongItem(song)); parent->appendRow(CreateSongItem(song));
@ -1321,3 +1480,31 @@ bool VkService::WaitForReply(Vreen::Reply* reply) {
timeout_timer.stop(); timeout_timer.stop();
return true; return true;
} }
Vreen::AudioItemList VkService::handleWallPosts(const QVariant &response)
{
Vreen::AudioItemList items;
auto list = response.toList();
foreach (auto i, list) {
auto attachments = i.toList();
foreach(auto ii, attachments) {
auto item = ii.toMap();
if (item.value("type") == "audio") {
auto map = item.value("audio").toMap();
Vreen::AudioItem audio;
audio.setId(map.value("id").toInt());
audio.setOwnerId(map.value("owner_id").toInt());
audio.setArtist(map.value("artist").toString());
audio.setTitle(map.value("title").toString());
audio.setDuration(map.value("duration").toReal());
audio.setAlbumId(map.value("album").toInt());
audio.setLyricsId(map.value("lyrics_id").toInt());
audio.setUrl(map.value("url").toUrl());
items.append(audio);
}
}
}
return items;
}

View File

@ -54,6 +54,9 @@ class MusicOwner {
int id() const { return id_; } int id() const { return id_; }
int song_count() const { return songs_count_; } int song_count() const { return songs_count_; }
static QList<MusicOwner> parseMusicOwnerList(const QVariant& request_result); static QList<MusicOwner> parseMusicOwnerList(const QVariant& request_result);
// quick and dirty solution for creating MusicOwner instance for
// logged in user
void setId(int id) { id_ = id; }
private: private:
friend QDataStream& operator<<(QDataStream& stream, const MusicOwner& val); friend QDataStream& operator<<(QDataStream& stream, const MusicOwner& val);
@ -110,6 +113,7 @@ class VkService : public InternetService {
static const char* kDefCacheFilename; static const char* kDefCacheFilename;
static QString DefaultCacheDir(); static QString DefaultCacheDir();
static const int kMaxVkSongList; static const int kMaxVkSongList;
static const int kMaxVkWallPostList;
static const int kCustomSongCount; static const int kCustomSongCount;
enum ItemType { enum ItemType {
@ -117,16 +121,19 @@ class VkService : public InternetService {
Type_More, Type_More,
Type_Recommendations, Type_Recommendations,
Type_MyMusic, Type_Music,
Type_Bookmark, Type_Bookmark,
Type_Album, Type_Album,
Type_Wall,
Type_AlbumList,
Type_Search Type_Search
}; };
enum Role { enum Role {
Role_MusicOwnerMetadata = InternetModel::RoleCount, Role_MusicOwnerMetadata = InternetModel::RoleCount,
Role_AlbumMetadata Role_AlbumMetadata,
Role_MoreMetadata
}; };
Application* app() const { return app_; } Application* app() const { return app_; }
@ -198,9 +205,11 @@ signals:
/* Music */ /* Music */
void SongStopped(); void SongStopped();
void UpdateMyMusic(); void UpdateMusic(QStandardItem *item);
void UpdateBookmarkSongs(QStandardItem* item); void UpdateAlbumList(QStandardItem* item);
void UpdateAlbumSongs(QStandardItem* item); void UpdateAlbumSongs(QStandardItem* item);
void UpdateWallSongs(QStandardItem* item);
void MoreWallSongs(QStandardItem *item);
void FindSongs(const QString& query); void FindSongs(const QString& query);
void FindMore(); void FindMore();
void UpdateRecommendations(); void UpdateRecommendations();
@ -219,14 +228,19 @@ signals:
void SongSearchReceived(const SearchID& id, Vreen::AudioItemListReply* reply); void SongSearchReceived(const SearchID& id, Vreen::AudioItemListReply* reply);
void GroupSearchReceived(const SearchID& id, Vreen::Reply* reply); void GroupSearchReceived(const SearchID& id, Vreen::Reply* reply);
void UserOrGroupReceived(const SearchID& id, Vreen::Reply* reply); void UserOrGroupReceived(const SearchID& id, Vreen::Reply* reply);
void AlbumListReceived(Vreen::AudioAlbumItemListReply* reply); void AlbumListReceived(QStandardItem* parent, Vreen::AudioAlbumItemListReply* reply);
void BroadcastChangeReceived(Vreen::IntReply* reply); void BroadcastChangeReceived(Vreen::IntReply* reply);
void AppendLoadedSongs(QStandardItem* item, Vreen::AudioItemListReply* reply); void AppendLoadedSongs(QStandardItem* item, Vreen::AudioItemListReply* reply);
void RecommendationsLoaded(Vreen::AudioItemListReply* reply); void RecommendationsLoaded(Vreen::AudioItemListReply* reply);
void SearchResultLoaded(const SearchID& id, const SongList& songs); void SearchResultLoaded(const SearchID& id, const SongList& songs);
void WallPostsLoaded(QStandardItem *item, Vreen::Reply *reply, int offset);
private: private:
bool isItemBusy(QStandardItem *item);
int TypeOfItem(QStandardItem *item);
Vreen::AudioItemList handleWallPosts(const QVariant &response);
/* Interface */ /* Interface */
QStandardItem* CreateAndAppendRow(QStandardItem* parent, QStandardItem* CreateAndAppendRow(QStandardItem* parent,
VkService::ItemType type); VkService::ItemType type);
@ -236,6 +250,7 @@ signals:
/* Music */ /* Music */
void LoadAndAppendSongList(QStandardItem* item, int uid, int album_id = -1); void LoadAndAppendSongList(QStandardItem* item, int uid, int album_id = -1);
void LoadAndAppendWallSongList(QStandardItem *item, const MusicOwner &owner, int offset = 0);
Song FromAudioItem(const Vreen::AudioItem& item); Song FromAudioItem(const Vreen::AudioItem& item);
SongList FromAudioList(const Vreen::AudioItemList& list); SongList FromAudioList(const Vreen::AudioItemList& list);
void AppendSongs(QStandardItem* parent, const SongList& songs); void AppendSongs(QStandardItem* parent, const SongList& songs);
@ -244,19 +259,23 @@ signals:
void SaveBookmarks(); void SaveBookmarks();
void LoadBookmarks(); void LoadBookmarks();
void LoadAlbums(); void LoadAlbums(QStandardItem* parent, const MusicOwner& owner);
QStandardItem* AppendAlbum(const Vreen::AudioAlbumItem& album); QStandardItem* AppendAlbum(QStandardItem* parent, const Vreen::AudioAlbumItem& album);
QStandardItem* AppendAlbumList(QStandardItem* parent, bool myself = false);
QStandardItem* AppendWall(QStandardItem *parent);
QStandardItem* AppendMusic(QStandardItem *parent, bool myself = false);
/* Interface */ /* Interface */
QStandardItem* root_item_; QStandardItem* root_item_;
QStandardItem* recommendations_item_; QStandardItem* recommendations_item_;
QStandardItem* my_music_item_; QStandardItem* my_music_item_;
QStandardItem* my_albums_item_;
QStandardItem* search_result_item_; QStandardItem* search_result_item_;
QMenu* context_menu_; QMenu* context_menu_;
QAction* update_item_; QAction* update_item_;
QAction* update_recommendations_;
QAction* find_this_artist_; QAction* find_this_artist_;
QAction* add_to_my_music_; QAction* add_to_my_music_;
QAction* remove_from_my_music_; QAction* remove_from_my_music_;