In this development diary, I provide an update on progress made on Koto in the first half of May 2021!
In Dev Diary 7, I talked about all the work I did on Playlist functionality. From updating our previous / next track logic, to track rendering, initial GtkActionBar work, and more. Most of my goals for the last couple weeks were related to wrapping up playlist functionality, implementing some other goodies, and standardizing the codebase styling. Here is a list of the items I wanted to address:
- 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.
All items excluding the cleanup of the indexer code are now complete!
Playlist modification is now supported. You can change the name or image for a playlist and it will update all the various aspects of the user experience such as the Koto playlist navigation button, header on the Playlist page, and the popover as part of our Playlist Add / Remove Tracks popover.
This is done as a result of our new “modified” signal in the KotoPlaylist.
All functionality related to single and multi-track selection on the Playlist page and the individual album disc views, including the GtkActionBar utilization, is now implemented.
- If you have one track selected, you will be able to play it directly. If you are on the Playlist page when you select a track, you can navigate directly to the artist’s page. When you have multiple tracks selected, those buttons will disappear dynamically.
- If you are on a Playlist’s page, you can directly click to remove tracks from a Playlist regardless of how many are selected.
- If you are on an Artist’s page, you can selected one or more tracks in a given disc of an album and either add or remove them from a Playlist.
After wrapping up that functionality, I moved on to implementing notification support for when a track changes. This just uses
notify-send at the moment, after I came across a few bugs with libnotify functionality that oddly does not affect notify-send itself. The plan is to circle back around though and drop libnotify / notify-send functionality altogether, instead we will have our own DBus client that will do the heavy lifting for us. One less dependency.
Once we got track change notifications working, I finally got around to finishing up my uncrustify configuration and formatted the entire project codebase. That was a fairly chonky commit, with 4847 additions and 1982 deletions.
Lastly, I wrapped up that couple weeks by renaming all the KotoIndexed structs to just be prefixed with Koto, for example KotoIndexedTrack just becomes KotoTrack. It is cleaner and not really related to “indexed” at this point.
During the Koto development session on May 18th, I started work on our configuration system. This leverages tomlc99 to support our desired TOML-based configuration format. TOML provides an INI-like configuration format with benefits like arrays, tables, and even arrays of tables. The idea behind this is we can cleanly divide settings up into various sections, like libraries, playback, UI, etc.
Here is what the current file format is likely to look like.
[[library]] directory = "/home/joshua/DifferentAudiobooksDir" override_builtin = TRUE [[library]] directory = "Audiobooks" name = "idk some name here" type = "audiobooks" uuid = "5e19dd80-abc1-4033-a8d1-a0fa39d4bc0b" [[library]] directory = "Podcasts" name = "Historical Podcasts" type = "podcasts" uuid = "5e19dd80-abc1-4033-a8d1-a0fa39d4bc0b" [playback] continue_on_playlist = FALSE last_volume = 73 maintain_shuffle = TRUE uuid = "fb969ea8-4caf-42c1-afca-9c169171769e" [ui] name = "gruvbox" override_app = TRUE
This should also give you insight as to my line of thinking for the multi-library support. Effectively, you have a list of libraries that can contain content that is one of three types:
It will be highly recommended, if you want them to be indexed correctly that is, to separate content into those types and have them in different directories. By default, we will use:
- XDG_HOME_DIR + Audiobooks for audiobooks
- XDG_MUSIC_DIR for music
- XDG_HOME_DIR + Podcasts for podcasts
These default / built-in libraries will not need to be specified, however you will be able to override them if desired to point them to a different directory, such as a different audiobooks directory. On top of this, you will be able to specify directories in a specific volume on a drive (a drive can have many volumes). A missing directory will imply to index all contents of a volume.
For playback, the current settings I have thought of are:
- Enabling the continuation of playback of a Playlist after selected and playing a specific song.
- Last used volume, which will be useful for keeping some predictability across user sessions.
- Maintaining the shuffle functionality across albums and playlists.
For the user interface, my desire is to have “sane defaults” (like using a built-in dark theme) with options to make Koto look the way you want. Some examples:
- Changing the internal theme to another built-in one, such as light (ew but okay) or eventually other options like gruvbox and solarized that I would like to bring to the table.
- Disabling the built-in theming, allowing the GTK theme to override the app. This may be useful if / when GTK themes implement their own tweaks for Koto.
I want Koto to fit in to your desktop (though if you are using Plasma, that may be more difficult). I am not one of those “do not theme my apps” developers. Go wild, make it pink and cyan for all I care. When Koto is ready, so will the documentation for styling it the way you like.
On top of all of this, we will inevitably have settings for each Playlist, such as those shown below.
[[playlist]] always_shuffle = TRUE sort_order = "oldest-first"
These settings will enable you to always enable shuffling when selecting a Playlist (this was a feature request on one of my Koto streams) or the sort order.
So the intent is to use tomlc99 for the TOML parsing. Apparently, it does not handle saving at all (weird since it already knows how to parse the file, why not provide a multiline string representation of the entire thing as a function), so I will need to implement that myself. On the plus side, this will enable me to introduce functionality like the omitting of configuration keys which are identical to the default, so we can keep the config as clean as possible.
This config will be stored in XDG_CONFIG_DIR +
config.toml. Per 👏 XDG 👏 Specifications 👏. Looks at other application developers.
Goals For Next Couple Weeks
So over the next couple weeks, my goals are:
- Implement the most relevant aspects of the TOML-based configuration support, ranging from setting key changes to file saving. We already have implemented the support for the file watcher, so if the config is modified outside of Koto, we can reload our internal representation of the config.
- Update our database tracks to have a reference to the Koto Library it belongs to.
- Update our Koto library logic and start implementing support for multiple libraries.
Ideally I would like to wrap those items by the end of the month, so I can move on to more library functionality, audiobook support, as well as developing “ephemeral” Koto Libraries for removable media (like mobile devices attached via USB), like we have “ephemeral” Koto playlists.
Thanks as always to all of you supporting my work on open source desktop Linux software!