Commit a587df64 authored by Camilo Higuita's avatar Camilo Higuita

youtube integration... own view table to search tracks and collect them using...

youtube integration... own view table to search tracks and collect them using youtube-dl all form the babe interface
parent 9fc4ad61
...@@ -7,7 +7,7 @@ QT += network ...@@ -7,7 +7,7 @@ QT += network
QT += xml QT += xml
QT += qml QT += qml
QT += quickcontrols2 QT += quickcontrols2
QT += webkit
TARGET = babe TARGET = babe
TEMPLATE = app TEMPLATE = app
...@@ -16,6 +16,7 @@ CONFIG += c++11 ...@@ -16,6 +16,7 @@ CONFIG += c++11
linux:unix:!android { linux:unix:!android {
QT += webkit
message(Building for Linux KDE) message(Building for Linux KDE)
include(kde/kde.pri) include(kde/kde.pri)
......
android { android {
QT += androidextras QT += androidextras webview
HEADERS += \ HEADERS += \
$$PWD/android.h \ $$PWD/android.h \
......
...@@ -378,6 +378,11 @@ void Babe::refreshCollection() ...@@ -378,6 +378,11 @@ void Babe::refreshCollection()
this->settings->refreshCollection(); this->settings->refreshCollection();
} }
void Babe::getYoutubeTrack(const QString &message)
{
this->settings->fetchYoutubeTrack(message);
}
QVariant Babe::loadSetting(const QString &key, const QString &group, const QVariant &defaultValue) QVariant Babe::loadSetting(const QString &key, const QString &group, const QVariant &defaultValue)
{ {
return BAE::loadSettings(key, group, defaultValue); return BAE::loadSettings(key, group, defaultValue);
......
...@@ -59,6 +59,7 @@ public: ...@@ -59,6 +59,7 @@ public:
Q_INVOKABLE void brainz(const bool &on); Q_INVOKABLE void brainz(const bool &on);
Q_INVOKABLE bool brainzState(); Q_INVOKABLE bool brainzState();
Q_INVOKABLE void refreshCollection(); Q_INVOKABLE void refreshCollection();
Q_INVOKABLE void getYoutubeTrack(const QString &message);
/* STATIC METHODS */ /* STATIC METHODS */
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <QStyleHints> #include <QStyleHints>
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
#include "./3rdparty/kirigami/src/kirigamiplugin.h" #include "./3rdparty/kirigami/src/kirigamiplugin.h"
#include <QtWebView/QtWebView>
//#include "java/notificationclient.h" //#include "java/notificationclient.h"
#endif #endif
...@@ -74,6 +75,7 @@ int main(int argc, char *argv[]) ...@@ -74,6 +75,7 @@ int main(int argc, char *argv[])
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
KirigamiPlugin::getInstance().registerTypes(); KirigamiPlugin::getInstance().registerTypes();
QtWebView::initialize();
#else #else
QQuickStyle::setStyle("nomad"); QQuickStyle::setStyle("nomad");
#endif #endif
......
...@@ -240,6 +240,12 @@ Kirigami.ApplicationWindow ...@@ -240,6 +240,12 @@ Kirigami.ApplicationWindow
currentView = viewsIndex.search currentView = viewsIndex.search
searchView.searchInput.forceActiveFocus() searchView.searchInput.forceActiveFocus()
} }
onYoutubeViewClicked:
{
pageStack.currentIndex = 1
currentView = viewsIndex.youtube
}
} }
footer: Item footer: Item
...@@ -758,11 +764,16 @@ Kirigami.ApplicationWindow ...@@ -758,11 +764,16 @@ Kirigami.ApplicationWindow
} }
} }
YouTube Loader
{ {
id: youtubeView id: youtubeView
source: isMobile ? "qrc:/services/web/YouTube-A.qml" : "qrc:/services/web/YouTube.qml"
} }
} }
} }
} }
...@@ -828,15 +839,7 @@ Kirigami.ApplicationWindow ...@@ -828,15 +839,7 @@ Kirigami.ApplicationWindow
/*CONNECTIONS*/ /*CONNECTIONS*/
Connections
{
target: youtube
onQueryResultsReady:
{
if(res.length > 0)
youtubeView.web.url= res[0].url
}
}
Connections Connections
{ {
......
...@@ -73,5 +73,6 @@ ...@@ -73,5 +73,6 @@
<file>widgets/SearchView/SearchTable.qml</file> <file>widgets/SearchView/SearchTable.qml</file>
<file>widgets/SearchView/SearchSuggestions.qml</file> <file>widgets/SearchView/SearchSuggestions.qml</file>
<file>services/web/YouTube.qml</file> <file>services/web/YouTube.qml</file>
<file>services/web/YouTube-A.qml</file>
</qresource> </qresource>
</RCC> </RCC>
import QtQuick 2.9
import QtWebView 1.1
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import "../../view_models"
Page
{
property alias web : webView
WebView
{
id: webView
anchors.fill: parent
onLoadingChanged: {
if (loadRequest.errorString)
console.error(loadRequest.errorString);
}
}
}
...@@ -3,17 +3,170 @@ import QtWebKit 3.0 ...@@ -3,17 +3,170 @@ import QtWebKit 3.0
import QtQuick.Controls 2.2 import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import "../../view_models" import "../../view_models"
import "../../view_models/BabeTable"
import org.kde.kirigami 2.2 as Kirigami
Page Page
{ {
id: youtubeViewRoot
property alias web : webView property alias web : webView
WebView property var searchRes : []
clip: true
Connections
{
target: youtube
onQueryResultsReady:
{
searchRes = res;
populate(searchRes)
youtubeTable.forceActiveFocus()
}
}
BabePopup
{
id: videoPlayback
WebView
{
id: webView
anchors.fill: parent
onLoadingChanged: {
if (loadRequest.errorString)
console.error(loadRequest.errorString);
}
}
}
function runSearch(searchTxt)
{
if(searchTxt)
if(searchTxt !== youtubeTable.headerBarTitle)
{
youtubeTable.headerBarTitle = searchTxt
youtube.getQuery(searchTxt)
}
}
function clearSearch()
{
searchInput.clear()
youtubeTable.clearTable()
youtubeTable.headerBarTitle = ""
searchRes = []
}
function populate(tracks)
{
youtubeTable.clearTable()
for(var i in tracks)
youtubeTable.model.append(tracks[i])
}
ColumnLayout
{ {
id: webView
anchors.fill: parent anchors.fill: parent
onLoadingChanged: { width: parent.width
if (loadRequest.errorString) height: parent.height
console.error(loadRequest.errorString);
Layout.margins: 0
spacing: 0
BabeTable
{
id: youtubeTable
Layout.fillHeight: true
Layout.fillWidth: true
trackNumberVisible: false
headerBarVisible: true
headerBarExit: true
headerBarExitIcon: "edit-clear"
holder.message: "No YouTube results!"
coverArtVisible: true
trackDuration: true
trackRating: true
onExit: clearSearch()
isArtworkRemote: true
appendBtn.visible: false
playAllBtn.visible: false
menuBtn.visible: false
headerBarRight: BabeButton
{
id: menuBtn
iconName: "application-menu"
}
onRowClicked:
{
videoPlayback.open()
webView.url= youtubeTable.model.get(index).url
}
onQuickPlayTrack:
{
bae.getYoutubeTrack(JSON.stringify(youtubeTable.model.get(index)))
}
}
Kirigami.Separator
{
visible: !isMobile
Layout.fillWidth: true
width: parent.width
height: 1
}
ToolBar
{
id: searchBox
Layout.fillWidth: true
width: parent.width
height: toolBarHeight
position: ToolBar.Footer
Rectangle
{
anchors.fill: parent
z: -999
color: backgroundColor
}
RowLayout
{
anchors.fill: parent
TextInput
{
id: searchInput
color: foregroundColor
Layout.fillWidth: true
Layout.fillHeight: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
selectByMouse: !root.isMobile
selectionColor: babeHighlightColor
selectedTextColor: foregroundColor
focus: true
text: ""
wrapMode: TextEdit.Wrap
onAccepted: runSearch(searchInput.text)
}
BabeButton
{
Layout.rightMargin: contentMargins
iconName: "edit-clear"
onClicked: searchInput.clear()
}
}
} }
} }
} }
...@@ -45,7 +45,7 @@ bool YouTube::getQuery(const QString &query) ...@@ -45,7 +45,7 @@ bool YouTube::getQuery(const QString &query)
auto url = this->API[METHOD::SEARCH]; auto url = this->API[METHOD::SEARCH];
url.append("q="+encodedQuery.toString()); url.append("q="+encodedQuery.toString());
url.append("&maxResults=5&part=snippet"); url.append("&maxResults=25&part=snippet");
url.append("&key="+this->KEY); url.append("&key="+this->KEY);
qDebug()<< url; qDebug()<< url;
...@@ -81,10 +81,43 @@ bool YouTube::packQueryResults(const QByteArray &array) ...@@ -81,10 +81,43 @@ bool YouTube::packQueryResults(const QByteArray &array)
auto id = itemMap.value("videoId").toString(); auto id = itemMap.value("videoId").toString();
auto url = "https://www.youtube.com/embed/"+id; auto url = "https://www.youtube.com/embed/"+id;
if(!url.isEmpty()) auto snippet = item.toMap().value("snippet").toMap();
auto comment = snippet.value("description").toString();
auto title = snippet.value("title").toString();
auto artwork = snippet.value("thumbnails").toMap().value("high").toMap().value("url").toString();
auto artist = BAE::SLANG[W::UNKNOWN];
auto album = BAE::SLANG[W::UNKNOWN];
if(title.contains("-"))
{ {
qDebug()<<url; auto data = title.split("-");
QVariantMap map = { {BAE::KEYMAP[BAE::KEY::ID], id}, {BAE::KEYMAP[BAE::KEY::URL], url} }; if(data.size() > 1)
{
artist = data[0].trimmed();
title = data[1].trimmed();
}
}
if(!id.isEmpty())
{
qDebug()<<url<<artwork;
QVariantMap map = {
{BAE::KEYMAP[BAE::KEY::ID], id},
{BAE::KEYMAP[BAE::KEY::URL], url},
{BAE::KEYMAP[BAE::KEY::TITLE], title},
{BAE::KEYMAP[BAE::KEY::ALBUM], album},
{BAE::KEYMAP[BAE::KEY::ARTIST], artist},
{BAE::KEYMAP[BAE::KEY::ARTWORK], artwork},
{BAE::KEYMAP[BAE::KEY::COMMENT], comment},
{BAE::KEYMAP[BAE::KEY::BABE], "0"},
{BAE::KEYMAP[BAE::KEY::STARS], "0"},
{BAE::KEYMAP[BAE::KEY::ART], ""},
{BAE::KEYMAP[BAE::KEY::TRACK], "0"}
};
res << map; res << map;
} }
} }
......
...@@ -66,7 +66,7 @@ BabeSettings::BabeSettings(QObject *parent) : QObject(parent) ...@@ -66,7 +66,7 @@ BabeSettings::BabeSettings(QObject *parent) : QObject(parent)
this->startBrainz(true, BAE::SEG::THREE); this->startBrainz(true, BAE::SEG::THREE);
}); });
connect(this->babeSocket, &Socket::message, this->ytFetch, &youtubedl::fetch); connect(this->babeSocket, &Socket::message, this, &BabeSettings::fetchYoutubeTrack);
connect(this->babeSocket, &Socket::connected, [this](const int &index) connect(this->babeSocket, &Socket::connected, [this](const int &index)
{ {
auto playlists = this->connection->getPlaylists(); auto playlists = this->connection->getPlaylists();
...@@ -116,6 +116,11 @@ void BabeSettings::refreshCollection() ...@@ -116,6 +116,11 @@ void BabeSettings::refreshCollection()
this->populateDB(this->connection->getSourcesFolders()); this->populateDB(this->connection->getSourcesFolders());
} }
void BabeSettings::fetchYoutubeTrack(const QString &message)
{
this->ytFetch->fetch(message);
}
void BabeSettings::checkCollectionBrainz(const bool &state) void BabeSettings::checkCollectionBrainz(const bool &state)
{ {
bDebug::Instance()->msg("BRAINZ STATE<<"+state); bDebug::Instance()->msg("BRAINZ STATE<<"+state);
......
...@@ -33,6 +33,7 @@ public: ...@@ -33,6 +33,7 @@ public:
~BabeSettings(); ~BabeSettings();
void checkCollectionBrainz(const bool &state); void checkCollectionBrainz(const bool &state);
void refreshCollection(); void refreshCollection();
void fetchYoutubeTrack(const QString &message);
public slots: public slots:
void startBrainz(const bool &on, const uint &speed = BAE::SEG::THREE); void startBrainz(const bool &on, const uint &speed = BAE::SEG::THREE);
......
...@@ -23,7 +23,11 @@ BabeList ...@@ -23,7 +23,11 @@ BabeList
property alias headerMenu: headerMenu property alias headerMenu: headerMenu
property alias contextMenu : contextMenu property alias contextMenu : contextMenu
property bool isArtworkRemote : false
property alias playAllBtn : playAllBtn
property alias appendBtn : appendBtn
property alias menuBtn : menuBtn
signal rowClicked(int index) signal rowClicked(int index)
signal rowPressed(int index) signal rowPressed(int index)
...@@ -98,7 +102,7 @@ BabeList ...@@ -98,7 +102,7 @@ BabeList
menuItem: menuItemVisible menuItem: menuItemVisible
color: babeTableRoot.textColor color: babeTableRoot.textColor
bgColor: headerBarColor bgColor: headerBarColor
remoteArtwork: isArtworkRemote
Connections Connections
{ {
target: delegate target: delegate
......
...@@ -15,6 +15,7 @@ BabeMenu ...@@ -15,6 +15,7 @@ BabeMenu
property alias menuItem: babeMenu.children property alias menuItem: babeMenu.children
Column Column
{ {
id: babeMenu id: babeMenu
......
...@@ -48,6 +48,7 @@ ItemDelegate ...@@ -48,6 +48,7 @@ ItemDelegate
property string trackMood : art property string trackMood : art
property alias trackRating : trackRating property alias trackRating : trackRating
property bool remoteArtwork: false
// NumberAnimation on x // NumberAnimation on x
// { // {
// running: ListView.isCurrentItem // running: ListView.isCurrentItem
...@@ -110,14 +111,15 @@ ItemDelegate ...@@ -110,14 +111,15 @@ ItemDelegate
id: artworkCover id: artworkCover
anchors.fill: parent anchors.fill: parent
source: typeof artwork === 'undefined' ? source: typeof artwork === 'undefined' ?
"qrc:/assets/cover.png" : "qrc:/assets/cover.png" :
(artwork && artwork.length > 0 && artwork !== "NONE")? "file://"+encodeURIComponent(artwork) : "qrc:/assets/cover.png" remoteArtwork ? artwork :
((artwork && artwork.length > 0 && artwork !== "NONE")? "file://"+encodeURIComponent(artwork) : "qrc:/assets/cover.png")
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
cache: false cache: false
antialiasing: false antialiasing: false
smooth: true smooth: true
} }
onDoubleClicked: artworkCoverDoubleClicked() onDoubleClicked: artworkCoverDoubleClicked()
...@@ -347,5 +349,5 @@ ItemDelegate ...@@ -347,5 +349,5 @@ ItemDelegate
// onClicked: rightClicked() // onClicked: rightClicked()
// } // }
// } // }
} }
} }
...@@ -195,6 +195,30 @@ ToolBar ...@@ -195,6 +195,30 @@ ToolBar
} }
} }
Item
{
Layout.fillHeight: true
Layout.fillWidth: true
Layout.maximumWidth: toolBarIconSize*2
Layout.maximumHeight: toolBarIconSize
BabeButton
{
anchors.centerIn: parent
iconName: "im-youtube"
iconColor: accent && currentIndex === viewsIndex.youtube ? accentColor : textColor
onClicked: youtubeViewClicked()
hoverEnabled: !isMobile
ToolTip.delay: 1000
ToolTip.timeout: 5000
ToolTip.visible: hovered && !isMobile
ToolTip.text: qsTr("YouTube")
}
}
Item Item
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment