diff --git a/main.qml b/main.qml index 63b511f..15fa87d 100644 --- a/main.qml +++ b/main.qml @@ -1,1060 +1,1065 @@ import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import QtQuick.Controls.Material 2.1 import "utils" import "widgets" import "widgets/PlaylistsView" import "widgets/MainPlaylist" import "widgets/SettingsView" import "widgets/SearchView" //import "widgets/CloudView" import "view_models" import "view_models/BabeTable" import "services/local" import "services/web" //import "services/web/Spotify" import "view_models/BabeGrid" import "widgets/InfoView" import "db/Queries.js" as Q import "utils/Help.js" as H import "utils/Player.js" as Player import org.kde.kirigami 2.6 as Kirigami import org.kde.mauikit 1.0 as Maui -import FMList 1.0 import Player 1.0 import AlbumsList 1.0 import TracksList 1.0 import BaseModel 1.0 import TracksList 1.0 Maui.ApplicationWindow { id: root title: qsTr("vvave") /***************************************************/ /******************** ALIASES ********************/ /*************************************************/ property alias mainPlaylist: mainPlaylist property alias selectionBar: _selectionBar property alias progressBar: progressBar about.appIcon: "qrc:/assets/vvave.svg" about.appDescription: qsTr("VVAVE will handle your whole music collection by retreaving semantic information from the web. Just relax, enjoy and discover your new music ") showAccounts: false /***************************************************/ /******************** PLAYBACK ********************/ /*************************************************/ property bool isShuffle: Maui.FM.loadSettings("SHUFFLE","PLAYBACK", false) property var currentTrack: ({ fav: "0", stars: "0" }) property int currentTrackIndex: -1 property int prevTrackIndex: 0 property string currentArtwork: !mainlistEmpty ? mainPlaylist.list.get(0).artwork : "" property bool currentBabe: currentTrack.fav == "0" ? false : true property alias durationTimeLabel: player.duration property string progressTimeLabel: player.transformTime(player.position/1000) property alias isPlaying: player.playing property int onQueue: 0 property bool mainlistEmpty: !mainPlaylist.table.count > 0 /***************************************************/ /******************** HANDLERS ********************/ /*************************************************/ property int currentView: viewsIndex.tracks readonly property var viewsIndex: ({ tracks: 0, albums: 1, artists: 2, playlists: 3, search: 4, folders: 5, // cloud: 6, // vvave: 7, // linking: 8, youtube: 6, // spotify: 10 }) property string syncPlaylist: "" property bool sync: false property string infoMsg: "" property bool infoLabels: Maui.FM.loadSettings("LABELS", "PLAYBACK", false) == "true" ? true : false // property bool isLinked: false // property bool isServing: false // property bool focusMode : false property bool selectionMode : false /***************************************************/ /******************** UI COLORS *******************/ /*************************************************/ readonly property color babeColor: "#f84172" /*SIGNALS*/ signal missingAlert(var track) /*HANDLE EVENTS*/ onClosing: Player.savePlaylist() onMissingAlert: { var message = track.title + " by " + track.artist + " is missing" var messageBody = "Do you want to remove it from your collection?" notify("alert", message, messageBody, function () { // bae.removeTrack(currentTrack.url) //todo mainPlaylist.table.model.remove(mainPlaylist.table.currentIndex) }) } /*COMPONENTS*/ Player { id: player volume: 100 onFinishedChanged: if (!mainlistEmpty) { if (currentTrack.url) mainPlaylist.list.countUp(currentTrackIndex) Player.nextTrack() } } // BabeNotify // { // id: babeNotify //todo // } /* UI */ altToolBars: false accentColor: babeColor // headBarFGColor: altColorText // headBarBGColor: "#212121" // altColorText: darkTextColor floatingBar: false headBar.spacing: space.big headBar.middleContent : Kirigami.ActionToolBar { - display: ToolButton.TextUnderIcon - + display: isWide ? ToolButton.TextBesideIcon : ToolButton.TextUnderIcon +Layout.fillWidth: true hiddenActions: [ Kirigami.Action { text: qsTr("Folders") icon.name: "folder" checked: currentView === viewsIndex.folders checkable: false onTriggered: currentView = viewsIndex.folders }, Kirigami.Action { text: qsTr("YouTube") checkable: false icon.name: "internet-services" checked: currentView === viewsIndex.youtube onTriggered: currentView = viewsIndex.youtube } ] actions: [ Kirigami.Action { icon.name: "view-media-track" checked: currentView === viewsIndex.tracks // showIndicator: true // icon.color: active ? babeColor : altColorText onTriggered: currentView = viewsIndex.tracks text: qsTr("Tracks") checkable: false // colorScheme.highlightColor: babeColor // spacing: 0 }, Kirigami.Action { text: qsTr("Albums") checkable: false checked: currentView === viewsIndex.albums icon.name: /*"album"*/ "view-media-album-cover" // icon.color: currentView === viewsIndex.albums ? babeColor : altColorText onTriggered: currentView = viewsIndex.albums // colorScheme.highlightColor: babeColor // showIndicator: true + }, Kirigami.Action { + Layout.fillWidth: true + text: qsTr("Artists") checkable: false checked: currentView === viewsIndex.artists icon.name: "view-media-artist" Kirigami.Theme.textColor: currentView === viewsIndex.artists ? babeColor : altColorText onTriggered: currentView = viewsIndex.artists // colorScheme.highlightColor: babeColor // showIndicator: true }, Kirigami.Action { + Layout.fillWidth: true + text: qsTr("Playlists") checkable: false checked: currentView === viewsIndex.playlists icon.name: "view-media-playlist" // icon.color: currentView === viewsIndex.playlists ? babeColor : altColorText onTriggered: currentView = viewsIndex.playlists // colorScheme.highlightColor: babeColor // showIndicator: true } ] } footBar.visible: !mainlistEmpty footBar.implicitHeight: footBar.visible ? toolBarHeight * 1.2 : 0 page.footBarItem: ColumnLayout { id: _footerLayout height: footBar.height width: root.width spacing: 0 Slider { id: progressBar Layout.preferredHeight: unit * (isMobile ? 6 : 8) Layout.fillWidth: true padding: 0 from: 0 to: 1000 value: player.pos spacing: 0 focus: true onMoved: { player.pos = value } background: Rectangle { implicitWidth: progressBar.width implicitHeight: progressBar.height width: progressBar.availableWidth height: implicitHeight color: "transparent" Rectangle { width: progressBar.visualPosition * parent.width height: progressBar.height color: babeColor } } handle: Rectangle { x: progressBar.leftPadding + progressBar.visualPosition * (progressBar.availableWidth - width) y: -(progressBar.height * 0.8) implicitWidth: progressBar.pressed ? iconSizes.medium : 0 implicitHeight: progressBar.pressed ? iconSizes.medium : 0 radius: progressBar.pressed ? iconSizes.medium : 0 color: babeColor } } Kirigami.Separator { Layout.fillWidth: true color: borderColor } Maui.ToolBar { Layout.fillHeight: true Layout.fillWidth: true leftContent: Maui.ToolButton { iconName: "headphones" visible: _drawer.modal iconColor: _drawer.visible ? babeColor : textColor onClicked: _drawer.visible = !_drawer.visible colorScheme.highlightColor: babeColor // text: qsTr("Now") } middleContent: [ Maui.ToolButton { id: babeBtnIcon iconName: "love" iconColor: currentBabe ? babeColor : textColor onClicked: if (!mainlistEmpty) { mainPlaylist.list.fav(currentTrackIndex, !(mainPlaylist.list.get(currentTrackIndex).fav == "1")) currentBabe = mainPlaylist.list.get(currentTrackIndex).fav == "1" } }, Maui.ToolButton { iconName: "media-skip-backward" iconColor: textColor onClicked: Player.previousTrack() onPressAndHold: Player.playAt(prevTrackIndex) }, Maui.ToolButton { id: playIcon iconColor: textColor iconName: isPlaying ? "media-playback-pause" : "media-playback-start" onClicked: player.playing = !player.playing }, Maui.ToolButton { id: nextBtn iconColor: textColor iconName: "media-skip-forward" onClicked: Player.nextTrack() onPressAndHold: Player.playAt(Player.shuffle()) }, Maui.ToolButton { id: shuffleBtn iconColor: babeColor iconName: isShuffle ? "media-playlist-shuffle" : "media-playlist-normal" onClicked: { isShuffle = !isShuffle Maui.FM.saveSettings("SHUFFLE", isShuffle, "PLAYBACK") } } ] } } // leftIcon.iconColor: currentView === viewsIndex.search ? babeColor : altColorText onSearchButtonClicked: { currentView = viewsIndex.search searchView.searchInput.forceActiveFocus() } InfoView { id: infoView maxWidth: parent.width * 0.8 maxHeight: parent.height * 0.9 } Maui.ShareDialog { id: shareDialog } Maui.FileDialog { id: fmDialog } SourcesDialog { id: sourcesDialog } mainMenu: [ // Maui.MenuItem // { // text: "Vvave Stream" // icon.name: "headphones" // onTriggered: // { // pageStack.currentIndex = 1 // currentView = viewsIndex.vvave // } // }, // Maui.MenuItem // { // text: qsTr("Linking") // icon.name: "view-links" // onTriggered: // { // pageStack.currentIndex = 1 // currentView = viewsIndex.linking // if(!isLinked) linkingView.linkingConf.open() // } // }, // Maui.MenuItem // { // text: qsTr("Cloud") // icon.name: "folder-cloud" // onTriggered: // { // pageStack.currentIndex = 1 // currentView = viewsIndex.cloud // } // }, // Maui.MenuItem // { // text: qsTr("Spotify") // icon.name: "internet-services" // onTriggered: // { // pageStack.currentIndex = 1 // currentView = viewsIndex.spotify // } // }, MenuSeparator{}, MenuItem { text: qsTr("Sources...") icon.name: "folder-add" onTriggered: sourcesDialog.open() }, MenuItem { text: qsTr("Open...") icon.name: "folder-add" onTriggered: { fmDialog.onlyDirs = false - fmDialog.filterType = FMList.AUDIO + fmDialog.filterType = Maui.FMList.AUDIO fmDialog.show(function(paths) { vvave.openUrls(paths) }) } }/*, Menu { title: qsTr("Collection") // icon.name: "settings-configure" MenuItem { text: qsTr("Re-Scan") onTriggered: bae.refreshCollection(); } MenuItem { text: qsTr("Refresh...") onTriggered: H.refreshCollection(); } MenuItem { text: qsTr("Clean") onTriggered: bae.removeMissingTracks(); } }*/ // Maui.Menu // { // title: qsTr("Settings...") // // Kirigami.Action // // { // // text: "Brainz" // // Kirigami.Action // // { // // id: brainzToggle // // text: checked ? "Turn OFF" : "Turn ON" // // checked: bae.brainzState() // // checkable: true // // onToggled: // // { // // checked = !checked // // bae.saveSetting("AUTO", checked, "BRAINZ") // //// bae.brainz(checked) // // } // // } // // } // Maui.MenuItem // { // text: "Info label" + checked ? "ON" : "OFF" // checked: infoLabels // checkable: true // onToggled: // { // infoLabels = checked // bae.saveSetting("LABELS", infoLabels ? true : false, "PLAYBACK") // } // } // Maui.MenuItem // { // text: "Autoplay" // checked: autoplay // checkable: true // onToggled: // { // autoplay = checked // bae.saveSetting("AUTOPLAY", autoplay ? true : false, "BABE") // } // } // } ] Item { id: message visible: infoMsg.length && sync anchors.bottom: parent.bottom width: parent.width height: iconSize z: 999 Rectangle { id: infoBg anchors.fill: parent z: -999 color: altColor opacity: 0.8 SequentialAnimation { id: animBg PropertyAnimation { target: infoBg property: "color" easing.type: Easing.InOutQuad to: babeColor duration: 250 } PropertyAnimation { target: infoBg property: "color" easing.type: Easing.InOutQuad to: altColor duration: 500 } } } Label { id: infoTxt anchors.centerIn: parent anchors.fill: parent height: parent.height width: parent.width font.pointSize: fontSizes.medium text: infoMsg horizontalAlignment: Qt.AlignHCenter verticalAlignment: Qt.AlignVCenter color: textColor SequentialAnimation { id: animTxt PropertyAnimation { target: infoTxt property: "color" easing.type: Easing.InOutQuad to: "white" duration: 250 } PropertyAnimation { target: infoTxt property: "color" easing.type: Easing.InOutQuad to: textColor duration: 500 } } } } PlaylistDialog { id: playlistDialog } globalDrawer: Maui.GlobalDrawer { id: _drawer width: Kirigami.Units.gridUnit * 18 height: root.height - root.headBar.implicitHeight - root.footBar.implicitHeight modal: !isWide handleVisible: false closePolicy: Popup.NoAutoClose contentItem: MainPlaylist { id: mainPlaylist Connections { target: mainPlaylist onCoverPressed: Player.appendAll(tracks) onCoverDoubleClicked: Player.playAll(tracks) } } } ColumnLayout { anchors.fill: parent SwipeView { id: swipeView Layout.fillHeight: true Layout.fillWidth: true interactive: isMobile currentIndex: currentView onCurrentItemChanged: currentItem.forceActiveFocus() onCurrentIndexChanged: { currentView = currentIndex // if (!babeitView.isConnected && currentIndex === viewsIndex.vvave) // babeitView.logginDialog.open() } + TracksView { id: tracksView Connections { target: tracksView onRowClicked: Player.addTrack(tracksView.list.get(index)) onQuickPlayTrack: Player.quickPlay(tracksView.list.get(index)) onPlayAll: { var query = Q.GET.allTracks mainPlaylist.list.clear() mainPlaylist.list.query = query Player.playAll() } onAppendAll: { mainPlaylist.list.appendQuery(Q.GET.allTracks) mainPlaylist.listView.positionViewAtEnd() } onQueueTrack: Player.queueTracks([tracksView.list.get(index)], index) } } AlbumsView { id: albumsView holder.emoji: "qrc:/assets/MusicBox.png" holder.isMask: false holder.title : "No Albums!" holder.body: "Add new music sources" holder.emojiSize: iconSizes.huge headBarTitle: count + qsTr(" albums") list.query: Albums.ALBUMS list.sortBy: Albums.ALBUM Connections { target: albumsView onRowClicked: Player.addTrack(track) onPlayTrack: Player.quickPlay(track) onAlbumCoverClicked: albumsView.populateTable(album, artist) onAlbumCoverPressedAndHold: { var query = Q.GET.albumTracks_.arg(album) query = query.arg(artist) mainPlaylist.list.clear() mainPlaylist.list.sortBy = Tracks.NONE mainPlaylist.list.query = query Player.playAll() } onPlayAll: { var query = Q.GET.albumTracks_.arg(album) query = query.arg(artist) query = query.arg(data.artist) mainPlaylist.list.clear() mainPlaylist.list.query = query Player.playAll() } onAppendAll: { var query = Q.GET.albumTracks_.arg(album) query = query.arg(artist) mainPlaylist.list.appendQuery(query) mainPlaylist.listView.positionViewAtEnd() } } } AlbumsView { id: artistsView holder.emoji: "qrc:/assets/MusicBox.png" holder.isMask: false holder.title : qsTr("No Artists!") holder.body: qsTr("Add new music sources") holder.emojiSize: iconSizes.huge headBarTitle: count + qsTr(" artists") list.query: Albums.ARTISTS list.sortBy: Albums.ARTIST table.list.sortBy: Tracks.NONE Connections { target: artistsView onRowClicked: Player.addTrack(track) onPlayTrack: Player.quickPlay(track) onAlbumCoverClicked: artistsView.populateTable(undefined, artist) onAlbumCoverPressedAndHold: { var query = Q.GET.artistTracks_.arg(artist) mainPlaylist.list.clear() mainPlaylist.list.sortBy = Tracks.NONE mainPlaylist.list.query = query Player.playAll() } onPlayAll: { var query = Q.GET.artistTracks_.arg(artist) query = query.arg(data.artist) mainPlaylist.list.clear() mainPlaylist.list.sortBy = Tracks.NONE mainPlaylist.list.query = query Player.playAll() } onAppendAll: { var query = Q.GET.artistTracks_.arg(artist) mainPlaylist.list.appendQuery(query) mainPlaylist.listView.positionViewAtEnd() } } } PlaylistsView { id: playlistsView Connections { target: playlistsView onRowClicked: Player.addTrack(track) onQuickPlayTrack: Player.quickPlay(track) onPlayAll: { var query = playlistsView.playlistQuery mainPlaylist.list.clear() mainPlaylist.list.sortBy = Tracks.NONE mainPlaylist.list.query = query Player.playAll() } onAppendAll: { var query = playlistsView.playlistQuery mainPlaylist.list.appendQuery(query) mainPlaylist.listView.positionViewAtEnd() } onPlaySync: { var query = playlistsView.playlistQuery mainPlaylist.list.appendQuery(query) Player.playAll() root.sync = true root.syncPlaylist = playlist root.infoMsg = qsTr("Syncing to ") + playlist } } } SearchTable { id: searchView Connections { target: searchView onRowClicked: Player.addTrack(searchView.list.get(index)) onQuickPlayTrack: Player.quickPlay(searchView.list.get(index)) onPlayAll: { mainPlaylist.list.clear() var tracks = searchView.list.getAll() for(var i in tracks) Player.appendTrack(tracks[i]) Player.playAll() } onAppendAll: Player.appendAll(searchView.list.getAll()) onArtworkDoubleClicked: { var query = Q.GET.albumTracks_.arg( searchView.searchTable.model.get( index).album) query = query.arg(searchView.searchTable.model.get( index).artist) mainPlaylist.list.clear() mainPlaylist.list.sortBy = Tracks.NONE mainPlaylist.list.query = query Player.playAll() } } } FoldersView { id: foldersView Connections { target: foldersView.list onRowClicked: Player.addTrack(foldersView.list.model.get(index)) onQuickPlayTrack: Player.quickPlay(foldersView.list.model.get(index)) onPlayAll: { mainPlaylist.list.clear() // mainPlaylist.list.sortBy = Tracks.NONE mainPlaylist.list.query = foldersView.list.list.query Player.playAll() } onAppendAll: { var query = foldersView.list.list.query mainPlaylist.list.appendQuery(query) mainPlaylist.listView.positionViewAtEnd() } onQueueTrack: Player.queueTracks([foldersView.list.model.get(index)], index) } } // CloudView // { // id: cloudView // onQuickPlayTrack: Player.quickPlay(cloudView.list.get(index)) // } // BabeitView // { // id: babeitView // } // LinkingView // { // id: linkingView // } YouTube { id: youtubeView } // Spotify // { // id: spotifyView // } } Maui.SelectionBar { id: _selectionBar property alias listView: _selectionBar.selectionList Layout.fillWidth: true Layout.margins: space.big Layout.topMargin: space.small Layout.bottomMargin: space.big onIconClicked: _contextMenu.popup() onExitClicked: clear() colorScheme.backgroundColor: "#212121" model: BaseModel { list: _selectionBarModelList } Tracks { id: _selectionBarModelList } SelectionBarMenu { id: _contextMenu } function append(item) { if(selectedPaths.indexOf(item.path) < 0) { selectedItems.push(item) selectedPaths.push(item.path) // for(var i = 0; i < selectionList.count ; i++ ) // if(selectionList.model.get(i).path === item.path) // { // selectionList.model.remove(i) // return // } selectionList.model.list.append(item) selectionList.positionViewAtEnd() if(position === Qt.Vertical) return if(typeof(riseContent) === "undefined") return riseContent() } } } } /*animations*/ /*FUNCTIONS*/ function infoMsgAnim() { animBg.running = true animTxt.running = true } function toggleMaximized() { if (root.visibility === Window.Maximized) { root.showNormal(); } else { root.showMaximized(); } } /*CONNECTIONS*/ Connections { target: vvave onRefreshTables: H.refreshCollection(size) onRefreshTracks: H.refreshTracks() onRefreshAlbums: H.refreshAlbums() onRefreshArtists: H.refreshArtists() // onCoverReady: // { // root.currentArtwork = path // currentTrack.artwork = currentArtwork // mainPlaylist.list.update(currentTrack, currentTrackIndex); // } // onTrackLyricsReady: // { // console.log(lyrics) // if (url === currentTrack.url) // Player.setLyrics(lyrics) // } // onSkipTrack: Player.nextTrack() // onBabeIt: if (!mainlistEmpty) // { // mainPlaylist.list.fav(currentTrackIndex, !(mainPlaylist.list.get(currentTrackIndex).fav == "1")) // currentBabe = mainPlaylist.list.get(currentTrackIndex).fav == "1" // } onOpenFiles: { Player.appendTracksAt(tracks, 0) Player.playAt(0) } } } diff --git a/services/web/YouTube.qml b/services/web/YouTube.qml index 22606a9..20e22d1 100644 --- a/services/web/YouTube.qml +++ b/services/web/YouTube.qml @@ -1,286 +1,286 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import "../../view_models" import "../../view_models/BabeTable" import org.kde.kirigami 2.2 as Kirigami import org.kde.mauikit 1.0 as Maui Maui.Page { id: youtubeViewRoot property var searchRes : [] clip: true margins: 0 property alias viewer : youtubeViewer property int openVideo : 0 headBar.visible: false Connections { target: youtube onQueryResultsReady: { searchRes = res; populate(searchRes) youtubeTable.forceActiveFocus() if(openVideo > 0) { console.log("trying to open video") watchVideo(youtubeTable.model.get(openVideo-1)) openVideo = 0 } } } /*this is for playing the track sin the background without showing the actual video*/ Loader { id: youtubePlayer source: isAndroid ? "qrc:/services/web/YoutubePlayer_A.qml" : "qrc:/services/web/YoutubePlayer.qml" } Maui.Popup { id: configPopup parent: parent margins: contentMargins GridLayout { anchors.centerIn: parent width: parent.width*0.8 height: parent.height*0.9 columns: 1 rows: 6 Item { Layout.column: 1 Layout.row: 1 Layout.fillWidth: true Layout.fillHeight: true } Label { text: qsTr("Custom API Key") verticalAlignment: Qt.AlignVCenter elide: Text.ElideRight font.pointSize: fontSizes.default Layout.column: 1 Layout.row: 2 Layout.fillWidth: true } TextField { Layout.column: 1 Layout.row: 3 Layout.fillWidth: true text: Maui.FM.loadSettings("YOUTUBEKEY", "BABE", youtube.getKey()) } Label { text: qsTr("Search results") verticalAlignment: Qt.AlignVCenter elide: Text.ElideRight font.pointSize: fontSizes.default Layout.column: 1 Layout.row: 4 Layout.fillWidth: true } SpinBox { Layout.alignment: Qt.AlignRight Layout.column: 1 Layout.row: 5 Layout.fillWidth: true from: 1 to: 50 value: Maui.FM.loadSettings("YOUTUBELIMIT", "BABE", 25) editable: true onValueChanged: { Maui.FM.saveSettings("YOUTUBELIMIT", value, "BABE") } } Item { Layout.column: 1 Layout.row: 6 Layout.fillWidth: true Layout.fillHeight: true } } } StackView { id: stackView anchors.fill: parent focus: true pushEnter: Transition { PropertyAnimation { property: "opacity" from: 0 to:1 duration: 200 } } pushExit: Transition { PropertyAnimation { property: "opacity" from: 1 to:0 duration: 200 } } popEnter: Transition { PropertyAnimation { property: "opacity" from: 0 to:1 duration: 200 } } popExit: Transition { PropertyAnimation { property: "opacity" from: 1 to:0 duration: 200 } } initialItem: BabeTable { id: youtubeTable trackNumberVisible: false headBar.visible: true headBarExit: true headBarExitIcon: "edit-clear" headBarTitle: "YouTube" holder.emoji: "qrc:/assets/Astronaut.png" holder.isMask: false holder.title : "No Results!" holder.body: "Try with another query" holder.emojiSize: iconSizes.huge coverArtVisible: true trackDuration: true trackRating: true onExit: clearSearch() isArtworkRemote: true allowMenu: false model: ListModel{} - appendBtn.visible: false - playAllBtn.visible: false +// appendBtn.visible: false +// playAllBtn.visible: false headBar.rightContent: Maui.ToolButton { id: menuBtn iconName: "application-menu" onClicked: configPopup.open() } onRowClicked: { watchVideo(youtubeTable.model.get(index)) } onQuickPlayTrack: { playTrack(youtubeTable.model.get(index).url) } } YoutubeViewer { id: youtubeViewer } } footBar.middleContent: Maui.TextField { id: searchInput Layout.fillWidth: true placeholderText: qsTr("Search videos...") wrapMode: TextEdit.Wrap onAccepted: runSearch(searchInput.text) } function watchVideo(track) { if(track && track.url) { var url = track.url if(url && url.length > 0) { youtubeViewer.currentYt = track youtubeViewer.webView.url = url+"?autoplay=1" stackView.push(youtubeViewer) } } } function playTrack(url) { if(url && url.length > 0) { var newURL = url.replace("embed/", "watch?v=") console.log(newURL) youtubePlayer.item.url = newURL+"?autoplay=1+&vq=tiny" youtubePlayer.item.runJavaScript("document.title", function(result) { console.log(result); }); } } function runSearch(searchTxt) { if(searchTxt) if(searchTxt !== youtubeTable.headBarTitle) { youtubeTable.headBarTitle = searchTxt youtube.getQuery(searchTxt, Maui.FM.loadSettings("YOUTUBELIMIT", "BABE", 25)) } } function clearSearch() { searchInput.clear() youtubeTable.clearTable() youtubeTable.headBarTitle = "" searchRes = [] } function populate(tracks) { youtubeTable.model.clear() for(var i in tracks) youtubeTable.model.append(tracks[i]) } } diff --git a/view_models/BabeList.qml b/view_models/BabeList.qml index d53d1e0..f689bfd 100644 --- a/view_models/BabeList.qml +++ b/view_models/BabeList.qml @@ -1,96 +1,87 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 -import org.kde.kirigami 2.2 as Kirigami -import QtQuick.Controls.Material 2.1 +import org.kde.kirigami 2.6 as Kirigami import org.kde.mauikit 1.0 as Maui Maui.Page { id: control - property alias listView : babeList + property alias listView : babeList.listView property alias model : babeList.model - property alias delegate : babeList.delegate - property alias count : babeList.count - property alias currentIndex : babeList.currentIndex property alias currentItem : babeList.currentItem property alias holder : holder property alias section : babeList.section property bool wasPulled : false signal pulled() focus: true margins: 0 Maui.Holder { id: holder visible: babeList.count === 0 focus: true } - ListView + + + Maui.ListBrowser { id: babeList anchors.fill: parent clip: true - highlight: Rectangle - { - width: babeList.width - height: babeList.currentItem.height - color: highlightColor - } - - focus: true - interactive: true - highlightFollowsCurrentItem: true - highlightMoveDuration: 0 - keyNavigationWraps: true - keyNavigationEnabled : true +// listView.highlight: Rectangle +// { +// width: babeList.width +// height: babeList.currentItem.height +// color: highlightColor +// } - Keys.onUpPressed: decrementCurrentIndex() - Keys.onDownPressed: incrementCurrentIndex() - Keys.onReturnPressed: rowClicked(currentIndex) - Keys.onEnterPressed: quickPlayTrack(currentIndex) +// Keys.onUpPressed: decrementCurrentIndex() +// Keys.onDownPressed: incrementCurrentIndex() +// Keys.onReturnPressed: rowClicked(currentIndex) +// Keys.onEnterPressed: quickPlayTrack(currentIndex) - boundsBehavior: !isMobile? Flickable.StopAtBounds : Flickable.OvershootBounds - flickableDirection: Flickable.AutoFlickDirection +// boundsBehavior: !isMobile? Flickable.StopAtBounds : Flickable.OvershootBounds +// flickableDirection: Flickable.AutoFlickDirection // snapMode: isMobile? ListView.SnapToItem : ListView.NoSnap - addDisplaced: Transition - { - NumberAnimation { properties: "x,y"; duration: 100 } - } +// addDisplaced: Transition +// { +// NumberAnimation { properties: "x,y"; duration: 100 } +// } - ScrollBar.vertical:BabeScrollBar { visible: !isMobile} +// ScrollBar.vertical:BabeScrollBar { visible: !isMobile} - onContentYChanged: - { - if(contentY < -120) - wasPulled = true +// onContentYChanged: +// { +// if(contentY < -120) +// wasPulled = true - if(contentY == 0 && wasPulled) - { pulled(); wasPulled = false} - } +// if(contentY == 0 && wasPulled) +// { pulled(); wasPulled = false} +// } // Scroll is too fast on desktop, see QTBUG-56075 // https://bugreports.qt.io/browse/QTBUG-56075 - ScrollHelper - { - enabled: !isMobile - id: scrollHelper - flickable: babeList - anchors.fill: babeList - } +// ScrollHelper +// { +// enabled: !isMobile +// id: scrollHelper +// flickable: babeList +// anchors.fill: babeList +// } } } diff --git a/view_models/BabeTable/BabeTable.qml b/view_models/BabeTable/BabeTable.qml index 7f99a0c..a8be554 100644 --- a/view_models/BabeTable/BabeTable.qml +++ b/view_models/BabeTable/BabeTable.qml @@ -1,450 +1,445 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.6 as Kirigami import org.kde.mauikit 1.0 as Maui import BaseModel 1.0 import TracksList 1.0 import "../../utils/Player.js" as Player import "../../utils/Help.js" as H import "../../db/Queries.js" as Q import ".." BabeList { id: babeTableRoot // cacheBuffer : 300 property alias list : _tracksList property alias listModel : _tracksModel property alias removeDialog : _removeDialog property bool trackNumberVisible property bool quickPlayVisible : true property bool coverArtVisible : false property bool menuItemVisible : isMobile property bool trackDuration property bool trackRating property bool allowMenu: true property bool isArtworkRemote : false property bool showIndicator : false property bool group : false property alias contextMenu : contextMenu property alias contextMenuItems : contextMenu.content property alias playAllBtn : playAllBtn property alias appendBtn : appendBtn signal rowClicked(int index) signal rowPressed(int index) signal quickPlayTrack(int index) signal queueTrack(int index) signal artworkDoubleClicked(int index) signal playAll() signal appendAll() // altToolBars: true onGroupChanged: groupBy() focus: true //headBar.middleStrech: false headBar.leftSretch: false headBar.rightContent: Kirigami.ActionToolBar { - Layout.fillWidth: true actions: [ Kirigami.Action { id : playAllBtn text: qsTr("Play all") icon.name : "media-playlist-play" onTriggered: playAll() }, Kirigami.Action { id: appendBtn text: qsTr("Append") icon.name : "media-playlist-append"//"media-repeat-track-amarok" onTriggered: appendAll() }, Kirigami.Action { id: sortBtn text: qsTr("Sort") icon.name: "view-sort" Kirigami.Action { text: qsTr("Title") checkable: true checked: list.sortBy === Tracks.TITLE onTriggered: list.sortBy = Tracks.TITLE } - Kirigami.Action - { - text: qsTr("Track") - checkable: true - checked: list.sortBy === Tracks.TRACK - onTriggered: list.sortBy = Tracks.TRACK - } - - Kirigami.Action - { - text: qsTr("Artist") - checkable: true - checked: list.sortBy === Tracks.ARTIST - onTriggered: list.sortBy = Tracks.ARTIST - } - - Kirigami.Action - { - text: qsTr("Album") - checkable: true - checked: list.sortBy === Tracks.ALBUM - onTriggered: list.sortBy = Tracks.ALBUM - } - - Kirigami.Action - { - text: qsTr("Most played") - checkable: true - checked: list.sortBy === Tracks.COUNT - onTriggered: list.sortBy = Tracks.COUNT - } - - Kirigami.Action - { - text: qsTr("Rate") - checkable: true - checked: list.sortBy === Tracks.RATE - onTriggered: list.sortBy = Tracks.RATE - } - - Kirigami.Action - { - text: qsTr("Fav") - checkable: true - checked: list.sortBy === Tracks.FAV - onTriggered: list.sortBy = Tracks.FAV - } - - Kirigami.Action - { - text: qsTr("Release date") - checkable: true - checked: list.sortBy === Tracks.RELEASEDATE - onTriggered: list.sortBy = Tracks.RELEASEDATE - } - - Kirigami.Action - { - text: qsTr("Add date") - checkable: true - checked: list.sortBy === Tracks.ADDDATE - onTriggered: list.sortBy = Tracks.ADDDATE - } - - - Kirigami.Action - { - text: qsTr("Group") - checkable: true - checked: group - onTriggered: group = !group - } +// Kirigami.Action +// { +// text: qsTr("Track") +// checkable: true +// checked: list.sortBy === Tracks.TRACK +// onTriggered: list.sortBy = Tracks.TRACK +// } + +// Kirigami.Action +// { +// text: qsTr("Artist") +// checkable: true +// checked: list.sortBy === Tracks.ARTIST +// onTriggered: list.sortBy = Tracks.ARTIST +// } + +// Kirigami.Action +// { +// text: qsTr("Album") +// checkable: true +// checked: list.sortBy === Tracks.ALBUM +// onTriggered: list.sortBy = Tracks.ALBUM +// } + +// Kirigami.Action +// { +// text: qsTr("Most played") +// checkable: true +// checked: list.sortBy === Tracks.COUNT +// onTriggered: list.sortBy = Tracks.COUNT +// } + +// Kirigami.Action +// { +// text: qsTr("Rate") +// checkable: true +// checked: list.sortBy === Tracks.RATE +// onTriggered: list.sortBy = Tracks.RATE +// } + +// Kirigami.Action +// { +// text: qsTr("Fav") +// checkable: true +// checked: list.sortBy === Tracks.FAV +// onTriggered: list.sortBy = Tracks.FAV +// } + +// Kirigami.Action +// { +// text: qsTr("Release date") +// checkable: true +// checked: list.sortBy === Tracks.RELEASEDATE +// onTriggered: list.sortBy = Tracks.RELEASEDATE +// } + +// Kirigami.Action +// { +// text: qsTr("Add date") +// checkable: true +// checked: list.sortBy === Tracks.ADDDATE +// onTriggered: list.sortBy = Tracks.ADDDATE +// } + + +// Kirigami.Action +// { +// text: qsTr("Group") +// checkable: true +// checked: group +// onTriggered: group = !group +// } }, Kirigami.Action { text: qsTr("Select") icon.name: "item-select" onTriggered: selectionMode = !selectionMode checkable: false checked: selectionMode } ] } Maui.Dialog { id: _removeDialog property int index title: qsTr("Remove track") message: qsTr("You can delete the file from your computer or remove it from your collection") rejectButton.text: qsTr("Delete") // rejectButton.icon.name: "archive-remove" acceptButton.text: qsTr("Remove") onAccepted: { list.remove(listView.currentIndex) close() } onRejected: { if(Maui.FM.removeFile(list.get(index).url)) list.remove(listView.currentIndex) close() } } TableMenu { id: contextMenu MenuSeparator {} Maui.MenuItem { text: qsTr("Go to Artist") onTriggered: goToArtist() } Maui.MenuItem { text: qsTr("Go to Album") onTriggered: goToAlbum() } onFavClicked: { list.fav(listView.currentIndex, !(list.get(listView.currentIndex).fav == "1")) } onQueueClicked: Player.queueTracks([list.get(listView.currentIndex)]) onSaveToClicked: { playlistDialog.tracks = [list.get(listView.currentIndex).url] playlistDialog.open() } onOpenWithClicked: Maui.FM.openLocation([list.get(listView.currentIndex).url]) onRemoveClicked: { _removeDialog.index= listView.currentIndex _removeDialog.open() } onRateClicked: { list.rate(listView.currentIndex, rate); } onColorClicked: { list.color(listView.currentIndex, color); } onInfoClicked: { infoView.show(list.get(listView.currentIndex)) } onCopyToClicked: { cloudView.list.upload(listView.currentIndex) } onShareClicked: { isAndroid ? Maui.Android.shareDialog(list.get(listView.currentIndex)) : shareDialog.show([list.get(listView.currentIndex).url]) } } - listView.highlightFollowsCurrentItem: false - listView.highlightMoveDuration: 0 - listView.highlight: Rectangle { } - section.criteria: ViewSection.FullString section.delegate: Maui.LabelDelegate { id: _sectionDelegate label: section isSection: true boldLabel: true colorScheme.backgroundColor: "#333" colorScheme.textColor: "#fafafa" background: Rectangle { color: colorScheme.backgroundColor } } BaseModel { id: _tracksModel list: _tracksList } Tracks { id: _tracksList onSortByChanged: if(babeTableRoot.group) babeTableRoot.groupBy() } model: _tracksModel // property alias animBabe: delegate.animBabe delegate: TableDelegate { id: delegate width: listView.width number : trackNumberVisible ? true : false quickPlay: quickPlayVisible coverArt : coverArtVisible ? (babeTableRoot.width > 300) : coverArtVisible trackDurationVisible : trackDuration trackRatingVisible : trackRating menuItem: menuItemVisible remoteArtwork: isArtworkRemote playingIndicator: showIndicator onPressAndHold: if(isMobile && allowMenu) openItemMenu(index) onRightClicked: if(allowMenu) openItemMenu(index) onClicked: { currentIndex = index if(selectionMode) { H.addToSelection(listView.model.get(listView.currentIndex)) return } if(isMobile) rowClicked(index) } onDoubleClicked: { currentIndex = index if(!isMobile) rowClicked(index) } onPlay: { currentIndex = index quickPlayTrack(index) } onArtworkCoverClicked: { currentIndex = index goToAlbum() } } function openItemMenu(index) { currentIndex = index contextMenu.rate = list.get(currentIndex).rate contextMenu.fav = list.get(currentIndex).fav == "1" contextMenu.popup() rowPressed(index) console.log(list.get(currentIndex).fav) } function saveList() { var trackList = [] if(model.count > 0) { for(var i = 0; i < model.count; ++i) trackList.push(model.get(i).url) playlistDialog.tracks = trackList playlistDialog.open() } } function queueList() { var trackList = [] if(model.count > 0) { for(var i = 0; i < model.count; ++i) trackList.push(model.get(i)) Player.queueTracks(trackList) } } function goToAlbum() { root.currentView = viewsIndex.albums var item = listView.model.get(listView.currentIndex) albumsView.populateTable(item.album, item.artist) contextMenu.close() } function goToArtist() { root.currentView = viewsIndex.artists var item = listView.model.get(listView.currentIndex) artistsView.populateTable(undefined, item.artist) contextMenu.close() } function groupBy() { var prop = "undefined" if(group) switch(list.sortBy) { case Tracks.TITLE: prop = "title" break case Tracks.ARTIST: prop = "artist" break case Tracks.ALBUM: prop = "album" break case Tracks.RATE: prop = "rate" break case Tracks.FAV: prop = "fav" break case Tracks.ADDDATE: prop = "adddate" break case Tracks.RELEASEDATE: prop = "releasedate" break; case Tracks.COUNT: prop = "count" break } section.property = prop } } diff --git a/widgets/TracksView.qml b/widgets/TracksView.qml index c0876ca..1d45f9e 100644 --- a/widgets/TracksView.qml +++ b/widgets/TracksView.qml @@ -1,28 +1,27 @@ import QtQuick 2.9 import org.kde.mauikit 1.0 as Maui import "../view_models/BabeTable" import "../view_models" import "../db/Queries.js" as Q import "../utils/Help.js" as H BabeTable { id: tracksViewTable trackNumberVisible: false trackDuration: true trackRating: true headBar.visible: !holder.visible // headBarTitle: count + " tracks" headBarExit: false coverArtVisible: false holder.emoji: "qrc:/assets/MusicCloud.png" holder.isMask: false holder.title : "No Tracks!" holder.body: "Add new music sources" holder.emojiSize: iconSizes.huge list.query: Q.GET.allTracks - }