all: reformat/fixes
This commit is contained in:
parent
26f27d0edd
commit
cbdad3fe39
8 changed files with 98 additions and 73 deletions
|
@ -1,9 +1,26 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Auxio Project
|
||||
* DetailGenerator.kt is part of Auxio.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package org.oxycblt.auxio.detail
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.StringRes
|
||||
import javax.inject.Inject
|
||||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.detail.list.DiscHeader
|
||||
import org.oxycblt.auxio.list.ListSettings
|
||||
import org.oxycblt.auxio.list.sort.Sort
|
||||
import org.oxycblt.auxio.music.Album
|
||||
|
@ -18,15 +35,18 @@ import org.oxycblt.auxio.music.Song
|
|||
import org.oxycblt.auxio.music.info.Disc
|
||||
import org.oxycblt.auxio.music.info.ReleaseType
|
||||
import org.oxycblt.auxio.util.logD
|
||||
import java.util.SortedMap
|
||||
import javax.inject.Inject
|
||||
|
||||
interface DetailGenerator {
|
||||
fun any(uid: Music.UID): Detail<out MusicParent>?
|
||||
|
||||
fun album(uid: Music.UID): Detail<Album>?
|
||||
|
||||
fun artist(uid: Music.UID): Detail<Artist>?
|
||||
|
||||
fun genre(uid: Music.UID): Detail<Genre>?
|
||||
|
||||
fun playlist(uid: Music.UID): Detail<Playlist>?
|
||||
|
||||
fun release()
|
||||
|
||||
interface Factory {
|
||||
|
@ -38,10 +58,10 @@ interface DetailGenerator {
|
|||
}
|
||||
}
|
||||
|
||||
class DetailGeneratorFactoryImpl @Inject constructor(
|
||||
private val listSettings: ListSettings,
|
||||
private val musicRepository: MusicRepository
|
||||
) : DetailGenerator.Factory {
|
||||
class DetailGeneratorFactoryImpl
|
||||
@Inject
|
||||
constructor(private val listSettings: ListSettings, private val musicRepository: MusicRepository) :
|
||||
DetailGenerator.Factory {
|
||||
override fun create(invalidator: DetailGenerator.Invalidator): DetailGenerator =
|
||||
DetailGeneratorImpl(invalidator, listSettings, musicRepository)
|
||||
}
|
||||
|
@ -102,11 +122,12 @@ private class DetailGeneratorImpl(
|
|||
val album = musicRepository.deviceLibrary?.findAlbum(uid) ?: return null
|
||||
val songs = listSettings.albumSongSort.songs(album.songs)
|
||||
val discs = songs.groupBy { it.disc }
|
||||
val section = if (discs.size > 1 || discs.keys.first() != null) {
|
||||
DetailSection.Discs(discs)
|
||||
} else {
|
||||
DetailSection.Songs(songs)
|
||||
}
|
||||
val section =
|
||||
if (discs.size > 1 || discs.keys.first() != null) {
|
||||
DetailSection.Discs(discs)
|
||||
} else {
|
||||
DetailSection.Songs(songs)
|
||||
}
|
||||
return Detail(album, listOf(section))
|
||||
}
|
||||
|
||||
|
@ -138,13 +159,14 @@ private class DetailGeneratorImpl(
|
|||
// implicit album list into the mapping.
|
||||
logD("Implicit albums present, adding to list")
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
(grouping as MutableMap<DetailSection.Albums.Category, Collection<Album>>)[DetailSection.Albums.Category.APPEARANCES] =
|
||||
artist.implicitAlbums
|
||||
(grouping as MutableMap<DetailSection.Albums.Category, Collection<Album>>)[
|
||||
DetailSection.Albums.Category.APPEARANCES] = artist.implicitAlbums
|
||||
}
|
||||
|
||||
val sections = grouping.mapTo(mutableListOf<DetailSection>()) { (category, albums) ->
|
||||
DetailSection.Albums(category, ARTIST_ALBUM_SORT.albums(albums))
|
||||
}
|
||||
val sections =
|
||||
grouping.mapTo(mutableListOf<DetailSection>()) { (category, albums) ->
|
||||
DetailSection.Albums(category, ARTIST_ALBUM_SORT.albums(albums))
|
||||
}
|
||||
val songs = DetailSection.Songs(listSettings.artistSongSort.songs(artist.songs))
|
||||
sections.add(songs)
|
||||
return Detail(artist, sections)
|
||||
|
@ -184,7 +206,8 @@ sealed interface DetailSection {
|
|||
override val stringRes = R.string.lbl_songs
|
||||
}
|
||||
|
||||
data class Albums(val category: Category, override val items: List<Album>) : PlainSection<Album>() {
|
||||
data class Albums(val category: Category, override val items: List<Album>) :
|
||||
PlainSection<Album>() {
|
||||
override val order = 1 + category.ordinal
|
||||
override val stringRes = category.stringRes
|
||||
|
||||
|
@ -203,7 +226,6 @@ sealed interface DetailSection {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
data class Songs(override val items: List<Song>) : PlainSection<Song>() {
|
||||
override val order = 12
|
||||
override val stringRes = R.string.lbl_songs
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Auxio Project
|
||||
* HomeModule.kt is part of Auxio.
|
||||
* DetailModule.kt is part of Auxio.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
|
@ -74,7 +74,6 @@ constructor(
|
|||
) : ViewModel(), DetailGenerator.Invalidator {
|
||||
private val detailGenerator = detailGeneratorFactory.create(this)
|
||||
|
||||
|
||||
private val _toShow = MutableEvent<Show>()
|
||||
/**
|
||||
* A [Show] command that is awaiting a view capable of responding to it. Null if none currently.
|
||||
|
@ -208,21 +207,18 @@ constructor(
|
|||
val album = detailGenerator.album(currentAlbum.value?.uid ?: return)
|
||||
refreshDetail(album, _currentAlbum, _albumSongList, _albumSongInstructions, replace)
|
||||
}
|
||||
|
||||
MusicType.ARTISTS -> {
|
||||
val artist = detailGenerator.artist(currentArtist.value?.uid ?: return)
|
||||
refreshDetail(artist, _currentArtist, _artistSongList, _artistSongInstructions, replace)
|
||||
refreshDetail(
|
||||
artist, _currentArtist, _artistSongList, _artistSongInstructions, replace)
|
||||
}
|
||||
|
||||
MusicType.GENRES -> {
|
||||
val genre = detailGenerator.genre(currentGenre.value?.uid ?: return)
|
||||
refreshDetail(genre, _currentGenre, _genreSongList, _genreSongInstructions, replace)
|
||||
}
|
||||
|
||||
MusicType.PLAYLISTS -> {
|
||||
refreshPlaylist(currentPlaylist.value?.uid ?: return)
|
||||
}
|
||||
|
||||
else -> error("Unexpected music type $type")
|
||||
}
|
||||
}
|
||||
|
@ -522,7 +518,6 @@ constructor(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private fun <T : MusicParent> refreshDetail(
|
||||
detail: Detail<T>?,
|
||||
parent: MutableStateFlow<T?>,
|
||||
|
@ -537,24 +532,23 @@ constructor(
|
|||
val newList = mutableListOf<Item>()
|
||||
var newInstructions: UpdateInstructions = UpdateInstructions.Diff
|
||||
for ((i, section) in detail.sections.withIndex()) {
|
||||
val items = when (section) {
|
||||
is DetailSection.PlainSection<*> -> {
|
||||
val header = if (section is DetailSection.Songs)
|
||||
SortHeader(section.stringRes) else BasicHeader(section.stringRes)
|
||||
newList.add(Divider(header))
|
||||
newList.add(header)
|
||||
section.items
|
||||
}
|
||||
|
||||
is DetailSection.Discs -> {
|
||||
val header = BasicHeader(section.stringRes)
|
||||
newList.add(Divider(header))
|
||||
newList.add(header)
|
||||
section.discs.flatMap {
|
||||
listOf(DiscHeader(it.key)) + it.value
|
||||
val items =
|
||||
when (section) {
|
||||
is DetailSection.PlainSection<*> -> {
|
||||
val header =
|
||||
if (section is DetailSection.Songs) SortHeader(section.stringRes)
|
||||
else BasicHeader(section.stringRes)
|
||||
newList.add(Divider(header))
|
||||
newList.add(header)
|
||||
section.items
|
||||
}
|
||||
is DetailSection.Discs -> {
|
||||
val header = BasicHeader(section.stringRes)
|
||||
newList.add(Divider(header))
|
||||
newList.add(header)
|
||||
section.discs.flatMap { listOf(DiscHeader(it.key)) + it.value }
|
||||
}
|
||||
}
|
||||
}
|
||||
// Currently only the final section (songs, which can be sorted) are invalidatable
|
||||
// and thus need to be replaced.
|
||||
if (replace == -1 && i == detail.sections.lastIndex) {
|
||||
|
@ -568,12 +562,16 @@ constructor(
|
|||
instructions.put(newInstructions)
|
||||
}
|
||||
|
||||
private fun refreshPlaylist(uid: Music.UID, instructions: UpdateInstructions = UpdateInstructions.Diff) {
|
||||
private fun refreshPlaylist(
|
||||
uid: Music.UID,
|
||||
instructions: UpdateInstructions = UpdateInstructions.Diff
|
||||
) {
|
||||
logD("Refreshing playlist list")
|
||||
val edited = editedPlaylist.value
|
||||
if (edited == null) {
|
||||
val playlist = detailGenerator.playlist(uid)
|
||||
refreshDetail(playlist, _currentPlaylist, _playlistSongList, _playlistSongInstructions, null)
|
||||
refreshDetail(
|
||||
playlist, _currentPlaylist, _playlistSongList, _playlistSongInstructions, null)
|
||||
return
|
||||
}
|
||||
val list = mutableListOf<Item>()
|
||||
|
|
|
@ -46,12 +46,19 @@ interface ListSettings : Settings<ListSettings.Listener> {
|
|||
|
||||
interface Listener {
|
||||
fun onSongSortChanged() {}
|
||||
|
||||
fun onAlbumSortChanged() {}
|
||||
|
||||
fun onAlbumSongSortChanged() {}
|
||||
|
||||
fun onArtistSortChanged() {}
|
||||
|
||||
fun onArtistSongSortChanged() {}
|
||||
|
||||
fun onGenreSortChanged() {}
|
||||
|
||||
fun onGenreSongSortChanged() {}
|
||||
|
||||
fun onPlaylistSortChanged() {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,13 +24,8 @@ import javax.inject.Inject
|
|||
import org.oxycblt.auxio.R
|
||||
import org.oxycblt.auxio.detail.DetailGenerator
|
||||
import org.oxycblt.auxio.detail.DetailSection
|
||||
import org.oxycblt.auxio.detail.list.SortHeader
|
||||
import org.oxycblt.auxio.home.HomeGenerator
|
||||
import org.oxycblt.auxio.list.BasicHeader
|
||||
import org.oxycblt.auxio.list.Divider
|
||||
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
|
||||
|
@ -98,13 +93,14 @@ private constructor(
|
|||
override fun invalidate(type: MusicType, replace: Int?) {
|
||||
val deviceLibrary = musicRepository.deviceLibrary ?: return
|
||||
val userLibrary = musicRepository.userLibrary ?: return
|
||||
val music = when (type) {
|
||||
MusicType.ALBUMS -> deviceLibrary.albums
|
||||
MusicType.ARTISTS -> deviceLibrary.artists
|
||||
MusicType.GENRES -> deviceLibrary.genres
|
||||
MusicType.PLAYLISTS -> userLibrary.playlists
|
||||
else -> return
|
||||
}
|
||||
val music =
|
||||
when (type) {
|
||||
MusicType.ALBUMS -> deviceLibrary.albums
|
||||
MusicType.ARTISTS -> deviceLibrary.artists
|
||||
MusicType.GENRES -> deviceLibrary.genres
|
||||
MusicType.PLAYLISTS -> userLibrary.playlists
|
||||
else -> return
|
||||
}
|
||||
if (music.isEmpty()) {
|
||||
return
|
||||
}
|
||||
|
@ -226,20 +222,23 @@ private constructor(
|
|||
val detail = detailGenerator.any(uid) ?: return null
|
||||
return detail.sections.flatMap { section ->
|
||||
when (section) {
|
||||
is DetailSection.Songs -> section.items.map { it.toMediaItem(context, null, header(section.stringRes)) }
|
||||
is DetailSection.Albums -> section.items.map { it.toMediaItem(context, null, header(section.stringRes)) }
|
||||
is DetailSection.Artists -> section.items.map { it.toMediaItem(context, header(section.stringRes)) }
|
||||
is DetailSection.Discs -> section.discs.flatMap {
|
||||
is DetailSection.Songs ->
|
||||
section.items.map { it.toMediaItem(context, null, header(section.stringRes)) }
|
||||
is DetailSection.Albums ->
|
||||
section.items.map { it.toMediaItem(context, null, header(section.stringRes)) }
|
||||
is DetailSection.Artists ->
|
||||
section.items.map { it.toMediaItem(context, header(section.stringRes)) }
|
||||
is DetailSection.Discs ->
|
||||
section.discs.flatMap { entry ->
|
||||
val disc = entry.key
|
||||
val discString = if (disc != null) {
|
||||
context.getString(R.string.fmt_disc_no, disc.number)
|
||||
} else {
|
||||
context.getString(R.string.def_disc)
|
||||
}
|
||||
val discString =
|
||||
if (disc != null) {
|
||||
context.getString(R.string.fmt_disc_no, disc.number)
|
||||
} else {
|
||||
context.getString(R.string.def_disc)
|
||||
}
|
||||
entry.value.map { it.toMediaItem(context, null, header(discString)) }
|
||||
}
|
||||
}
|
||||
else -> error("Unknown section type: $section")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ private constructor(
|
|||
private val exoHolder = exoHolderFactory.create()
|
||||
private val sessionHolder = sessionHolderFactory.create(context, foregroundListener)
|
||||
private val widgetComponent = widgetComponentFactory.create(context)
|
||||
private val systemReceiver = systemReceiverFactory.create(context)
|
||||
private val systemReceiver = systemReceiverFactory.create(context, widgetComponent)
|
||||
|
||||
val token: MediaSessionCompat.Token
|
||||
get() = sessionHolder.token
|
||||
|
|
|
@ -47,10 +47,9 @@ private constructor(
|
|||
@Inject
|
||||
constructor(
|
||||
private val playbackManager: PlaybackStateManager,
|
||||
private val playbackSettings: PlaybackSettings,
|
||||
private val widgetComponent: WidgetComponent
|
||||
private val playbackSettings: PlaybackSettings
|
||||
) {
|
||||
fun create(context: Context): SystemPlaybackReceiver {
|
||||
fun create(context: Context, widgetComponent: WidgetComponent): SystemPlaybackReceiver {
|
||||
val receiver =
|
||||
SystemPlaybackReceiver(playbackManager, playbackSettings, widgetComponent)
|
||||
ContextCompat.registerReceiver(
|
||||
|
|
2
media
2
media
|
@ -1 +1 @@
|
|||
Subproject commit 34b33175c00183dc95cdcb8c735033b6785041e1
|
||||
Subproject commit 9fc2401b8fdc2b23905402462e775c6db4e1527f
|
Loading…
Reference in a new issue