Dev Diary 8: Koto May Progress Report (A-side)
dev-diary koto opensource tech

In this development diary, I provide an update on progress made on Koto in the first half of May 2021!

This content releases early on my Patreon! If you like what you see and want to support development of this and many other projects, check it out. If Patreon isn’t your thing, I am on Liberapay as well!

Wrap Up

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:

  1. Implementation of a playlist-metadata signal for KotoPlaylist so we can notify when a playlist has been modified.
  2. 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.
  3. Implement playlist modification UX.
  4. Finish the uncrustify config so I can have a standardized code styling.
  5. Implement song-specific playback
  6. Implement notifications for track switching.
  7. Rename “indexed” classes like KotoIndexedArtist to just KotoArtist
  8. 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.

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.

Coming Up

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:

  1. Audiobooks
  2. Music
  3. Podcasts

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:

  1. XDG_HOME_DIR + Audiobooks for audiobooks
  2. XDG_MUSIC_DIR for music
  3. 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:

  1. Enabling the continuation of playback of a Playlist after selected and playing a specific song.
  2. Last used volume, which will be useful for keeping some predictability across user sessions.
  3. 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:

  1. 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.
  2. 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 + com.github.joshstrobl.koto as config.toml. Per 👏 XDG 👏 Specifications 👏. Looks at other application developers.

Goals For Next Couple Weeks

So over the next couple weeks, my goals are:

  1. 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.
  2. Update our database tracks to have a reference to the Koto Library it belongs to.
  3. 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!