diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ff5f1eb..b8df861 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -57,7 +57,7 @@ jobs: set -x assets=() for asset in RPMS/*.rpm; do - assets+=("-a" "$asset") + assets+=("$asset") done tag_name="${GITHUB_REF##*/}" gh release create "$tag_name" "${assets[@]}" @@ -70,7 +70,7 @@ jobs: set -x assets=() for asset in RPMS/*.rpm; do - assets+=("-a" "$asset") + assets+=("$asset") done tag_name="${GITHUB_REF##*/}" gh release create "$tag_name" -p -n "This is a pre-release for testing purposes only. It may or may not be unstable." "${assets[@]}" diff --git a/qml/harbour-tidalplayer.qml b/qml/harbour-tidalplayer.qml index e684a6a..580e85e 100644 --- a/qml/harbour-tidalplayer.qml +++ b/qml/harbour-tidalplayer.qml @@ -271,8 +271,9 @@ ApplicationWindow signal searchFinished() signal trackAdded(int id, string title, string album, string artist, string image, int duration) - signal albumAdded(int id, string title, string artist, string image) - signal artistAdded(int id, string name) + signal albumAdded(int id, string title, string artist, string image, int duration) + signal artistAdded(int id, string name, string image) + signal playlistSearchAdded(int id, string name, string image, int duration, string uid) signal trackChanged(int id, string title, string album, string artist, string image, int duration) signal albumChanged(int id, string title, string artist, string image) @@ -321,13 +322,18 @@ ApplicationWindow } ); - setHandler('addArtist', function(id, name){ - pythonApi.artistAdded(id, name) + setHandler('addArtist', function(id, name, image){ + pythonApi.artistAdded(id, name,image) } ); - setHandler('addAlbum', function(id, title, album, artist, image){ - pythonApi.albumAdded(id, title, album, artist, image) + setHandler('addAlbum', function(id, title, album, artist, image, duration){ + pythonApi.albumAdded(id, title, album, artist, image, duration) + } + ); + + setHandler('addPlaylist', function(id, name, image, duration, uid){ + pythonApi.playlistSearchAdded(id, name, image, duration, uid) } ); diff --git a/qml/pages/AlbumPage.qml b/qml/pages/AlbumPage.qml index 2ff6d25..c5c5654 100644 --- a/qml/pages/AlbumPage.qml +++ b/qml/pages/AlbumPage.qml @@ -102,6 +102,15 @@ Page { aLtrackList.type = 2 aLtrackList.addTrack(title, artist, album, id, duration) } + + onTrackChanged: + { + for(var i = 1; i < aLtrackList.listModel.count; ++i) + if(aLtrackList.listModel.get(i).name === title) + { + aLtrackList.scrollTo(i); + } + } } } } diff --git a/qml/pages/ArtistPage.qml b/qml/pages/ArtistPage.qml index 58ec91a..7fcbaee 100644 --- a/qml/pages/ArtistPage.qml +++ b/qml/pages/ArtistPage.qml @@ -73,7 +73,6 @@ Page { TrackList { id: topTracks title : "Popular Tracks" - anchors { top: infoCoulumn.bottom// Anker oben an den unteren Rand der Column topMargin: 650 // Abstand zwischen der Column und dem ListView @@ -84,7 +83,6 @@ Page { //bottom: parent.bottom// Anker unten am unteren Rand des Eltern-Elements (Page) } height: 600 - start_on_top : true } } diff --git a/qml/pages/FirstPage.qml b/qml/pages/FirstPage.qml index 0b5b07f..f61b1c4 100644 --- a/qml/pages/FirstPage.qml +++ b/qml/pages/FirstPage.qml @@ -70,7 +70,7 @@ Page { id: searchString width: parent.width placeholderText: "Type and Search" - text: "" + text: "Cover" label: "Please wait for login ..." EnterKey.enabled: text.length > 0 EnterKey.iconSource: "image://theme/icon-m-search" @@ -186,18 +186,29 @@ Page { rightMargin: Theme.horizontalPageMargin verticalCenter: parent.verticalCenter } - IconButton { + + Image { id: mediaType - icon.source: { + source: { + if(model.image === "") + { if(listModel.get(model.index).type === 1) "image://theme/icon-m-media-songs" else if(listModel.get(model.index).type === 3) "image://theme/icon-m-media-artists" else if (listModel.get(model.index).type === 2) "image://theme/icon-m-media-albums" + else if (listModel.get(model.index).type === 4) + "image://theme/icon-m-media-playlists" + else if (listModel.get(model.index).type === 5) + "image://theme/icon-m-video" + } + else + model.image } + fillMode: Image.PreserveAspectFit - height: trackName.height + //width: 32 } Column { @@ -216,6 +227,8 @@ Page { model.name else if (listModel.get(model.index).type === 2) model.name + " (" + dur +")" + else if (listModel.get(model.index).type === 4) + model.name + " (" + dur +")" } x: Theme.horizontalPageMargin @@ -226,7 +239,7 @@ Page { Label { id: artistName color: listEntry.highlighted ? Theme.highlightColor : Theme.primaryColor - text: model.artist + " ( "+model.album +" )" + text: model.artist + " ( " + model.album + " )" visible: listModel.get(model.index).type === 1 x: Theme.horizontalPageMargin truncationMode: elide @@ -245,6 +258,8 @@ Page { playlistManager.playTrack(listModel.get(model.index).id) else if(listModel.get(model.index).type === 2) playlistManager.playAlbum(listModel.get(model.index).id) + else if(listModel.get(model.index).type === 4) + pythonApi.playPlaylist(listModel.get(model.index).uid) } @@ -282,7 +297,7 @@ Page { { if(listModel.get(model.index).type === 1) { - pageStack.push(Qt.resolvedUrl("TrackPage.qml")) + pageStack.push(Qt.resolvedUrl("AlbumPage.qml")) pythonApi.getTrackInfo(listModel.get(model.index).id) }else if(listModel.get(model.index).type === 2) { @@ -317,7 +332,8 @@ Page { listModel.append( { "name": name, "id" : id, - "type" : 3 + "type" : 3, + "image" : image }) } @@ -327,7 +343,22 @@ Page { listModel.append( { "name": title, "id" : id, - "type" : 2 + "type" : 2, + "image" : image, + "duration" : duration + }) + } + + onPlaylistSearchAdded: + { + console.log(id) + listModel.append( + { "name": name, + "id" : id, + "type" : 4, + "image" : image, + "duration" : duration, + "uid" : uid }) } diff --git a/qml/pages/PlaylistPage.qml b/qml/pages/PlaylistPage.qml index e76e2bc..665486c 100644 --- a/qml/pages/PlaylistPage.qml +++ b/qml/pages/PlaylistPage.qml @@ -16,6 +16,12 @@ Page { width: parent.width anchors.fill: parent PullDownMenu { + MenuItem { + text: minPlayerPanel.open ? "Hide player" : "Show player" + onClicked: minPlayerPanel.open = !minPlayerPanel.open + anchors.horizontalCenter: parent.horizontalCenter + } + MenuItem { text: qsTr("Clear") onClicked: @@ -30,7 +36,8 @@ Page { id: pLtrackList title : "Current Playlist" allow_add: false - start_on_top : true + start_on_tap : true + allow_play: false anchors { top : parent.bottom fill: parent diff --git a/qml/pages/TrackList.qml b/qml/pages/TrackList.qml index c48e723..38e93d0 100644 --- a/qml/pages/TrackList.qml +++ b/qml/pages/TrackList.qml @@ -12,9 +12,10 @@ Column property string track_list property string track_id_list property bool allow_add : true - property bool start_on_top : false + property bool start_on_tap : false property int highlight_index : -1 property int type : 0 + property bool allow_play : true property string title : "Track List" SectionHeader { @@ -37,9 +38,15 @@ Column }) } + function scrollTo(index) + { + tracks.positionViewAtIndex(index) + } + IconButton { - icon.source: "image://theme/icon-m-play" + icon.source: "image://theme/icon-m-simple-play" + visible: allow_play onClicked: { playlistManager.clearPlayList() @@ -50,6 +57,7 @@ Column } SilicaListView { + id:tracks anchors { top: sectionHeader.bottom// Anker oben an den unteren Rand der Column topMargin: 120 // Abstand zwischen der Column und dem ListView @@ -69,46 +77,59 @@ SilicaListView { id: listEntry Row { Column { + Row { + Label { + id: trackName + color: (listEntry.highlighted || model.index === highlight_index) ? Theme.highlightColor : Theme.primaryColor + text: model.name + x: Theme.horizontalPageMargin + truncationMode: Fade + font.pixelSize: Theme.fontSizeSmall + } Label { property string dur: { if ((model.duration) > 3599) Format.formatDuration(model.duration , Formatter.DurationLong) else return Format.formatDuration(model.duration , Formatter.DurationShort) } - id: trackName + id: time color: (listEntry.highlighted || model.index === highlight_index) ? Theme.highlightColor : Theme.primaryColor - text: model.name + " (" + dur +")" + text: " (" + dur + ")" x: Theme.horizontalPageMargin - truncationMode: elide + truncationMode: Fade font.pixelSize: Theme.fontSizeSmall } - + } + Row{ Label { id: artistName color: (listEntry.highlighted || model.index === highlight_index) ? Theme.highlightColor : Theme.primaryColor - text: - { - if(type == 2 ) - { - model.artist - } - else if(type == 1 ) - { - model.artist + " ( "+model.album +" )" - } - } + text: model.artist visible: listModel.get(model.index).type === 1 x: Theme.horizontalPageMargin - truncationMode: elide + truncationMode: Fade font.pixelSize: Theme.fontSizeSmall } + + Label { + + id: albumName + color: (listEntry.highlighted || model.index === highlight_index) ? Theme.highlightColor : Theme.primaryColor + text: " - " + model.album + + visible: listModel.get(model.index).type === 1 + x: Theme.horizontalPageMargin + truncationMode: Fade + font.pixelSize: Theme.fontSizeSmall + } + } } } onClicked: { - if(start_on_top) + if(start_on_tap) { mediaPlayer.blockAutoNext = true playlistManager.playPosition(model.index) diff --git a/qml/tidal.py b/qml/tidal.py index 1683083..32a7b5d 100644 --- a/qml/tidal.py +++ b/qml/tidal.py @@ -72,19 +72,33 @@ def genericSearch(self, text): self.tracks = result["tracks"] for i in self.tracks: try: - pyotherside.send("addTrack", i.id, i.name, i.album.name, i.artist.name, i.album.image(320), i.duration) - except AttributeError: + pyotherside.send("addTrack", i.id, i.name, i.album.name, i.artist.name, i.album.image(80), i.duration) + print(i.name) + except Exception as e: pyotherside.send("addTrack", i.id, i.name, i.album.name, i.artist.name, "", i.duration) + logging.error(traceback.format_exc()) + self.artists = result["artists"] for i in self.artists: - pyotherside.send("addArtist", i.id, i.name) + try: + pyotherside.send("addArtist", i.id, i.name, i.image(80)) + except AttributeError: + pyotherside.send("addArtist", i.id, i.name, "") + except ValueError: + pyotherside.send("addArtist", i.id, i.name, "") self.albums = result["albums"] for i in self.albums: try: - pyotherside.send("addAlbum", i.id, i.name, i.artist.name, i.image(320)) + pyotherside.send("addAlbum", i.id, i.name, i.artist.name, i.image(80), i.duration) except AttributeError: - pyotherside.send("addAlbum", i.id, i.name, i.artist.name, "") + pyotherside.send("addAlbum", i.id, i.name, i.artist.name, "", i.duration) + + self.playlists = result["playlists"] + for i in self.playlists: + pyotherside.send("addPlaylist", i.id, i.name, "", i.duration, i.id) + + def searchTracks(self, text, number): pyotherside.send("trackSearchFinished")