#Playlists
In Dev Diary 6, I had the following goals related to playlist functionality:- Implementation of a playlist-metadata signal for KotoPlaylist so we can notify when a playlist has been modified.
- Updating our logic for going to the previous and next tracks to leverage our currently selected model (or default based on the type we set during creation) and base the tracks on that instead.
- Implement the track rendering in the GtkListView.
- Implement the selection handling and GtkActionBar rendering, events, etc. when clicking on one or more tracks.
- Implement playlist-removed handling in the KotoNav to delete the button.
- We create two different GQueue objects and one GListStore of KOTO_TYPE_INDEXED_TRACK. One of the GQueue is basically for the unmodified version of tracks, so no matter the sorting it is the same. The other GQueue is our sorted tracks, which is used to determine what the previous and next tracks are based on the current UUID of the current track playing (if any). Our GListStore is used for any models which leverage it via GListModel for a GtkListView, such as the Playlist page.
- Whenever we add a track, whether during the initial loading of the Playlist or otherwise, we add the UUID of the track to the tracks and sorted tracks GQueues and append the KotoIndexedTrack to the GListStore.
- If we have marked the playlist as finalized (this is done so we can track whether we should do a sort or wait until a mass addition of tracks are added to a playlist, e.g. during first load of Koto), we will re-sort the sorted GQueue and GListStore. This updates our data model and the graphical model instantly!
- Our "apply model" for changing the sorting model no longer rebuilds the GQueue and GListStore in their entirety. Instead, we apply a re-sort of the GQueue via
koto_playlist_model_sort_by_uuid, which gets the two KotoIndexedTracks by the UUIDs provided in the GQueue and passes it tokoto_playlist_model_sort_by_track, which is also used by our GListStore. This allows us to keep the data model and the graphical model in sync.
So the tldr of all of this is: When you change the sorting model via the UI, it updates the data model and your playlist playback next / previous tracks update accordingly. This was a royal pain to get sorted, as was using the GtkListView to begin with, so unfortunately that put me a little behind on other items.
For example, I was not able to get around to implementing the playlist-metadata signal for KotoPlaylist yet. That is trivial and can be done within a couple hours though, so not really worried on that front. I was not able to get around to implementing the functionality for using GtkActionBar for the selection handling either due to the time eaten up by implementing the GtkListView or various GTK4 Popover bugs.
Our GTK4 Popover called KotoAddRemoveTrackPopover, while not currently fancy, does the job for adding and removing one or more tracks from a playlist. It is already developed in a manner that supports passing in a list of tracks, which means we can add or remove multiple tracks at once. This popover leverages our KotoCartographer's playlist-added and playlist-removed signals to dynamically create GtkCheckButtons for each playlist, and whenever we set the tracks we want to add or remove before showing the popover, we will update the popover checkboxes in a predictable manner, which is:
- If you only have one track selected, the per-playlist checkboxes will be checked if that track is already in the playlist.
- If you have more than one track selected, the per-playlist checkboxes will only be checked if all of the tracks are in the playlist.
#Other Items
Work over the last couple weeks has almost exclusively been related to Playlist functionality, however I did get around to a few other items I really wanted to take care of:- Implement helper functions as part of our KotoButton for "click" and touch gesture setup to avoid repetitive GtkEventController / Gesture code.
- Refactoring the album artwork image used in the KotoAlbumView into a generic widget that can be leveraged in our KotoPlaylistPage.
- Finish necessary VS Code bits so I can hopefully launch Koto in various modes and stop using GNOME Builder (too buggy for me).
koto_button_add_click_handler function. This will use our predefined GTK gestures and event controllers, allowing us to just pass in a GLib Callback and the desired primary or secondary button enumerated value and it sets up the signal connection for us. This transforms 5-6 repetitive lines used pretty much everywhere into a single line, which is nice.
Our album artwork image has been refactored into a KotoCoverArtButton component, allowing us to reuse it across the playlist page and the KotoAlbumView for playing either a playlist or an album.
I finished my move from GNOME Builder to Visual Studio Code. This was achievable thanks to a mix of their task system and a bit of shoehorning and trickery of their "launch" system as well, which is typically used for debugging purposes but just pass a "miDebuggerPath" of nothing (empty string) for it to not launch the app with gdb.
My uncrustify config is mostly done, aside from some minor issues with pointer positions being inconsistent between variables and return types for functions. Simple enough to fix up, just been focused on actually implementing code.
I did some polishing of the theming. The track information in the playerbar looks halfway decent now and some parts of the UI is using what is likely going to be the primary color of Koto (a lime-ish green). Pretty happy with it so far, but feedback is always appreciated.
#Upcoming
Playlist functionality is starting to get wrapped up and I expect it to be done over the next couple weeks. At that point, I can actively dogfood Koto and it brings it one step closer to being available for testing as alpha builds. Here is what is coming up over the next couple weeks:- Implementation of a playlist-metadata signal for KotoPlaylist so we can notify when a playlist has been modified.
- Implement the selection handling and GtkActionBar rendering, events, etc. when clicking on one or more tracks. This will be done in the album view and the playlist page.
- Implement playlist modification UX.
- Finish the uncrustify config so I can have a standardized code styling.
- Implement song-specific playback
- Implement notifications for track switching.
- Rename "indexed" classes like KotoIndexedArtist to just KotoArtist
- Start cleanup of indexer and library code for multiple library "types" in preparation multi-library support leading into audiobooks.
As I mentioned in Dev Diary #6, my goal was to adopt GitHub's project Kanban workboards and mass file issues on work I need to get done, in addition to various milestones. The intent with this was to provide clarity on progress, when various builds should be expected, and transparency on planned work.
I have filed 30 "issues" for tracking various TODO items and broke them apart across Alpha 1, Alpha 2, and Beta 1. As we get closer to various builds / milestones, items may shift around or be re-prioritized, but this should provide a clear path leading closer to a stable release. There is still a fair bit to do after beta 1, like auto-generated playlists for different times of the day (as an example) but should be comprehensive enough for folks.
#Streams
All development streams happen on my Twitch every Tuesday and Thursday from 12pm-5pm GMT+3 / EEST (Eastern European Time). If you miss these streams, I upload all of them to Odysee so be sure to check them out! I am part of Odysee's Viewer Rewards Program, so if you have an Odysee account, you can now get a daily watch reward of a bit of LBRY Credits (LBC) when you watch my videos, and I get some too!