diff --git a/assets/vvave192.png b/assets/vvave192.png new file mode 100644 index 0000000..e9cabf9 Binary files /dev/null and b/assets/vvave192.png differ diff --git a/assets/vvave72.png b/assets/vvave72.png new file mode 100644 index 0000000..da2d7ea Binary files /dev/null and b/assets/vvave72.png differ diff --git a/assets/vvave96.png b/assets/vvave96.png new file mode 100644 index 0000000..e36f7f0 Binary files /dev/null and b/assets/vvave96.png differ diff --git a/main.qml b/main.qml index cf55524..b291456 100644 --- a/main.qml +++ b/main.qml @@ -1,1072 +1,1072 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 import QtQuick.Controls.Material 2.1 import "utils" import "widgets" import "widgets/MyBeatView" import "widgets/PlaylistsView" import "widgets/MainPlaylist" import "widgets/SettingsView" import "widgets/SearchView" import "view_models" import "view_models/BabeDialog" import "view_models/BabeTable" import "services/local" import "services/web" import "services/web/Spotify" import "view_models/BabeGrid" import "db/Queries.js" as Q import "utils/Help.js" as H import "utils/Player.js" as Player import org.kde.kirigami 2.2 as Kirigami import org.kde.maui 1.0 as Maui Maui.ApplicationWindow { id: root // minimumWidth: !isMobile ? columnWidth : 0 // minimumHeight: !isMobile ? columnWidth + 64 : 0 // flags: Qt.FramelessWindowHint title: qsTr("vvave") /***************************************************/ /******************** ALIASES ********************/ /*************************************************/ property alias playIcon: playIcon property alias babeBtnIcon: babeBtnIcon property alias progressBar: mainPlaylist.progressBar property alias animFooter: mainPlaylist.animFooter property alias mainPlaylist: mainPlaylist property alias selectionBar: selectionBar /***************************************************/ /******************** PLAYBACK ********************/ /*************************************************/ property bool isShuffle: bae.loadSetting("SHUFFLE","PLAYBACK", false) == "true" ? true : false property var currentTrack: ({ babe: "0", stars: "0" }) property int currentTrackIndex: 0 property int prevTrackIndex: 0 property string currentArtwork: !mainlistEmpty ? mainPlaylist.list.model.get(0).artwork : "" property bool currentBabe: currentTrack.babe == "0" ? false : true property string durationTimeLabel: "00:00" property string progressTimeLabel: "00:00" property bool isPlaying: false property bool autoplay: bae.loadSetting("AUTOPLAY", "BABE", false) === "true" ? true : false property int onQueue: 0 property bool mainlistEmpty: !mainPlaylist.table.count > 0 /***************************************************/ /******************** UI PROPS ********************/ /*************************************************/ readonly property real opacityLevel: 0.8 property int miniArtSize: iconSizes.large property int columnWidth: Kirigami.Units.gridUnit * 17 property int coverSize: focusMode ? columnWidth : (isAndroid ? Math.sqrt(root.width * root.height) * 0.4 : columnWidth * (isMobile ? 0.7 : 0.6)) /***************************************************/ /******************** HANDLERS ********************/ /*************************************************/ property int currentView: viewsIndex.tracks readonly property var viewsIndex: ({ tracks: 0, albums: 1, artists: 2, playlists: 3, search: 4, folders: 5, vvave: 6, linking: 7, youtube: 8, spotify: 9 }) property string syncPlaylist: "" property bool sync: false property string infoMsg: "" property bool infoLabels: bae.loadSetting("LABELS", "PLAYBACK", false) == "true" ? true : false property bool isLinked: false property bool isServing: false property bool focusMode : false property bool selectionMode : false /***************************************************/ /******************** UI COLORS *******************/ /*************************************************/ property string babeColor: bae.babeColor() /*SIGNALS*/ signal missingAlert(var track) /*CONF*/ pageStack.defaultColumnWidth: columnWidth pageStack.initialPage: [mainPlaylist, views] pageStack.interactive: isMobile pageStack.separatorVisible: pageStack.wideMode /*HANDLE EVENTS*/ onWidthChanged: if (isMobile) { if (width > height) mainPlaylist.cover.visible = false else mainPlaylist.cover.visible = true } onClosing: Player.savePlaylist() // pageStack.onCurrentIndexChanged: // { // if(pageStack.currentIndex === 0 && isMobile && !pageStack.wideMode) // { // bae.androidStatusBarColor(babeColor) // Material.background = babeColor // }else // { // bae.androidStatusBarColor(babeAltColor) // Material.background = babeAltColor // } // } onMissingAlert: { missingDialog.message = track.title + " by " + track.artist + " is missing" missingDialog.messageBody = "Do you want to remove it from your collection?" missingDialog.open() } /*COMPONENTS*/ BabeNotify { id: babeNotify } BabeMessage { id: missingDialog width: parent.width * (isMobile ? 0.9 : 0.4) title: "Missing file" onAccepted: { bae.removeTrack(currentTrack.url) mainPlaylist.table.model.remove(mainPlaylist.table.currentIndex) } } /* UI */ property bool accent : pageStack.wideMode || (!pageStack.wideMode && pageStack.currentIndex === 1) headBar.middleContent : [ Maui.ToolButton { iconName: "view-media-track" iconColor: accent && currentView === viewsIndex.tracks ? babeColor : textColor display: pageStack.wideMode ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly onClicked: { pageStack.currentIndex = 1 currentView = viewsIndex.tracks } text: qsTr("Tracks") }, Maui.ToolButton { text: qsTr("Albums") iconName: /*"album"*/ "view-media-album-cover" iconColor: accent && currentView === viewsIndex.albums ? babeColor : textColor display: pageStack.wideMode ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly onClicked: { pageStack.currentIndex = 1 albumsView.currentIndex = 0 currentView = viewsIndex.albums } }, Maui.ToolButton { text: qsTr("Artists") iconName: "view-media-artist" iconColor: accent && currentView === viewsIndex.artists ? babeColor : textColor display: pageStack.wideMode ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly onClicked: { pageStack.currentIndex = 1 artistsView.currentIndex = 0 currentView = viewsIndex.artists } }, Maui.ToolButton { text: qsTr("Playlists") iconName: "view-media-playlist" iconColor: accent && currentView === viewsIndex.playlists ? babeColor : textColor display: pageStack.wideMode ? AbstractButton.TextBesideIcon : AbstractButton.IconOnly onClicked: { pageStack.currentIndex = 1 currentView = viewsIndex.playlists } } ] onSearchButtonClicked: { pageStack.currentIndex = 1 currentView = viewsIndex.search searchView.searchInput.forceActiveFocus() riseContent() } FloatingDisk { id: floatingDisk x: space.big y: pageStack.height - height z: 999 } Maui.ShareDialog { id: shareDialog } Maui.FileDialog { id: fmDialog } SourcesDialog { id: sourcesDialog } BabeConsole { id: babeConsole } - menuDrawer.bannerImageSource: "qrc:/assets/banner.svg" +// menuDrawer.bannerImageSource: "qrc:/assets/banner.svg" menuDrawer.actions: [ Kirigami.Action { text: "Vvave Stream" iconName: "love" onTriggered: { pageStack.currentIndex = 1 currentView = viewsIndex.vvave } }, Kirigami.Action { text: qsTr("Folders") iconName: "folder" onTriggered: { pageStack.currentIndex = 1 currentView = viewsIndex.folders } }, Kirigami.Action { text: qsTr("Linking") iconName: isMobile ? "computer-laptop" : "phone" onTriggered: { pageStack.currentIndex = 1 currentView = viewsIndex.linking if(!isLinked) linkingView.linkingConf.open() } }, Kirigami.Action { text: qsTr("YouTube") iconName: "im-youtube" onTriggered: { pageStack.currentIndex = 1 currentView = viewsIndex.youtube } }, Kirigami.Action { text: qsTr("Spotify") onTriggered: { pageStack.currentIndex = 1 currentView = viewsIndex.spotify } }, Kirigami.Action { text: qsTr("Collection") iconName: "database-index" Kirigami.Action { text: qsTr("Sources...") onTriggered: sourcesDialog.open() iconName: "folder-new" } Kirigami.Action { text: qsTr("Re-Scan") onTriggered: bae.refreshCollection(); } Kirigami.Action { text: qsTr("Refresh...") iconName: "view-refresh" Kirigami.Action { text: qsTr("Tracks") onTriggered: H.refreshTracks(); } Kirigami.Action { text: qsTr("Albums") onTriggered: H.refreshAlbums(); } Kirigami.Action { text: qsTr("Artists") onTriggered: H.refreshArtists(); } Kirigami.Action { text: qsTr("All") onTriggered: H.refreshCollection(); } } Kirigami.Action { text: qsTr("Clean") onTriggered: bae.removeMissingTracks(); iconName: "edit-clear" } }, Kirigami.Action { text: qsTr("Settings...") iconName: "view-media-config" // 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) // } // } // } Kirigami.Action { text: "Appearance" Kirigami.Action { text: "Icon size" Kirigami.Action { text: iconSizes.small onTriggered : { bae.saveSetting("ICON_SIZE", text, "BABE") toolBarIconSize = text } } Kirigami.Action { text: iconSizes.medium onTriggered : { bae.saveSetting("ICON_SIZE", text, "BABE") iconSizeChanged(text) } } Kirigami.Action { text: iconSizes.big onTriggered : { bae.saveSetting("ICON_SIZE", text, "BABE") iconSizeChanged(text) } } } } Kirigami.Action { text: "Player" Kirigami.Action { text: "Info label" Kirigami.Action { text: checked ? "ON" : "OFF" checked: infoLabels checkable: true onToggled: { infoLabels = checked bae.saveSetting("LABELS", infoLabels ? true : false, "PLAYBACK") } } } Kirigami.Action { text: "Autoplay" checked: autoplay checkable: true onToggled: { autoplay = checked bae.saveSetting("AUTOPLAY", autoplay ? true : false, "BABE") } } } }, Kirigami.Action { text: "Developer" iconName: "code-context" Kirigami.Action { text: "Wiki" } Kirigami.Action { text: "Console log" onTriggered: babeConsole.open() } }, Kirigami.Action { text: "About..." iconName: "help-about" Kirigami.Action { text: "VVAVEIt" } Kirigami.Action { text: "VVAVE" } Kirigami.Action { text: "Pulpo" } Kirigami.Action { text: "Kirigami" } } ] Item { id: message visible: infoMsg.length > 0 && sync anchors.bottom: parent.bottom width: pageStack.wideMode ? columnWidth : parent.width height: iconSize z: 999 Rectangle { id: infoBg anchors.fill: parent z: -999 color: altColor opacity: opacityLevel 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 } MainPlaylist { id: mainPlaylist Connections { target: mainPlaylist onCoverPressed: Player.appendAll(tracks) onCoverDoubleClicked: Player.playAll(tracks) } floatingBar: true footBarOverlap: true footBarVisible: !mainlistEmpty headBarVisible: !mainlistEmpty footBar.leftContent: Label { visible: !mainlistEmpty && infoLabels text: progressTimeLabel color: darkTextColor clip: true } footBar.rightContent: Label { visible: !mainlistEmpty && infoLabels text: durationTimeLabel color: darkTextColor clip: true } footBar.middleContent: [ Maui.ToolButton { id: babeBtnIcon iconName: "love" iconColor: currentBabe ? babeColor : darkTextColor onClicked: if (!mainlistEmpty) { var value = H.faveIt([mainPlaylist.list.model.get(currentTrackIndex).url]) currentBabe = value mainPlaylist.list.model.get(currentTrackIndex).babe = value ? "1" : "0" } }, Maui.ToolButton { iconName: "media-skip-backward" iconColor: darkTextColor onClicked: Player.previousTrack() onPressAndHold: Player.playAt(prevTrackIndex) }, Maui.ToolButton { id: playIcon iconColor: darkTextColor iconName: isPlaying ? "media-playback-pause" : "media-playback-start" onClicked: { if (isPlaying) Player.pauseTrack() else Player.resumeTrack() } }, Maui.ToolButton { id: nextBtn iconColor: darkTextColor iconName: "media-skip-forward" onClicked: Player.nextTrack() onPressAndHold: Player.playAt(Player.shuffle()) }, Maui.ToolButton { id: shuffleBtn iconColor: darkTextColor iconName: isShuffle ? "media-playlist-shuffle" : "media-playlist-repeat" onClicked: { isShuffle = !isShuffle bae.saveSetting("SHUFFLE",isShuffle, "PLAYBACK") } } ] } Maui.Page { id: views headBarVisible: false margins: 0 // focusPolicy: Qt.WheelFocus // visualFocus: true ColumnLayout { anchors.fill: parent SwipeView { id: swipeView Layout.fillHeight: true Layout.fillWidth: true interactive: isMobile // contentItem: ListView // { // model: swipeView.contentModel // interactive: swipeView.interactive // currentIndex: swipeView.currentIndex // spacing: swipeView.spacing // orientation: swipeView.orientation // snapMode: ListView.SnapOneItem // boundsBehavior: Flickable.StopAtBounds // highlightRangeMode: ListView.StrictlyEnforceRange // preferredHighlightBegin: 0 // preferredHighlightEnd: 0 // highlightMoveDuration: 250 // // min:10 // maximumFlickVelocity: 10 * (swipeView.orientation === // Qt.Horizontal ? width : height) // } currentIndex: currentView onCurrentItemChanged: currentItem.forceActiveFocus() onCurrentIndexChanged: { currentView = currentIndex if (!babeitView.isConnected && currentIndex === viewsIndex.vvave) babeitView.logginDialog.open() if(currentView === viewsIndex.search) riseContent() } TracksView { id: tracksView Connections { target: tracksView onRowClicked: Player.addTrack(tracksView.model.get(index)) onQuickPlayTrack: Player.quickPlay(tracksView.model.get(index)) onPlayAll: Player.playAll(bae.get(Q.GET.allTracks)) onAppendAll: Player.appendAll(bae.get(Q.GET.allTracks)) onQueueTrack: Player.queueTracks([tracksView.model.get(index)], index) } } AlbumsView { id: albumsView grid.holder.emoji: "qrc:/assets/MusicBox.png" grid.holder.isMask: false grid.holder.title : "No Albums!" grid.holder.body: "Add new music sources" grid.holder.emojiSize: iconSizes.huge 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) var map = bae.get(query) albumsView.playAlbum(map) } onPlayAll: { var query = Q.GET.albumTracks_.arg(album) query = query.arg(artist) query = query.arg(data.artist) var tracks = bae.get(query) Player.playAll(tracks) } onAppendAll: { var query = Q.GET.albumTracks_.arg(album) query = query.arg(artist) var tracks = bae.get(query) Player.appendAll(tracks) } } } AlbumsView { id: artistsView grid.holder.emoji: "qrc:/assets/MusicBox.png" grid.holder.isMask: false grid.holder.title : "No Artists!" grid.holder.body: "Add new music sources" grid.holder.emojiSize: iconSizes.huge Connections { target: artistsView onRowClicked: Player.addTrack(track) onPlayTrack: Player.quickPlay(track) onAlbumCoverClicked: artistsView.populateTable(undefined, artist) onAlbumCoverPressedAndHold: { var query = Q.GET.artistTracks_.arg(artist) var map = bae.get(query) artistsView.playAlbum(map) } onPlayAll: { var query = Q.GET.artistTracks_.arg(artist) query = query.arg(data.artist) var tracks = bae.get(query) Player.playAll(tracks) } onAppendAll: { var query = Q.GET.artistTracks_.arg(artist) var tracks = bae.get(query) Player.appendAll(tracks) } } } PlaylistsView { id: playlistsView Connections { target: playlistsView onRowClicked: Player.addTrack(track) onQuickPlayTrack: Player.quickPlay(track) onPlayAll: Player.playAll(tracks) onAppendAll: Player.appendAll(tracks) onPlaySync: { var tracks = bae.get(Q.GET.playlistTracks_.arg(playlist)) Player.playAll(tracks) root.sync = true root.syncPlaylist = playlist root.infoMsg = "Syncing to " + playlist } } } SearchTable { id: searchView Connections { target: searchView.searchTable onRowClicked: Player.addTrack(searchView.searchTable.model.get(index)) onQuickPlayTrack: Player.quickPlay(searchView.searchTable.model.get(index)) onPlayAll: Player.playAll(searchView.searchRes) onAppendAll: Player.appendAll(searchView.searchRes) onArtworkDoubleClicked: { var query = Q.GET.albumTracks_.arg( searchView.searchTable.model.get( index).album) query = query.arg(searchView.searchTable.model.get( index).artist) Player.playAll(bae.get(query)) } } } FoldersView { id: foldersView Connections { target: foldersView.list onRowClicked: Player.addTrack(foldersView.list.model.get(index)) onQuickPlayTrack: Player.quickPlay(foldersView.list.model.get(index)) onPlayAll: Player.playAll(foldersView.getTracks()) onAppendAll: Player.appendAll(foldersView.getTracks()) onQueueTrack: Player.queueTracks([foldersView.list.model.get(index)], index) } } BabeitView { id: babeitView } LinkingView { id: linkingView } YouTube { id: youtubeView } Spotify { id: spotifyView } } Maui.SelectionBar { id: selectionBar Layout.fillWidth: true Layout.margins: space.huge Layout.topMargin: space.small Layout.bottomMargin: space.big onIconClicked: contextMenu.show(selectedPaths) onExitClicked: clear() TableMenu { id: contextMenu menuItem: MenuItem { text: qsTr("Play all") onTriggered: { var data = bae.getList(selectionBar.selectedPaths) contextMenu.close() selectionMode = false selectionBar.clear() Player.playAll(data) } } onFavClicked: H.faveIt(paths) onQueueClicked: H.queueIt(paths) onSaveToClicked: { playlistDialog.tracks = paths playlistDialog.open() } onOpenWithClicked: bae.showFolder(paths) onRemoveClicked: { } onRateClicked: H.rateIt(paths, rate) onColorClicked: H.moodIt(paths, color) } } } } /*animations*/ /*FUNCTIONS*/ function infoMsgAnim() { animBg.running = true animTxt.running = true } function toggleMaximized() { if (root.visibility === Window.Maximized) { root.showNormal(); } else { root.showMaximized(); } } Component.onCompleted: { // if(isAndroid) // switchColorScheme(colorScheme.Dark) } /*CONNECTIONS*/ Connections { target: player onPos: progressBar.value = pos onTiming: progressTimeLabel = time onDurationChanged: durationTimeLabel = time onFinished: if (!mainlistEmpty) { if (currentTrack.url) bae.playedTrack(currentTrack.url) Player.nextTrack() } onIsPlaying: isPlaying = playing } Connections { target: bae onRefreshTables: H.refreshCollection(size) onRefreshTracks: H.refreshTracks() onRefreshAlbums: H.refreshAlbums() onRefreshArtists: H.refreshArtists() onTrackLyricsReady: { if (url === currentTrack.url) Player.setLyrics(lyrics) } onSkipTrack: Player.nextTrack() onBabeIt: Player.babeTrack() onOpenFiles: Player.playAll(tracks) } } diff --git a/mauikit b/mauikit index 6c3b797..e76fff5 160000 --- a/mauikit +++ b/mauikit @@ -1 +1 @@ -Subproject commit 6c3b7973691c25249c7e74512d797a0cce8f2c46 +Subproject commit e76fff5a4a9086d81f29dccda7680aaec710ab0d diff --git a/vvave.pro b/vvave.pro index 38cf69f..81ae3e4 100644 --- a/vvave.pro +++ b/vvave.pro @@ -1,129 +1,129 @@ QT += quick QT += multimedia QT += sql QT += websockets QT += network QT += xml QT += qml QT += widgets +QT += quickcontrols2 TARGET = vvave TEMPLATE = app CONFIG += ordered CONFIG += c++11 linux:unix:!android { message(Building for Linux KDE) include(kde/kde.pri) } else:android { message(Building helpers for Android) - include(android/android.pri) - include(3rdparty/taglib.pri) - include(android-openssl.pri) - include(3rdparty/kirigami/kirigami.pri) - - DEFINES += STATIC_KIRIGAMI + include($$PWD/3rdparty/kirigami/kirigami.pri) + include($$PWD/android/android.pri) + include($$PWD/3rdparty/taglib.pri) + include($$PWD/android-openssl.pri) + DEFINES += STATIC_KIRIGAMI } else { message("Unknown configuration") } include(mauikit/mauikit.pri) include(pulpo/pulpo.pri) # The following define makes your compiler emit warnings if you use # any feature of Qt which as been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it. DEFINES += QT_DEPRECATED_WARNINGS # You can also make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += main.cpp \ db/collectionDB.cpp \ services/local/taginfo.cpp \ services/local/player.cpp \ utils/brain.cpp \ - services/local/socket.cpp \ - services/web/youtube.cpp \ + services/local/socket.cpp \ + services/web/youtube.cpp \ babe.cpp \ settings/BabeSettings.cpp \ db/conthread.cpp \ services/web/babeit.cpp \ utils/babeconsole.cpp \ services/local/youtubedl.cpp \ services/local/linking.cpp \ settings/fileloader.cpp \ services/web/Spotify/spotify.cpp RESOURCES += qml.qrc \ # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = # Additional import path used to resolve QML modules just for Qt Quick Designer QML_DESIGNER_IMPORT_PATH = # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target DISTFILES += \ db/script.sql \ CMakeLists.txt HEADERS += \ db/collectionDB.h \ utils/bae.h \ settings/fileloader.h \ services/local/taginfo.h \ services/local/player.h \ utils/brain.h \ - services/local/socket.h \ - services/web/youtube.h \ + services/local/socket.h \ + services/web/youtube.h \ babe.h \ settings/BabeSettings.h \ db/conthread.h \ services/web/babeit.h \ utils/babeconsole.h \ utils/singleton.h \ services/local/youtubedl.h \ services/local/linking.h \ services/web/Spotify/spotify.h #TAGLIB #INCLUDEPATH += /usr/include/python3.6m #LIBS += -lpython3.6m #defineReplace(copyToDir) { # files = $$1 # DIR = $$2 # LINK = # for(FILE, files) { # LINK += $$QMAKE_COPY $$shell_path($$FILE) $$shell_path($$DIR) $$escape_expand(\\n\\t) # } # return($$LINK) #} #defineReplace(copyToBuilddir) { # return($$copyToDir($$1, $$OUT_PWD)) #} ## Copy the binary files dependent on the system architecture #unix:!macx { # message("Linux") # QMAKE_POST_LINK += $$copyToBuilddir($$PWD/library/cat) #} diff --git a/widgets/AlbumsView.qml b/widgets/AlbumsView.qml index 9ae06d2..c7ccdc3 100644 --- a/widgets/AlbumsView.qml +++ b/widgets/AlbumsView.qml @@ -1,188 +1,191 @@ import QtQuick 2.9 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 import "../view_models/BabeGrid" import "../view_models/BabeTable" import "../db/Queries.js" as Q import "../utils/Help.js" as H import org.kde.kirigami 2.2 as Kirigami import org.kde.maui 1.0 as Maui Kirigami.PageRow { id: albumsPageRoot clip: true separatorVisible: wideMode initialPage: [albumsViewGrid, albumFilter] defaultColumnWidth: albumsViewGrid.albumCoverSize * 4 interactive: currentIndex === 1 property string currentAlbum: "" property string currentArtist: "" property var tracks: [] property alias grid : albumsViewGrid property alias table : albumsViewTable property alias tagBar : tagBar signal rowClicked(var track) signal playTrack(var track) signal queueTrack(var track) signal appendAll(string album, string artist) signal playAll(string album, string artist) signal albumCoverClicked(string album, string artist) signal albumCoverPressedAndHold(string album, string artist) BabeGrid { id: albumsViewGrid visible: true onAlbumCoverClicked: albumsPageRoot.albumCoverClicked(album, artist) onAlbumCoverPressed: albumCoverPressedAndHold(album, artist) } ColumnLayout { id: albumFilter anchors.fill: parent spacing: 0 BabeTable { id: albumsViewTable Layout.fillHeight: true Layout.fillWidth: true trackNumberVisible: true headBarVisible: true headBarExit: !albumsPageRoot.wideMode headBarExitIcon: "go-previous" coverArtVisible: true quickPlayVisible: true focus: true holder.emoji: "qrc:/assets/ElectricPlug.png" holder.isMask: false holder.title : "Oops!" holder.body: "This list is empty" holder.emojiSize: iconSizes.huge onRowClicked: { albumsPageRoot.rowClicked(model.get(index)) } onQuickPlayTrack: { albumsPageRoot.playTrack(model.get(index)) } onQueueTrack: { albumsPageRoot.queueTrack(model.get(index)) } onPlayAll: { albumsPageRoot.currentIndex = 0 albumsPageRoot.playAll(currentAlbum, currentArtist) } onAppendAll: { albumsPageRoot.currentIndex = 0 albumsPageRoot.appendAll(currentAlbum, currentArtist) } onExit: albumsPageRoot.currentIndex = 0 } Maui.TagsBar { id: tagBar Layout.fillWidth: true allowEditMode: false onTagClicked: H.searchFor("tag:"+tag) } } function populate(query) { var map = bae.get(query) if(map.length > 0) for(var i in map) grid.gridModel.append(map[i]) } function populateTable(album, artist) { + console.log("PAPULATE ALBUMS VIEW") + table.clearTable() albumsPageRoot.currentIndex = 1 var query = "" var tagq = "" currentAlbum = album === undefined ? "" : album currentArtist= artist if(album && artist) { query = Q.GET.albumTracks_.arg(album) query = query.arg(artist) albumsView.table.headBarTitle = album tagq = Q.GET.albumTags_.arg(album) }else if(artist && album === undefined) { query = Q.GET.artistTracks_.arg(artist) artistsView.table.headBarTitle = artist tagq = Q.GET.artistTags_.arg(artist) } tracks = bae.get(query) if(tracks.length > 0) { for(var i in tracks) albumsViewTable.model.append(tracks[i]) tagq = tagq.arg(artist) - - tagBar.populate(bae.get(tagq)) + var tags = bae.get(tagq) + console.log(tagq, "TAGS", tags) + tagBar.populate(tags) } } function filter(tracks) { var matches = [] for(var i = 0; i0) { for(var i = 0; i < n; i++) { var where = "url = \""+list[i]+"\"" var query = Q.GET.tracksWhere_.arg(where) var track = bae.get(query) Player.appendTrack(track[0]) } }else { where = "babe = 1" query = Q.GET.tracksWhere_.arg(where) var tracks = bae.get(query) for(var pos=0; pos< tracks.length; pos++) Player.appendTrack(tracks[pos]) } if(autoplay) Player.playAt(0) // var pos = bae.lastPlaylistPos() // console.log("POSSS:", pos) // list.currentIndex = pos // play(list.model.get(pos)) } } InfoView { id: infoView } } } Slider { id: progressBar height: unit * (isMobile ? 6 : 8) width: parent.width Layout.fillWidth: true padding: 0 from: 0 to: 1000 value: 0 spacing: 0 focus: true onMoved: player.seek(player.duration() / 1000 * 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.7) implicitWidth: progressBar.pressed ? iconSizes.medium : 0 implicitHeight: progressBar.pressed ? iconSizes.medium : 0 radius: progressBar.pressed ? iconSizes.medium : 0 color: babeColor } } } function goFocusMode() { if(focusMode) { if(isMobile) { root.width = screenWidth root.height= screenHeight }else { cover.y = 0 root.maximumWidth = screenWidth root.minimumWidth = columnWidth root.maximumHeight = screenHeight root.minimumHeight = columnWidth root.width = columnWidth root.height = 700 } }else { if(isMobile) { }else { root.maximumWidth = columnWidth root.minimumWidth = columnWidth root.maximumHeight = columnWidth root.minimumHeight = columnWidth // root.footer.visible = false // mainlistContext.visible = false } } focusMode = !focusMode } function play(index) { prevTrackIndex = currentTrackIndex Player.playAt(index) } }