home: mirror tabs to mediasession browser
This commit is contained in:
parent
29d663f500
commit
3832c4e525
7 changed files with 175 additions and 124 deletions
|
@ -1,6 +1,6 @@
|
|||
package org.oxycblt.auxio.home.list
|
||||
package org.oxycblt.auxio.home
|
||||
|
||||
import org.oxycblt.auxio.home.HomeSettings
|
||||
import org.oxycblt.auxio.home.tabs.Tab
|
||||
import org.oxycblt.auxio.list.ListSettings
|
||||
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
||||
import org.oxycblt.auxio.music.Album
|
||||
|
@ -10,39 +10,46 @@ import org.oxycblt.auxio.music.MusicRepository
|
|||
import org.oxycblt.auxio.music.MusicType
|
||||
import org.oxycblt.auxio.music.Playlist
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.playback.PlaybackSettings
|
||||
import org.oxycblt.auxio.util.logD
|
||||
import javax.inject.Inject
|
||||
|
||||
interface HomeListGenerator {
|
||||
interface HomeGenerator {
|
||||
fun songs(): List<Song>
|
||||
fun albums(): List<Album>
|
||||
fun artists(): List<Artist>
|
||||
fun genres(): List<Genre>
|
||||
fun playlists(): List<Playlist>
|
||||
fun tabs(): List<MusicType>
|
||||
fun release()
|
||||
|
||||
interface Invalidator {
|
||||
fun invalidate(type: MusicType, instructions: UpdateInstructions)
|
||||
fun invalidateMusic(type: MusicType, instructions: UpdateInstructions)
|
||||
fun invalidateTabs()
|
||||
}
|
||||
|
||||
interface Factory {
|
||||
fun create(invalidator: Invalidator): HomeListGenerator
|
||||
fun create(invalidator: Invalidator): HomeGenerator
|
||||
}
|
||||
}
|
||||
|
||||
private class HomeListGeneratorImpl(
|
||||
private val invalidator: HomeListGenerator.Invalidator,
|
||||
private class HomeGeneratorImpl(
|
||||
private val invalidator: HomeGenerator.Invalidator,
|
||||
private val homeSettings: HomeSettings,
|
||||
private val listSettings: ListSettings,
|
||||
private val musicRepository: MusicRepository,
|
||||
) : HomeListGenerator, HomeSettings.Listener, ListSettings.Listener, MusicRepository.UpdateListener {
|
||||
) : HomeGenerator, HomeSettings.Listener, ListSettings.Listener, MusicRepository.UpdateListener {
|
||||
override fun songs() =
|
||||
musicRepository.deviceLibrary?.let { listSettings.songSort.songs(it.songs) } ?: emptyList()
|
||||
override fun albums() = musicRepository.deviceLibrary?.let { listSettings.albumSort.albums(it.albums) } ?: emptyList()
|
||||
override fun artists() = musicRepository.deviceLibrary?.let { listSettings.artistSort.artists(it.artists) } ?: emptyList()
|
||||
override fun genres() = musicRepository.deviceLibrary?.let { listSettings.genreSort.genres(it.genres) } ?: emptyList()
|
||||
override fun playlists() = musicRepository.userLibrary?.let { listSettings.playlistSort.playlists(it.playlists) } ?: emptyList()
|
||||
override fun tabs() =
|
||||
homeSettings.homeTabs.filterIsInstance<Tab.Visible>().map { it.type }
|
||||
|
||||
|
||||
override fun onTabsChanged() {
|
||||
invalidator.invalidateTabs()
|
||||
}
|
||||
|
||||
init {
|
||||
homeSettings.registerListener(this)
|
||||
|
@ -51,9 +58,9 @@ private class HomeListGeneratorImpl(
|
|||
}
|
||||
|
||||
override fun release() {
|
||||
homeSettings.unregisterListener(this)
|
||||
listSettings.unregisterListener(this)
|
||||
musicRepository.removeUpdateListener(this)
|
||||
listSettings.unregisterListener(this)
|
||||
homeSettings.unregisterListener(this)
|
||||
}
|
||||
|
||||
override fun onHideCollaboratorsChanged() {
|
||||
|
@ -65,27 +72,27 @@ private class HomeListGeneratorImpl(
|
|||
|
||||
override fun onSongSortChanged() {
|
||||
super.onSongSortChanged()
|
||||
invalidator.invalidate(MusicType.SONGS, UpdateInstructions.Replace(0))
|
||||
invalidator.invalidateMusic(MusicType.SONGS, UpdateInstructions.Replace(0))
|
||||
}
|
||||
|
||||
override fun onAlbumSortChanged() {
|
||||
super.onAlbumSortChanged()
|
||||
invalidator.invalidate(MusicType.ALBUMS, UpdateInstructions.Replace(0))
|
||||
invalidator.invalidateMusic(MusicType.ALBUMS, UpdateInstructions.Replace(0))
|
||||
}
|
||||
|
||||
override fun onArtistSortChanged() {
|
||||
super.onArtistSortChanged()
|
||||
invalidator.invalidate(MusicType.ARTISTS, UpdateInstructions.Replace(0))
|
||||
invalidator.invalidateMusic(MusicType.ARTISTS, UpdateInstructions.Replace(0))
|
||||
}
|
||||
|
||||
override fun onGenreSortChanged() {
|
||||
super.onGenreSortChanged()
|
||||
invalidator.invalidate(MusicType.GENRES, UpdateInstructions.Replace(0))
|
||||
invalidator.invalidateMusic(MusicType.GENRES, UpdateInstructions.Replace(0))
|
||||
}
|
||||
|
||||
override fun onPlaylistSortChanged() {
|
||||
super.onPlaylistSortChanged()
|
||||
invalidator.invalidate(MusicType.PLAYLISTS, UpdateInstructions.Replace(0))
|
||||
invalidator.invalidateMusic(MusicType.PLAYLISTS, UpdateInstructions.Replace(0))
|
||||
}
|
||||
|
||||
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
||||
|
@ -94,16 +101,16 @@ private class HomeListGeneratorImpl(
|
|||
logD("Refreshing library")
|
||||
// Get the each list of items in the library to use as our list data.
|
||||
// Applying the preferred sorting to them.
|
||||
invalidator.invalidate(MusicType.SONGS, UpdateInstructions.Diff)
|
||||
invalidator.invalidate(MusicType.ALBUMS, UpdateInstructions.Diff)
|
||||
invalidator.invalidate(MusicType.ARTISTS, UpdateInstructions.Diff)
|
||||
invalidator.invalidate(MusicType.GENRES, UpdateInstructions.Diff)
|
||||
invalidator.invalidateMusic(MusicType.SONGS, UpdateInstructions.Diff)
|
||||
invalidator.invalidateMusic(MusicType.ALBUMS, UpdateInstructions.Diff)
|
||||
invalidator.invalidateMusic(MusicType.ARTISTS, UpdateInstructions.Diff)
|
||||
invalidator.invalidateMusic(MusicType.GENRES, UpdateInstructions.Diff)
|
||||
}
|
||||
|
||||
val userLibrary = musicRepository.userLibrary
|
||||
if (changes.userLibrary && userLibrary != null) {
|
||||
logD("Refreshing playlists")
|
||||
invalidator.invalidate(MusicType.PLAYLISTS, UpdateInstructions.Diff)
|
||||
invalidator.invalidateMusic(MusicType.PLAYLISTS, UpdateInstructions.Diff)
|
||||
}
|
||||
}
|
||||
|
|
@ -23,15 +23,14 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
|||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.oxycblt.auxio.home.list.HomeListGenerator
|
||||
import org.oxycblt.auxio.home.tabs.Tab
|
||||
import org.oxycblt.auxio.home.tabs.TabListGenerator
|
||||
import org.oxycblt.auxio.list.ListSettings
|
||||
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
||||
import org.oxycblt.auxio.list.sort.Sort
|
||||
import org.oxycblt.auxio.music.Album
|
||||
import org.oxycblt.auxio.music.Artist
|
||||
import org.oxycblt.auxio.music.Genre
|
||||
import org.oxycblt.auxio.music.MusicRepository
|
||||
import org.oxycblt.auxio.music.MusicType
|
||||
import org.oxycblt.auxio.music.Playlist
|
||||
import org.oxycblt.auxio.music.Song
|
||||
|
@ -50,12 +49,11 @@ import org.oxycblt.auxio.util.logD
|
|||
class HomeViewModel
|
||||
@Inject
|
||||
constructor(
|
||||
private val homeSettings: HomeSettings,
|
||||
private val listSettings: ListSettings,
|
||||
private val playbackSettings: PlaybackSettings,
|
||||
homeGeneratorFactory: HomeListGenerator.Factory
|
||||
) : ViewModel(), HomeSettings.Listener, HomeListGenerator.Invalidator {
|
||||
private val generator = homeGeneratorFactory.create(this)
|
||||
homeGeneratorFactory: HomeGenerator.Factory
|
||||
) : ViewModel(), HomeGenerator.Invalidator {
|
||||
private val homeGenerator = homeGeneratorFactory.create(this)
|
||||
|
||||
private val _songList = MutableStateFlow(listOf<Song>())
|
||||
/** A list of [Song]s, sorted by the preferred [Sort], to be shown in the home view. */
|
||||
|
@ -138,7 +136,7 @@ constructor(
|
|||
* A list of [MusicType] corresponding to the current [Tab] configuration, excluding invisible
|
||||
* [Tab]s.
|
||||
*/
|
||||
var currentTabTypes = makeTabTypes()
|
||||
var currentTabTypes = homeGenerator.tabs()
|
||||
private set
|
||||
|
||||
private val _currentTabType = MutableStateFlow(currentTabTypes[0])
|
||||
|
@ -166,45 +164,38 @@ constructor(
|
|||
val showOuter: Event<Outer>
|
||||
get() = _showOuter
|
||||
|
||||
init {
|
||||
homeSettings.registerListener(this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
homeSettings.unregisterListener(this)
|
||||
generator.release()
|
||||
homeGenerator.release()
|
||||
}
|
||||
|
||||
override fun invalidate(type: MusicType, instructions: UpdateInstructions) {
|
||||
override fun invalidateMusic(type: MusicType, instructions: UpdateInstructions) {
|
||||
when (type) {
|
||||
MusicType.SONGS -> {
|
||||
_songList.value = generator.songs()
|
||||
_songList.value = homeGenerator.songs()
|
||||
_songInstructions.put(instructions)
|
||||
}
|
||||
MusicType.ALBUMS -> {
|
||||
_albumList.value = generator.albums()
|
||||
_albumList.value = homeGenerator.albums()
|
||||
_albumInstructions.put(instructions)
|
||||
}
|
||||
MusicType.ARTISTS -> {
|
||||
_artistList.value = generator.artists()
|
||||
_artistList.value = homeGenerator.artists()
|
||||
_artistInstructions.put(instructions)
|
||||
}
|
||||
MusicType.GENRES -> {
|
||||
_genreList.value = generator.genres()
|
||||
_genreList.value = homeGenerator.genres()
|
||||
_genreInstructions.put(instructions)
|
||||
}
|
||||
MusicType.PLAYLISTS -> {
|
||||
_playlistList.value = generator.playlists()
|
||||
_playlistList.value = homeGenerator.playlists()
|
||||
_playlistInstructions.put(instructions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTabsChanged() {
|
||||
// Tabs changed, update the current tabs and set up a re-create event.
|
||||
currentTabTypes = makeTabTypes()
|
||||
logD("Updating tabs: ${currentTabType.value}")
|
||||
override fun invalidateTabs() {
|
||||
currentTabTypes = homeGenerator.tabs()
|
||||
_shouldRecreate.put(Unit)
|
||||
}
|
||||
|
||||
|
@ -290,15 +281,6 @@ constructor(
|
|||
fun showAbout() {
|
||||
_showOuter.put(Outer.About)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of [MusicType]s representing a simpler version of the [Tab] configuration.
|
||||
*
|
||||
* @return A list of the [MusicType]s for each visible [Tab] in the configuration, ordered in
|
||||
* the same way as the configuration.
|
||||
*/
|
||||
private fun makeTabTypes() =
|
||||
homeSettings.homeTabs.filterIsInstance<Tab.Visible>().map { it.type }
|
||||
}
|
||||
|
||||
sealed interface Outer {
|
||||
|
|
|
@ -37,40 +37,23 @@ class AdaptiveTabStrategy(context: Context, private val tabs: List<MusicType>) :
|
|||
private val width = context.resources.configuration.smallestScreenWidthDp
|
||||
|
||||
override fun onConfigureTab(tab: TabLayout.Tab, position: Int) {
|
||||
val icon: Int
|
||||
val string: Int
|
||||
|
||||
when (tabs[position]) {
|
||||
MusicType.SONGS -> {
|
||||
icon = R.drawable.ic_song_24
|
||||
string = R.string.lbl_songs
|
||||
}
|
||||
MusicType.ALBUMS -> {
|
||||
icon = R.drawable.ic_album_24
|
||||
string = R.string.lbl_albums
|
||||
}
|
||||
MusicType.ARTISTS -> {
|
||||
icon = R.drawable.ic_artist_24
|
||||
string = R.string.lbl_artists
|
||||
}
|
||||
MusicType.GENRES -> {
|
||||
icon = R.drawable.ic_genre_24
|
||||
string = R.string.lbl_genres
|
||||
}
|
||||
MusicType.PLAYLISTS -> {
|
||||
icon = R.drawable.ic_playlist_24
|
||||
string = R.string.lbl_playlists
|
||||
}
|
||||
val homeTab = tabs[position]
|
||||
val icon = when (homeTab) {
|
||||
MusicType.SONGS -> R.drawable.ic_song_24
|
||||
MusicType.ALBUMS -> R.drawable.ic_album_24
|
||||
MusicType.ARTISTS -> R.drawable.ic_artist_24
|
||||
MusicType.GENRES -> R.drawable.ic_genre_24
|
||||
MusicType.PLAYLISTS -> R.drawable.ic_playlist_24
|
||||
}
|
||||
|
||||
// Use expected sw* size thresholds when choosing a configuration.
|
||||
when {
|
||||
// On small screens, only display an icon.
|
||||
width < 370 -> tab.setIcon(icon).setContentDescription(string)
|
||||
width < 370 -> tab.setIcon(icon).setContentDescription(homeTab.nameRes)
|
||||
// On large screens, display an icon and text.
|
||||
width < 600 -> tab.setText(string)
|
||||
width < 600 -> tab.setText(homeTab.nameRes).setIcon(icon)
|
||||
// On medium-size screens, display text.
|
||||
else -> tab.setIcon(icon).setText(string)
|
||||
else -> tab.setIcon(icon).setText(homeTab.nameRes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.oxycblt.auxio.music
|
||||
|
||||
import org.oxycblt.auxio.IntegerTable
|
||||
import org.oxycblt.auxio.R
|
||||
|
||||
/**
|
||||
* General configuration enum to control what kind of music is being worked with.
|
||||
|
@ -52,6 +53,16 @@ enum class MusicType {
|
|||
PLAYLISTS -> IntegerTable.MUSIC_MODE_PLAYLISTS
|
||||
}
|
||||
|
||||
val nameRes: Int
|
||||
get() =
|
||||
when (this) {
|
||||
SONGS -> R.string.lbl_songs
|
||||
ALBUMS -> R.string.lbl_albums
|
||||
ARTISTS -> R.string.lbl_artists
|
||||
GENRES -> R.string.lbl_genres
|
||||
PLAYLISTS -> R.string.lbl_playlists
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Convert a [MusicType] integer representation into an instance.
|
||||
|
|
|
@ -44,8 +44,8 @@ import org.oxycblt.auxio.playback.formatDurationDs
|
|||
import org.oxycblt.auxio.util.getPlural
|
||||
|
||||
sealed interface MediaSessionUID {
|
||||
data class CategoryItem(val category: Category) : MediaSessionUID {
|
||||
override fun toString() = "$ID_CATEGORY:${category.id}"
|
||||
data class Tab(val node: TabNode) : MediaSessionUID {
|
||||
override fun toString() = "$ID_CATEGORY:${node.id}"
|
||||
}
|
||||
|
||||
data class SingleItem(val uid: Music.UID) : MediaSessionUID {
|
||||
|
@ -66,7 +66,7 @@ sealed interface MediaSessionUID {
|
|||
return null
|
||||
}
|
||||
return when (parts[0]) {
|
||||
ID_CATEGORY -> CategoryItem(Category.fromString(parts[1]) ?: return null)
|
||||
ID_CATEGORY -> Tab(TabNode.fromString(parts[1]) ?: return null)
|
||||
ID_ITEM -> {
|
||||
val uids = parts[1].split(">", limit = 2)
|
||||
if (uids.size == 1) {
|
||||
|
@ -148,12 +148,12 @@ private fun makeExtras(context: Context, vararg sugars: Sugar): Bundle {
|
|||
return Bundle().apply { sugars.forEach { this.it(context) } }
|
||||
}
|
||||
|
||||
fun Category.toMediaItem(context: Context): MediaItem {
|
||||
fun TabNode.toMediaItem(context: Context): MediaItem {
|
||||
val extras =
|
||||
makeExtras(
|
||||
context,
|
||||
style(MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM))
|
||||
val mediaSessionUID = MediaSessionUID.CategoryItem(this)
|
||||
val mediaSessionUID = MediaSessionUID.Tab(this)
|
||||
val description =
|
||||
MediaDescriptionCompat.Builder()
|
||||
.setMediaId(mediaSessionUID.toString())
|
||||
|
|
|
@ -23,7 +23,7 @@ import android.support.v4.media.MediaBrowserCompat.MediaItem
|
|||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import javax.inject.Inject
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.home.list.HomeListGenerator
|
||||
import org.oxycblt.auxio.home.HomeGenerator
|
||||
import org.oxycblt.auxio.list.ListSettings
|
||||
import org.oxycblt.auxio.list.adapter.UpdateInstructions
|
||||
import org.oxycblt.auxio.list.sort.Sort
|
||||
|
@ -35,8 +35,6 @@ import org.oxycblt.auxio.music.MusicRepository
|
|||
import org.oxycblt.auxio.music.MusicType
|
||||
import org.oxycblt.auxio.music.Playlist
|
||||
import org.oxycblt.auxio.music.Song
|
||||
import org.oxycblt.auxio.music.device.DeviceLibrary
|
||||
import org.oxycblt.auxio.music.user.UserLibrary
|
||||
import org.oxycblt.auxio.search.SearchEngine
|
||||
|
||||
class MusicBrowser
|
||||
|
@ -46,13 +44,13 @@ constructor(
|
|||
private val musicRepository: MusicRepository,
|
||||
private val searchEngine: SearchEngine,
|
||||
private val listSettings: ListSettings,
|
||||
homeGeneratorFactory: HomeListGenerator.Factory
|
||||
) : MusicRepository.UpdateListener, HomeListGenerator.Invalidator {
|
||||
homeGeneratorFactory: HomeGenerator.Factory
|
||||
) : MusicRepository.UpdateListener, HomeGenerator.Invalidator {
|
||||
interface Invalidator {
|
||||
fun invalidateMusic(ids: Set<String>)
|
||||
}
|
||||
|
||||
private val generator = homeGeneratorFactory.create(this)
|
||||
private val homeGenerator = homeGeneratorFactory.create(this)
|
||||
private var invalidator: Invalidator? = null
|
||||
|
||||
fun attach(invalidator: Invalidator) {
|
||||
|
@ -64,26 +62,24 @@ constructor(
|
|||
musicRepository.removeUpdateListener(this)
|
||||
}
|
||||
|
||||
override fun invalidate(type: MusicType, instructions: UpdateInstructions) {
|
||||
val category = when (type) {
|
||||
MusicType.SONGS -> Category.Songs
|
||||
MusicType.ALBUMS -> Category.Albums
|
||||
MusicType.ARTISTS -> Category.Artists
|
||||
MusicType.GENRES -> Category.Genres
|
||||
MusicType.PLAYLISTS -> Category.Playlists
|
||||
}
|
||||
val id = MediaSessionUID.CategoryItem(category).toString()
|
||||
override fun invalidateMusic(type: MusicType, instructions: UpdateInstructions) {
|
||||
val id = MediaSessionUID.Tab(TabNode.Home(type)).toString()
|
||||
invalidator?.invalidateMusic(setOf(id))
|
||||
}
|
||||
|
||||
override fun invalidateTabs() {
|
||||
for (i in 0..10) {
|
||||
// TODO: Temporary bodge, move the amount parameter to a bundle extra
|
||||
val rootId = MediaSessionUID.Tab(TabNode.Root(i)).toString()
|
||||
val moreId = MediaSessionUID.Tab(TabNode.More(i)).toString()
|
||||
invalidator?.invalidateMusic(setOf(rootId, moreId))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
||||
val deviceLibrary = musicRepository.deviceLibrary
|
||||
val invalidate = mutableSetOf<String>()
|
||||
if (changes.deviceLibrary && deviceLibrary != null) {
|
||||
Category.DEVICE_MUSIC.forEach {
|
||||
invalidate.add(MediaSessionUID.CategoryItem(it).toString())
|
||||
}
|
||||
|
||||
deviceLibrary.albums.forEach {
|
||||
val id = MediaSessionUID.SingleItem(it.uid).toString()
|
||||
invalidate.add(id)
|
||||
|
@ -101,9 +97,6 @@ constructor(
|
|||
}
|
||||
val userLibrary = musicRepository.userLibrary
|
||||
if (changes.userLibrary && userLibrary != null) {
|
||||
Category.USER_MUSIC.forEach {
|
||||
invalidate.add(MediaSessionUID.CategoryItem(it).toString())
|
||||
}
|
||||
userLibrary.playlists.forEach {
|
||||
val id = MediaSessionUID.SingleItem(it.uid).toString()
|
||||
invalidate.add(id)
|
||||
|
@ -118,7 +111,7 @@ constructor(
|
|||
fun getItem(mediaId: String): MediaItem? {
|
||||
val music =
|
||||
when (val uid = MediaSessionUID.fromString(mediaId)) {
|
||||
is MediaSessionUID.CategoryItem -> return uid.category.toMediaItem(context)
|
||||
is MediaSessionUID.Tab -> return uid.node.toMediaItem(context)
|
||||
is MediaSessionUID.SingleItem ->
|
||||
musicRepository.find(uid.uid)?.let { musicRepository.find(it.uid) }
|
||||
is MediaSessionUID.ChildItem ->
|
||||
|
@ -186,8 +179,8 @@ constructor(
|
|||
id: String
|
||||
): List<MediaItem>? {
|
||||
return when (val mediaSessionUID = MediaSessionUID.fromString(id)) {
|
||||
is MediaSessionUID.CategoryItem -> {
|
||||
getCategoryMediaItems(mediaSessionUID.category)
|
||||
is MediaSessionUID.Tab -> {
|
||||
getCategoryMediaItems(mediaSessionUID.node)
|
||||
}
|
||||
is MediaSessionUID.SingleItem -> {
|
||||
getChildMediaItems(mediaSessionUID.uid)
|
||||
|
@ -202,25 +195,30 @@ constructor(
|
|||
}
|
||||
|
||||
private fun getCategoryMediaItems(
|
||||
category: Category
|
||||
node: TabNode
|
||||
) =
|
||||
when (category) {
|
||||
is Category.Root -> {
|
||||
val base = Category.MUSIC.take(category.amount - 1)
|
||||
if (base.size < Category.MUSIC.size) {
|
||||
base + Category.More(Category.MUSIC.size - base.size)
|
||||
when (node) {
|
||||
is TabNode.Root -> {
|
||||
val tabs = homeGenerator.tabs()
|
||||
val base = tabs.take(node.amount - 1).map { TabNode.Home(it) }
|
||||
if (base.size < tabs.size) {
|
||||
base + TabNode.More(Category.MUSIC.size - base.size)
|
||||
} else {
|
||||
base
|
||||
}
|
||||
.map { it.toMediaItem(context) }
|
||||
}
|
||||
is Category.More ->
|
||||
Category.MUSIC.takeLast(category.remainder).map { it.toMediaItem(context) }
|
||||
is Category.Songs -> generator.songs().map { it.toMediaItem(context) }
|
||||
is Category.Albums -> generator.albums().map { it.toMediaItem(context) }
|
||||
is Category.Artists -> generator.artists().map { it.toMediaItem(context) }
|
||||
is Category.Genres -> generator.genres().map { it.toMediaItem(context) }
|
||||
is Category.Playlists -> generator.playlists().map { it.toMediaItem(context) }
|
||||
is TabNode.More ->
|
||||
homeGenerator.tabs().takeLast(node.remainder).map {
|
||||
TabNode.Home(it).toMediaItem(context) }
|
||||
is TabNode.Home ->
|
||||
when (node.type) {
|
||||
MusicType.SONGS -> homeGenerator.songs().map { it.toMediaItem(context, null) }
|
||||
MusicType.ALBUMS -> homeGenerator.albums().map { it.toMediaItem(context) }
|
||||
MusicType.ARTISTS -> homeGenerator.artists().map { it.toMediaItem(context) }
|
||||
MusicType.GENRES -> homeGenerator.genres().map { it.toMediaItem(context) }
|
||||
MusicType.PLAYLISTS -> homeGenerator.playlists().map { it.toMediaItem(context) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun getChildMediaItems(uid: Music.UID): List<MediaItem>? {
|
||||
|
|
70
app/src/main/java/org/oxycblt/auxio/music/service/TabNode.kt
Normal file
70
app/src/main/java/org/oxycblt/auxio/music/service/TabNode.kt
Normal file
|
@ -0,0 +1,70 @@
|
|||
package org.oxycblt.auxio.music.service
|
||||
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.home.tabs.Tab
|
||||
import org.oxycblt.auxio.music.MusicType
|
||||
|
||||
sealed class TabNode {
|
||||
abstract val id: String
|
||||
abstract val data: Int
|
||||
abstract val nameRes: Int
|
||||
abstract val bitmapRes: Int?
|
||||
|
||||
override fun toString() = "${id}/${data}"
|
||||
|
||||
data class Root(val amount: Int) : TabNode() {
|
||||
override val id = ID
|
||||
override val data = amount
|
||||
override val nameRes = R.string.info_app_name
|
||||
override val bitmapRes = null
|
||||
|
||||
companion object {
|
||||
const val ID = "root"
|
||||
}
|
||||
}
|
||||
|
||||
data class More(val remainder: Int) : TabNode() {
|
||||
override val id = ID
|
||||
override val data = remainder
|
||||
override val nameRes = R.string.lbl_more
|
||||
override val bitmapRes = null
|
||||
|
||||
companion object {
|
||||
const val ID = "more"
|
||||
}
|
||||
}
|
||||
|
||||
data class Home(val type: MusicType) : TabNode() {
|
||||
override val id = ID
|
||||
override val data = type.intCode
|
||||
override val bitmapRes: Int
|
||||
get() = when (type) {
|
||||
MusicType.SONGS -> R.drawable.ic_song_bitmap_24
|
||||
MusicType.ALBUMS -> R.drawable.ic_album_bitmap_24
|
||||
MusicType.ARTISTS -> R.drawable.ic_artist_bitmap_24
|
||||
MusicType.GENRES -> R.drawable.ic_genre_bitmap_24
|
||||
MusicType.PLAYLISTS -> R.drawable.ic_playlist_bitmap_24
|
||||
}
|
||||
override val nameRes = type.nameRes
|
||||
|
||||
companion object {
|
||||
const val ID = "home"
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromString(str: String): TabNode? {
|
||||
val split = str.split("/", limit = 2)
|
||||
if (split.size != 2) {
|
||||
return null
|
||||
}
|
||||
val data = split[1].toIntOrNull() ?: return null
|
||||
return when (split[0]) {
|
||||
Root.ID -> Root(data)
|
||||
More.ID -> More(data)
|
||||
Home.ID -> Home(MusicType.fromIntCode(data) ?: return null)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue