music: update search results when library changes
This commit is contained in:
parent
c8571a4df3
commit
a3e74cbd1e
2 changed files with 67 additions and 14 deletions
|
@ -57,7 +57,9 @@ constructor(
|
||||||
private var invalidator: Invalidator? = null
|
private var invalidator: Invalidator? = null
|
||||||
|
|
||||||
interface Invalidator {
|
interface Invalidator {
|
||||||
fun invalidate(ids: List<String>)
|
data class ParentId(val id: String, val itemCount: Int)
|
||||||
|
|
||||||
|
fun invalidate(ids: Map<String, Int>)
|
||||||
|
|
||||||
fun invalidate(controller: ControllerInfo, query: String, itemCount: Int)
|
fun invalidate(controller: ControllerInfo, query: String, itemCount: Int)
|
||||||
}
|
}
|
||||||
|
@ -76,23 +78,43 @@ constructor(
|
||||||
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
override fun onMusicChanges(changes: MusicRepository.Changes) {
|
||||||
val deviceLibrary = musicRepository.deviceLibrary
|
val deviceLibrary = musicRepository.deviceLibrary
|
||||||
var invalidateSearch = false
|
var invalidateSearch = false
|
||||||
val invalidate = mutableListOf<MediaSessionUID>()
|
val invalidate = mutableMapOf<String, Int>()
|
||||||
if (changes.deviceLibrary && deviceLibrary != null) {
|
if (changes.deviceLibrary && deviceLibrary != null) {
|
||||||
invalidate.addAll(MediaSessionUID.Category.DEVICE_MUSIC)
|
MediaSessionUID.Category.DEVICE_MUSIC.forEach {
|
||||||
deviceLibrary.albums.mapTo(invalidate) { MediaSessionUID.Single(it.uid) }
|
invalidate[it.toString()] = getCategorySize(it, musicRepository)
|
||||||
deviceLibrary.artists.mapTo(invalidate) { MediaSessionUID.Single(it.uid) }
|
}
|
||||||
deviceLibrary.genres.mapTo(invalidate) { MediaSessionUID.Single(it.uid) }
|
|
||||||
|
deviceLibrary.albums.forEach {
|
||||||
|
val id = MediaSessionUID.Single(it.uid).toString()
|
||||||
|
invalidate[id] = it.songs.size
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceLibrary.artists.forEach {
|
||||||
|
val id = MediaSessionUID.Single(it.uid).toString()
|
||||||
|
invalidate[id] = it.songs.size + it.explicitAlbums.size + it.implicitAlbums.size
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceLibrary.genres.forEach {
|
||||||
|
val id = MediaSessionUID.Single(it.uid).toString()
|
||||||
|
invalidate[id] = it.songs.size + it.artists.size
|
||||||
|
}
|
||||||
|
|
||||||
invalidateSearch = true
|
invalidateSearch = true
|
||||||
}
|
}
|
||||||
val userLibrary = musicRepository.userLibrary
|
val userLibrary = musicRepository.userLibrary
|
||||||
if (changes.userLibrary && userLibrary != null) {
|
if (changes.userLibrary && userLibrary != null) {
|
||||||
invalidate.addAll(MediaSessionUID.Category.USER_MUSIC)
|
MediaSessionUID.Category.USER_MUSIC.forEach {
|
||||||
userLibrary.playlists.mapTo(invalidate) { MediaSessionUID.Single(it.uid) }
|
invalidate[it.toString()] = getCategorySize(it, musicRepository)
|
||||||
|
}
|
||||||
|
userLibrary.playlists.forEach {
|
||||||
|
val id = MediaSessionUID.Single(it.uid).toString()
|
||||||
|
invalidate[id] = it.songs.size
|
||||||
|
}
|
||||||
invalidateSearch = true
|
invalidateSearch = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidate.isNotEmpty()) {
|
if (invalidate.isNotEmpty()) {
|
||||||
invalidator?.invalidate(invalidate.map { it.toString() })
|
invalidator?.invalidate(invalidate)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (invalidateSearch) {
|
if (invalidateSearch) {
|
||||||
|
@ -119,8 +141,10 @@ constructor(
|
||||||
is MediaSessionUID.Category -> return uid.toMediaItem(context)
|
is MediaSessionUID.Category -> return uid.toMediaItem(context)
|
||||||
is MediaSessionUID.Single ->
|
is MediaSessionUID.Single ->
|
||||||
musicRepository.find(uid.uid)?.let { musicRepository.find(it.uid) }
|
musicRepository.find(uid.uid)?.let { musicRepository.find(it.uid) }
|
||||||
|
|
||||||
is MediaSessionUID.Joined ->
|
is MediaSessionUID.Joined ->
|
||||||
musicRepository.find(uid.childUid)?.let { musicRepository.find(it.uid) }
|
musicRepository.find(uid.childUid)?.let { musicRepository.find(it.uid) }
|
||||||
|
|
||||||
null -> null
|
null -> null
|
||||||
}
|
}
|
||||||
?: return null
|
?: return null
|
||||||
|
@ -155,32 +179,40 @@ constructor(
|
||||||
when (mediaSessionUID) {
|
when (mediaSessionUID) {
|
||||||
MediaSessionUID.Category.ROOT ->
|
MediaSessionUID.Category.ROOT ->
|
||||||
MediaSessionUID.Category.IMPORTANT.map { it.toMediaItem(context) }
|
MediaSessionUID.Category.IMPORTANT.map { it.toMediaItem(context) }
|
||||||
|
|
||||||
MediaSessionUID.Category.SONGS ->
|
MediaSessionUID.Category.SONGS ->
|
||||||
listSettings.songSort.songs(deviceLibrary.songs).map {
|
listSettings.songSort.songs(deviceLibrary.songs).map {
|
||||||
it.toMediaItem(context, null)
|
it.toMediaItem(context, null)
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaSessionUID.Category.ALBUMS ->
|
MediaSessionUID.Category.ALBUMS ->
|
||||||
listSettings.albumSort.albums(deviceLibrary.albums).map {
|
listSettings.albumSort.albums(deviceLibrary.albums).map {
|
||||||
it.toMediaItem(context)
|
it.toMediaItem(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaSessionUID.Category.ARTISTS ->
|
MediaSessionUID.Category.ARTISTS ->
|
||||||
listSettings.artistSort.artists(deviceLibrary.artists).map {
|
listSettings.artistSort.artists(deviceLibrary.artists).map {
|
||||||
it.toMediaItem(context)
|
it.toMediaItem(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaSessionUID.Category.GENRES ->
|
MediaSessionUID.Category.GENRES ->
|
||||||
listSettings.genreSort.genres(deviceLibrary.genres).map {
|
listSettings.genreSort.genres(deviceLibrary.genres).map {
|
||||||
it.toMediaItem(context)
|
it.toMediaItem(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaSessionUID.Category.PLAYLISTS ->
|
MediaSessionUID.Category.PLAYLISTS ->
|
||||||
userLibrary.playlists.map { it.toMediaItem(context) }
|
userLibrary.playlists.map { it.toMediaItem(context) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is MediaSessionUID.Single -> {
|
is MediaSessionUID.Single -> {
|
||||||
getChildMediaItems(mediaSessionUID.uid)
|
getChildMediaItems(mediaSessionUID.uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
is MediaSessionUID.Joined -> {
|
is MediaSessionUID.Joined -> {
|
||||||
getChildMediaItems(mediaSessionUID.childUid)
|
getChildMediaItems(mediaSessionUID.childUid)
|
||||||
}
|
}
|
||||||
|
|
||||||
null -> {
|
null -> {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -193,25 +225,45 @@ constructor(
|
||||||
val songs = listSettings.albumSongSort.songs(item.songs)
|
val songs = listSettings.albumSongSort.songs(item.songs)
|
||||||
songs.map { it.toMediaItem(context, item) }
|
songs.map { it.toMediaItem(context, item) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is Artist -> {
|
is Artist -> {
|
||||||
val albums = ARTIST_ALBUMS_SORT.albums(item.explicitAlbums + item.implicitAlbums)
|
val albums = ARTIST_ALBUMS_SORT.albums(item.explicitAlbums + item.implicitAlbums)
|
||||||
val songs = listSettings.artistSongSort.songs(item.songs)
|
val songs = listSettings.artistSongSort.songs(item.songs)
|
||||||
albums.map { it.toMediaItem(context) } + songs.map { it.toMediaItem(context, item) }
|
albums.map { it.toMediaItem(context) } + songs.map { it.toMediaItem(context, item) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is Genre -> {
|
is Genre -> {
|
||||||
val artists = GENRE_ARTISTS_SORT.artists(item.artists)
|
val artists = GENRE_ARTISTS_SORT.artists(item.artists)
|
||||||
val songs = listSettings.genreSongSort.songs(item.songs)
|
val songs = listSettings.genreSongSort.songs(item.songs)
|
||||||
artists.map { it.toMediaItem(context) } +
|
artists.map { it.toMediaItem(context) } +
|
||||||
songs.map { it.toMediaItem(context, null) }
|
songs.map { it.toMediaItem(context, null) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is Playlist -> {
|
is Playlist -> {
|
||||||
item.songs.map { it.toMediaItem(context, item) }
|
item.songs.map { it.toMediaItem(context, item) }
|
||||||
}
|
}
|
||||||
|
|
||||||
is Song,
|
is Song,
|
||||||
null -> return null
|
null -> return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getCategorySize(
|
||||||
|
category: MediaSessionUID.Category,
|
||||||
|
musicRepository: MusicRepository
|
||||||
|
): Int {
|
||||||
|
val deviceLibrary = musicRepository.deviceLibrary ?: return 0
|
||||||
|
val userLibrary = musicRepository.userLibrary ?: return 0
|
||||||
|
return when (category) {
|
||||||
|
MediaSessionUID.Category.ROOT -> MediaSessionUID.Category.IMPORTANT.size
|
||||||
|
MediaSessionUID.Category.SONGS -> deviceLibrary.songs.size
|
||||||
|
MediaSessionUID.Category.ALBUMS -> deviceLibrary.albums.size
|
||||||
|
MediaSessionUID.Category.ARTISTS -> deviceLibrary.artists.size
|
||||||
|
MediaSessionUID.Category.GENRES -> deviceLibrary.genres.size
|
||||||
|
MediaSessionUID.Category.PLAYLISTS -> userLibrary.playlists.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun prepareSearch(query: String, controller: ControllerInfo) {
|
suspend fun prepareSearch(query: String, controller: ControllerInfo) {
|
||||||
searchSubscribers[controller] = query
|
searchSubscribers[controller] = query
|
||||||
val existing = searchResults[query]
|
val existing = searchResults[query]
|
||||||
|
@ -287,7 +339,8 @@ constructor(
|
||||||
deviceLibrary.albums,
|
deviceLibrary.albums,
|
||||||
deviceLibrary.artists,
|
deviceLibrary.artists,
|
||||||
deviceLibrary.genres,
|
deviceLibrary.genres,
|
||||||
userLibrary.playlists)
|
userLibrary.playlists
|
||||||
|
)
|
||||||
val results = searchEngine.search(items, query)
|
val results = searchEngine.search(items, query)
|
||||||
for (entry in searchSubscribers.entries) {
|
for (entry in searchSubscribers.entries) {
|
||||||
if (entry.value == query) {
|
if (entry.value == query) {
|
||||||
|
|
|
@ -255,9 +255,9 @@ constructor(
|
||||||
mediaSession.setCustomLayout(layout)
|
mediaSession.setCustomLayout(layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidate(ids: List<String>) {
|
override fun invalidate(ids: Map<String, Int>){
|
||||||
for (id in ids) {
|
for (id in ids) {
|
||||||
mediaSession.notifyChildrenChanged(id, Int.MAX_VALUE, null)
|
mediaSession.notifyChildrenChanged(id.key, id.value, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue