EARHORNMUSIC UPnP · Android TV · Phones · Android Auto · GNU/Linux
Release 0.5.0

Destinations.kt

package dev.stave.ui.nav

import android.net.Uri

object Destinations {
    const val SERVERS = "servers"
    const val WELCOME = "welcome"
    const val BROWSE = "browse/{udn}/{containerId}"
    const val DETAIL = "detail/{udn}/{containerId}"
    const val NOW_PLAYING = "now_playing"
    const val QUEUE = "queue"
    const val MORE = "more/{udn}/{mode}/{query}?highlight={highlight}"
    const val SEARCH = "search"
    const val RANDOM_PICKER = "random_picker"
    const val ABOUT = "about"
    const val GUIDE = "guide"
    const val METADATA = "metadata"
    const val LYRICS = "lyrics"
    const val PLAYLISTS = "playlists"
    const val PLAYLIST_SAVE = "playlist_save"
    const val SETTINGS = "settings"
    const val PLAYBACK_SETTINGS = "playback_settings"

    /** Local music (on-device files) routes. Sit alongside UPnP rather than
     *  pretending to BE a UPnP server — a separate code path keeps both
     *  simpler. */
    const val LOCAL_HUB = "local_hub"
    const val LOCAL_ALBUMS = "local_albums"
    const val LOCAL_ARTISTS = "local_artists"
    const val LOCAL_SONGS = "local_songs"
    const val LOCAL_GENRES = "local_genres"
    /** Tracks matching a specific genre. */
    const val LOCAL_GENRE_DETAIL = "local_genre/{genreName}"
    /** Tracks within a single local album. */
    const val LOCAL_ALBUM = "local_album/{albumId}"
    /** Albums by a single local artist. */
    const val LOCAL_ARTIST = "local_artist/{artistId}/{artistName}"

    fun localAlbum(albumId: Long) = "local_album/$albumId"
    fun localArtist(artistId: Long, artistName: String) =
        "local_artist/$artistId/${Uri.encode(artistName)}"
    fun localGenre(genreName: String) = "local_genre/${Uri.encode(genreName)}"

    fun browse(udn: String, containerId: String) =
        "browse/${Uri.encode(udn)}/${Uri.encode(containerId)}"

    fun detail(udn: String, containerId: String) =
        "detail/${Uri.encode(udn)}/${Uri.encode(containerId)}"

    /** Build a "more" destination URL.
     *
     *  [highlightContainerId] is optional. When provided, MoreScreen will
     *  scroll to and focus the row whose container ID matches, instead of
     *  defaulting to row 0. Used by NowPlayingScreen's "Albums by …" picker
     *  so the user lands on the album they're currently listening to,
     *  surrounded by the artist's other work, rather than on the alphabetical-
     *  first album in the list. */
    fun more(udn: String, mode: String, query: String, highlightContainerId: String? = null): String {
        val base = "more/${Uri.encode(udn)}/${Uri.encode(mode)}/${Uri.encode(query)}"
        return if (highlightContainerId.isNullOrEmpty()) base
        else "$base?highlight=${Uri.encode(highlightContainerId)}"
    }

    /** METADATA is parameterless — the track reference is stashed in MetadataHandoff.
     *  We include a separate fn for symmetry with the other routes. */
    fun metadata(@Suppress("UNUSED_PARAMETER") trackId: String): String = METADATA
}