Merge branch 'dev' into weblate-auxio-strings

This commit is contained in:
Alexander Capehart 2025-01-01 18:11:44 -05:00 committed by GitHub
commit 71abe8553b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
33 changed files with 168 additions and 135 deletions

View file

@ -323,6 +323,8 @@ class HomeFragment :
findNavController()
.navigateSafe(HomeFragmentDirections.reportError(state.error))
}
} else {
binding.homeIndexingContainer.setOnClickListener(null)
}
}
is IndexingState.Indexing -> {

View file

@ -36,6 +36,8 @@ interface HomeGenerator {
fun release()
fun empty(): Boolean
fun songs(): List<Song>
fun albums(): List<Album>
@ -49,6 +51,8 @@ interface HomeGenerator {
fun tabs(): List<MusicType>
interface Invalidator {
fun invalidateEmpty() {}
fun invalidateMusic(type: MusicType, instructions: UpdateInstructions)
fun invalidateTabs()
@ -119,6 +123,8 @@ private class HomeGeneratorImpl(
}
override fun onMusicChanges(changes: MusicRepository.Changes) {
invalidator.invalidateEmpty()
val library = musicRepository.library
if (changes.deviceLibrary && library != null) {
L.d("Refreshing library")
@ -142,6 +148,9 @@ private class HomeGeneratorImpl(
homeSettings.unregisterListener(this)
}
override fun empty() =
musicRepository.library?.empty() ?: true
override fun songs() =
musicRepository.library?.let { listSettings.songSort.songs(it.songs) } ?: emptyList()

View file

@ -120,6 +120,10 @@ constructor(
val playlistList: StateFlow<List<Playlist>>
get() = _playlistList
private val _empty = MutableStateFlow(false)
val empty: StateFlow<Boolean>
get() = _empty
private val _playlistInstructions = MutableEvent<UpdateInstructions>()
/** Instructions for how to update [genreList] in the UI. */
val playlistInstructions: Event<UpdateInstructions>
@ -129,6 +133,7 @@ constructor(
val playlistSort: Sort
get() = listSettings.playlistSort
private val homeGenerator = homeGeneratorFactory.create(this)
/**
@ -172,6 +177,10 @@ constructor(
homeGenerator.release()
}
override fun invalidateEmpty() {
_empty.value = homeGenerator.empty()
}
override fun invalidateMusic(type: MusicType, instructions: UpdateInstructions) {
when (type) {
MusicType.SONGS -> {

View file

@ -37,7 +37,6 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.AlbumViewHolder
import org.oxycblt.auxio.list.recycler.FastScrollRecyclerView
import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.music.IndexingState
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.resolve
import org.oxycblt.auxio.playback.PlaybackViewModel
@ -82,11 +81,16 @@ class AlbumListFragment :
listener = this@AlbumListFragment
}
binding.homeNoMusicMsg.text = getString(R.string.lng_no_albums)
binding.homeNoMusicPlaceholder.apply {
setImageResource(R.drawable.ic_album_48)
contentDescription = getString(R.string.lbl_albums)
}
binding.homeNoMusicMsg.text = getString(R.string.lng_empty_albums)
binding.homeChooseMusicSources.setOnClickListener { homeModel.startChooseMusicLocations() }
binding.homeNoMusicAction.setOnClickListener { homeModel.startChooseMusicLocations() }
collectImmediately(homeModel.albumList, musicModel.indexingState, ::updateAlbums)
collectImmediately(homeModel.albumList, ::updateAlbums)
collectImmediately(homeModel.empty, ::updateNoMusicIndicator)
collectImmediately(listModel.selected, ::updateSelection)
collectImmediately(
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
@ -150,15 +154,16 @@ class AlbumListFragment :
listModel.openMenu(R.menu.album, item)
}
private fun updateAlbums(albums: List<Album>, indexingState: IndexingState?) {
requireBinding().apply {
homeRecycler.isInvisible = albums.isEmpty()
homeNoMusic.isInvisible =
indexingState !is IndexingState.Completed || albums.isNotEmpty()
}
private fun updateAlbums(albums: List<Album>) {
albumAdapter.update(albums, homeModel.albumInstructions.consume())
}
private fun updateNoMusicIndicator(empty: Boolean) {
val binding = requireBinding()
binding.homeRecycler.isInvisible = empty
binding.homeNoMusic.isInvisible = !empty
}
private fun updateSelection(selection: List<Music>) {
albumAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
}

View file

@ -35,7 +35,6 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.ArtistViewHolder
import org.oxycblt.auxio.list.recycler.FastScrollRecyclerView
import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.music.IndexingState
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.formatDurationMs
@ -76,11 +75,16 @@ class ArtistListFragment :
listener = this@ArtistListFragment
}
binding.homeNoMusicMsg.text = getString(R.string.lng_no_artists)
binding.homeNoMusicPlaceholder.apply {
setImageResource(R.drawable.ic_artist_48)
contentDescription = getString(R.string.lbl_artists)
}
binding.homeNoMusicMsg.text = getString(R.string.lng_empty_artists)
binding.homeChooseMusicSources.setOnClickListener { homeModel.startChooseMusicLocations() }
binding.homeNoMusicAction.setOnClickListener { homeModel.startChooseMusicLocations() }
collectImmediately(homeModel.artistList, musicModel.indexingState, ::updateArtists)
collectImmediately(homeModel.artistList, ::updateArtists)
collectImmediately(homeModel.empty, ::updateNoMusicIndicator)
collectImmediately(listModel.selected, ::updateSelection)
collectImmediately(
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
@ -125,15 +129,16 @@ class ArtistListFragment :
listModel.openMenu(R.menu.parent, item)
}
private fun updateArtists(artists: List<Artist>, indexingState: IndexingState?) {
requireBinding().apply {
homeRecycler.isInvisible = artists.isEmpty()
homeNoMusic.isInvisible =
indexingState !is IndexingState.Completed || artists.isNotEmpty()
}
private fun updateArtists(artists: List<Artist>) {
artistAdapter.update(artists, homeModel.artistInstructions.consume())
}
private fun updateNoMusicIndicator(empty: Boolean) {
val binding = requireBinding()
binding.homeRecycler.isInvisible = empty
binding.homeNoMusic.isInvisible = !empty
}
private fun updateSelection(selection: List<Music>) {
artistAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
}

View file

@ -35,7 +35,6 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.FastScrollRecyclerView
import org.oxycblt.auxio.list.recycler.GenreViewHolder
import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.music.IndexingState
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.formatDurationMs
@ -75,11 +74,16 @@ class GenreListFragment :
listener = this@GenreListFragment
}
binding.homeNoMusicMsg.text = getString(R.string.lng_no_genres)
binding.homeNoMusicPlaceholder.apply {
setImageResource(R.drawable.ic_genre_48)
contentDescription = getString(R.string.lbl_genres)
}
binding.homeNoMusicMsg.text = getString(R.string.lng_empty_genres)
binding.homeChooseMusicSources.setOnClickListener { homeModel.startChooseMusicLocations() }
binding.homeNoMusicAction.setOnClickListener { homeModel.startChooseMusicLocations() }
collectImmediately(homeModel.genreList, musicModel.indexingState, ::updateGenres)
collectImmediately(homeModel.genreList, ::updateGenres)
collectImmediately(homeModel.empty, ::updateNoMusicIndicator)
collectImmediately(listModel.selected, ::updateSelection)
collectImmediately(
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
@ -124,15 +128,16 @@ class GenreListFragment :
listModel.openMenu(R.menu.parent, item)
}
private fun updateGenres(genres: List<Genre>, indexingState: IndexingState?) {
requireBinding().apply {
homeRecycler.isInvisible = genres.isEmpty()
homeNoMusic.isInvisible =
indexingState !is IndexingState.Completed || genres.isNotEmpty()
}
private fun updateGenres(genres: List<Genre>) {
genreAdapter.update(genres, homeModel.genreInstructions.consume())
}
private fun updateNoMusicIndicator(empty: Boolean) {
val binding = requireBinding()
binding.homeRecycler.isInvisible = empty
binding.homeNoMusic.isInvisible = !empty
}
private fun updateSelection(selection: List<Music>) {
genreAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
}

View file

@ -34,7 +34,6 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.FastScrollRecyclerView
import org.oxycblt.auxio.list.recycler.PlaylistViewHolder
import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.music.IndexingState
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.formatDurationMs
@ -73,11 +72,14 @@ class PlaylistListFragment :
listener = this@PlaylistListFragment
}
binding.homeNoMusicMsg.text = getString(R.string.lng_no_playlists)
binding.homeNoMusicPlaceholder.apply {
setImageResource(R.drawable.ic_playlist_48)
contentDescription = getString(R.string.lbl_playlists)
}
binding.homeNoMusicMsg.text = getString(R.string.lng_empty_playlists)
binding.homeChooseMusicSources.setOnClickListener { homeModel.startChooseMusicLocations() }
collectImmediately(homeModel.playlistList, musicModel.indexingState, ::updatePlaylists)
collectImmediately(homeModel.playlistList, ::updatePlaylists)
collectImmediately(homeModel.empty, homeModel.playlistList, ::updateNoMusicIndicator)
collectImmediately(listModel.selected, ::updateSelection)
collectImmediately(
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
@ -122,15 +124,23 @@ class PlaylistListFragment :
listModel.openMenu(R.menu.playlist, item)
}
private fun updatePlaylists(playlists: List<Playlist>, indexingState: IndexingState?) {
requireBinding().apply {
homeRecycler.isInvisible = playlists.isEmpty()
homeNoMusic.isInvisible =
indexingState !is IndexingState.Completed || playlists.isNotEmpty()
}
private fun updatePlaylists(playlists: List<Playlist>) {
playlistAdapter.update(playlists, homeModel.playlistInstructions.consume())
}
private fun updateNoMusicIndicator(empty: Boolean, playlists: List<Playlist>) {
val binding = requireBinding()
binding.homeRecycler.isInvisible = empty
binding.homeNoMusic.isInvisible = !empty && playlists.isNotEmpty()
if (!empty && playlists.isEmpty()) {
binding.homeNoMusicAction.text = getString(R.string.lbl_new_playlist)
binding.homeNoMusicAction.setOnClickListener { musicModel.createPlaylist() }
} else {
binding.homeNoMusicAction.text = getString(R.string.lbl_music_sources)
binding.homeNoMusicAction.setOnClickListener { homeModel.startChooseMusicLocations() }
}
}
private fun updateSelection(selection: List<Music>) {
playlistAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
}

View file

@ -36,7 +36,6 @@ import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter
import org.oxycblt.auxio.list.recycler.FastScrollRecyclerView
import org.oxycblt.auxio.list.recycler.SongViewHolder
import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.music.IndexingState
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.music.resolve
import org.oxycblt.auxio.playback.PlaybackViewModel
@ -80,11 +79,16 @@ class SongListFragment :
listener = this@SongListFragment
}
binding.homeNoMusicMsg.text = getString(R.string.lng_no_songs)
binding.homeNoMusicPlaceholder.apply {
setImageResource(R.drawable.ic_song_48)
contentDescription = getString(R.string.lbl_songs)
}
binding.homeNoMusicMsg.text = getString(R.string.lng_empty_songs)
binding.homeChooseMusicSources.setOnClickListener { homeModel.startChooseMusicLocations() }
binding.homeNoMusicAction.setOnClickListener { homeModel.startChooseMusicLocations() }
collectImmediately(homeModel.songList, musicModel.indexingState, ::updateSongs)
collectImmediately(homeModel.songList, ::updateSongs)
collectImmediately(homeModel.empty, ::updateNoMusicIndicator)
collectImmediately(listModel.selected, ::updateSelection)
collectImmediately(
playbackModel.song, playbackModel.parent, playbackModel.isPlaying, ::updatePlayback)
@ -150,15 +154,16 @@ class SongListFragment :
listModel.openMenu(R.menu.song, item, homeModel.playWith)
}
private fun updateSongs(songs: List<Song>, indexingState: IndexingState?) {
requireBinding().apply {
homeRecycler.isInvisible = songs.isEmpty()
homeNoMusic.isInvisible =
indexingState !is IndexingState.Completed || songs.isNotEmpty()
}
private fun updateSongs(songs: List<Song>) {
songAdapter.update(songs, homeModel.songInstructions.consume())
}
private fun updateNoMusicIndicator(empty: Boolean) {
val binding = requireBinding()
binding.homeRecycler.isInvisible = empty
binding.homeNoMusic.isInvisible = !empty
}
private fun updateSelection(selection: List<Music>) {
songAdapter.setSelected(selection.filterIsInstanceTo(mutableSetOf()))
}

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M480,644Q550,644 600,596.5Q650,549 650,480Q650,409 600.5,359.5Q551,310 480,310Q411,310 363.5,360Q316,410 316,480Q316,549 363.5,596.5Q411,644 480,644ZM480,520Q463,520 451.5,508.5Q440,497 440,480Q440,463 451.5,451.5Q463,440 480,440Q497,440 508.5,451.5Q520,463 520,480Q520,497 508.5,508.5Q497,520 480,520ZM480,880Q398,880 325,848.5Q252,817 197.5,762.5Q143,708 111.5,635Q80,562 80,480Q80,397 111.5,324Q143,251 197.5,197Q252,143 325,111.5Q398,80 480,80Q563,80 636,111.5Q709,143 763,197Q817,251 848.5,324Q880,397 880,480Q880,562 848.5,635Q817,708 763,762.5Q709,817 636,848.5Q563,880 480,880ZM480,820Q622,820 721,720.5Q820,621 820,480Q820,338 721,239Q622,140 480,140Q339,140 239.5,239Q140,338 140,480Q140,621 239.5,720.5Q339,820 480,820ZM480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Q480,480 480,480Z"/>
</vector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M0,720L0,667Q0,628.43 41.5,604.22Q83,580 150.38,580Q162.54,580 173.77,580.5Q185,581 196,582.65Q188,600 184,617.82Q180,635.63 180,655L180,720L0,720ZM240,720L240,655Q240,623 257.5,596.5Q275,570 307,550Q339,530 383.5,520Q428,510 480,510Q533,510 577.5,520Q622,530 654,550Q686,570 703,596.5Q720,623 720,655L720,720L240,720ZM780,720L780,655Q780,635.14 776.5,617.57Q773,600 765,582.73Q776,581 787.17,580.5Q798.34,580 810,580Q877.5,580 918.75,603.77Q960,627.54 960,667L960,720L780,720ZM300,660L660,660L660,654Q660,617 609.5,593.5Q559,570 480,570Q401,570 350.5,593.5Q300,617 300,655L300,660ZM149.57,550Q121,550 100.5,529.44Q80,508.87 80,480Q80,451 100.56,430.5Q121.13,410 150,410Q179,410 199.5,430.5Q220,451 220,480.43Q220,509 199.5,529.5Q179,550 149.57,550ZM809.57,550Q781,550 760.5,529.44Q740,508.87 740,480Q740,451 760.56,430.5Q781.13,410 810,410Q839,410 859.5,430.5Q880,451 880,480.43Q880,509 859.5,529.5Q839,550 809.57,550ZM480,480Q430,480 395,445Q360,410 360,360Q360,309 395,274.5Q430,240 480,240Q531,240 565.5,274.5Q600,309 600,360Q600,410 565.5,445Q531,480 480,480ZM480.35,420Q506,420 523,402.65Q540,385.3 540,359.65Q540,334 522.85,317Q505.7,300 480.35,300Q455,300 437.5,317.15Q420,334.3 420,359.65Q420,385 437.35,402.5Q454.7,420 480.35,420ZM480,660L480,660Q480,660 480,660Q480,660 480,660Q480,660 480,660Q480,660 480,660L480,660ZM480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Q480,360 480,360Z"/>
</vector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M215,843Q181.17,843 148.08,831.5Q115,820 90,794Q125,782 140,759Q155,736 155,697Q155,653.25 185.68,622.62Q216.35,592 260.18,592Q304,592 334.5,622.62Q365,653.25 365,697Q365,761 321.5,802Q278,843 215,843ZM215,783Q250,783 277.5,758Q305,733 305,697Q305,677 292.5,664.5Q280,652 260,652Q240,652 227.5,664.5Q215,677 215,697Q215,736 206.5,754.5Q198,773 175,777Q181,778 195,780.5Q209,783 215,783ZM445,606L355,511L731,135Q745,121 762,120.5Q779,120 794,135L823,164Q838,179 837.5,196.5Q837,214 823,228L445,606ZM260,697Q260,697 260,697Q260,697 260,697Q260,697 260,697Q260,697 260,697Q260,697 260,697Q260,697 260,697Q260,697 260,697Q260,697 260,697Q260,697 260,697Q260,697 260,697Z"/>
</vector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M120,630L120,570L426,570L426,630L120,630ZM120,465L120,405L593,405L593,465L120,465ZM120,300L120,240L593,240L593,300L120,300ZM662,840L662,518L880,679L662,840Z"/>
</vector>

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M393,840Q330,840 286.5,796.5Q243,753 243,690Q243,627 286.5,583.5Q330,540 393,540Q421,540 443.5,548Q466,556 483,570L483,120L717,120L717,255L543,255L543,690Q543,753 499.5,796.5Q456,840 393,840Z"/>
</vector>

View file

@ -33,7 +33,7 @@
android:layout_width="@dimen/size_icon_huge"
android:layout_height="@dimen/size_icon_huge"
android:layout_marginBottom="@dimen/spacing_small"
android:src="@drawable/ic_song_24"
android:src="@drawable/ic_song_48"
app:tint="?attr/colorOnSurface" />
<TextView
@ -41,12 +41,12 @@
android:layout_width="256dp"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/spacing_small"
tools:text="@string/lng_no_songs"
tools:text="@string/lng_empty_songs"
android:textAlignment="center"
android:textAppearance="?attr/textAppearanceBodyLarge" />
<org.oxycblt.auxio.ui.RippleFixMaterialButton
android:id="@+id/home_choose_music_sources"
android:id="@+id/home_no_music_action"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lbl_music_sources" />

View file

@ -329,11 +329,6 @@
<string name="lbl_feedback">Zpětná vazba</string>
<string name="lbl_github">Vytvořit problém na GitHubu</string>
<string name="lbl_email">Poslat e-mail</string>
<string name="lng_no_artists">Vaši umělci se zobrazí zde, jakmile přidáte nějakou hudbu.</string>
<string name="lng_no_genres">Vaše žánry se zobrazí zde, jakmile přidáte nějakou hudbu.</string>
<string name="lng_no_playlists">Vaše seznamy skladeb se zobrazí zde, jakmile přidáte nějakou hudbu.</string>
<string name="lng_no_songs">Vaše skladby se zobrazí zde, jakmile přidáte nějakou hudbu.</string>
<string name="lng_no_albums">Vaše alba se zobrazí zde, jakmile přidáte nějakou hudbu.</string>
<string name="lbl_music_sources">Vybrat složky</string>
<string name="def_album">Neznámé album</string>
<string name="cnt_mp4">MPEG-4 obsahující %s</string>

View file

@ -320,12 +320,7 @@
<string name="lbl_github">Ein Issue auf GitHub erstellen</string>
<string name="lbl_feedback">Rückmeldung</string>
<string name="lbl_email">Eine E-Mail senden</string>
<string name="lng_no_albums">Deine Alben werden hier angezeigt, sobald du Musik hinzufügst.</string>
<string name="lbl_music_sources">Ordner auswählen</string>
<string name="lng_no_songs">Deine Lieder werden hier angezeigt, sobald du Musik hinzufügst.</string>
<string name="lng_no_artists">Deine Künstler werden hier angezeigt, sobald du Musik hinzufügst.</string>
<string name="lng_no_playlists">Deine Wiedergabelisten werden hier angezeigt, sobald du Musik hinzufügst.</string>
<string name="lng_no_genres">Deine Genres werden hier angezeigt, sobald du Musik hinzufügst.</string>
<string name="cnt_mp4">MPEG-4, enthält %s</string>
<string name="cdc_alac">Apple Lossless Audio Codec (ALAC)</string>
<string name="cdc_unknown">Unbekannt</string>

View file

@ -325,11 +325,6 @@
<string name="lbl_email">Enviar un correo electrónico</string>
<string name="lbl_feedback">Retroalimentación</string>
<string name="lbl_music_sources">Seleccionar carpetas</string>
<string name="lng_no_playlists">Tus listas de reproducción aparecerán aquí una vez que agregues música.</string>
<string name="lng_no_songs">Tus canciones aparecerán aquí una vez que agregues algo de música.</string>
<string name="lng_no_albums">Tus álbumes aparecerán aquí una vez que agregues algo de música.</string>
<string name="lng_no_artists">Tus artistas aparecerán aquí una vez que agregues algo de música.</string>
<string name="lng_no_genres">Tus géneros musicales aparecerán aquí una vez que agregues algo de música.</string>
<string name="def_album">Álbum desconocido</string>
<string name="cdc_unknown">Desconocido</string>
<string name="cnt_mp4">El MPEG-4 contiene %s</string>

View file

@ -313,11 +313,6 @@
<string name="lbl_github">Koosta GitHubis veateade või ettepanek</string>
<string name="lbl_email">Saada e-kiri</string>
<string name="lbl_music_sources">Vali kaustad</string>
<string name="lng_no_songs">Kui oled muusikat lisanud, siis on sinu palad siin näha.</string>
<string name="lng_no_albums">Kui oled muusikat lisanud, siis on sinu albumid siin näha.</string>
<string name="lng_no_artists">Kui oled muusikat lisanud, siis on sinu esitajad siin näha.</string>
<string name="lng_no_genres">Kui oled muusikat lisanud, siis on žanrid siin näha.</string>
<string name="lng_no_playlists">Kui oled muusikat lisanud, siis on sinu esitusloendid siin näha.</string>
<string name="def_album">Tundmatu album</string>
<string name="cnt_mp4">MPEG-4 %s koodekiga</string>
<string name="cdc_alac">Apple Lossless Audio Codec (ALAC)</string>

View file

@ -308,12 +308,7 @@
<string name="lbl_more">Lisää</string>
<string name="lbl_feedback">Palaute</string>
<string name="lng_tasker_start">Käynnistää Auxion käyttämällä aiemmin tallennettua tilaa. Jos tallennettua tilaa ei ole saatavilla, kaikki kappaleet sekoitetaan. Toisto alkaa välittömästi.\n\nVaroitus: Ole varovainen tämän palvelun hallinnassa. Jos suljet sen ja yrität sitten käyttää sitä uudelleen, sovellus todennäköisesti kaatuu.</string>
<string name="lng_no_songs">Kappaleesi näkyvät täällä, kun lisäät musiikkia.</string>
<string name="lng_no_artists">Artistisi näkyvät täällä, kun lisäät musiikkia.</string>
<string name="lng_no_playlists">Soittolistasi näkyvät täällä, kun lisäät musiikkia.</string>
<string name="set_pre_amp_without">Säätö ilman tunnisteita</string>
<string name="lng_no_albums">Albumisi näkyvät täällä, kun lisäät musiikkia.</string>
<string name="lng_no_genres">Tyylilajisi näkyvät tässä, kun lisäät musiikkia.</string>
<string name="set_pre_amp_desc">Esivahvistinta käytetään olemassa olevaan säätöön toiston aikana</string>
<string name="set_pre_amp_with">Säätö tunnisteilla</string>
<string name="def_album">Tuntematon albumi</string>

View file

@ -321,9 +321,4 @@
<string name="lbl_github">Faire un ticket sur GitHub</string>
<string name="lbl_email">Envoyer un courriel</string>
<string name="lbl_music_sources">Choisir des dossiers</string>
<string name="lng_no_songs">Vos titres apparaîtront ici une fois que vous aurez ajouté de la musique.</string>
<string name="lng_no_albums">Vos albums apparaîtront ici une fois que vous aurez ajouté de la musique.</string>
<string name="lng_no_artists">Vos artistes apparaîtront ici une fois que vous aurez ajouté de la musique.</string>
<string name="lng_no_genres">Vos genres apparaîtront ici une fois que vous aurez ajouté de la musique.</string>
<string name="lng_no_playlists">Vos listes de lecture apparaîtront ici une fois que vous aurez ajouté de la musique.</string>
</resources>

View file

@ -316,11 +316,6 @@
<string name="lbl_github">Prijavi problem na GitHubu</string>
<string name="lbl_email">Pošalji e-mail</string>
<string name="lbl_music_sources">Odaberi mape</string>
<string name="lng_no_albums">Tvoji albumi će se ovdje prikazati kada dodaš neku glazbu.</string>
<string name="lng_no_artists">Tvoji izvođači će se ovdje prikazati kada dodaš neku glazbu.</string>
<string name="lng_no_playlists">Tvoj popis pjesama će se ovdje prikazati kada dodaš neku glazbu.</string>
<string name="lng_no_genres">Tvoji žanri će se ovdje prikazati kada dodaš neku glazbu.</string>
<string name="lng_no_songs">Tvoje pjesme će se ovdje prikazati kada dodaš neku glazbu.</string>
<string name="cdc_alac">Appleov kodek zvuka bez gubitaka (ALAC)</string>
<string name="def_album">Nepoznat album</string>
<string name="cdc_unknown">Nepoznato</string>

View file

@ -319,11 +319,6 @@
<string name="lbl_more">더 보기</string>
<string name="lbl_music_sources">폴더 선택</string>
<string name="lbl_email">전자우편을 전송합니다</string>
<string name="lng_no_albums">당신이 음악을 추가하면 여기에 자신의 앨범이 표시됩니다.</string>
<string name="lng_no_artists">당신이 음악을 추가하면 여기에 자신의 음악가가 표시됩니다.</string>
<string name="lbl_github">깃허브에 문제를 제기합니다</string>
<string name="lbl_feedback">응답</string>
<string name="lng_no_songs">당신이 음악을 추가하면 여기에 표시됩니다.</string>
<string name="lng_no_playlists">당신이 음악을 여기에 추가하면 자신의 재생목록이 표시됩니다.</string>
<string name="lng_no_genres">당신이 음악을 추가하면 여기에 자신의 장르가 표시됩니다.</string>
</resources>

View file

@ -311,9 +311,4 @@
<string name="lbl_feedback">Gi tilbakemelding</string>
<string name="lbl_email">Send en e-post</string>
<string name="lbl_music_sources">Velg mapper</string>
<string name="lng_no_genres">Sjangrene dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
<string name="lng_no_playlists">Spillelistene dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
<string name="lng_no_artists">Artistene dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
<string name="lng_no_songs">Sporene dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
<string name="lng_no_albums">Albumene dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
</resources>

View file

@ -311,9 +311,4 @@
<string name="fmt_lib_album_count">Innlasta album: %d</string>
<string name="fmt_lib_total_duration">Total lengd: %s</string>
<string name="lbl_music_sources">Vel mapper</string>
<string name="lng_no_songs">Spora dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
<string name="lng_no_artists">Artistane dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
<string name="lng_no_genres">Sjangrane dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
<string name="lng_no_albums">Albuma dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
<string name="lng_no_playlists">Spelelistene dine vil dukke opp her etter at du har lagt til musikk i biblioteket ditt.</string>
</resources>

View file

@ -322,14 +322,9 @@
<string name="lbl_email">Envie um e-mail</string>
<string name="lbl_github">Crie uma issue no GitHub</string>
<string name="lbl_music_sources">Escolher pastas</string>
<string name="lng_no_albums">Os seus álbuns aparecerão aqui quando você adicionar um pouco de música.</string>
<string name="lng_no_songs">As suas músicas aparecerão aqui quando você adicionar um pouco de música.</string>
<string name="lng_no_genres">Os seus gêneros aparecerão aqui quando você adicionar um pouco de música.</string>
<string name="lng_no_playlists">As suas playlists aparecerão aqui quando você adicionar um pouco de música.</string>
<string name="cnt_mp4">MPEG-4 contendo %s</string>
<string name="cdc_alac">Apple Lossless Audio Codec (ALAC)</string>
<string name="cdc_unknown">Desconhecido</string>
<string name="def_album">Álbum desconhecido</string>
<string name="lng_no_artists">Os seus artistas aparecerão aqui quando você adicionar um pouco de música.</string>
<string name="lbl_feedback">Feedback</string>
</resources>

View file

@ -313,10 +313,5 @@
<string name="lbl_feedback">Opinião</string>
<string name="lbl_github">Crie um problema no GitHub</string>
<string name="lbl_email">Envie um e-mail</string>
<string name="lng_no_artists">Seus artistas aparecerão aqui assim que você adicionar alguma música.</string>
<string name="lng_no_genres">Seus gêneros aparecerão aqui assim que você adicionar alguma música.</string>
<string name="lng_no_playlists">Suas playlists aparecerão aqui assim que você adicionar alguma música.</string>
<string name="lbl_music_sources">Escolha pastas</string>
<string name="lng_no_albums">Seus álbuns aparecerão aqui assim que você adicionar alguma música.</string>
<string name="lng_no_songs">Suas músicas aparecerão aqui assim que você adicionar alguma música.</string>
</resources>

View file

@ -326,5 +326,4 @@
<string name="lbl_more">Больше</string>
<string name="lbl_feedback">Отзывы</string>
<string name="lbl_email">Отправить электронное письмо</string>
<string name="lng_no_songs">Ваши песни появятся здесь, как только вы добавите музыку.</string>
</resources>

View file

@ -171,11 +171,6 @@
<string name="lng_supporters_promo">உங்கள் பெயரை இங்கே சேர்க்க திட்டத்திற்கு நன்கொடை அளிக்கவும்!</string>
<string name="lng_search_library">உங்கள் நூலகத்தைத் தேடுங்கள்…</string>
<string name="lng_tasker_start">முன்னர் சேமிக்கப்பட்ட நிலையைப் பயன்படுத்தி ஆக்சியோவைத் தொடங்குகிறது. சேமிக்கப்பட்ட நிலை எதுவும் கிடைக்கவில்லை என்றால், எல்லா பாடல்களும் மாற்றப்படும். பிளேபேக் உடனடியாக தொடங்கும்.\n\n எச்சரிக்கை: இந்த சேவையை கட்டுப்படுத்துவதில் கவனமாக இருங்கள், நீங்கள் அதை மூடிவிட்டு அதை மீண்டும் பயன்படுத்த முயற்சித்தால், நீங்கள் பயன்பாட்டை செயலிழக்கச் செய்வீர்கள்.</string>
<string name="lng_no_songs">நீங்கள் சில இசையைச் சேர்த்தவுடன் உங்கள் பாடல்கள் இங்கே காண்பிக்கப்படும்.</string>
<string name="lng_no_albums">நீங்கள் சில இசையைச் சேர்த்தவுடன் உங்கள் ஆல்பங்கள் இங்கே காண்பிக்கப்படும்.</string>
<string name="lng_no_artists">நீங்கள் சில இசையைச் சேர்த்தவுடன் உங்கள் கலைஞர்கள் இங்கே காண்பிப்பார்கள்.</string>
<string name="lng_no_genres">நீங்கள் சில இசையைச் சேர்த்தவுடன் உங்கள் வகைகள் இங்கே காண்பிக்கப்படும்.</string>
<string name="lng_no_playlists">நீங்கள் சில இசையைச் சேர்த்தவுடன் உங்கள் பிளேலிச்ட்கள் இங்கே காண்பிக்கப்படும்.</string>
<string name="set_ui_desc">பயன்பாட்டின் கருப்பொருள் மற்றும் வண்ணங்களை மாற்றவும்</string>
<string name="set_theme">கருப்பொருள்</string>
<string name="set_theme_auto">தானியங்கி</string>

View file

@ -323,13 +323,8 @@
<string name="lbl_more">Більше</string>
<string name="lbl_music_sources">Виберіть папки</string>
<string name="lbl_feedback">Зворотній зв\'язок</string>
<string name="lng_no_artists">Ваші виконавці з’являться тут, коли ви додасте музику.</string>
<string name="lng_no_genres">Ваші жанри з’являться тут, коли ви додасте музику.</string>
<string name="lng_no_songs">Ваші пісні з’являться тут, коли ви додасте музику.</string>
<string name="lbl_github">Зробіть випуск на GitHub</string>
<string name="lbl_email">Надіслати електронний лист</string>
<string name="lng_no_playlists">Ваші списки відтворення з’являться тут, коли ви додасте музику.</string>
<string name="lng_no_albums">Ваші альбоми з’являться тут, коли ви додасте музику.</string>
<string name="def_album">Невідомий альбом</string>
<string name="cnt_mp4">MPEG-4, що містить %s</string>
<string name="cdc_unknown">Невідомий</string>

View file

@ -319,11 +319,6 @@
<string name="lbl_email">发送电子邮件</string>
<string name="lbl_feedback">反馈</string>
<string name="lbl_music_sources">选择文件夹</string>
<string name="lng_no_artists">一旦添加了一些音乐,艺术家会显示在此处。</string>
<string name="lng_no_songs">一旦添加了一些音乐,歌曲会显示在此处。</string>
<string name="lng_no_albums">一旦添加了一些音乐,专辑会显示在此处。</string>
<string name="lng_no_genres">一旦添加了一些音乐,流派会显示在此处。</string>
<string name="lng_no_playlists">一旦添加了一些音乐,播放列表会显示在此处。</string>
<string name="def_album">未知专辑</string>
<string name="cnt_mp4">含 %s 的 MPEG-4</string>
<string name="cdc_alac">Apple 无损音频编解码器ALAC</string>

View file

@ -215,11 +215,11 @@
Starts Auxio using the previously saved state. If no saved state is available, all songs will be shuffled. Playback will start immediately.
\n\nWARNING: Be careful controlling this service, if you close it and then try to use it again, you will probably crash the app.
</string>
<string name="lng_no_songs">Your songs will show up here once you add some music.</string>
<string name="lng_no_albums">Your albums will show up here once you add some music.</string>
<string name="lng_no_artists">Your artists will show up here once you add some music.</string>
<string name="lng_no_genres">Your genres will show up here once you add some music.</string>
<string name="lng_no_playlists">Your playlists will show up here once you add some music.</string>
<string name="lng_empty_songs">Your songs will show up here.</string>
<string name="lng_empty_albums">Your albums will show up here.</string>
<string name="lng_empty_artists">Your artists will show up here.</string>
<string name="lng_empty_genres">Your genres will show up here once.</string>
<string name="lng_empty_playlists">Your playlists will show up here.</string>
<!-- Settings namespace | Settings-related labels -->
<eat-comment />

View file

@ -27,6 +27,8 @@ interface Library {
val genres: Collection<Genre>
val playlists: Collection<Playlist>
fun empty(): Boolean
fun findSong(uid: Music.UID): Song?
fun findSongByPath(path: Path): Song?

View file

@ -42,6 +42,8 @@ internal data class LibraryImpl(
private val genreUidMap = genres.associateBy { it.uid }
private val playlistUidMap = playlists.associateBy { it.uid }
override fun empty() = songs.isEmpty()
override fun findSong(uid: Music.UID) = songUidMap[uid]
override fun findSongByPath(path: Path) = songs.find { it.path == path }