diff --git a/view_models/BabeTable/BabeTable.qml b/view_models/BabeTable/BabeTable.qml index 3f0d19e..b6d569e 100644 --- a/view_models/BabeTable/BabeTable.qml +++ b/view_models/BabeTable/BabeTable.qml @@ -1,542 +1,542 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.3 import org.kde.kirigami 2.7 as Kirigami import org.kde.mauikit 1.0 as Maui 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: control // cacheBuffer : 300 property alias list : _tracksList property alias listModel : _tracksModel property alias removeDialog : _removeDialog property bool trackNumberVisible property bool coverArtVisible : false property bool allowMenu: true property bool showQuickActions : true property bool group : false property alias contextMenu : contextMenu property alias contextMenuItems : contextMenu.contentData // property alias playAllBtn : playAllBtn // property alias appendBtn : appendBtn signal rowClicked(int index) signal rowDoubleClicked(int index) signal rowPressed(int index) signal quickPlayTrack(int index) signal queueTrack(int index) signal appendTrack(int index) signal artworkDoubleClicked(int index) signal playAll() signal appendAll() focus: true holder.visible: list.count === 0 listView.spacing: Maui.Style.space.small * (Kirigami.Settings.isMobile ? 1.4 : 1.2) listView.header: Column { width: control.width z: listView.z + 9 visible: list.count > 0 Maui.ToolBar { Kirigami.Theme.inherit: false position: ToolBar.Header width: parent.width leftContent: [ ToolButton { id : playAllBtn icon.name : "media-playlist-play" onClicked: playAll() }, ToolButton { id: appendBtn icon.name : "media-playlist-append" onClicked: appendAll() }] middleContent: Label { Layout.fillWidth: true text: control.title elide : Text.ElideRight font.bold : false font.weight: Font.Bold color : Kirigami.Theme.textColor font.pointSize: Maui.Style.fontSizes.big horizontalAlignment : Text.AlignHCenter verticalAlignment : Text.AlignVCenter } rightContent: [ ToolButton { icon.name: "item-select" onClicked: selectionMode = !selectionMode checkable: false checked: selectionMode }, Maui.ToolButtonMenu { id: sortBtn icon.name: "view-sort" visible: list.count > 2 MenuItem { text: qsTr("Title") checkable: true checked: list.sortBy === Tracks.TITLE onTriggered: list.sortBy = Tracks.TITLE autoExclusive: true } MenuItem { text: qsTr("Track") checkable: true checked: list.sortBy === Tracks.TRACK onTriggered: list.sortBy = Tracks.TRACK autoExclusive: true } MenuItem { text: qsTr("Artist") checkable: true checked: list.sortBy === Tracks.ARTIST onTriggered: list.sortBy = Tracks.ARTIST autoExclusive: true } MenuItem { text: qsTr("Album") checkable: true checked: list.sortBy === Tracks.ALBUM onTriggered: list.sortBy = Tracks.ALBUM autoExclusive: true } MenuItem { text: qsTr("Most played") checkable: true checked: list.sortBy === Tracks.COUNT onTriggered: list.sortBy = Tracks.COUNT autoExclusive: true } MenuItem { text: qsTr("Rate") checkable: true checked: list.sortBy === Tracks.RATE onTriggered: list.sortBy = Tracks.RATE autoExclusive: true } MenuItem { text: qsTr("Favorite") checkable: true checked: list.sortBy === Tracks.FAV onTriggered: list.sortBy = Tracks.FAV autoExclusive: true } MenuItem { text: qsTr("Release date") checkable: true checked: list.sortBy === Tracks.RELEASEDATE onTriggered: list.sortBy = Tracks.RELEASEDATE autoExclusive: true } MenuItem { text: qsTr("Add date") checkable: true checked: list.sortBy === Tracks.ADDDATE onTriggered: list.sortBy = Tracks.ADDDATE autoExclusive: true } MenuSeparator{} MenuItem { text: qsTr("Group") checkable: true checked: group onTriggered: { group = !group groupBy() } } }, ToolButton { id: _filterButton icon.name: "view-filter" checkable: true visible: list.count > 10 } ] } Maui.ToolBar { Kirigami.Theme.inherit: false // Kirigami.Theme.backgroundColor: control.Kirigami.Theme.backgroundColor visible: _filterButton.checked && _filterButton.visible width: parent.width position: ToolBar.Header middleContent: Maui.TextField { Layout.fillWidth: true onAccepted: listModel.setFilterString(text) onTextChanged: listModel.setFilterString(text) } } } 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") acceptButton.text: qsTr("Remove") page.padding: Maui.Style.space.huge onAccepted: { list.remove(listView.currentIndex) close() } onRejected: { if(Maui.FM.removeFile(listModel.get(index).url)) list.remove(listView.currentIndex) close() } } TableMenu { id: contextMenu MenuSeparator {} MenuItem { text: qsTr("Go to Artist") onTriggered: goToArtist() } MenuItem { text: qsTr("Go to Album") onTriggered: goToAlbum() } onFavClicked: { list.fav(listView.currentIndex, !(listModel.get(listView.currentIndex).fav == "1")) } onQueueClicked: Player.queueTracks([listModel.get(listView.currentIndex)]) onPlayClicked: quickPlayTrack(listView.currentIndex) onAppendClicked: appendTrack(listView.currentIndex) onSaveToClicked: { playlistDialog.tracks = [listModel.get(listView.currentIndex).url] playlistDialog.open() } onOpenWithClicked: Maui.FM.openLocation([listModel.get(listView.currentIndex).url]) onDeleteClicked: { _removeDialog.index= listView.currentIndex _removeDialog.open() } onRateClicked: { list.rate(listView.currentIndex, rate); } onColorClicked: { list.color(listView.currentIndex, color); } onInfoClicked: { infoView.show(listModel.get(listView.currentIndex)) } onCopyToClicked: { cloudView.list.upload(listView.currentIndex) } onShareClicked: { const url = listModel.get(listView.currentIndex).url if(isAndroid) { Maui.Android.shareDialog(url) return } _dialogLoader.sourceComponent = _shareDialogComponent root.dialog.show([url]) } } section.criteria: ViewSection.FullString section.delegate: Maui.LabelDelegate { id: _sectionDelegate label: section isSection: true width: control.width Kirigami.Theme.backgroundColor: "#333" Kirigami.Theme.textColor: "#fafafa" background: Rectangle { color: Kirigami.Theme.backgroundColor } } Maui.BaseModel { id: _tracksModel list: _tracksList recursiveFilteringEnabled: true sortCaseSensitivity: Qt.CaseInsensitive filterCaseSensitivity: Qt.CaseInsensitive } Tracks { id: _tracksList onSortByChanged: if(control.group) control.groupBy() } model: _tracksModel // property alias animBabe: delegate.animBabe delegate: TableDelegate { id: delegate width: listView.width number : trackNumberVisible ? true : false coverArt : coverArtVisible ? (control.width > 200) : coverArtVisible - onPressAndHold: if(Kirigami.Settings.isMobile && allowMenu) openItemMenu(index) + onPressAndHold: if(Maui.Handy.isTouch && allowMenu) openItemMenu(index) onRightClicked: if(allowMenu) openItemMenu(index) onLeftEmblemClicked: H.addToSelection(listModel.get(index)) isSelected: selectionBar.contains(model.url) sameAlbum: { if(coverArt) { if(listModel.get(index-1)) { if(listModel.get(index-1).album === album && listModel.get(index-1).artist === artist) true else false }else false }else false } ToolButton { Layout.fillHeight: true Layout.preferredWidth: implicitWidth - visible: control.showQuickActions && (Kirigami.Settings.isMobile ? true : delegate.hovered) + visible: control.showQuickActions && (Maui.Handy.isTouch ? true : delegate.hovered) icon.name: "media-playlist-append" onClicked: delegate.append() opacity: delegate.hovered ? 0.8 : 0.6 } onClicked: { currentIndex = index if(selectionMode) { H.addToSelection(listModel.get(listView.currentIndex)) return } - if(Kirigami.Settings.isMobile) + if(Maui.Handy.isTouch) rowClicked(index) } onDoubleClicked: { currentIndex = index - if(!Kirigami.Settings.isMobile) + if(!Maui.Handy.isTouch) rowClicked(index) } onPlay: { currentIndex = index quickPlayTrack(index) } onAppend: { currentIndex = index appendTrack(index) } onArtworkCoverClicked: { currentIndex = index goToAlbum() } Connections { target: selectionBar onUriRemoved: { if(uri === model.url) delegate.isSelected = false } onUriAdded: { if(uri === model.url) delegate.isSelected = true } onCleared: delegate.isSelected = false } } function openItemMenu(index) { currentIndex = index contextMenu.rate = listModel.get(currentIndex).rate contextMenu.fav = listModel.get(currentIndex).fav == "1" contextMenu.popup() rowPressed(index) } function saveList() { var trackList = [] if(list.count > 0) { for(var i = 0; i < list.count; ++i) trackList.push(listModel.get(i).url) playlistDialog.tracks = trackList playlistDialog.open() } } function queueList() { var trackList = [] if(list.count > 0) { for(var i = 0; i < list.count; ++i) trackList.push(listModel.get(i)) Player.queueTracks(trackList) } } function goToAlbum() { swipeView.currentIndex = viewsIndex.albums const item = listModel.get(listView.currentIndex) swipeView.currentItem.item.populateTable(item.album, item.artist) contextMenu.close() } function goToArtist() { swipeView.currentIndex = viewsIndex.artists const item = listModel.get(listView.currentIndex) swipeView.currentItem.item.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/MainPlaylist/MainPlaylist.qml b/widgets/MainPlaylist/MainPlaylist.qml index e6880b6..a60491b 100644 --- a/widgets/MainPlaylist/MainPlaylist.qml +++ b/widgets/MainPlaylist/MainPlaylist.qml @@ -1,229 +1,229 @@ import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.12 import QtGraphicalEffects 1.0 import org.kde.kirigami 2.2 as Kirigami import org.kde.mauikit 1.0 as Maui import "../../utils/Player.js" as Player import "../../db/Queries.js" as Q import "../../utils" import "../../widgets" import "../../view_models" import "../../view_models/BabeTable" Maui.Page { id: control property alias list : table.list property alias listModel: table.listModel property alias listView : table.listView property alias table: table property alias menu : playlistMenu property alias contextMenu: table.contextMenu signal coverDoubleClicked(var tracks) signal coverPressed(var tracks) focus: true headBar.visible: false PlaylistMenu { id: playlistMenu onClearOut: Player.clearOutPlaylist() onClean: Player.cleanPlaylist() onSaveToClicked: table.saveList() } footer: AlbumsRoll { id: _albumsRoll width: table.width position: ToolBar.Footer } BabeTable { id: table anchors.fill: parent focus: true headBar.visible: false footBar.visible: false coverArtVisible: true holder.emoji: "qrc:/assets/dialog-information.svg" holder.isMask: false holder.title : "Meh!" holder.body: "Start putting together your playlist!" holder.emojiSize: Maui.Style.iconSizes.huge Kirigami.Theme.colorSet: Kirigami.Theme.Window listView.header: Rectangle { visible: root.sync Kirigami.Theme.inherit: false Kirigami.Theme.colorSet:Kirigami.Theme.Complementary z: table.z + 999 width: table.width height: visible ? Maui.Style.rowHeightAlt : 0 color: Kirigami.Theme.backgroundColor RowLayout { anchors.fill: parent anchors.leftMargin: Maui.Style.space.small Label { Layout.fillWidth: true Layout.fillHeight: true anchors.margins: Maui.Style.space.small text: qsTr("Syncing to ") + root.syncPlaylist } ToolButton { Layout.fillHeight: true icon.name: "dialog-close" onClicked: { root.sync = false root.syncPlaylist = "" } } } } delegate: TableDelegate { id: delegate width: listView.width number : false coverArt : true showEmblem: false - onPressAndHold: if(Kirigami.Settings.isMobile && table.allowMenu) table.openItemMenu(index) + onPressAndHold: if(Maui.Handy.isTouch && table.allowMenu) table.openItemMenu(index) onRightClicked: if(table.allowMenu) table.openItemMenu(index) sameAlbum: { if(coverArt) { if(list.get(index-1)) { if(list.get(index-1).album === album && list.get(index-1).artist === artist) true else false }else false }else false } ToolButton { Layout.fillHeight: true Layout.preferredWidth: implicitWidth - visible: (Kirigami.Settings.isMobile ? true : delegate.hovered) + visible: (Maui.Handy.isTouch ? true : delegate.hovered) icon.name: "edit-clear" onClicked: { if(index === currentTrackIndex) player.stop() list.remove(index) } opacity: delegate.hovered ? 0.8 : 0.6 } onClicked: { table.currentIndex = index - if(Kirigami.Settings.isMobile) + if(Maui.Handy.isTouch) control.play(index) } onDoubleClicked: { table.currentIndex = index - if(!Kirigami.Settings.isMobile) + if(!Maui.Handy.isTouch) control.play(index) } } onArtworkDoubleClicked: contextMenu.babeIt(index) property int startContentY Component.onCompleted: { var lastplaylist = Maui.FM.loadSettings("LASTPLAYLIST", "PLAYLIST", []) var n = lastplaylist.length if(n>0) { for(var i = 0; i < n; i++) { var where = "url = \""+lastplaylist[i]+"\"" var query = Q.GET.tracksWhere_.arg(where) table.list.appendQuery(query); } }else { where = "fav = 1" query = Q.GET.tracksWhere_.arg(where) table.list.appendQuery(query); } // if(autoplay) // Player.playAt(0) } } // 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) } } diff --git a/widgets/PlaylistsView/PlaylistsViewModel.qml b/widgets/PlaylistsView/PlaylistsViewModel.qml index 08d4b05..5b9df94 100644 --- a/widgets/PlaylistsView/PlaylistsViewModel.qml +++ b/widgets/PlaylistsView/PlaylistsViewModel.qml @@ -1,242 +1,242 @@ import QtQuick 2.10 import QtQuick.Layouts 1.3 import QtQuick.Controls 2.10 import QtGraphicalEffects 1.12 import org.kde.kirigami 2.6 as Kirigami import org.kde.mauikit 1.0 as Maui import PlaylistsList 1.0 import TracksList 1.0 import "../../utils" import "../../view_models" import "../../db/Queries.js" as Q import "../../utils/Help.js" as H BabeList { id: control topPadding: Maui.Style.contentMargins holder.emoji: "qrc:/assets/dialog-information.svg" holder.title : qsTr("No Playlists!") holder.body: qsTr("Start creating new custom playlists") Connections { target: holder onActionTriggered: newPlaylistDialog.open() } Menu { id: _playlistMenu MenuItem { text: qsTr("Play") onTriggered: populate(Q.GET.playlistTracks_.arg(currentPlaylist), true) } MenuItem { text: qsTr("Rename") } MenuSeparator{} MenuItem { text: qsTr("Delete") Kirigami.Theme.textColor: Kirigami.Theme.negativeTextColor onTriggered: removePlaylist() } } Maui.BaseModel { id: _playlistsModel list: playlistsList } model: _playlistsModel section.criteria: ViewSection.FullString section.property: "type" section.delegate: Maui.LabelDelegate { label: "Personal" isSection: true width: control.width } delegate : Maui.ListDelegate { id: delegate width: control.width label: model.playlist Connections { target : delegate onClicked : { control.currentIndex = index currentPlaylist = playlistsList.get(index).playlist filterList.group = false populate(Q.GET.playlistTracks_.arg(currentPlaylist), true); } onRighClicked: { control.currentIndex = index currentPlaylist = playlistsList.get(index).playlist _playlistMenu.popup() } onPressAndHold: { control.currentIndex = index currentPlaylist = playlistsList.get(index).playlist _playlistMenu.popup() } } } - listView.header: Rectangle + listView.header: Rectangle { z: control.z + 999 width: control.width height: 100 + Maui.Style.rowHeight Kirigami.Theme.inherit: false Kirigami.Theme.colorSet: Kirigami.Theme.View color: Kirigami.Theme.backgroundColor ColumnLayout { anchors.fill: parent ListView { id: _defaultPlaylists Layout.fillHeight: true Layout.fillWidth: true Layout.margins: Maui.Style.space.medium spacing: Maui.Style.space.medium orientation :ListView.Horizontal model: playlistsList.defaultPlaylists() delegate: ItemDelegate { id: _delegate readonly property color m_color: modelData.color readonly property string playlist : modelData.playlist Kirigami.Theme.inherit: false Kirigami.Theme.backgroundColor: Qt.rgba(m_color.r, m_color.g, m_color.b, 0.9) Kirigami.Theme.textColor: "white" anchors.verticalCenter: parent.verticalCenter width: 200 height: parent.height * 0.9 background: Rectangle { color : Kirigami.Theme.backgroundColor radius: Maui.Style.radiusV * 2 border.color: m_color } Maui.ListItemTemplate { anchors.fill: parent iconSizeHint: Maui.Style.iconSizes.big label1.text: playlist label1.font.pointSize: Maui.Style.fontSizes.big label1.font.weight: Font.Bold label1.font.bold: true label2.text: modelData.description iconSource: modelData.icon iconVisible: true } Connections { target: _delegate onClicked: { _defaultPlaylists.currentIndex = index currentPlaylist = _delegate.playlist switch(currentPlaylist) { case "Most Played": populate(Q.GET.mostPlayedTracks, false); filterList.list.sortBy = Tracks.COUNT break; case "Rating": filterList.list.sortBy = Tracks.RATE filterList.group = true populate(Q.GET.favoriteTracks, false); break; case "Recent": populate(Q.GET.recentTracks, false); filterList.list.sortBy = Tracks.ADDDATE filterList.group = true break; case "Favs": populate(Q.GET.babedTracks, false); break; case "Online": populate(Q.GET.favoriteTracks, false); break; case "Tags": populateExtra(Q.GET.tags, "Tags") break; case "Relationships": populate(Q.GET.favoriteTracks, false); break; case "Popular": populate(Q.GET.favoriteTracks, false); break; case "Genres": populateExtra(Q.GET.genres, "Genres") break; default: break; } } } } } Item { Layout.fillWidth: true Layout.margins: Maui.Style.space.medium Layout.preferredHeight: Maui.Style.rowHeight ColorTagsBar { anchors.fill: parent onColorClicked: populate(Q.GET.colorTracks_.arg(color.toLowerCase()), true) } } } } } diff --git a/widgets/SearchView/SearchTable.qml b/widgets/SearchView/SearchTable.qml index 1fc3d36..1b6c807 100644 --- a/widgets/SearchView/SearchTable.qml +++ b/widgets/SearchView/SearchTable.qml @@ -1,122 +1,122 @@ import QtQuick 2.10 import QtQuick.Controls 2.10 import org.kde.kirigami 2.2 as Kirigami import org.kde.mauikit 1.0 as Maui import QtQuick.Layouts 1.3 import "../../view_models" import QtGraphicalEffects 1.0 import "../../view_models/BabeTable" import "../../db/Queries.js" as Q BabeTable { id: searchTable property alias searchInput : searchInput property var savedQueries : [] // property bool autoSuggestions : bae.loadSetting("AUTOSUGGESTIONS", "BABE", false) === "true" ? true : false property bool autoSuggestions : false trackNumberVisible: false headBar.visible: count holder.emoji: "qrc:/assets/dialog-information.svg" - holder.isMask: false + holder.isMask: true holder.title : "No search results!" holder.body: "Try with another query" holder.emojiSize: Maui.Style.iconSizes.huge coverArtVisible: true headBar.leftContent: ToolButton { icon.name: "edit-clear" onClicked: clearSearch() } footBar.middleContent: Maui.TextField { id: searchInput placeholderText: qsTr("Search...") Layout.fillWidth: true onAccepted: runSearch(searchInput.text) // onActiveFocusChanged: if(activeFocus && autoSuggestions) suggestionsPopup.open() onTextEdited: if(autoSuggestions) suggestionsPopup.updateSuggestions() } // footBar.leftContent: ToolButton // { // visible: true // icon.name: "view-filter" // icon.color: autoSuggestions ? babeColor : textColor // onClicked: // { // autoSuggestions = !autoSuggestions // Maui.FM.saveSettings("AUTOSUGGESTIONS", autoSuggestions, "BABE") // if(!autoSuggestions) // suggestionsPopup.close() // } // } SearchSuggestions { id: suggestionsPopup // focus: false parent: parent // modal: false // closePolicy: Popup.CloseOnPressOutsideParent } Rectangle { visible: suggestionsPopup.visible width: parent.width height: parent.height - searchInput.height color: Kirigami.Theme.backgroundColor z: 999 opacity: 0.5 } function runSearch(searchTxt) { if(searchTxt) if(searchTxt !== searchTable.title) { if(savedQueries.indexOf(searchTxt) < 0) { savedQueries.unshift(searchTxt) // suggestionsPopup.model.insert(0, {suggestion: searchInput.text}) Maui.FM.saveSettings("QUERIES", savedQueries.join(","), "BABE") } searchTable.title = searchTxt var queries = searchTxt.split(",") searchTable.list.searchQueries(queries) searchTable.forceActiveFocus() suggestionsPopup.close() } } function clearSearch() { searchInput.clear() searchTable.list.clear() searchTable.title = "" suggestionsPopup.close() } function populate(tracks) { searchTable.clearTable() for(var i in tracks) searchTable.model.append(tracks[i]) } }