music: re-add song de-duplication
Re-add song deduplication, which apparently was lost at some point in 3.0.0's development cycle.
This commit is contained in:
parent
018e2ef310
commit
b7726607ff
6 changed files with 12 additions and 12 deletions
|
@ -23,6 +23,7 @@ file manager
|
||||||
- Fixed genre picker from repeatedly showing up when device rotates
|
- Fixed genre picker from repeatedly showing up when device rotates
|
||||||
- Fixed multi-value genres not being recognized on vorbis files
|
- Fixed multi-value genres not being recognized on vorbis files
|
||||||
- Fixed sharp-cornered widget bar appearing even when round mode was enabled
|
- Fixed sharp-cornered widget bar appearing even when round mode was enabled
|
||||||
|
- Fixed duplicate song items from appearing
|
||||||
|
|
||||||
#### What's Changed
|
#### What's Changed
|
||||||
- Implemented new queue system
|
- Implemented new queue system
|
||||||
|
|
|
@ -35,7 +35,7 @@ import org.oxycblt.auxio.util.logD
|
||||||
*/
|
*/
|
||||||
class Library(rawSongs: List<Song.Raw>, settings: MusicSettings) {
|
class Library(rawSongs: List<Song.Raw>, settings: MusicSettings) {
|
||||||
/** All [Song]s that were detected on the device. */
|
/** All [Song]s that were detected on the device. */
|
||||||
val songs = Sort(Sort.Mode.ByName, true).songs(rawSongs.map { Song(it, settings) })
|
val songs = Sort(Sort.Mode.ByName, true).songs(rawSongs.map { Song(it, settings) }.distinct())
|
||||||
/** All [Album]s found on the device. */
|
/** All [Album]s found on the device. */
|
||||||
val albums = buildAlbums(songs)
|
val albums = buildAlbums(songs)
|
||||||
/** All [Artist]s found on the device. */
|
/** All [Artist]s found on the device. */
|
||||||
|
|
|
@ -97,7 +97,7 @@ data class Sort(val mode: Mode, val isAscending: Boolean) {
|
||||||
* Sort a *mutable* list of [Song]s in-place using this [Sort]'s configuration.
|
* Sort a *mutable* list of [Song]s in-place using this [Sort]'s configuration.
|
||||||
* @param songs The [Song]s to sort.
|
* @param songs The [Song]s to sort.
|
||||||
*/
|
*/
|
||||||
fun songsInPlace(songs: MutableList<Song>) {
|
private fun songsInPlace(songs: MutableList<Song>) {
|
||||||
songs.sortWith(mode.getSongComparator(isAscending))
|
songs.sortWith(mode.getSongComparator(isAscending))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), EditableListL
|
||||||
val binding = requireBinding()
|
val binding = requireBinding()
|
||||||
|
|
||||||
// Replace or diff the queue depending on the type of change it is.
|
// Replace or diff the queue depending on the type of change it is.
|
||||||
val instructions = queueModel.instructions
|
val instructions = queueModel.queueListInstructions
|
||||||
queueAdapter.submitList(queue, instructions?.update ?: BasicListInstructions.DIFF)
|
queueAdapter.submitList(queue, instructions?.update ?: BasicListInstructions.DIFF)
|
||||||
// Update position in list (and thus past/future items)
|
// Update position in list (and thus past/future items)
|
||||||
queueAdapter.setPosition(index, isPlaying)
|
queueAdapter.setPosition(index, isPlaying)
|
||||||
|
|
|
@ -44,20 +44,20 @@ class QueueViewModel : ViewModel(), PlaybackStateManager.Listener {
|
||||||
get() = _index
|
get() = _index
|
||||||
|
|
||||||
/** Specifies how to update the list when the queue changes. */
|
/** Specifies how to update the list when the queue changes. */
|
||||||
var instructions: Instructions? = null
|
var queueListInstructions: ListInstructions? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
playbackManager.addListener(this)
|
playbackManager.addListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onIndexMoved(queue: Queue) {
|
override fun onIndexMoved(queue: Queue) {
|
||||||
instructions = Instructions(null, queue.index)
|
queueListInstructions = ListInstructions(null, queue.index)
|
||||||
_index.value = queue.index
|
_index.value = queue.index
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueueChanged(queue: Queue, change: Queue.ChangeResult) {
|
override fun onQueueChanged(queue: Queue, change: Queue.ChangeResult) {
|
||||||
// Queue changed trivially due to item mo -> Diff queue, stay at current index.
|
// Queue changed trivially due to item mo -> Diff queue, stay at current index.
|
||||||
instructions = Instructions(BasicListInstructions.DIFF, null)
|
queueListInstructions = ListInstructions(BasicListInstructions.DIFF, null)
|
||||||
_queue.value = queue.resolve()
|
_queue.value = queue.resolve()
|
||||||
if (change != Queue.ChangeResult.MAPPING) {
|
if (change != Queue.ChangeResult.MAPPING) {
|
||||||
// Index changed, make sure it remains updated without actually scrolling to it.
|
// Index changed, make sure it remains updated without actually scrolling to it.
|
||||||
|
@ -67,14 +67,14 @@ class QueueViewModel : ViewModel(), PlaybackStateManager.Listener {
|
||||||
|
|
||||||
override fun onQueueReordered(queue: Queue) {
|
override fun onQueueReordered(queue: Queue) {
|
||||||
// Queue changed completely -> Replace queue, update index
|
// Queue changed completely -> Replace queue, update index
|
||||||
instructions = Instructions(BasicListInstructions.REPLACE, queue.index)
|
queueListInstructions = ListInstructions(BasicListInstructions.REPLACE, queue.index)
|
||||||
_queue.value = queue.resolve()
|
_queue.value = queue.resolve()
|
||||||
_index.value = queue.index
|
_index.value = queue.index
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNewPlayback(queue: Queue, parent: MusicParent?) {
|
override fun onNewPlayback(queue: Queue, parent: MusicParent?) {
|
||||||
// Entirely new queue -> Replace queue, update index
|
// Entirely new queue -> Replace queue, update index
|
||||||
instructions = Instructions(BasicListInstructions.REPLACE, queue.index)
|
queueListInstructions = ListInstructions(BasicListInstructions.REPLACE, queue.index)
|
||||||
_queue.value = queue.resolve()
|
_queue.value = queue.resolve()
|
||||||
_index.value = queue.index
|
_index.value = queue.index
|
||||||
}
|
}
|
||||||
|
@ -119,10 +119,10 @@ class QueueViewModel : ViewModel(), PlaybackStateManager.Listener {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Signal that the specified [Instructions] in [instructions] were performed. */
|
/** Signal that the specified [ListInstructions] in [queueListInstructions] were performed. */
|
||||||
fun finishInstructions() {
|
fun finishInstructions() {
|
||||||
instructions = null
|
queueListInstructions = null
|
||||||
}
|
}
|
||||||
|
|
||||||
class Instructions(val update: BasicListInstructions?, val scrollTo: Int?)
|
class ListInstructions(val update: BasicListInstructions?, val scrollTo: Int?)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
Loading…
Reference in a new issue