Roon Extension: Roon Web Controller v1.1.1

Both great ideas. Sorting the Genre is something I can look into, but I do not think it is something I can implement. What is showed is what the API returns and it is based on the number of albums/artists in each of the Genres. It is the same order as in the official client. The order is dictated by the “item_key” value (see below). Sorting this would take operations on an intermediate array which could slow things down a bit. This would break further if there are more than 100 entries since the API always returns a maximum of 100 entries - even if the application requests another list size. Same is true for the Album sort.

There is a little bit of control over the Artist and Composer sort options in the “Settings” section - but those are both options that are provided by the API, so it controls what the server returns.

Unfortunately, caching is impractical based on what the Roon API provides. (I REALLY wanted to do caching, but couldn’t!)

For a better explanation, I will give you an example of a typical flow of data as returned by the API.

Click home:

[ { title: 'Library',
    subtitle: null,
    image_key: null,
    item_key: '1572:0' },
  { title: 'Playlists',
    subtitle: null,
    image_key: null,
    item_key: '1572:1' },
  { title: 'Internet Radio',
    subtitle: null,
    image_key: null,
    item_key: '1572:2' },
  { title: 'Genres',
    subtitle: null,
    image_key: null,
    item_key: '1572:3' },
  { title: 'Settings',
    subtitle: null,
    image_key: null,
    item_key: '1572:4' } ]

Click Library:

[ { title: 'Search',
    subtitle: null,
    image_key: null,
    item_key: '1573:0',
    input_prompt: { prompt: 'Search', action: 'Go' } },
  { title: 'Artists',
    subtitle: null,
    image_key: null,
    item_key: '1573:1' },
  { title: 'Albums',
    subtitle: null,
    image_key: null,
    item_key: '1573:2' },
  { title: 'Tracks',
    subtitle: null,
    image_key: null,
    item_key: '1573:3' },
  { title: 'Composers',
    subtitle: null,
    image_key: null,
    item_key: '1573:4' } ]

Click Home:

[ { title: 'Library',
    subtitle: null,
    image_key: null,
    item_key: '1574:0' },
  { title: 'Playlists',
    subtitle: null,
    image_key: null,
    item_key: '1574:1' },
  { title: 'Internet Radio',
    subtitle: null,
    image_key: null,
    item_key: '1574:2' },
  { title: 'Genres',
    subtitle: null,
    image_key: null,
    item_key: '1574:3' },
  { title: 'Settings',
    subtitle: null,
    image_key: null,
    item_key: '1574:4' } ]

Notice that the “item_key” field increments with every click. Unfortunately that is what is returned by the API. This behavior is mentioned in these threads as well (Browse API questions and Questions on Browse APIs). And that means that any entry that is cached will have an old/incorrect “item_key” - and navigation fails with an incorrect “item_key”. So caching is not useful.

Unfortunately this also means that if you start browsing on one device, move to another device, then return to the original device, the original device will not browse until you hit the “Refresh” icon to get the current “item_key” (which incidentally is why it is there! :slight_smile:)

The ever changing “item_key” is also one of the reasons why the web app uses HTTP POST to retrieve data from the Node server. HTTP POST requests are never cached and cannot be bookmarked, whereas HTTP GET requests can be.

Another reason is the fact that HTTP POST requests have an unlimited body size, whereas HTTP GET requests are limited to a URL length of 2,048 characters - which may be an issue if components of this web app is embedded in another web app. And since one of the features of this release is support for being embedded in other web pages, URL length could become an issue.