diff --git a/3rdparty/vreen/vreen/src/api/audio.cpp b/3rdparty/vreen/vreen/src/api/audio.cpp index fb73323c7..07245f0d3 100644 --- a/3rdparty/vreen/vreen/src/api/audio.cpp +++ b/3rdparty/vreen/vreen/src/api/audio.cpp @@ -210,6 +210,29 @@ IntReply *AudioProvider::removeFromLibrary(int aid, int oid) return reply; } +IdListReply *AudioProvider::setBroadcast(int aid, int oid, const IdList &targetIds) +{ + Q_D(AudioProvider); + + QVariantMap args; + args.insert("audio", QString("%1_%2").arg(oid).arg(aid)); + args.insert("target_ids", join(targetIds)); + + auto reply = d->client->request("audio.setBroadcast", args, ReplyPrivate::handleIdList); + return reply; +} + +IdListReply *AudioProvider::resetBroadcast(const IdList &targetIds) +{ + Q_D(AudioProvider); + + QVariantMap args; + args.insert("audio",""); + args.insert("target_ids", join(targetIds)); + auto reply = d->client->request("audio.setBroadcast", args, ReplyPrivate::handleIdList); + return reply; +} + AudioItemListReply *AudioProvider::getAudiosByIds(const QString &ids) { Q_D(AudioProvider); diff --git a/3rdparty/vreen/vreen/src/api/audio.h b/3rdparty/vreen/vreen/src/api/audio.h index 204e2fe43..37f42c520 100644 --- a/3rdparty/vreen/vreen/src/api/audio.h +++ b/3rdparty/vreen/vreen/src/api/audio.h @@ -26,6 +26,7 @@ #define VK_AUDIO_H #include +#include "vk_global.h" #include "audioitem.h" #include "abstractlistmodel.h" #include "reply.h" @@ -35,6 +36,7 @@ namespace Vreen { class Client; typedef ReplyBase AudioItemListReply; typedef ReplyBase AudioAlbumItemListReply; +typedef ReplyBase> IdListReply; class AudioProviderPrivate; class VK_SHARED_EXPORT AudioProvider : public QObject @@ -60,6 +62,8 @@ public: IntReply *getCount(int oid = 0); IntReply *addToLibrary(int aid, int oid, int gid = 0); IntReply *removeFromLibrary(int aid, int oid); + IdListReply *setBroadcast(int aid, int oid, const IdList& targetIds); + IdListReply *resetBroadcast(const IdList& targetIds); protected: QScopedPointer d_ptr; }; diff --git a/3rdparty/vreen/vreen/src/api/reply.cpp b/3rdparty/vreen/vreen/src/api/reply.cpp index acaf54b04..b3683df73 100644 --- a/3rdparty/vreen/vreen/src/api/reply.cpp +++ b/3rdparty/vreen/vreen/src/api/reply.cpp @@ -122,6 +122,16 @@ void ReplyPrivate::_q_network_reply_error(QNetworkReply::NetworkError code) emit q->resultReady(response); } +QVariant ReplyPrivate::handleIdList(const QVariant &response) +{ + IdList ids; + auto list = response.toList(); + foreach (auto item, list) { + ids.append(item.toInt()); + } + return QVariant::fromValue(ids); +} + QVariant MessageListHandler::operator()(const QVariant &response) { diff --git a/3rdparty/vreen/vreen/src/api/reply_p.h b/3rdparty/vreen/vreen/src/api/reply_p.h index 4fd1809f8..8b3949d6f 100644 --- a/3rdparty/vreen/vreen/src/api/reply_p.h +++ b/3rdparty/vreen/vreen/src/api/reply_p.h @@ -50,15 +50,16 @@ public: void _q_reply_finished(); void _q_network_reply_error(QNetworkReply::NetworkError); - static QVariant handleInt(const QVariant &response) { return response.toInt(); } + static QVariant handleInt(const QVariant &response) { return response.toInt(); } + static QVariant handleIdList(const QVariant& response); }; struct MessageListHandler { - MessageListHandler(int clientId) : clientId(clientId) {} - QVariant operator()(const QVariant &response); + MessageListHandler(int clientId) : clientId(clientId) {} + QVariant operator()(const QVariant &response); - int clientId; + int clientId; }; } //namespace Vreen diff --git a/src/internet/vkconnection.cpp b/src/internet/vkconnection.cpp index 7d50580d5..6b1c6f5c7 100644 --- a/src/internet/vkconnection.cpp +++ b/src/internet/vkconnection.cpp @@ -30,32 +30,31 @@ static const QUrl kVkOAuthEndpoint("https://oauth.vk.com/authorize"); static const QUrl kVkOAuthTokenEndpoint("https://oauth.vk.com/access_token"); static const QUrl kApiUrl("https://api.vk.com/method/"); -static const char *kScopeNames[] = { "notify", "friends", "photos", "audio", - "video", "docs", "notes", "pages", "status", "offers", "questions", "wall", - "groups", "messages", "notifications", "stats", "ads", "offline" }; +static const char* kScopeNames[] = { + "notify", "friends", "photos", "audio", "video", "docs", + "notes", "pages", "status", "offers", "questions", "wall", + "groups", "messages", "notifications", "stats", "ads", "offline"}; static const QString kAppID = "3421812"; static const QString kAppSecret = "cY7KMyX46Fq3nscZlbdo"; static const VkConnection::Scopes kScopes = - VkConnection::Offline | - VkConnection::Audio | - VkConnection::Friends | - VkConnection::Groups; + VkConnection::Offline | VkConnection::Audio | VkConnection::Friends | + VkConnection::Groups | VkConnection::Status; static const char* kSettingsGroup = "Vk.com/oauth"; VkConnection::VkConnection(QObject* parent) - : Connection(parent), - state_(Vreen::Client::StateOffline), - expires_in_(0), - uid_(0) { + : Connection(parent), + state_(Vreen::Client::StateOffline), + expires_in_(0), + uid_(0) { loadToken(); } -VkConnection::~VkConnection() { -} +VkConnection::~VkConnection() {} -void VkConnection::connectToHost(const QString& login, const QString& password) { +void VkConnection::connectToHost(const QString& login, + const QString& password) { Q_UNUSED(login) Q_UNUSED(password) if (hasAccount()) { @@ -84,16 +83,17 @@ void VkConnection::clear() { } bool VkConnection::hasAccount() { - return !access_token_.isNull() - && (expires_in_ > static_cast(QDateTime::currentDateTime().toTime_t())); + return !access_token_.isNull() && + (expires_in_ > + static_cast(QDateTime::currentDateTime().toTime_t())); } -QNetworkRequest VkConnection::makeRequest(const QString& method, const QVariantMap& args) { +QNetworkRequest VkConnection::makeRequest(const QString& method, + const QVariantMap& args) { QUrl url = kApiUrl; url.setPath(url.path() % QLatin1Literal("/") % method); for (auto it = args.constBegin(); it != args.constEnd(); ++it) { - url.addQueryItem(it.key(), - it.value().toString()); + url.addQueryItem(it.key(), it.value().toString()); } url.addEncodedQueryItem("access_token", access_token_); return QNetworkRequest(url); @@ -118,9 +118,9 @@ void VkConnection::requestAccessToken() { qLog(Debug) << "Try to login to Vk.com" << url; - NewClosure(server, SIGNAL(Finished()), - this, SLOT(codeRecived(LocalRedirectServer*, QUrl)), - server, server->url()); + NewClosure(server, SIGNAL(Finished()), this, + SLOT(codeRecived(LocalRedirectServer*, QUrl)), server, + server->url()); QDesktopServices::openUrl(url); } diff --git a/src/internet/vkmusiccache.cpp b/src/internet/vkmusiccache.cpp index 05d4b69a6..8a93430fe 100644 --- a/src/internet/vkmusiccache.cpp +++ b/src/internet/vkmusiccache.cpp @@ -25,44 +25,40 @@ #include "core/taskmanager.h" VkMusicCache::VkMusicCache(Application* app, VkService* service) - : QObject(service), - app_(app), - service_(service), - current_cashing_index(0), - is_downloading(false), - is_aborted(false), - task_id(0), - file_(NULL), - network_manager_(new QNetworkAccessManager), - reply_(NULL) { -} + : QObject(service), + app_(app), + service_(service), + current_song_index(0), + is_downloading(false), + is_aborted(false), + task_id(0), + file_(NULL), + network_manager_(new QNetworkAccessManager), + reply_(NULL) {} QUrl VkMusicCache::Get(const QUrl& url) { - QString cached_filename = CachedFilename(url); QUrl result; - if (InCache(cached_filename)) { + if (InCache(url)) { + QString cached_filename = CachedFilename(url); qLog(Info) << "Use cashed file" << cached_filename; result = QUrl::fromLocalFile(cached_filename); - } else { - result = service_->GetSongPlayUrl(url, false); - - if (service_->isCachingEnabled()) { - AddToQueue(cached_filename, result); - current_cashing_index = queue_.size(); - } } return result; } -void VkMusicCache::ForceCache(const QUrl& url) { - AddToQueue(CachedFilename(url), service_->GetSongPlayUrl(url)); +void VkMusicCache::AddToCache(const QUrl& url, const QUrl& media_url, + bool force) { + AddToQueue(CachedFilename(url), media_url); + if (!force) { + current_song_index = queue_.size(); + } } void VkMusicCache::BreakCurrentCaching() { - if (current_cashing_index > 0) { + if (current_song_index > 0) { // Current song in queue - queue_.removeAt(current_cashing_index - 1); - } else if (current_cashing_index == 0) { + queue_.removeAt(current_song_index - 1); + } else if (current_song_index == 0) { // Current song is downloading if (reply_) { reply_->abort(); @@ -75,7 +71,8 @@ void VkMusicCache::BreakCurrentCaching() { * Queue operations */ -void VkMusicCache::AddToQueue(const QString& filename, const QUrl& download_url) { +void VkMusicCache::AddToQueue(const QString& filename, + const QUrl& download_url) { DownloadItem item; item.filename = filename; item.url = download_url; @@ -93,11 +90,12 @@ void VkMusicCache::DownloadNext() { } else { current_download = queue_.first(); queue_.pop_front(); - current_cashing_index--; + current_song_index--; // Check file path and file existance first if (QFile::exists(current_download.filename)) { - qLog(Warning) << "Tried to overwrite already cached file" << current_download.filename; + qLog(Warning) << "Tried to overwrite already cached file" + << current_download.filename; return; } @@ -117,14 +115,15 @@ void VkMusicCache::DownloadNext() { // Start downloading is_aborted = false; is_downloading = true; - task_id = app_->task_manager()-> - StartTask(tr("Caching %1") - .arg(QFileInfo(current_download.filename).baseName())); + task_id = app_->task_manager()->StartTask( + tr("Caching %1").arg(QFileInfo(current_download.filename).baseName())); reply_ = network_manager_->get(QNetworkRequest(current_download.url)); connect(reply_, SIGNAL(finished()), SLOT(Downloaded())); connect(reply_, SIGNAL(readyRead()), SLOT(DownloadReadyToRead())); - connect(reply_, SIGNAL(downloadProgress(qint64, qint64)), SLOT(DownloadProgress(qint64, qint64))); - qLog(Info)<< "Start cashing" << current_download.filename << "from" << current_download.url; + connect(reply_, SIGNAL(downloadProgress(qint64, qint64)), + SLOT(DownloadProgress(qint64, qint64))); + qLog(Info) << "Start cashing" << current_download.filename << "from" + << current_download.url; } } @@ -154,13 +153,13 @@ void VkMusicCache::Downloaded() { QString path = service_->cacheDir(); - if (file_->size() > 0) { + if (file_->size() > 0) { QDir(path).mkpath(QFileInfo(current_download.filename).path()); if (file_->copy(current_download.filename)) { qLog(Info) << "Cached" << current_download.filename; } else { - qLog(Error) << "Unable to save" << current_download.filename - << ":" << file_->errorString(); + qLog(Error) << "Unable to save" << current_download.filename << ":" + << file_->errorString(); } } else { qLog(Error) << "File" << current_download.filename << "is empty"; @@ -181,12 +180,8 @@ void VkMusicCache::Downloaded() { * Utils */ -bool VkMusicCache::InCache(const QString& filename) { - return QFile::exists(filename); -} - bool VkMusicCache::InCache(const QUrl& url) { - return InCache(CachedFilename(url)); + return QFile::exists(CachedFilename(url)); } QString VkMusicCache::CachedFilename(const QUrl& url) { @@ -198,7 +193,8 @@ QString VkMusicCache::CachedFilename(const QUrl& url) { cache_filename.replace("%artist", args[2]); cache_filename.replace("%title", args[3]); } else { - qLog(Warning) << "Song url with args" << args << "does not contain artist and title" + qLog(Warning) << "Song url with args" << args + << "does not contain artist and title" << "use id as file name for cache."; cache_filename = args[1]; } @@ -209,5 +205,5 @@ QString VkMusicCache::CachedFilename(const QUrl& url) { return ""; } // TODO(Vk): Maybe use extenstion from link? Seems it's always mp3. - return cache_dir+QDir::separator()+cache_filename+".mp3"; + return cache_dir + QDir::separator() + cache_filename + ".mp3"; } diff --git a/src/internet/vkmusiccache.h b/src/internet/vkmusiccache.h index e85cfa052..11b02a385 100644 --- a/src/internet/vkmusiccache.h +++ b/src/internet/vkmusiccache.h @@ -30,30 +30,29 @@ class Application; class VkMusicCache : public QObject { Q_OBJECT -public: + public: explicit VkMusicCache(Application* app, VkService* service); ~VkMusicCache() {} // Return file path if file in cache otherwise // return internet url and add song to caching queue QUrl Get(const QUrl& url); - void ForceCache(const QUrl& url); + void AddToCache(const QUrl& url, const QUrl& media_url, bool force = false); void BreakCurrentCaching(); bool InCache(const QUrl& url); -private slots: - bool InCache(const QString& filename); + private slots: void AddToQueue(const QString& filename, const QUrl& download_url); void DownloadNext(); void DownloadProgress(qint64 bytesReceived, qint64 bytesTotal); void DownloadReadyToRead(); void Downloaded(); -private: + private: struct DownloadItem { QString filename; QUrl url; - bool operator ==(const DownloadItem& rhv) { + bool operator==(const DownloadItem& rhv) { return filename == rhv.filename; } }; @@ -63,9 +62,10 @@ private: Application* app_; VkService* service_; QList queue_; - // Contain index of current song in queue, need for removing if song was skipped. - // Is zero if song downloading now, and less that zero if current song not caching or cached. - int current_cashing_index; + // Contain index of current song in queue, need for removing if song was + // skipped. It's zero if song downloading now, and less that zero + // if current song not caching or cached. + int current_song_index; DownloadItem current_download; bool is_downloading; bool is_aborted; diff --git a/src/internet/vkservice.cpp b/src/internet/vkservice.cpp index 286eb12c7..1a256b2a9 100644 --- a/src/internet/vkservice.cpp +++ b/src/internet/vkservice.cpp @@ -312,7 +312,7 @@ void VkService::EnsureMenuCreated() { add_song_to_cache_ = context_menu_->addAction(QIcon(":vk/download.png"), tr("Add song to cache"), this, - SLOT(AddToCache())); + SLOT(AddSelectedToCache())); copy_share_url_ = context_menu_->addAction( QIcon(":vk/link.png"), tr("Copy share url to clipboard"), this, @@ -367,7 +367,7 @@ void VkService::ShowContextMenu(const QPoint& global_pos) { current.data(InternetModel::Role_SongMetadata).value(); is_in_mymusic = is_my_music_item || ExtractIds(selected_song_.url()).owner_id == UserID(); - is_cached = cache()->InCache(selected_song_.url()); + is_cached = cache_->InCache(selected_song_.url()); } update_item_->setVisible(is_updatable); @@ -443,7 +443,7 @@ QList VkService::playlistitem_actions(const Song& song) { copy_share_url_->setVisible(true); actions << copy_share_url_; - if (!cache()->InCache(selected_song_.url())) { + if (!cache_->InCache(selected_song_.url())) { add_song_to_cache_->setVisible(true); actions << add_song_to_cache_; } @@ -835,7 +835,7 @@ void VkService::AddToMyMusic() { } void VkService::AddToMyMusicCurrent() { - if (isLoveAddToMyMusic()) { + if (isLoveAddToMyMusic() && current_song_.is_valid()) { selected_song_ = current_song_; AddToMyMusic(); } @@ -852,8 +852,10 @@ void VkService::RemoveFromMyMusic() { } } -void VkService::AddToCache() { - url_handler_->ForceAddToCache(selected_song_.url()); +void VkService::AddSelectedToCache() { + QUrl selected_song_media_url = + GetAudioItemFromUrl(selected_song_.url()).url(); + cache_->AddToCache(selected_song_.url(), selected_song_media_url, true); } void VkService::CopyShareUrl() { @@ -999,12 +1001,12 @@ SongList VkService::FromAudioList(const Vreen::AudioItemList& list) { * Url handling */ -QUrl VkService::GetSongPlayUrl(const QUrl& url, bool is_playing) { +Vreen::AudioItem VkService::GetAudioItemFromUrl(const QUrl& url) { QStringList tokens = url.path().split('/'); if (tokens.count() < 2) { qLog(Error) << "Wrong song url" << url; - return QUrl(); + return Vreen::AudioItem(); } QString song_id = tokens[1]; @@ -1016,17 +1018,35 @@ QUrl VkService::GetSongPlayUrl(const QUrl& url, bool is_playing) { bool success = WaitForReply(song_request); if (success && !song_request->result().isEmpty()) { - Vreen::AudioItem song = song_request->result()[0]; - if (is_playing) { - current_song_ = FromAudioItem(song); - current_song_.set_url(url); - } - return song.url(); + return song_request->result()[0]; } } qLog(Info) << "Unresolved url by id" << song_id; - return QUrl(); + return Vreen::AudioItem(); +} + +UrlHandler::LoadResult VkService::GetSongResult(const QUrl& url) { + // Try get from cache + QUrl media_url = cache_->Get(url); + if (media_url.isValid()) { + SongStarting(url); + return UrlHandler::LoadResult(url, UrlHandler::LoadResult::TrackAvailable, + media_url); + } + + // Otherwise get fresh link + auto audio_item = GetAudioItemFromUrl(url); + media_url = audio_item.url(); + if (media_url.isValid()) { + Song song = FromAudioItem(audio_item); + SongStarting(song); + cache_->AddToCache(url, media_url); + return UrlHandler::LoadResult(url, UrlHandler::LoadResult::TrackAvailable, + media_url, song.length_nanosec()); + } + + return UrlHandler::LoadResult(); } UrlHandler::LoadResult VkService::GetGroupNextSongUrl(const QUrl& url) { @@ -1054,7 +1074,7 @@ UrlHandler::LoadResult VkService::GetGroupNextSongUrl(const QUrl& url) { if (success && !song_request->result().isEmpty()) { Vreen::AudioItem song = song_request->result()[0]; current_group_url_ = url; - current_song_ = FromAudioItem(song); + SongStarting(FromAudioItem(song)); emit StreamMetadataFound(url, current_song_); return UrlHandler::LoadResult(url, UrlHandler::LoadResult::TrackAvailable, song.url(), current_song_.length_nanosec()); @@ -1065,8 +1085,48 @@ UrlHandler::LoadResult VkService::GetGroupNextSongUrl(const QUrl& url) { return UrlHandler::LoadResult(); } -void VkService::SetCurrentSongFromUrl(const QUrl& url) { - current_song_ = SongFromUrl(url); +/*** + * Song playing + */ + +void VkService::SongStarting(const QUrl& url) { + SongStarting(SongFromUrl(url)); +} + +void VkService::SongStarting(const Song& song) { + current_song_ = song; + + if (isBroadcasting() && HasAccount()) { + auto id = ExtractIds(song.url()); + auto reply = + audio_provider_->setBroadcast(id.audio_id, id.owner_id, IdList()); + NewClosure(reply, SIGNAL(resultReady(QVariant)), this, + SLOT(BroadcastChangeReceived(Vreen::IntReply*)), reply); + connect(app_->player(), SIGNAL(Stopped()), this, SLOT(SongStopped()), + Qt::UniqueConnection); + qLog(Debug) << "Broadcasting" << song.artist() << "-" << song.title(); + } +} + +void VkService::SongSkipped() { + current_song_.set_valid(false); + cache_->BreakCurrentCaching(); +} + +void VkService::SongStopped() { + current_song_.set_valid(false); + + if (isBroadcasting() && HasAccount()) { + auto reply = audio_provider_->resetBroadcast(IdList()); + NewClosure(reply, SIGNAL(resultReady(QVariant)), this, + SLOT(BroadcastChangeReceived(Vreen::IntReply*)), reply); + disconnect(app_->player(), SIGNAL(Stopped()), this, SLOT(SongStopped())); + qLog(Debug) << "End of broadcasting"; + } +} + +void VkService::BroadcastChangeReceived(Vreen::IntReply* reply) { + qLog(Debug) << "Broadcast changed for " << reply->result(); } /*** @@ -1234,6 +1294,12 @@ void VkService::ReloadSettings() { cacheFilename_ = s.value("cache_filename", kDefCacheFilename).toString(); love_is_add_to_mymusic_ = s.value("love_is_add_to_my_music", false).toBool(); groups_in_global_search_ = s.value("groups_in_global_search", false).toBool(); + + if (!s.contains("enable_broadcast")) { + // Need to update premissions + Logout(); + } + enable_broadcast_ = s.value("enable_broadcast", false).toBool(); } void VkService::ClearStandardItem(QStandardItem* item) { diff --git a/src/internet/vkservice.h b/src/internet/vkservice.h index 80bd9f6b6..82daa7b14 100644 --- a/src/internet/vkservice.h +++ b/src/internet/vkservice.h @@ -44,11 +44,8 @@ class VkSearchDialog; * using in bookmarks. */ class MusicOwner { -public: - MusicOwner() : - songs_count_(0), - id_(0) - {} + public: + MusicOwner() : songs_count_(0), id_(0) {} explicit MusicOwner(const QUrl& group_url); Song toOwnerRadio() const; @@ -58,7 +55,7 @@ public: int song_count() const { return songs_count_; } static QList parseMusicOwnerList(const QVariant& request_result); -private: + private: friend QDataStream& operator<<(QDataStream& stream, const MusicOwner& val); friend QDataStream& operator>>(QDataStream& stream, MusicOwner& val); friend QDebug operator<<(QDebug d, const MusicOwner& owner); @@ -66,7 +63,8 @@ private: int songs_count_; int id_; // if id > 0 is user otherwise id group QString name_; - // name used in url http://vk.com/ for example: http://vk.com/shedward + // name used in url http://vk.com/ for example: + // http://vk.com/shedward QString screen_name_; QUrl photo_; }; @@ -84,20 +82,13 @@ QDebug operator<<(QDebug d, const MusicOwner& owner); * how to react to the received request or quickly skip unwanted. */ struct SearchID { - enum Type { - GlobalSearch, - LocalSearch, - MoreLocalSearch, - UserOrGroup - }; + enum Type { GlobalSearch, LocalSearch, MoreLocalSearch, UserOrGroup }; - explicit SearchID(Type type) - : type_(type) { - id_= last_id_++; - } + explicit SearchID(Type type) : type_(type) { id_ = last_id_++; } int id() const { return id_; } Type type() const { return type_; } -private: + + private: static uint last_id_; int id_; Type type_; @@ -109,7 +100,7 @@ private: class VkService : public InternetService { Q_OBJECT -public: + public: explicit VkService(Application* app, InternetModel* parent); ~VkService(); @@ -133,8 +124,12 @@ public: Type_Search }; - enum Role { Role_MusicOwnerMetadata = InternetModel::RoleCount, - Role_AlbumMetadata }; + enum Role { + Role_MusicOwnerMetadata = InternetModel::RoleCount, + Role_AlbumMetadata + }; + + Application* app() const { return app_; } /* InternetService interface */ QStandardItem* CreateRootItem(); @@ -155,13 +150,16 @@ public: bool WaitForReply(Vreen::Reply* reply); /* Music */ - VkMusicCache* cache() const { return cache_; } - void SetCurrentSongFromUrl(const QUrl& url); // Used if song taked from cache. - QUrl GetSongPlayUrl(const QUrl& url, bool is_playing = true); + void SongStarting(const Song& song); + void SongStarting(const QUrl& url); // Used if song taked from cache. + void SongSkipped(); + UrlHandler::LoadResult GetSongResult(const QUrl& url); + Vreen::AudioItem GetAudioItemFromUrl(const QUrl& url); // Return random song result from group playlist. UrlHandler::LoadResult GetGroupNextSongUrl(const QUrl& url); - void SongSearch(SearchID id, const QString& query, int count = 50, int offset = 0); + void SongSearch(SearchID id, const QString& query, int count = 50, + int offset = 0); void GroupSearch(SearchID id, const QString& query); /* Settings */ @@ -169,6 +167,7 @@ public: int maxGlobalSearch() const { return maxGlobalSearch_; } bool isCachingEnabled() const { return cachingEnabled_; } bool isGroupsInGlobalSearch() const { return groups_in_global_search_; } + bool isBroadcasting() const { return enable_broadcast_; } QString cacheDir() const { return cacheDir_; } QString cacheFilename() const { return cacheFilename_; } bool isLoveAddToMyMusic() const { return love_is_add_to_mymusic_; } @@ -179,15 +178,16 @@ signals: void LoginSuccess(bool success); void SongSearchResult(const SearchID& id, const SongList& songs); void GroupSearchResult(const SearchID& id, const MusicOwnerList& groups); - void UserOrGroupSearchResult(const SearchID& id, const MusicOwnerList& owners); + void UserOrGroupSearchResult(const SearchID& id, + const MusicOwnerList& owners); void StopWaiting(); -public slots: + public slots: void UpdateRoot(); void ShowConfig(); void FindUserOrGroup(const QString& q); -private slots: + private slots: /* Interface */ void UpdateItem(); @@ -197,6 +197,7 @@ private slots: void Error(Vreen::Client::Error error); /* Music */ + void SongStopped(); void UpdateMyMusic(); void UpdateBookmarkSongs(QStandardItem* item); void UpdateAlbumSongs(QStandardItem* item); @@ -208,7 +209,7 @@ private slots: void AddToMyMusic(); void AddToMyMusicCurrent(); void RemoveFromMyMusic(); - void AddToCache(); + void AddSelectedToCache(); void CopyShareUrl(); void ShowSearchDialog(); @@ -219,14 +220,16 @@ private slots: void GroupSearchReceived(const SearchID& id, Vreen::Reply* reply); void UserOrGroupReceived(const SearchID& id, Vreen::Reply* reply); void AlbumListReceived(Vreen::AudioAlbumItemListReply* reply); + void BroadcastChangeReceived(Vreen::IntReply* reply); void AppendLoadedSongs(QStandardItem* item, Vreen::AudioItemListReply* reply); void RecommendationsLoaded(Vreen::AudioItemListReply* reply); void SearchResultLoaded(const SearchID& id, const SongList& songs); -private: + private: /* Interface */ - QStandardItem* CreateAndAppendRow(QStandardItem* parent, VkService::ItemType type); + QStandardItem* CreateAndAppendRow(QStandardItem* parent, + VkService::ItemType type); void ClearStandardItem(QStandardItem* item); QStandardItem* GetBookmarkItemById(int id); void EnsureMenuCreated(); @@ -279,7 +282,7 @@ private: uint last_search_id_; QString last_query_; Song selected_song_; // Store for context menu actions. - Song current_song_; // Store for actions with now playing song. + Song current_song_; // Store for actions with now playing song. // Store current group url for actions with it. QUrl current_group_url_; @@ -288,6 +291,7 @@ private: bool cachingEnabled_; bool love_is_add_to_mymusic_; bool groups_in_global_search_; + bool enable_broadcast_; QString cacheDir_; QString cacheFilename_; }; diff --git a/src/internet/vksettingspage.cpp b/src/internet/vksettingspage.cpp index 7cc27e81b..2d48a1d9a 100644 --- a/src/internet/vksettingspage.cpp +++ b/src/internet/vksettingspage.cpp @@ -25,32 +25,29 @@ #include "core/logging.h" #include "internet/vkservice.h" -VkSettingsPage::VkSettingsPage(SettingsDialog *parent) - : SettingsPage(parent), - ui_(new Ui::VkSettingsPage), - service_(dialog()->app()->internet_model()->Service()) { +VkSettingsPage::VkSettingsPage(SettingsDialog* parent) + : SettingsPage(parent), + ui_(new Ui::VkSettingsPage), + service_(dialog()->app()->internet_model()->Service()) { ui_->setupUi(this); - connect(service_, SIGNAL(LoginSuccess(bool)), - SLOT(LoginSuccess(bool))); - connect(ui_->choose_path, SIGNAL(clicked()), - SLOT(CacheDirBrowse())); - connect(ui_->reset, SIGNAL(clicked()), - SLOT(ResetCasheFilenames())); + connect(service_, SIGNAL(LoginSuccess(bool)), SLOT(LoginSuccess(bool))); + connect(ui_->choose_path, SIGNAL(clicked()), SLOT(CacheDirBrowse())); + connect(ui_->reset, SIGNAL(clicked()), SLOT(ResetCasheFilenames())); } -VkSettingsPage::~VkSettingsPage() { - delete ui_; -} +VkSettingsPage::~VkSettingsPage() { delete ui_; } void VkSettingsPage::Load() { service_->ReloadSettings(); - ui_->maxGlobalSearch->setValue(service_->maxGlobalSearch()); + ui_->max_global_search->setValue(service_->maxGlobalSearch()); ui_->enable_caching->setChecked(service_->isCachingEnabled()); ui_->cache_dir->setText(service_->cacheDir()); ui_->cache_filename->setText(service_->cacheFilename()); - ui_->love_button_is_add_to_mymusic->setChecked(service_->isLoveAddToMyMusic()); + ui_->love_button_is_add_to_mymusic->setChecked( + service_->isLoveAddToMyMusic()); ui_->groups_in_global_search->setChecked(service_->isGroupsInGlobalSearch()); + ui_->enable_broadcast->setChecked(service_->isBroadcasting()); if (service_->HasAccount()) { LogoutWidgets(); @@ -63,12 +60,15 @@ void VkSettingsPage::Save() { QSettings s; s.beginGroup(VkService::kSettingGroup); - s.setValue("max_global_search", ui_->maxGlobalSearch->value()); + s.setValue("max_global_search", ui_->max_global_search->value()); s.setValue("cache_enabled", ui_->enable_caching->isChecked()); s.setValue("cache_dir", ui_->cache_dir->text()); s.setValue("cache_filename", ui_->cache_filename->text()); - s.setValue("love_is_add_to_my_music", ui_->love_button_is_add_to_mymusic->isChecked()); - s.setValue("groups_in_global_search", ui_->groups_in_global_search->isChecked()); + s.setValue("love_is_add_to_my_music", + ui_->love_button_is_add_to_mymusic->isChecked()); + s.setValue("groups_in_global_search", + ui_->groups_in_global_search->isChecked()); + s.setValue("enable_broadcast", ui_->enable_broadcast->isChecked()); service_->ReloadSettings(); } @@ -94,7 +94,7 @@ void VkSettingsPage::Logout() { void VkSettingsPage::CacheDirBrowse() { QString directory = QFileDialog::getExistingDirectory( - this, tr("Choose Vk.com cache directory"), ui_->cache_dir->text()); + this, tr("Choose Vk.com cache directory"), ui_->cache_dir->text()); if (directory.isEmpty()) { return; } @@ -111,10 +111,9 @@ void VkSettingsPage::LoginWidgets() { ui_->name->setText(""); ui_->login_button->setEnabled(true); - connect(ui_->login_button, SIGNAL(clicked()), - SLOT(Login()), Qt::UniqueConnection); - disconnect(ui_->login_button, SIGNAL(clicked()), - this, SLOT(Logout())); + connect(ui_->login_button, SIGNAL(clicked()), SLOT(Login()), + Qt::UniqueConnection); + disconnect(ui_->login_button, SIGNAL(clicked()), this, SLOT(Logout())); } void VkSettingsPage::LogoutWidgets() { @@ -122,12 +121,11 @@ void VkSettingsPage::LogoutWidgets() { ui_->name->setText(tr("Loading...")); ui_->login_button->setEnabled(true); - connect(service_, SIGNAL(NameUpdated(QString)), - ui_->name, SLOT(setText(QString)), Qt::UniqueConnection); + connect(service_, SIGNAL(NameUpdated(QString)), ui_->name, + SLOT(setText(QString)), Qt::UniqueConnection); service_->RequestUserProfile(); - connect(ui_->login_button, SIGNAL(clicked()), - SLOT(Logout()), Qt::UniqueConnection); - disconnect(ui_->login_button, SIGNAL(clicked()), - this, SLOT(Login())); + connect(ui_->login_button, SIGNAL(clicked()), SLOT(Logout()), + Qt::UniqueConnection); + disconnect(ui_->login_button, SIGNAL(clicked()), this, SLOT(Login())); } diff --git a/src/internet/vksettingspage.ui b/src/internet/vksettingspage.ui index 29d251c4c..abc500411 100644 --- a/src/internet/vksettingspage.ui +++ b/src/internet/vksettingspage.ui @@ -64,12 +64,12 @@ Max global search results - maxGlobalSearch + max_global_search - + 50 @@ -110,6 +110,13 @@ + + + + Show playing song on your page + + + diff --git a/src/internet/vkurlhandler.cpp b/src/internet/vkurlhandler.cpp index 9d4872cf3..5368897d2 100644 --- a/src/internet/vkurlhandler.cpp +++ b/src/internet/vkurlhandler.cpp @@ -19,45 +19,39 @@ #include "core/application.h" #include "core/logging.h" +#include "core/player.h" #include "vkservice.h" #include "vkmusiccache.h" VkUrlHandler::VkUrlHandler(VkService* service, QObject* parent) - : UrlHandler(parent), - service_(service) { -} + : UrlHandler(parent), service_(service) {} UrlHandler::LoadResult VkUrlHandler::StartLoading(const QUrl& url) { QStringList args = url.path().split("/"); LoadResult result; if (args.size() < 2) { - qLog(Error) << "Invalid Vk.com URL: " << url - << "Url format should be vk:///." - << "For example vk://song/61145020_166946521/Daughtry/Gone Too Soon"; + qLog(Error) + << "Invalid Vk.com URL: " << url + << "Url format should be vk:///." + << "For example vk://song/61145020_166946521/Daughtry/Gone Too Soon"; } else { QString action = url.host(); if (action == "song") { - service_->SetCurrentSongFromUrl(url); - result = LoadResult(url, LoadResult::TrackAvailable, service_->cache()->Get(url)); + result = service_->GetSongResult(url); } else if (action == "group") { result = service_->GetGroupNextSongUrl(url); } else { qLog(Error) << "Invalid vk.com url action:" << action; } } + return result; } -void VkUrlHandler::TrackSkipped() { - service_->cache()->BreakCurrentCaching(); -} - -void VkUrlHandler::ForceAddToCache(const QUrl& url) { - service_->cache()->ForceCache(url); -} +void VkUrlHandler::TrackSkipped() { service_->SongSkipped(); } UrlHandler::LoadResult VkUrlHandler::LoadNext(const QUrl& url) { if (url.host() == "group") { diff --git a/src/internet/vkurlhandler.h b/src/internet/vkurlhandler.h index 30b9c6d39..e25d25d26 100644 --- a/src/internet/vkurlhandler.h +++ b/src/internet/vkurlhandler.h @@ -28,16 +28,15 @@ class VkMusicCache; class VkUrlHandler : public UrlHandler { Q_OBJECT -public: + public: VkUrlHandler(VkService* service, QObject* parent); QString scheme() const { return "vk"; } QIcon icon() const { return QIcon(":providers/vk.png"); } LoadResult StartLoading(const QUrl& url); void TrackSkipped(); - void ForceAddToCache(const QUrl& url); LoadResult LoadNext(const QUrl& url); -private: + private: VkService* service_; };