#Background

#Bootstrapped
During the first stream of Koto, I worked on bootstrapping Koto, that is to say I set up the project (which GNOME Builder was an immense help in enabling, especially with the Meson build files and postinstall bits) and some of the initial structure to the application, such as the GtkWindow, HeaderBar, etc. There was a lot of fumbling about early on, since my more formal introduction to C aside from needing to patch other software (or the kernel) was just days prior starting with a rather well written C Primer by the Enlightenment Foundation Library (EFL) developers. Writing GTK applications in C was foreign to me, not to say there is not considerably more to learn about GTK and GLib still. I was fairly optimistic early on that the application would be GTK4 and while that is certainly remains a possibility for the future, unfortunately there was considerable changes made in GTK4 which made sub-classing some classes, such as the GtkHeaderBar, no longer possible. This is actually something I discovered when researching a compilation error and it turns out there is actually a Vala issue filed regarding it as well. Sub-classing is especially useful because it enables you to derive your own classes (in our case of the GtkHeaderbar it would be a "custom" headerbar with our own methods, members, etc.) while inheriting the variables and methods of its parent class.
#Widget Galore
While having the Matryoshka doll equivalent to classes and widgets (where a widget is used in another widget, which builds on top of yet another widget) might sound convoluted, if done right it can lend itself to a simpler, more consistent codebase, as you are centralizing the logic for various functionality, whether that is something as simple as updating an icon in a custom button to having shared logic for navigation to a generic content indexing backend. Over the last couple weeks of streams, as the foundations for Koto's backend and frontend have developed, I have been proactively working to reduce code duplication. Some examples:- Initially when implementing the PlayerBar, I had some repetitive code for generating various buttons for backwards, play / pause, forward, etc. buttons. I recognized this was going to be a problem quickly and changed it to be a utility function called
koto_create_flat_icon_button
which took in the name of the icon and the desired size, applying theflat
class and returning the GtkButton. Nothing crazy. - During my second stream when I was diving into building out the Koto sidepane navigation widget class (
KotoNav
), I recognized that across the primary navigation as well as the Devices sidepane, there would be duplicate logic for the expanders. So I implemented aKotoExpander
which has a custom header and uses the GtkRevealer to toggle the visibility of content we set via a GtkBox. Furthermore, I implemented aKotoFlipperButton
which allows us to easily flip between two different images / icons for a GtkButton, enabling us to for example switch between ▼ and ▲ caret icons depending on the Expander state. - During my third and fourth stream, I implemented a shared
KotoButton
class to leverage across various parts of the UI, immediately moving to leverage it in theKotoExpander
. This enables me to have unified logic for buttons with icons and images (both treated as GdkPixBuf), text, and even a custom badge (useful for indicating in the navigation that you have new podcasts to listen to, as an example).
koto_create_flat_icon_button
function will be deprecated in favor of using the KotoButton
for our expander arrows, and KotoFlipperButton
with either be deprecated or switched to sub-classing our KotoButton
.
To break it down a little better, here is a wire-frame design of Koto that details how is / it will be (after the above mentioned deprecations and sub-classing). Some of the dimensions are exaggerated to assist with visualizing, other design elements omitted that are not relevant.

#Indexer
Towards the end of the stream which took place on February 9th 2021, I started work on the file indexer for Koto. This file indexer will be responsible for iterating through a list of content libraries provided as directories, currently set toXDG_MUSIC_DIR
but will be expanded on as the indexer work continues. It will look for files in the immediate directory, as well as all sub-directories, and does so on a separate thread to prevent blocking the UI. This iteration is done through usual syscalls like opendir
and readdir
to get the directory entry structs. When we encounter a file, we leverage libmagic
to get the MIME type of the file, rejecting anything that isn't an audio file (starts with audio/
) or an image file (image/
), as these are currently the two types of files we care about. No doubt it will be expanded on in the future, but the primary task at the moment is to take all that information, and break it out into the following structures:
KotoIndexedLibrary
: This will hold references to all our indexed content for that specific library, such as audiobooks, podcasts, and music. Within the library structure, we will have a HashTable (think of it as a basic key/value storage) for various content, currentlymusic_artists
. The value of each artists is aKotoIndexedArtist
.KotoIndexedArtist
: This structure will detail the name of each artist, the path to the artwork for the artist (if any), the filepath to it on the system, and contains a HashTable of albums, the value of each album is aKotoIndexedAlbum
KotoIndexedAlbum
: This structure will detail the name of each album, the path to the artwork (if any), and a HashTable of songs, the value of each being aKotoIndexedFile
.KotoIndexedFile
: This structure simply has the "parsed name", file name and path. The parsed name is expected to be either extrapolated based on various formats (01 - In Your Honor
from theIn Your Honor
album ofFoo Fighters
just beingIn Your Honor
as the parsed name) or from the ID3v2 information. I expect this indexed file data to grow significantly as we integrate playlists, tags, genres, etc.
#Summary of Work
Over the last few weeks, the following has been done:- Initial bootstrapping of the project.
- Building several widgets, taking the project from being just a window and a headerbar to having a playerbar, navigation, and a clear separation between the navigation and "primary" content view.
- Beginnings of the file indexer.
#Upcoming
Over the next couple weeks, my goals are:- Migrate the KotoWindow and KotoHeaderBar away from using Glade UI templating.
- Deprecate
koto_create_flat_icon_button
and updateKotoFlipperButton
to leverage our newKotoButton
. - Leverage the file indexer in building our the structures we have made currently, changing them as needed.
- Investigate various ID3 parsing libraries to determine the best to use (e.g. id3lib and taglib).
- Design the Sqlite database schema and begin to perform transactions based on our structured data.
- Set up SASS / SCSS compilation and move existing styling from CSS to SASS, continuing to polish the user experience to reflect the mockup as time goes on.
#Streams (So Far)
All development streams happen on my Twitch every Tuesday and Thursday from 12pm-5pm GMT+2 / EEST (Eastern European Standard Time). If you miss these streams, Iupload all of them to Odysee so be sure to check them out!