From 900bcd142e957bee699fa1106378b0f939632a3a Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Fri, 20 Jan 2023 15:16:04 -0700 Subject: [PATCH] list: disable complex diffing for now Disable the new instructions-based system for now. The way I was doing reflection was likely far too unsafe and prone to bugs. I'll want to do it some other way. --- CHANGELOG.md | 5 +- .../auxio/detail/AlbumDetailFragment.kt | 5 +- .../auxio/detail/ArtistDetailFragment.kt | 5 +- .../java/org/oxycblt/auxio/detail/Detail.kt | 15 ---- .../oxycblt/auxio/detail/DetailViewModel.kt | 90 ++++--------------- .../auxio/detail/GenreDetailFragment.kt | 5 +- .../auxio/detail/recycler/DetailAdapter.kt | 47 +--------- .../org/oxycblt/auxio/home/HomeViewModel.kt | 49 ---------- .../auxio/home/list/AlbumListFragment.kt | 6 +- .../auxio/home/list/ArtistListFragment.kt | 6 +- .../auxio/home/list/GenreListFragment.kt | 6 +- .../auxio/home/list/SongListFragment.kt | 5 +- .../oxycblt/auxio/list/adapter/AdapterUtil.kt | 42 --------- .../oxycblt/auxio/list/adapter/ListDiffer.kt | 10 +-- 14 files changed, 39 insertions(+), 257 deletions(-) delete mode 100644 app/src/main/java/org/oxycblt/auxio/list/adapter/AdapterUtil.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 1418b016a..148a07ed0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,8 @@ #### What's New - Added ability to play/shuffle selections -- Resigned header components -- Resigned settings view +- Redesigned header components +- Redesigned settings view #### What's Improved - Added ability to edit previously played or currently playing items in the queue @@ -13,7 +13,6 @@ - Pressing the button will now clear the current selection before navigating back - Added support for non-standard `ARTISTS` tags - Play Next and Add To Queue now start playback if there is no queue to add -- Made resorting list animations consistent across app #### What's Fixed - Fixed unreliable ReplayGain adjustment application in certain situations diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt index de445255a..90689c188 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -31,6 +31,7 @@ import org.oxycblt.auxio.databinding.FragmentDetailBinding import org.oxycblt.auxio.detail.recycler.AlbumDetailAdapter import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.ListFragment +import org.oxycblt.auxio.list.adapter.BasicListInstructions import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Music @@ -259,9 +260,7 @@ class AlbumDetailFragment : } private fun updateList(items: List) { - detailAdapter.submitList( - items, detailModel.albumListInstructions ?: DetailListInstructions.Diff) - detailModel.finishAlbumListInstructions() + detailAdapter.submitList(items, BasicListInstructions.DIFF) } private fun updateSelection(selected: List) { diff --git a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt index 3438fa4bd..5734ee1a8 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -31,6 +31,7 @@ import org.oxycblt.auxio.detail.recycler.ArtistDetailAdapter import org.oxycblt.auxio.detail.recycler.DetailAdapter import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.ListFragment +import org.oxycblt.auxio.list.adapter.BasicListInstructions import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Music @@ -235,9 +236,7 @@ class ArtistDetailFragment : } private fun updateList(items: List) { - detailAdapter.submitList( - items, detailModel.artistListInstructions ?: DetailListInstructions.Diff) - detailModel.finishArtistListInstructions() + detailAdapter.submitList(items, BasicListInstructions.DIFF) } private fun updateSelection(selected: List) { diff --git a/app/src/main/java/org/oxycblt/auxio/detail/Detail.kt b/app/src/main/java/org/oxycblt/auxio/detail/Detail.kt index 802f8ac3b..1788b4ddd 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/Detail.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/Detail.kt @@ -48,18 +48,3 @@ data class SongProperties( val sampleRateHz: Int?, val resolvedMimeType: MimeType ) - -/** - * Represents the specific way to update a list of items in the detail lists. - * @author Alexander Capehart (OxygenCobalt) - */ -sealed class DetailListInstructions { - /** Do a plain asynchronous diff. */ - object Diff : DetailListInstructions() - - /** - * Replace all the items starting at the given index. - * @param at The index to start replacing at. - */ - data class ReplaceRest(val at: Int) : DetailListInstructions() -} diff --git a/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt b/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt index 47c2cbc2c..d51cd3734 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/DetailViewModel.kt @@ -78,18 +78,14 @@ class DetailViewModel(application: Application) : /** The current list data derived from [currentAlbum]. */ val albumList: StateFlow> get() = _albumList - /** Specifies how to update [albumList] when it changes. */ - var albumListInstructions: DetailListInstructions? = null - private set /** The current [Sort] used for [Song]s in [albumList]. */ var albumSongSort: Sort get() = musicSettings.albumSongSort set(value) { musicSettings.albumSongSort = value - // Refresh the album list to reflect the new sort. Make sure we only visually replace - // the song information, however. - currentAlbum.value?.let { refreshAlbumList(it, true) } + // Refresh the album list to reflect the new sort. + currentAlbum.value?.let(::refreshAlbumList) } // --- ARTIST --- @@ -102,18 +98,14 @@ class DetailViewModel(application: Application) : private val _artistList = MutableStateFlow(listOf()) /** The current list derived from [currentArtist]. */ val artistList: StateFlow> = _artistList - /** Specifies how to update [artistList] when it changes. */ - var artistListInstructions: DetailListInstructions? = null - private set /** The current [Sort] used for [Song]s in [artistList]. */ var artistSongSort: Sort get() = musicSettings.artistSongSort set(value) { musicSettings.artistSongSort = value - // Refresh the artist list to reflect the new sort. Make sure we only visually replace - // the song information, however. - currentArtist.value?.let { refreshArtistList(it, true) } + // Refresh the artist list to reflect the new sort. + currentArtist.value?.let(::refreshArtistList) } // --- GENRE --- @@ -126,18 +118,14 @@ class DetailViewModel(application: Application) : private val _genreList = MutableStateFlow(listOf()) /** The current list data derived from [currentGenre]. */ val genreList: StateFlow> = _genreList - /** Specifies how to update [genreList] when it changes. */ - var genreListInstructions: DetailListInstructions? = null - private set /** The current [Sort] used for [Song]s in [genreList]. */ var genreSongSort: Sort get() = musicSettings.genreSongSort set(value) { musicSettings.genreSongSort = value - // Refresh the genre list to reflect the new sort. Make sure we only visually replace - // the song information, however. - currentGenre.value?.let { refreshGenreList(it, true) } + // Refresh the genre list to reflect the new sort. + currentGenre.value?.let(::refreshGenreList) } /** @@ -173,19 +161,19 @@ class DetailViewModel(application: Application) : val album = currentAlbum.value if (album != null) { - _currentAlbum.value = library.sanitize(album)?.also { refreshAlbumList(it, false) } + _currentAlbum.value = library.sanitize(album)?.also(::refreshAlbumList) logD("Updated genre to ${currentAlbum.value}") } val artist = currentArtist.value if (artist != null) { - _currentArtist.value = library.sanitize(artist)?.also { refreshArtistList(it, false) } + _currentArtist.value = library.sanitize(artist)?.also(::refreshArtistList) logD("Updated genre to ${currentArtist.value}") } val genre = currentGenre.value if (genre != null) { - _currentGenre.value = library.sanitize(genre)?.also { refreshGenreList(it, false) } + _currentGenre.value = library.sanitize(genre)?.also(::refreshGenreList) logD("Updated genre to ${currentGenre.value}") } } @@ -215,7 +203,7 @@ class DetailViewModel(application: Application) : return } logD("Opening Album [uid: $uid]") - _currentAlbum.value = requireMusic(uid)?.also { refreshAlbumList(it, false) } + _currentAlbum.value = requireMusic(uid)?.also(::refreshAlbumList) } /** @@ -229,7 +217,7 @@ class DetailViewModel(application: Application) : return } logD("Opening Artist [uid: $uid]") - _currentArtist.value = requireMusic(uid)?.also { refreshArtistList(it, false) } + _currentArtist.value = requireMusic(uid)?.also(::refreshArtistList) } /** @@ -243,29 +231,7 @@ class DetailViewModel(application: Application) : return } logD("Opening Genre [uid: $uid]") - _currentGenre.value = requireMusic(uid)?.also { refreshGenreList(it, false) } - } - - /** - * Signal that the specified [DetailListInstructions] in [albumListInstructions] were performed. - */ - fun finishAlbumListInstructions() { - albumListInstructions = null - } - - /** - * Signal that the specified [DetailListInstructions] in [artistListInstructions] were - * performed. - */ - fun finishArtistListInstructions() { - artistListInstructions = null - } - - /** - * Signal that the specified [DetailListInstructions] in [genreListInstructions] were performed. - */ - fun finishGenreListInstructions() { - genreListInstructions = null + _currentGenre.value = requireMusic(uid)?.also(::refreshGenreList) } private fun requireMusic(uid: Music.UID) = musicStore.library?.find(uid) @@ -348,11 +314,11 @@ class DetailViewModel(application: Application) : return SongProperties(bitrate, sampleRate, resolvedMimeType) } - private fun refreshAlbumList(album: Album, replace: Boolean): Int { + private fun refreshAlbumList(album: Album) { logD("Refreshing album data") val data = mutableListOf(album) data.add(SortHeader(R.string.lbl_songs)) - val songsStartIndex = data.size + // To create a good user experience regarding disc numbers, we group the album's // songs up by disc and then delimit the groups by a disc header. val songs = albumSongSort.songs(album.songs) @@ -368,17 +334,11 @@ class DetailViewModel(application: Application) : // Album only has one disc, don't add any redundant headers data.addAll(songs) } - albumListInstructions = - if (replace) { - DetailListInstructions.ReplaceRest(songsStartIndex) - } else { - DetailListInstructions.Diff - } + _albumList.value = data - return songsStartIndex } - private fun refreshArtistList(artist: Artist, replace: Boolean) { + private fun refreshArtistList(artist: Artist) { logD("Refreshing artist data") val data = mutableListOf(artist) val albums = Sort(Sort.Mode.ByDate, false).albums(artist.albums) @@ -411,40 +371,24 @@ class DetailViewModel(application: Application) : data.addAll(entry.value) } - var songsStartIndex: Int? = null // Artists may not be linked to any songs, only include a header entry if we have any. if (artist.songs.isNotEmpty()) { logD("Songs present in this artist, adding header") data.add(SortHeader(R.string.lbl_songs)) - songsStartIndex = data.size data.addAll(artistSongSort.songs(artist.songs)) } - artistListInstructions = - if (replace) { - DetailListInstructions.ReplaceRest( - requireNotNull(songsStartIndex) { "Cannot replace empty artist song list" }) - } else { - DetailListInstructions.Diff - } _artistList.value = data.toList() } - private fun refreshGenreList(genre: Genre, replace: Boolean) { + private fun refreshGenreList(genre: Genre) { logD("Refreshing genre data") val data = mutableListOf(genre) // Genre is guaranteed to always have artists and songs. data.add(Header(R.string.lbl_artists)) data.addAll(genre.artists) data.add(SortHeader(R.string.lbl_songs)) - val songsStartIndex = data.size data.addAll(genreSongSort.songs(genre.songs)) - genreListInstructions = - if (replace) { - DetailListInstructions.ReplaceRest(songsStartIndex) - } else { - DetailListInstructions.Diff - } _genreList.value = data } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt index b69598d2b..5d6ac4482 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt @@ -31,6 +31,7 @@ import org.oxycblt.auxio.detail.recycler.DetailAdapter import org.oxycblt.auxio.detail.recycler.GenreDetailAdapter import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.ListFragment +import org.oxycblt.auxio.list.adapter.BasicListInstructions import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Artist import org.oxycblt.auxio.music.Genre @@ -218,9 +219,7 @@ class GenreDetailFragment : } private fun updateList(items: List) { - detailAdapter.submitList( - items, detailModel.genreListInstructions ?: DetailListInstructions.Diff) - detailModel.finishGenreListInstructions() + detailAdapter.submitList(items, BasicListInstructions.DIFF) } private fun updateSelection(selected: List) { diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/DetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/DetailAdapter.kt index 70541a004..2ce12a786 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/DetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/DetailAdapter.kt @@ -20,23 +20,15 @@ package org.oxycblt.auxio.detail.recycler import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.TooltipCompat -import androidx.recyclerview.widget.AdapterListUpdateCallback -import androidx.recyclerview.widget.AsyncDifferConfig -import androidx.recyclerview.widget.AsyncListDiffer import androidx.recyclerview.widget.DiffUtil -import androidx.recyclerview.widget.ListUpdateCallback import androidx.recyclerview.widget.RecyclerView import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.databinding.ItemSortHeaderBinding -import org.oxycblt.auxio.detail.DetailListInstructions import org.oxycblt.auxio.detail.SortHeader import org.oxycblt.auxio.list.Header import org.oxycblt.auxio.list.Item import org.oxycblt.auxio.list.SelectableListListener -import org.oxycblt.auxio.list.adapter.ListDiffer -import org.oxycblt.auxio.list.adapter.SelectionIndicatorAdapter -import org.oxycblt.auxio.list.adapter.SimpleDiffCallback -import org.oxycblt.auxio.list.adapter.overwriteList +import org.oxycblt.auxio.list.adapter.* import org.oxycblt.auxio.list.recycler.* import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.util.context @@ -53,8 +45,8 @@ abstract class DetailAdapter( private val listener: Listener<*>, diffCallback: DiffUtil.ItemCallback ) : - SelectionIndicatorAdapter( - DetailListDiffer.Factory(diffCallback)), + SelectionIndicatorAdapter( + ListDiffer.Async(diffCallback)), AuxioRecyclerView.SpanSizeLookup { override fun getItemViewType(position: Int) = @@ -124,39 +116,6 @@ abstract class DetailAdapter( } } -private class DetailListDiffer( - private val updateCallback: ListUpdateCallback, - diffCallback: DiffUtil.ItemCallback -) : ListDiffer { - private val inner = - AsyncListDiffer(updateCallback, AsyncDifferConfig.Builder(diffCallback).build()) - - override val currentList: List - get() = inner.currentList - - override fun submitList( - newList: List, - instructions: DetailListInstructions, - onDone: () -> Unit - ) { - when (instructions) { - is DetailListInstructions.Diff -> inner.submitList(newList, onDone) - is DetailListInstructions.ReplaceRest -> { - val amount = newList.size - instructions.at - updateCallback.onRemoved(instructions.at, amount) - inner.overwriteList(newList) - updateCallback.onInserted(instructions.at, amount) - } - } - } - - class Factory(private val diffCallback: DiffUtil.ItemCallback) : - ListDiffer.Factory() { - override fun new(adapter: RecyclerView.Adapter<*>) = - DetailListDiffer(AdapterListUpdateCallback(adapter), diffCallback) - } -} - /** * A [RecyclerView.ViewHolder] that displays a [SortHeader], a variation on [Header] that adds a * button opening a menu for sorting. Use [from] to create an instance. diff --git a/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt b/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt index fa299eaad..a70fdad16 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/HomeViewModel.kt @@ -45,17 +45,11 @@ class HomeViewModel(application: Application) : /** A list of [Song]s, sorted by the preferred [Sort], to be shown in the home view. */ val songsList: StateFlow> get() = _songsList - /** Specifies how to update [songsList] when it changes. */ - var songsListInstructions: BasicListInstructions? = null - private set private val _albumsLists = MutableStateFlow(listOf()) /** A list of [Album]s, sorted by the preferred [Sort], to be shown in the home view. */ val albumsList: StateFlow> get() = _albumsLists - /** Specifies how to update [albumsList] when it changes. */ - var albumsListInstructions: BasicListInstructions? = null - private set private val _artistsList = MutableStateFlow(listOf()) /** @@ -65,17 +59,11 @@ class HomeViewModel(application: Application) : */ val artistsList: MutableStateFlow> get() = _artistsList - /** Specifies how to update [artistsList] when it changes. */ - var artistsListInstructions: BasicListInstructions? = null - private set private val _genresList = MutableStateFlow(listOf()) /** A list of [Genre]s, sorted by the preferred [Sort], to be shown in the home view. */ val genresList: StateFlow> get() = _genresList - /** Specifies how to update [genresList] when it changes. */ - var genresListInstructions: BasicListInstructions? = null - private set /** The [MusicMode] to use when playing a [Song] from the UI. */ val playbackMode: MusicMode @@ -120,11 +108,8 @@ class HomeViewModel(application: Application) : logD("Library changed, refreshing library") // Get the each list of items in the library to use as our list data. // Applying the preferred sorting to them. - songsListInstructions = BasicListInstructions.DIFF _songsList.value = musicSettings.songSort.songs(library.songs) - albumsListInstructions = BasicListInstructions.DIFF _albumsLists.value = musicSettings.albumSort.albums(library.albums) - artistsListInstructions = BasicListInstructions.DIFF _artistsList.value = musicSettings.artistSort.artists( if (homeSettings.shouldHideCollaborators) { @@ -133,7 +118,6 @@ class HomeViewModel(application: Application) : } else { library.artists }) - genresListInstructions = BasicListInstructions.DIFF _genresList.value = musicSettings.genreSort.genres(library.genres) } } @@ -173,56 +157,23 @@ class HomeViewModel(application: Application) : when (_currentTabMode.value) { MusicMode.SONGS -> { musicSettings.songSort = sort - songsListInstructions = BasicListInstructions.REPLACE _songsList.value = sort.songs(_songsList.value) } MusicMode.ALBUMS -> { musicSettings.albumSort = sort - albumsListInstructions = BasicListInstructions.REPLACE _albumsLists.value = sort.albums(_albumsLists.value) } MusicMode.ARTISTS -> { musicSettings.artistSort = sort - artistsListInstructions = BasicListInstructions.REPLACE _artistsList.value = sort.artists(_artistsList.value) } MusicMode.GENRES -> { musicSettings.genreSort = sort - genresListInstructions = BasicListInstructions.REPLACE _genresList.value = sort.genres(_genresList.value) } } } - /** - * Signal that the specified [BasicListInstructions] in [songsListInstructions] were performed. - */ - fun finishSongsListInstructions() { - songsListInstructions = null - } - - /** - * Signal that the specified [BasicListInstructions] in [albumsListInstructions] were performed. - */ - fun finishAlbumsListInstructions() { - albumsListInstructions = null - } - - /** - * Signal that the specified [BasicListInstructions] in [artistsListInstructions] were - * performed. - */ - fun finishArtistsListInstructions() { - artistsListInstructions = null - } - - /** - * Signal that the specified [BasicListInstructions] in [genresListInstructions] were performed. - */ - fun finishGenresListInstructions() { - genresListInstructions = null - } - /** * Update [currentTabMode] to reflect a new ViewPager2 position * @param pagerPos The new position of the ViewPager2 instance. diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt index ff0e1fc06..e56a9c39e 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/AlbumListFragment.kt @@ -132,9 +132,7 @@ class AlbumListFragment : } private fun updateList(albums: List) { - albumAdapter.submitList( - albums, homeModel.albumsListInstructions ?: BasicListInstructions.DIFF) - homeModel.finishAlbumsListInstructions() + albumAdapter.submitList(albums, BasicListInstructions.REPLACE) } private fun updateSelection(selection: List) { @@ -152,7 +150,7 @@ class AlbumListFragment : */ private class AlbumAdapter(private val listener: SelectableListListener) : SelectionIndicatorAdapter( - ListDiffer.Async(AlbumViewHolder.DIFF_CALLBACK)) { + ListDiffer.Blocking(AlbumViewHolder.DIFF_CALLBACK)) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = AlbumViewHolder.from(parent) diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt index 8a9665b5b..a0a4aed08 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/ArtistListFragment.kt @@ -110,9 +110,7 @@ class ArtistListFragment : } private fun updateList(artists: List) { - artistAdapter.submitList( - artists, homeModel.artistsListInstructions ?: BasicListInstructions.DIFF) - homeModel.finishArtistsListInstructions() + artistAdapter.submitList(artists, BasicListInstructions.REPLACE) } private fun updateSelection(selection: List) { @@ -130,7 +128,7 @@ class ArtistListFragment : */ private class ArtistAdapter(private val listener: SelectableListListener) : SelectionIndicatorAdapter( - ListDiffer.Async(ArtistViewHolder.DIFF_CALLBACK)) { + ListDiffer.Blocking(ArtistViewHolder.DIFF_CALLBACK)) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ArtistViewHolder.from(parent) diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt index e69641f8b..83b49723d 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/GenreListFragment.kt @@ -109,9 +109,7 @@ class GenreListFragment : } private fun updateList(artists: List) { - genreAdapter.submitList( - artists, homeModel.genresListInstructions ?: BasicListInstructions.DIFF) - homeModel.finishGenresListInstructions() + genreAdapter.submitList(artists, BasicListInstructions.REPLACE) } private fun updateSelection(selection: List) { @@ -129,7 +127,7 @@ class GenreListFragment : */ private class GenreAdapter(private val listener: SelectableListListener) : SelectionIndicatorAdapter( - ListDiffer.Async(GenreViewHolder.DIFF_CALLBACK)) { + ListDiffer.Blocking(GenreViewHolder.DIFF_CALLBACK)) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = GenreViewHolder.from(parent) diff --git a/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt b/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt index b09bdf907..eba715958 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/list/SongListFragment.kt @@ -139,8 +139,7 @@ class SongListFragment : } private fun updateList(songs: List) { - songAdapter.submitList(songs, homeModel.songsListInstructions ?: BasicListInstructions.DIFF) - homeModel.finishSongsListInstructions() + songAdapter.submitList(songs, BasicListInstructions.REPLACE) } private fun updateSelection(selection: List) { @@ -162,7 +161,7 @@ class SongListFragment : */ private class SongAdapter(private val listener: SelectableListListener) : SelectionIndicatorAdapter( - ListDiffer.Async(SongViewHolder.DIFF_CALLBACK)) { + ListDiffer.Blocking(SongViewHolder.DIFF_CALLBACK)) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = SongViewHolder.from(parent) diff --git a/app/src/main/java/org/oxycblt/auxio/list/adapter/AdapterUtil.kt b/app/src/main/java/org/oxycblt/auxio/list/adapter/AdapterUtil.kt deleted file mode 100644 index 4e40e6191..000000000 --- a/app/src/main/java/org/oxycblt/auxio/list/adapter/AdapterUtil.kt +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2023 Auxio Project - * - * 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 . - */ - -package org.oxycblt.auxio.list.adapter - -import androidx.recyclerview.widget.AsyncListDiffer -import java.lang.reflect.Field -import org.oxycblt.auxio.util.lazyReflectedField -import org.oxycblt.auxio.util.requireIs - -val ASD_MAX_GENERATION_FIELD: Field by - lazyReflectedField(AsyncListDiffer::class, "mMaxScheduledGeneration") -val ASD_MUTABLE_LIST_FIELD: Field by lazyReflectedField(AsyncListDiffer::class, "mList") -val ASD_READ_ONLY_LIST_FIELD: Field by lazyReflectedField(AsyncListDiffer::class, "mReadOnlyList") - -/** - * Force-update an [AsyncListDiffer] with new data. It's hard to state how incredibly dangerous this - * is, so only use it when absolutely necessary. - * @param newList The new list to write to the [AsyncListDiffer]. - */ -fun AsyncListDiffer.overwriteList(newList: List) { - // Should update the generation field to prevent any previous jobs from conflicting, then - // updates the mutable list to it's nullable value, and then updates the read-only list to - // it's non-nullable value. - ASD_MAX_GENERATION_FIELD.set(this, requireIs(ASD_MAX_GENERATION_FIELD.get(this)) + 1) - ASD_MUTABLE_LIST_FIELD.set(this, newList.ifEmpty { null }) - ASD_READ_ONLY_LIST_FIELD.set(this, newList) -} diff --git a/app/src/main/java/org/oxycblt/auxio/list/adapter/ListDiffer.kt b/app/src/main/java/org/oxycblt/auxio/list/adapter/ListDiffer.kt index f02800fa7..5e5adcaba 100644 --- a/app/src/main/java/org/oxycblt/auxio/list/adapter/ListDiffer.kt +++ b/app/src/main/java/org/oxycblt/auxio/list/adapter/ListDiffer.kt @@ -112,7 +112,7 @@ private abstract class BasicListDiffer : ListDiffer } private class RealAsyncListDiffer( - private val updateCallback: ListUpdateCallback, + updateCallback: ListUpdateCallback, diffCallback: DiffUtil.ItemCallback ) : BasicListDiffer() { private val inner = @@ -126,13 +126,9 @@ private class RealAsyncListDiffer( } override fun replaceList(newList: List, onDone: () -> Unit) { - if (inner.currentList != newList) { - val oldListSize = inner.currentList.size - updateCallback.onRemoved(0, oldListSize) - inner.overwriteList(newList) - updateCallback.onInserted(0, newList.size) + inner.submitList(null) { + inner.submitList(newList, onDone) } - onDone() } }