settings: remove about screen reliance on home

Remove the about screen's reliance on the home data.

The home view's data can no longer be trusted now due to the "hide
collaborators" setting, so now the about screen uses statistics
derived from MusicStore itself. This also avoids constantly
resumming the duration when the UI is initially created.
This commit is contained in:
Alexander Capehart 2022-11-19 16:43:51 -07:00
parent 8df89db77b
commit fd61f5bb9f
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
3 changed files with 46 additions and 36 deletions

View file

@ -156,7 +156,7 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
collect(homeModel.recreateTabs, ::handleRecreateTabs) collect(homeModel.recreateTabs, ::handleRecreateTabs)
collectImmediately(homeModel.currentTab, ::updateCurrentTab) collectImmediately(homeModel.currentTab, ::updateCurrentTab)
collectImmediately(musicModel.libraryExists, homeModel.isFastScrolling, ::updateFab) collectImmediately(homeModel.songs, homeModel.isFastScrolling, ::updateFab)
collectImmediately(musicModel.indexerState, ::handleIndexerState) collectImmediately(musicModel.indexerState, ::handleIndexerState)
collect(navModel.exploreNavigationItem, ::handleNavigation) collect(navModel.exploreNavigationItem, ::handleNavigation)
} }
@ -373,9 +373,9 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
} }
} }
private fun updateFab(hasLoaded: Boolean, isFastScrolling: Boolean) { private fun updateFab(songs: List<Song>, isFastScrolling: Boolean) {
val binding = requireBinding() val binding = requireBinding()
if (!hasLoaded || isFastScrolling) { if (songs.isEmpty() || isFastScrolling) {
binding.homeFab.hide() binding.homeFab.hide()
} else { } else {
binding.homeFab.show() binding.homeFab.show()

View file

@ -31,14 +31,12 @@ class MusicViewModel : ViewModel(), Indexer.Callback {
private val indexer = Indexer.getInstance() private val indexer = Indexer.getInstance()
private val _indexerState = MutableStateFlow<Indexer.State?>(null) private val _indexerState = MutableStateFlow<Indexer.State?>(null)
/** The current music indexing state. */ /** The current music indexing state. */
val indexerState: StateFlow<Indexer.State?> = _indexerState val indexerState: StateFlow<Indexer.State?> = _indexerState
private val _libraryExists = MutableStateFlow(false) private val _statistics = MutableStateFlow<Statistics?>(null)
/** The current statistics of the music library. */
/** Whether a music library has successfully been loaded. */ val statistics: StateFlow<Statistics?> get() = _statistics
val libraryExists: StateFlow<Boolean> = _libraryExists
init { init {
indexer.registerCallback(this) indexer.registerCallback(this)
@ -56,12 +54,35 @@ class MusicViewModel : ViewModel(), Indexer.Callback {
override fun onIndexerStateChanged(state: Indexer.State?) { override fun onIndexerStateChanged(state: Indexer.State?) {
logD("New state: $state") logD("New state: $state")
_indexerState.value = state _indexerState.value = state
if (state is Indexer.State.Complete && state.response is Indexer.Response.Ok) { if (state is Indexer.State.Complete && state.response is Indexer.Response.Ok) {
_libraryExists.value = true val library = state.response.library
_statistics.value = Statistics(
library.songs.size,
library.albums.size,
library.artists.size,
library.genres.size,
library.songs.sumOf { it.durationMs }
)
} }
} }
override fun onCleared() { override fun onCleared() {
indexer.unregisterCallback(this) indexer.unregisterCallback(this)
} }
/**
* Non-manipulated statistics about the music library.
*/
data class Statistics(
/** The amount of songs. */
val songs: Int,
/** The amount of albums. */
val albums: Int,
/** The amount of artists. */
val artists: Int,
/** The amount of genres. */
val genres: Int,
val durationMs: Long
)
} }

View file

@ -25,20 +25,16 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.view.updatePadding import androidx.core.view.updatePadding
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.google.android.material.transition.MaterialFadeThrough import com.google.android.material.transition.MaterialFadeThrough
import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentAboutBinding import org.oxycblt.auxio.databinding.FragmentAboutBinding
import org.oxycblt.auxio.home.HomeViewModel import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.formatDurationMs import org.oxycblt.auxio.playback.formatDurationMs
import org.oxycblt.auxio.ui.fragment.ViewBindingFragment import org.oxycblt.auxio.ui.fragment.ViewBindingFragment
import org.oxycblt.auxio.util.androidActivityViewModels
import org.oxycblt.auxio.util.collectImmediately import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.showToast import org.oxycblt.auxio.util.showToast
@ -49,7 +45,7 @@ import org.oxycblt.auxio.util.systemBarInsetsCompat
* @author OxygenCobalt * @author OxygenCobalt
*/ */
class AboutFragment : ViewBindingFragment<FragmentAboutBinding>() { class AboutFragment : ViewBindingFragment<FragmentAboutBinding>() {
private val homeModel: HomeViewModel by androidActivityViewModels() private val musicModel: MusicViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -72,32 +68,25 @@ class AboutFragment : ViewBindingFragment<FragmentAboutBinding>() {
binding.aboutFaq.setOnClickListener { openLinkInBrowser(LINK_FAQ) } binding.aboutFaq.setOnClickListener { openLinkInBrowser(LINK_FAQ) }
binding.aboutLicenses.setOnClickListener { openLinkInBrowser(LINK_LICENSES) } binding.aboutLicenses.setOnClickListener { openLinkInBrowser(LINK_LICENSES) }
collectImmediately(homeModel.songs, ::updateSongCount) collectImmediately(musicModel.statistics, ::updateStatistics)
collectImmediately(homeModel.albums, ::updateAlbumCount)
collectImmediately(homeModel.artists, ::updateArtistCount)
collectImmediately(homeModel.genres, ::updateGenreCount)
} }
private fun updateSongCount(songs: List<Song>) { private fun updateStatistics(statistics: MusicViewModel.Statistics?) {
val binding = requireBinding() val binding = requireBinding()
binding.aboutSongCount.text = getString(R.string.fmt_lib_song_count, songs.size) binding.aboutSongCount.text = getString(R.string.fmt_lib_song_count, statistics?.songs ?: 0)
requireBinding().aboutAlbumCount.text = getString(R.string.fmt_lib_album_count, statistics?.albums ?: 0)
requireBinding().aboutArtistCount.text =
getString(R.string.fmt_lib_artist_count, statistics?.artists ?: 0)
requireBinding().aboutGenreCount.text = getString(R.string.fmt_lib_genre_count, statistics?.genres ?: 0)
binding.aboutTotalDuration.text = binding.aboutTotalDuration.text =
getString( getString(
R.string.fmt_lib_total_duration, R.string.fmt_lib_total_duration,
songs.sumOf { it.durationMs }.formatDurationMs(false)) (statistics?.durationMs ?: 0).formatDurationMs(false))
}
private fun updateAlbumCount(albums: List<Album>) {
requireBinding().aboutAlbumCount.text = getString(R.string.fmt_lib_album_count, albums.size)
}
private fun updateArtistCount(artists: List<Artist>) {
requireBinding().aboutArtistCount.text =
getString(R.string.fmt_lib_artist_count, artists.size)
}
private fun updateGenreCount(genres: List<Genre>) {
requireBinding().aboutGenreCount.text = getString(R.string.fmt_lib_genre_count, genres.size)
} }
/** Go through the process of opening a [link] in a browser. */ /** Go through the process of opening a [link] in a browser. */