Skip to content

Enable sorting genres by song count #174

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ android {


testImplementation(libs.junit)
testImplementation(libs.mockk)
testImplementation(libs.kotlinx.coroutines.test)

// WorkManager
implementation(libs.androidx.work.runtime.ktx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.SharedPreferences
import com.simplecityapps.shuttle.persistence.get
import com.simplecityapps.shuttle.persistence.put
import com.simplecityapps.shuttle.sorting.AlbumSortOrder
import com.simplecityapps.shuttle.sorting.GenreSortOrder
import com.simplecityapps.shuttle.sorting.SongSortOrder
import timber.log.Timber

Expand Down Expand Up @@ -32,4 +33,17 @@ class SortPreferenceManager(private val sharedPreferences: SharedPreferences) {
AlbumSortOrder.AlbumName
}
}

var sortOrderGenreList: GenreSortOrder
set(value) {
sharedPreferences.put("sort_order_genre_list", value.name)
}
get() {
return try {
GenreSortOrder.valueOf(sharedPreferences.get("sort_order_genre_list", GenreSortOrder.Name.name))
} catch (e: IllegalArgumentException) {
Timber.e(e, "Failed to retrieve sort order")
GenreSortOrder.Name
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import androidx.compose.ui.unit.dp
import com.simplecityapps.mediaprovider.Progress
import com.simplecityapps.shuttle.model.Genre
import com.simplecityapps.shuttle.model.Playlist
import com.simplecityapps.shuttle.sorting.GenreSortOrder
import com.simplecityapps.shuttle.ui.screens.playlistmenu.PlaylistData

@Composable
fun GenreList(
viewState: GenreListViewModel.ViewState,
playlists: List<Playlist>,
setToolbarMenu: (sortOrder: GenreSortOrder) -> Unit,
setLoadingState: (GenreListFragment.LoadingState) -> Unit,
setLoadingProgress: (progress: Progress?) -> Unit,
onSelectGenre: (genre: Genre) -> Unit,
Expand All @@ -37,6 +39,7 @@ fun GenreList(
is GenreListViewModel.ViewState.Scanning -> {
setLoadingState(GenreListFragment.LoadingState.Scanning)
setLoadingProgress(viewState.progress)
setToolbarMenu(viewState.sortOrder)
}

is GenreListViewModel.ViewState.Loading -> {
Expand All @@ -50,6 +53,8 @@ fun GenreList(
setLoadingState(GenreListFragment.LoadingState.None)
}

setToolbarMenu(viewState.sortOrder)

GenreList(
genres = viewState.genres,
playlists = playlists,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package com.simplecityapps.shuttle.ui.screens.library.genres

import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
Expand All @@ -16,11 +19,13 @@ import com.simplecityapps.mediaprovider.Progress
import com.simplecityapps.shuttle.R
import com.simplecityapps.shuttle.model.Genre
import com.simplecityapps.shuttle.model.Song
import com.simplecityapps.shuttle.sorting.GenreSortOrder
import com.simplecityapps.shuttle.ui.common.autoCleared
import com.simplecityapps.shuttle.ui.common.dialog.TagEditorAlertDialog
import com.simplecityapps.shuttle.ui.common.error.userDescription
import com.simplecityapps.shuttle.ui.common.view.CircularLoadingView
import com.simplecityapps.shuttle.ui.common.view.HorizontalLoadingView
import com.simplecityapps.shuttle.ui.common.view.findToolbarHost
import com.simplecityapps.shuttle.ui.screens.library.genres.detail.GenreDetailFragmentArgs
import com.simplecityapps.shuttle.ui.screens.playlistmenu.CreatePlaylistDialogFragment
import com.simplecityapps.shuttle.ui.screens.playlistmenu.PlaylistData
Expand Down Expand Up @@ -48,6 +53,12 @@ class GenreListFragment :

// Lifecycle

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setHasOptionsMenu(true)
}

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand Down Expand Up @@ -82,6 +93,9 @@ class GenreListFragment :
) {
GenreList(
viewState = viewState,
setToolbarMenu = { sortOrder ->
updateToolbarMenu(sortOrder)
},
playlists = playlistMenuPresenter.playlists,
setLoadingState = {
setLoadingState(it)
Expand Down Expand Up @@ -135,12 +149,47 @@ class GenreListFragment :
}
}

override fun onCreateOptionsMenu(
menu: Menu,
inflater: MenuInflater
) {
super.onCreateOptionsMenu(menu, inflater)

inflater.inflate(R.menu.menu_genre_list, menu)
}

override fun onDestroyView() {
playlistMenuPresenter.unbindView()

super.onDestroyView()
}

// Toolbar item selection

override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
R.id.sortGenreName -> {
viewModel.setSortOrder(GenreSortOrder.Name)
true
}
R.id.sortSongCount -> {
viewModel.setSortOrder(GenreSortOrder.SongCount)
true
}
else -> false
}

private fun updateToolbarMenu(sortOrder: GenreSortOrder) {
findToolbarHost()?.toolbar?.menu?.let { menu ->
when (sortOrder) {
GenreSortOrder.Name -> menu.findItem(R.id.sortGenreName)?.isChecked = true
GenreSortOrder.SongCount -> menu.findItem(R.id.sortSongCount)?.isChecked = true
else -> {
// Nothing to do
}
}
}
}

fun onAddedToQueue(genre: Genre) {
Toast.makeText(context, Phrase.from(requireContext(), R.string.queue_item_added).put("item_name", genre.name).format(), Toast.LENGTH_SHORT).show()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,28 @@ import com.simplecityapps.mediaprovider.Progress
import com.simplecityapps.mediaprovider.SongImportState
import com.simplecityapps.mediaprovider.repository.genres.GenreQuery
import com.simplecityapps.mediaprovider.repository.genres.GenreRepository
import com.simplecityapps.mediaprovider.repository.genres.comparator
import com.simplecityapps.mediaprovider.repository.songs.SongRepository
import com.simplecityapps.playback.PlaybackManager
import com.simplecityapps.playback.queue.QueueManager
import com.simplecityapps.shuttle.model.Genre
import com.simplecityapps.shuttle.model.Song
import com.simplecityapps.shuttle.persistence.GeneralPreferenceManager
import com.simplecityapps.shuttle.query.SongQuery
import com.simplecityapps.shuttle.sorting.GenreSortOrder
import com.simplecityapps.shuttle.ui.screens.library.SortPreferenceManager
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import timber.log.Timber

@OpenForTesting
@HiltViewModel
Expand All @@ -32,6 +38,7 @@ class GenreListViewModel @Inject constructor(
private val songRepository: SongRepository,
private val playbackManager: PlaybackManager,
private val queueManager: QueueManager,
private val sortPreferenceManager: SortPreferenceManager,
preferenceManager: GeneralPreferenceManager,
mediaImportObserver: MediaImportObserver
) : ViewModel() {
Expand All @@ -40,13 +47,13 @@ class GenreListViewModel @Inject constructor(

init {
combine(
genreRepository.getGenres(GenreQuery.All()),
genreRepository.getGenres(GenreQuery.All(sortOrder = sortPreferenceManager.sortOrderGenreList)),
mediaImportObserver.songImportState
) { genres, songImportState ->
if (songImportState is SongImportState.ImportProgress) {
_viewState.emit(ViewState.Scanning(songImportState.progress))
_viewState.emit(ViewState.Scanning(songImportState.progress, sortPreferenceManager.sortOrderGenreList))
} else {
_viewState.emit(ViewState.Ready(genres))
_viewState.emit(ViewState.Ready(genres, sortPreferenceManager.sortOrderGenreList))
}
}
.onStart {
Expand Down Expand Up @@ -106,13 +113,31 @@ class GenreListViewModel @Inject constructor(
}
}

fun setSortOrder(sortOrder: GenreSortOrder) {
if (sortPreferenceManager.sortOrderGenreList == sortOrder) return

Timber.i("Updating sort order: $sortOrder")
viewModelScope.launch {
withContext(Dispatchers.IO) {
sortPreferenceManager.sortOrderGenreList = sortOrder
}
when (val state = _viewState.value) {
is ViewState.Scanning -> _viewState.emit(ViewState.Scanning(state.progress, sortOrder))
is ViewState.Ready -> _viewState.emit(ViewState.Ready(state.genres.sortedWith(sortOrder.comparator), sortOrder))
else -> {
// View is not created
}
}
}
}

private suspend fun getSongsForGenreOrEmpty(genre: Genre) = genreRepository.getSongsForGenre(genre.name, SongQuery.All())
.firstOrNull()
.orEmpty()

sealed class ViewState {
data class Scanning(val progress: Progress?) : ViewState()
data object Loading : ViewState()
data class Ready(val genres: List<Genre>) : ViewState()
data class Scanning(val progress: Progress?, val sortOrder: GenreSortOrder) : ViewState()
data class Ready(val genres: List<Genre>, val sortOrder: GenreSortOrder) : ViewState()
}
}
21 changes: 21 additions & 0 deletions android/app/src/main/res/menu/menu_genre_list.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/genreSortOrder"
android:icon="@drawable/ic_baseline_sort_24"
android:title="@string/menu_title_sort_by"
app:showAsAction="never">

<menu>
<group android:checkableBehavior="single">
<item
android:id="@+id/sortGenreName"
android:title="@string/menu_title_sort_name" />
<item
android:id="@+id/sortSongCount"
android:title="@string/menu_title_sort_song_count" />
</group>
</menu>
</item>
</menu>
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-de/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Song-Name</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Jahr</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Name</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">"Liedanzahl"</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Dauer</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-en-rGB/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Song Name</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Year</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Name</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">Song Count</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Duration</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-es-rES/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Nombre de canción</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Año</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Nombre</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">Número de canciones</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Duración</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-es/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Nombre de canción</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Año</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Nombre</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">Número de canciones</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Duración</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-fr/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Titre de chanson</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Année</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Nom</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">Nombre de chansons</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Durée</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-hi/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">गीत का नाम</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">साल</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">"नाम "</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">गानों की संख्या</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">समयांतराल</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-it/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Nome della canzone</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Anno</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Nome</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">Numero di canzoni</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Durata</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-ja/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">曲名</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">年</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">"名前"</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">曲数</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">再生時間</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-nl/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Titel van een liedje</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Jaar</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Naam</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">Aantal nummers</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Looptijd</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-pl/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Nazwa piosenki</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Rok</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Imię</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">Liczba piosenek</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Trwanie</string>
<!-- Menu option to sort by last modified date -->
Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values-pt-rBR/strings_menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
<string name="menu_title_sort_song_name">Nome da música</string>
<!-- Menu option to sort by year-->
<string name="menu_title_sort_year">Ano</string>
<!-- Menu option to sort by name -->
<string name="menu_title_sort_name">Nome</string>
<!-- Menu option to sort by song count -->
<string name="menu_title_sort_song_count">Quantidade de músicas</string>
<!-- Menu option to sort by song duration -->
<string name="menu_title_sort_duration">Duração</string>
<!-- Menu option to sort by last modified date -->
Expand Down
Loading