all: update logging
Improve logging use across the app.
This commit is contained in:
parent
2f85d694d1
commit
3d8d2e0975
31 changed files with 142 additions and 95 deletions
|
@ -46,7 +46,7 @@ import org.oxycblt.auxio.util.canScroll
|
||||||
import org.oxycblt.auxio.util.collectWith
|
import org.oxycblt.auxio.util.collectWith
|
||||||
import org.oxycblt.auxio.util.launch
|
import org.oxycblt.auxio.util.launch
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ class AlbumDetailFragment :
|
||||||
override fun onOpenMenu(item: Item, anchor: View) {
|
override fun onOpenMenu(item: Item, anchor: View) {
|
||||||
when (item) {
|
when (item) {
|
||||||
is Song -> musicMenu(anchor, R.menu.menu_album_song_actions, item)
|
is Song -> musicMenu(anchor, R.menu.menu_album_song_actions, item)
|
||||||
else -> logW("Unexpected datatype when opening menu: ${item::class.java}")
|
else -> logEOrThrow("Unexpected datatype when opening menu: ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +204,7 @@ class AlbumDetailFragment :
|
||||||
.navigate(AlbumDetailFragmentDirections.actionShowArtist(item.id))
|
.navigate(AlbumDetailFragmentDirections.actionShowArtist(item.id))
|
||||||
}
|
}
|
||||||
null -> {}
|
null -> {}
|
||||||
else -> logW("Unsupported navigation item ${item::class.java}")
|
else -> logEOrThrow("Unexpected navigation item ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ import org.oxycblt.auxio.util.applySpans
|
||||||
import org.oxycblt.auxio.util.collectWith
|
import org.oxycblt.auxio.util.collectWith
|
||||||
import org.oxycblt.auxio.util.launch
|
import org.oxycblt.auxio.util.launch
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ class ArtistDetailFragment :
|
||||||
when (item) {
|
when (item) {
|
||||||
is Song -> musicMenu(anchor, R.menu.menu_artist_song_actions, item)
|
is Song -> musicMenu(anchor, R.menu.menu_artist_song_actions, item)
|
||||||
is Album -> musicMenu(anchor, R.menu.menu_artist_album_actions, item)
|
is Album -> musicMenu(anchor, R.menu.menu_artist_album_actions, item)
|
||||||
else -> logW("Unexpected datatype when opening menu: ${item::class.java}")
|
else -> logEOrThrow("Unexpected datatype when opening menu: ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +179,7 @@ class ArtistDetailFragment :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
null -> {}
|
null -> {}
|
||||||
else -> logW("Unsupported navigation item ${item::class.java}")
|
else -> logEOrThrow("Unexpected navigation item ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,17 +156,19 @@ class DetailViewModel(application: Application) :
|
||||||
|
|
||||||
private fun generateDetailSong(song: Song) {
|
private fun generateDetailSong(song: Song) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
_currentSong.value =
|
_currentSong.value = withContext(Dispatchers.IO) { generateDetailSongImpl(song) }
|
||||||
withContext(Dispatchers.IO) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateDetailSongImpl(song: Song): DetailSong {
|
||||||
val extractor = MediaExtractor()
|
val extractor = MediaExtractor()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
|
||||||
extractor.setDataSource(application, song.uri, emptyMap())
|
extractor.setDataSource(application, song.uri, emptyMap())
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logW("Unable to extract song attributes.")
|
logW("Unable to extract song attributes.")
|
||||||
logW(e.stackTraceToString())
|
logW(e.stackTraceToString())
|
||||||
return@withContext DetailSong(song, null, null, song.mimeType)
|
return DetailSong(song, null, null, song.mimeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
val format = extractor.getTrackFormat(0)
|
val format = extractor.getTrackFormat(0)
|
||||||
|
@ -202,9 +204,7 @@ class DetailViewModel(application: Application) :
|
||||||
MimeType(song.mimeType.fromExtension, formatMimeType)
|
MimeType(song.mimeType.fromExtension, formatMimeType)
|
||||||
}
|
}
|
||||||
|
|
||||||
DetailSong(song, bitrate, sampleRate, resolvedMimeType)
|
return DetailSong(song, bitrate, sampleRate, resolvedMimeType)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun refreshAlbumData(album: Album) {
|
private fun refreshAlbumData(album: Album) {
|
||||||
|
@ -255,6 +255,7 @@ class DetailViewModel(application: Application) :
|
||||||
if (library != null) {
|
if (library != null) {
|
||||||
val song = currentSong.value
|
val song = currentSong.value
|
||||||
if (song != null) {
|
if (song != null) {
|
||||||
|
logD("Song changed, refreshing data")
|
||||||
val newSong = library.sanitize(song.song)
|
val newSong = library.sanitize(song.song)
|
||||||
if (newSong != null) {
|
if (newSong != null) {
|
||||||
generateDetailSong(newSong)
|
generateDetailSong(newSong)
|
||||||
|
@ -263,6 +264,7 @@ class DetailViewModel(application: Application) :
|
||||||
|
|
||||||
val album = currentAlbum.value
|
val album = currentAlbum.value
|
||||||
if (album != null) {
|
if (album != null) {
|
||||||
|
logD("Album changed, refreshing data")
|
||||||
val newAlbum = library.sanitize(album).also { _currentAlbum.value = it }
|
val newAlbum = library.sanitize(album).also { _currentAlbum.value = it }
|
||||||
if (newAlbum != null) {
|
if (newAlbum != null) {
|
||||||
refreshAlbumData(newAlbum)
|
refreshAlbumData(newAlbum)
|
||||||
|
@ -271,6 +273,7 @@ class DetailViewModel(application: Application) :
|
||||||
|
|
||||||
val artist = currentArtist.value
|
val artist = currentArtist.value
|
||||||
if (artist != null) {
|
if (artist != null) {
|
||||||
|
logD("Artist changed, refreshing data")
|
||||||
val newArtist = library.sanitize(artist).also { _currentArtist.value = it }
|
val newArtist = library.sanitize(artist).also { _currentArtist.value = it }
|
||||||
if (newArtist != null) {
|
if (newArtist != null) {
|
||||||
refreshArtistData(newArtist)
|
refreshArtistData(newArtist)
|
||||||
|
|
|
@ -44,7 +44,7 @@ import org.oxycblt.auxio.util.applySpans
|
||||||
import org.oxycblt.auxio.util.collectWith
|
import org.oxycblt.auxio.util.collectWith
|
||||||
import org.oxycblt.auxio.util.launch
|
import org.oxycblt.auxio.util.launch
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ class GenreDetailFragment :
|
||||||
override fun onOpenMenu(item: Item, anchor: View) {
|
override fun onOpenMenu(item: Item, anchor: View) {
|
||||||
when (item) {
|
when (item) {
|
||||||
is Song -> musicMenu(anchor, R.menu.menu_song_actions, item)
|
is Song -> musicMenu(anchor, R.menu.menu_song_actions, item)
|
||||||
else -> logW("Unexpected datatype when opening menu: ${item::class.java}")
|
else -> logEOrThrow("Unexpected datatype when opening menu: ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,6 @@ import org.oxycblt.auxio.util.launch
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logE
|
import org.oxycblt.auxio.util.logE
|
||||||
import org.oxycblt.auxio.util.logTraceOrThrow
|
import org.oxycblt.auxio.util.logTraceOrThrow
|
||||||
import org.oxycblt.auxio.util.logW
|
|
||||||
import org.oxycblt.auxio.util.textSafe
|
import org.oxycblt.auxio.util.textSafe
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
|
@ -282,7 +281,7 @@ class HomeFragment : ViewBindingFragment<FragmentHomeBinding>(), Toolbar.OnMenuI
|
||||||
is Indexer.State.Complete -> handleIndexerResponse(binding, state.response)
|
is Indexer.State.Complete -> handleIndexerResponse(binding, state.response)
|
||||||
is Indexer.State.Indexing -> handleIndexingState(binding, state.indexing)
|
is Indexer.State.Indexing -> handleIndexingState(binding, state.indexing)
|
||||||
null -> {
|
null -> {
|
||||||
logW("Indexer is in indeterminate state, doing nothing")
|
logD("Indexer is in indeterminate state, doing nothing")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ class HomeViewModel : ViewModel(), SettingsManager.Callback, MusicStore.Callback
|
||||||
* begins to fast scroll.
|
* begins to fast scroll.
|
||||||
*/
|
*/
|
||||||
fun updateFastScrolling(scrolling: Boolean) {
|
fun updateFastScrolling(scrolling: Boolean) {
|
||||||
|
logD("Updating fast scrolling state: $scrolling")
|
||||||
_isFastScrolling.value = scrolling
|
_isFastScrolling.value = scrolling
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ import org.oxycblt.auxio.ui.Sort
|
||||||
import org.oxycblt.auxio.ui.SyncBackingData
|
import org.oxycblt.auxio.ui.SyncBackingData
|
||||||
import org.oxycblt.auxio.util.formatDuration
|
import org.oxycblt.auxio.util.formatDuration
|
||||||
import org.oxycblt.auxio.util.launch
|
import org.oxycblt.auxio.util.launch
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +86,7 @@ class AlbumListFragment : HomeListFragment<Album>() {
|
||||||
override fun onOpenMenu(item: Item, anchor: View) {
|
override fun onOpenMenu(item: Item, anchor: View) {
|
||||||
when (item) {
|
when (item) {
|
||||||
is Album -> musicMenu(anchor, R.menu.menu_album_actions, item)
|
is Album -> musicMenu(anchor, R.menu.menu_album_actions, item)
|
||||||
else -> logW("Unexpected datatype when opening menu: ${item::class.java}")
|
else -> logEOrThrow("Unexpected datatype when opening menu: ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ import org.oxycblt.auxio.ui.Sort
|
||||||
import org.oxycblt.auxio.ui.SyncBackingData
|
import org.oxycblt.auxio.ui.SyncBackingData
|
||||||
import org.oxycblt.auxio.util.formatDuration
|
import org.oxycblt.auxio.util.formatDuration
|
||||||
import org.oxycblt.auxio.util.launch
|
import org.oxycblt.auxio.util.launch
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +80,7 @@ class ArtistListFragment : HomeListFragment<Artist>() {
|
||||||
override fun onOpenMenu(item: Item, anchor: View) {
|
override fun onOpenMenu(item: Item, anchor: View) {
|
||||||
when (item) {
|
when (item) {
|
||||||
is Artist -> musicMenu(anchor, R.menu.menu_genre_artist_actions, item)
|
is Artist -> musicMenu(anchor, R.menu.menu_genre_artist_actions, item)
|
||||||
else -> logW("Unexpected datatype when opening menu: ${item::class.java}")
|
else -> logEOrThrow("Unexpected datatype when opening menu: ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ import org.oxycblt.auxio.ui.Sort
|
||||||
import org.oxycblt.auxio.ui.SyncBackingData
|
import org.oxycblt.auxio.ui.SyncBackingData
|
||||||
import org.oxycblt.auxio.util.formatDuration
|
import org.oxycblt.auxio.util.formatDuration
|
||||||
import org.oxycblt.auxio.util.launch
|
import org.oxycblt.auxio.util.launch
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +80,7 @@ class GenreListFragment : HomeListFragment<Genre>() {
|
||||||
override fun onOpenMenu(item: Item, anchor: View) {
|
override fun onOpenMenu(item: Item, anchor: View) {
|
||||||
when (item) {
|
when (item) {
|
||||||
is Genre -> musicMenu(anchor, R.menu.menu_genre_artist_actions, item)
|
is Genre -> musicMenu(anchor, R.menu.menu_genre_artist_actions, item)
|
||||||
else -> logW("Unexpected datatype when opening menu: ${item::class.java}")
|
else -> logEOrThrow("Unexpected datatype when opening menu: ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.oxycblt.auxio.ui.Sort
|
||||||
import org.oxycblt.auxio.ui.SyncBackingData
|
import org.oxycblt.auxio.ui.SyncBackingData
|
||||||
import org.oxycblt.auxio.util.formatDuration
|
import org.oxycblt.auxio.util.formatDuration
|
||||||
import org.oxycblt.auxio.util.launch
|
import org.oxycblt.auxio.util.launch
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,7 +87,7 @@ class SongListFragment : HomeListFragment<Song>() {
|
||||||
override fun onOpenMenu(item: Item, anchor: View) {
|
override fun onOpenMenu(item: Item, anchor: View) {
|
||||||
when (item) {
|
when (item) {
|
||||||
is Song -> musicMenu(anchor, R.menu.menu_song_actions, item)
|
is Song -> musicMenu(anchor, R.menu.menu_song_actions, item)
|
||||||
else -> logW("Unexpected datatype when opening menu: ${item::class.java}")
|
else -> logEOrThrow("Unexpected datatype when opening menu: ${item::class.java}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.settings.SettingsManager
|
import org.oxycblt.auxio.settings.SettingsManager
|
||||||
import org.oxycblt.auxio.util.getColorStateListSafe
|
import org.oxycblt.auxio.util.getColorStateListSafe
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Effectively a super-charged [StyledImageView].
|
* Effectively a super-charged [StyledImageView].
|
||||||
|
|
|
@ -118,6 +118,7 @@ class Indexer {
|
||||||
* the indexing process to re-index music.
|
* the indexing process to re-index music.
|
||||||
*/
|
*/
|
||||||
fun requestReindex() {
|
fun requestReindex() {
|
||||||
|
logD("Requesting reindex")
|
||||||
for (callback in callbacks) {
|
for (callback in callbacks) {
|
||||||
callback.onRequestReindex()
|
callback.onRequestReindex()
|
||||||
}
|
}
|
||||||
|
@ -130,6 +131,7 @@ class Indexer {
|
||||||
* corrupt the current state.
|
* corrupt the current state.
|
||||||
*/
|
*/
|
||||||
fun cancelLast() {
|
fun cancelLast() {
|
||||||
|
logD("Cancelling last job")
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
currentGeneration++
|
currentGeneration++
|
||||||
emitIndexing(null, currentGeneration)
|
emitIndexing(null, currentGeneration)
|
||||||
|
|
|
@ -90,6 +90,7 @@ class IndexerService : Service(), Indexer.Callback {
|
||||||
is Indexer.State.Complete -> {
|
is Indexer.State.Complete -> {
|
||||||
if (state.response is Indexer.Response.Ok &&
|
if (state.response is Indexer.Response.Ok &&
|
||||||
state.response.library != musicStore.library) {
|
state.response.library != musicStore.library) {
|
||||||
|
logD("Applying new library")
|
||||||
// Load was completed successfully, so apply the new library if we
|
// Load was completed successfully, so apply the new library if we
|
||||||
// have not already.
|
// have not already.
|
||||||
musicStore.library = state.response.library
|
musicStore.library = state.response.library
|
||||||
|
@ -174,6 +175,7 @@ private class IndexerNotification(private val context: Context) :
|
||||||
fun updateIndexingState(indexing: Indexer.Indexing): Boolean {
|
fun updateIndexingState(indexing: Indexer.Indexing): Boolean {
|
||||||
when (indexing) {
|
when (indexing) {
|
||||||
is Indexer.Indexing.Indeterminate -> {
|
is Indexer.Indexing.Indeterminate -> {
|
||||||
|
logD("Updating state to $indexing")
|
||||||
setContentText(context.getString(R.string.lbl_indexing))
|
setContentText(context.getString(R.string.lbl_indexing))
|
||||||
setProgress(0, 0, true)
|
setProgress(0, 0, true)
|
||||||
return true
|
return true
|
||||||
|
@ -181,6 +183,7 @@ private class IndexerNotification(private val context: Context) :
|
||||||
is Indexer.Indexing.Songs -> {
|
is Indexer.Indexing.Songs -> {
|
||||||
// Only update the notification every 50 songs to prevent excessive updates.
|
// Only update the notification every 50 songs to prevent excessive updates.
|
||||||
if (indexing.current % 50 == 0) {
|
if (indexing.current % 50 == 0) {
|
||||||
|
logD("Updating state to $indexing")
|
||||||
setContentText(
|
setContentText(
|
||||||
context.getString(R.string.fmt_indexing, indexing.current, indexing.total))
|
context.getString(R.string.fmt_indexing, indexing.current, indexing.total))
|
||||||
setProgress(indexing.total, indexing.current, false)
|
setProgress(indexing.total, indexing.current, false)
|
||||||
|
|
|
@ -23,6 +23,7 @@ import android.database.Cursor
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import androidx.core.text.isDigitsOnly
|
import androidx.core.text.isDigitsOnly
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
/** Shortcut for making a [ContentResolver] query with less superfluous arguments. */
|
/** Shortcut for making a [ContentResolver] query with less superfluous arguments. */
|
||||||
fun ContentResolver.queryCursor(
|
fun ContentResolver.queryCursor(
|
||||||
|
|
|
@ -113,9 +113,11 @@ val StorageVolume.directoryCompat: String?
|
||||||
@SuppressLint("NewApi")
|
@SuppressLint("NewApi")
|
||||||
fun StorageVolume.getDescriptionCompat(context: Context): String = getDescription(context)
|
fun StorageVolume.getDescriptionCompat(context: Context): String = getDescription(context)
|
||||||
|
|
||||||
|
/** If this volume is the primary volume. May still be removable storage. */
|
||||||
val StorageVolume.isPrimaryCompat: Boolean
|
val StorageVolume.isPrimaryCompat: Boolean
|
||||||
@SuppressLint("NewApi") get() = isPrimary
|
@SuppressLint("NewApi") get() = isPrimary
|
||||||
|
|
||||||
|
/** If this volume is emulated. */
|
||||||
val StorageVolume.isEmulatedCompat: Boolean
|
val StorageVolume.isEmulatedCompat: Boolean
|
||||||
@SuppressLint("NewApi") get() = isEmulated
|
@SuppressLint("NewApi") get() = isEmulated
|
||||||
|
|
||||||
|
|
|
@ -167,8 +167,6 @@ class MusicDirsDialog :
|
||||||
DocumentsContract.buildDocumentUriUsingTree(
|
DocumentsContract.buildDocumentUriUsingTree(
|
||||||
uri, DocumentsContract.getTreeDocumentId(uri))
|
uri, DocumentsContract.getTreeDocumentId(uri))
|
||||||
|
|
||||||
logD(uri)
|
|
||||||
|
|
||||||
// Turn it into a semi-usable path
|
// Turn it into a semi-usable path
|
||||||
val treeUri = DocumentsContract.getTreeDocumentId(docUri)
|
val treeUri = DocumentsContract.getTreeDocumentId(docUri)
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ import kotlin.math.max
|
||||||
import org.oxycblt.auxio.databinding.ViewSeekBarBinding
|
import org.oxycblt.auxio.databinding.ViewSeekBarBinding
|
||||||
import org.oxycblt.auxio.util.formatDuration
|
import org.oxycblt.auxio.util.formatDuration
|
||||||
import org.oxycblt.auxio.util.inflater
|
import org.oxycblt.auxio.util.inflater
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.textSafe
|
import org.oxycblt.auxio.util.textSafe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,6 +98,7 @@ constructor(
|
||||||
// Sanity check 2: If the current value exceeds the new duration value, clamp it
|
// Sanity check 2: If the current value exceeds the new duration value, clamp it
|
||||||
// down so that we don't crash and instead have an annoying visual flicker.
|
// down so that we don't crash and instead have an annoying visual flicker.
|
||||||
if (positionSecs > to) {
|
if (positionSecs > to) {
|
||||||
|
logD("Clamping invalid position [current: $positionSecs new max: $to]")
|
||||||
binding.seekBarSlider.value = to.toFloat()
|
binding.seekBarSlider.value = to.toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,12 +107,14 @@ constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartTrackingTouch(slider: Slider) {
|
override fun onStartTrackingTouch(slider: Slider) {
|
||||||
|
logD("Starting seek mode")
|
||||||
// User has begun seeking, place the SeekBar into a "Suspended" mode in which no
|
// User has begun seeking, place the SeekBar into a "Suspended" mode in which no
|
||||||
// position updates are sent and is indicated by the position value turning accented.
|
// position updates are sent and is indicated by the position value turning accented.
|
||||||
isActivated = true
|
isActivated = true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStopTrackingTouch(slider: Slider) {
|
override fun onStopTrackingTouch(slider: Slider) {
|
||||||
|
logD("Confirming seek")
|
||||||
// End of seek event, send off new value to callback.
|
// End of seek event, send off new value to callback.
|
||||||
isActivated = false
|
isActivated = false
|
||||||
callback?.seekTo(slider.value.toLong())
|
callback?.seekTo(slider.value.toLong())
|
||||||
|
|
|
@ -30,7 +30,6 @@ import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||||
import org.oxycblt.auxio.settings.SettingsManager
|
import org.oxycblt.auxio.settings.SettingsManager
|
||||||
import org.oxycblt.auxio.util.clamp
|
import org.oxycblt.auxio.util.clamp
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
import org.oxycblt.auxio.util.logW
|
|
||||||
import org.oxycblt.auxio.util.unlikelyToBeNull
|
import org.oxycblt.auxio.util.unlikelyToBeNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +64,7 @@ class ReplayGainAudioProcessor : BaseAudioProcessor() {
|
||||||
*/
|
*/
|
||||||
fun applyReplayGain(metadata: Metadata?) {
|
fun applyReplayGain(metadata: Metadata?) {
|
||||||
if (settingsManager.replayGainMode == ReplayGainMode.OFF) {
|
if (settingsManager.replayGainMode == ReplayGainMode.OFF) {
|
||||||
logW("ReplayGain not enabled")
|
logD("ReplayGain not enabled")
|
||||||
volume = 1f
|
volume = 1f
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import android.database.sqlite.SQLiteDatabase
|
||||||
import android.database.sqlite.SQLiteOpenHelper
|
import android.database.sqlite.SQLiteOpenHelper
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.storage.StorageManager
|
import android.os.storage.StorageManager
|
||||||
|
import android.util.Log
|
||||||
import androidx.core.content.edit
|
import androidx.core.content.edit
|
||||||
import org.oxycblt.auxio.music.Directory
|
import org.oxycblt.auxio.music.Directory
|
||||||
import org.oxycblt.auxio.music.directoryCompat
|
import org.oxycblt.auxio.music.directoryCompat
|
||||||
|
@ -37,6 +38,8 @@ import org.oxycblt.auxio.util.queryAll
|
||||||
|
|
||||||
fun handleAccentCompat(prefs: SharedPreferences): Accent {
|
fun handleAccentCompat(prefs: SharedPreferences): Accent {
|
||||||
if (prefs.contains(OldKeys.KEY_ACCENT2)) {
|
if (prefs.contains(OldKeys.KEY_ACCENT2)) {
|
||||||
|
Log.d("SettingsCompat", "Migrating ${OldKeys.KEY_ACCENT2}")
|
||||||
|
|
||||||
var accent = prefs.getInt(OldKeys.KEY_ACCENT2, 5)
|
var accent = prefs.getInt(OldKeys.KEY_ACCENT2, 5)
|
||||||
|
|
||||||
// Blue grey was merged with Light Blue in 2.0.0
|
// Blue grey was merged with Light Blue in 2.0.0
|
||||||
|
@ -62,6 +65,8 @@ fun handleAccentCompat(prefs: SharedPreferences): Accent {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prefs.contains(OldKeys.KEY_ACCENT3)) {
|
if (prefs.contains(OldKeys.KEY_ACCENT3)) {
|
||||||
|
Log.d("SettingsCompat", "Migrating ${OldKeys.KEY_ACCENT3}")
|
||||||
|
|
||||||
var accent = prefs.getInt(OldKeys.KEY_ACCENT3, 5)
|
var accent = prefs.getInt(OldKeys.KEY_ACCENT3, 5)
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
// Accents were previously frozen as soon as the OS was updated to android twelve,
|
// Accents were previously frozen as soon as the OS was updated to android twelve,
|
||||||
|
@ -82,7 +87,8 @@ fun handleAccentCompat(prefs: SharedPreferences): Accent {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts paths from the old excluded directory database to a list of modern [Dir] instances.
|
* Converts paths from the old excluded directory database to a list of modern [Directory]
|
||||||
|
* instances.
|
||||||
*
|
*
|
||||||
* Historically, Auxio used an excluded directory database shamelessly ripped from Phonograph. This
|
* Historically, Auxio used an excluded directory database shamelessly ripped from Phonograph. This
|
||||||
* was a dumb idea, as the choice of a full-blown database for a few paths was overkill, version
|
* was a dumb idea, as the choice of a full-blown database for a few paths was overkill, version
|
||||||
|
@ -93,6 +99,7 @@ fun handleAccentCompat(prefs: SharedPreferences): Accent {
|
||||||
* rolled into this conversion.
|
* rolled into this conversion.
|
||||||
*/
|
*/
|
||||||
fun handleExcludedCompat(context: Context, storageManager: StorageManager): List<Directory> {
|
fun handleExcludedCompat(context: Context, storageManager: StorageManager): List<Directory> {
|
||||||
|
Log.d("SettingsCompat", "Migrating old excluded database")
|
||||||
val db = LegacyExcludedDatabase(context)
|
val db = LegacyExcludedDatabase(context)
|
||||||
// /storage/emulated/0 (the old path prefix) should correspond to primary *emulated* storage.
|
// /storage/emulated/0 (the old path prefix) should correspond to primary *emulated* storage.
|
||||||
val primaryVolume =
|
val primaryVolume =
|
||||||
|
|
|
@ -33,7 +33,7 @@ class SettingsFragment : ViewBindingFragment<FragmentSettingsBinding>() {
|
||||||
FragmentSettingsBinding.inflate(inflater)
|
FragmentSettingsBinding.inflate(inflater)
|
||||||
|
|
||||||
override fun onBindingCreated(binding: FragmentSettingsBinding, savedInstanceState: Bundle?) {
|
override fun onBindingCreated(binding: FragmentSettingsBinding, savedInstanceState: Bundle?) {
|
||||||
binding.settingsToolbar.setNavigationOnClickListener { findNavController().navigateUp() }
|
|
||||||
binding.settingsAppbar.liftOnScrollTargetViewId = androidx.preference.R.id.recycler_view
|
binding.settingsAppbar.liftOnScrollTargetViewId = androidx.preference.R.id.recycler_view
|
||||||
|
binding.settingsToolbar.setNavigationOnClickListener { findNavController().navigateUp() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -291,6 +291,8 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) :
|
||||||
panelRange = measuredHeight - barView.measuredHeight
|
panelRange = measuredHeight - barView.measuredHeight
|
||||||
|
|
||||||
if (!isLaidOut) {
|
if (!isLaidOut) {
|
||||||
|
logD("Doing initial panel layout")
|
||||||
|
|
||||||
// This is our first layout, so make sure we know what offset we should work with
|
// This is our first layout, so make sure we know what offset we should work with
|
||||||
// before we measure our content
|
// before we measure our content
|
||||||
panelOffset =
|
panelOffset =
|
||||||
|
@ -383,6 +385,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) :
|
||||||
// not apply any window insets at all, which results in scroll desynchronization on
|
// not apply any window insets at all, which results in scroll desynchronization on
|
||||||
// certain views. This is considered tolerable as the other options are to convert
|
// certain views. This is considered tolerable as the other options are to convert
|
||||||
// the playback fragments to views, which is not nice.
|
// the playback fragments to views, which is not nice.
|
||||||
|
logD("Readjusting window insets")
|
||||||
val bars = insets.getSystemBarInsetsCompat(this)
|
val bars = insets.getSystemBarInsetsCompat(this)
|
||||||
val consumedByPanel = computePanelTopPosition(panelOffset) - measuredHeight
|
val consumedByPanel = computePanelTopPosition(panelOffset) - measuredHeight
|
||||||
val adjustedBottomInset = (consumedByPanel + bars.bottom).coerceAtLeast(0)
|
val adjustedBottomInset = (consumedByPanel + bars.bottom).coerceAtLeast(0)
|
||||||
|
@ -495,9 +498,11 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyle: Int = 0) :
|
||||||
|
|
||||||
private fun setPanelStateInternal(state: PanelState) {
|
private fun setPanelStateInternal(state: PanelState) {
|
||||||
if (panelState == state) {
|
if (panelState == state) {
|
||||||
|
logD("State is already $state, not applying")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logD("new state: $state")
|
||||||
panelState = state
|
panelState = state
|
||||||
|
|
||||||
sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
|
sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED)
|
||||||
|
|
|
@ -51,19 +51,16 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
add(topDivider)
|
add(topDivider)
|
||||||
add(bottomDivider)
|
add(bottomDivider)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
addOnScrollListener(
|
override fun onScrolled(dx: Int, dy: Int) {
|
||||||
object : RecyclerView.OnScrollListener() {
|
super.onScrolled(dx, dy)
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
|
|
||||||
val manager = recyclerView.layoutManager as LinearLayoutManager
|
val manager = layoutManager as LinearLayoutManager
|
||||||
topDivider.isInvisible = manager.findFirstCompletelyVisibleItemPosition() < 1
|
topDivider.isInvisible = manager.findFirstCompletelyVisibleItemPosition() < 1
|
||||||
bottomDivider.isInvisible =
|
bottomDivider.isInvisible =
|
||||||
manager.findLastCompletelyVisibleItemPosition() == (manager.itemCount - 1)
|
manager.findLastCompletelyVisibleItemPosition() == (manager.itemCount - 1)
|
||||||
}
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
|
override fun onMeasure(widthSpec: Int, heightSpec: Int) {
|
||||||
super.onMeasure(widthSpec, heightSpec)
|
super.onMeasure(widthSpec, heightSpec)
|
||||||
|
|
|
@ -29,7 +29,6 @@ import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import org.oxycblt.auxio.util.getSystemBarInsetsCompat
|
import org.oxycblt.auxio.util.getSystemBarInsetsCompat
|
||||||
import org.oxycblt.auxio.util.logW
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An [AppBarLayout] that fixes a bug with the default implementation where the lifted state will
|
* An [AppBarLayout] that fixes a bug with the default implementation where the lifted state will
|
||||||
|
@ -90,7 +89,7 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
|
||||||
if (liftOnScrollTargetViewId != ResourcesCompat.ID_NULL) {
|
if (liftOnScrollTargetViewId != ResourcesCompat.ID_NULL) {
|
||||||
scrollingChild = (parent as ViewGroup).findViewById(liftOnScrollTargetViewId)
|
scrollingChild = (parent as ViewGroup).findViewById(liftOnScrollTargetViewId)
|
||||||
} else {
|
} else {
|
||||||
logW("liftOnScrollTargetViewId was not specified, ignoring scroll events")
|
error("liftOnScrollTargetViewId was not specified")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,8 @@ import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.Genre
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logD
|
||||||
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
import org.oxycblt.auxio.util.showToast
|
import org.oxycblt.auxio.util.showToast
|
||||||
|
|
||||||
abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
|
@ -39,6 +40,8 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
protected val navModel: NavigationViewModel by activityViewModels()
|
protected val navModel: NavigationViewModel by activityViewModels()
|
||||||
|
|
||||||
protected fun musicMenu(anchor: View, @MenuRes menuRes: Int, song: Song) {
|
protected fun musicMenu(anchor: View, @MenuRes menuRes: Int, song: Song) {
|
||||||
|
logD("Launching new song menu: ${song.rawName}")
|
||||||
|
|
||||||
musicMenuImpl(anchor, menuRes) { id ->
|
musicMenuImpl(anchor, menuRes) { id ->
|
||||||
when (id) {
|
when (id) {
|
||||||
R.id.action_play_next -> {
|
R.id.action_play_next -> {
|
||||||
|
@ -59,7 +62,7 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
navModel.mainNavigateTo(MainNavigationAction.SongDetails(song))
|
navModel.mainNavigateTo(MainNavigationAction.SongDetails(song))
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
logW("Unknown menu item selected")
|
logEOrThrow("Unexpected menu item selected")
|
||||||
return@musicMenuImpl false
|
return@musicMenuImpl false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +72,8 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun musicMenu(anchor: View, @MenuRes menuRes: Int, album: Album) {
|
protected fun musicMenu(anchor: View, @MenuRes menuRes: Int, album: Album) {
|
||||||
|
logD("Launching new album menu: ${album.rawName}")
|
||||||
|
|
||||||
musicMenuImpl(anchor, menuRes) { id ->
|
musicMenuImpl(anchor, menuRes) { id ->
|
||||||
when (id) {
|
when (id) {
|
||||||
R.id.action_play -> {
|
R.id.action_play -> {
|
||||||
|
@ -89,7 +94,7 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
navModel.exploreNavigateTo(album.artist)
|
navModel.exploreNavigateTo(album.artist)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
logW("Unknown menu item selected")
|
logEOrThrow("Unexpected menu item selected")
|
||||||
return@musicMenuImpl false
|
return@musicMenuImpl false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +104,8 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun musicMenu(anchor: View, @MenuRes menuRes: Int, artist: Artist) {
|
protected fun musicMenu(anchor: View, @MenuRes menuRes: Int, artist: Artist) {
|
||||||
|
logD("Launching new artist menu: ${artist.rawName}")
|
||||||
|
|
||||||
musicMenuImpl(anchor, menuRes) { id ->
|
musicMenuImpl(anchor, menuRes) { id ->
|
||||||
when (id) {
|
when (id) {
|
||||||
R.id.action_play -> {
|
R.id.action_play -> {
|
||||||
|
@ -116,7 +123,7 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
requireContext().showToast(R.string.lbl_queue_added)
|
requireContext().showToast(R.string.lbl_queue_added)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
logW("Unknown menu item selected")
|
logEOrThrow("Unexpected menu item selected")
|
||||||
return@musicMenuImpl false
|
return@musicMenuImpl false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,6 +133,8 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun musicMenu(anchor: View, @MenuRes menuRes: Int, genre: Genre) {
|
protected fun musicMenu(anchor: View, @MenuRes menuRes: Int, genre: Genre) {
|
||||||
|
logD("Launching new genre menu: ${genre.rawName}")
|
||||||
|
|
||||||
musicMenuImpl(anchor, menuRes) { id ->
|
musicMenuImpl(anchor, menuRes) { id ->
|
||||||
when (id) {
|
when (id) {
|
||||||
R.id.action_play -> {
|
R.id.action_play -> {
|
||||||
|
@ -143,7 +152,7 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
requireContext().showToast(R.string.lbl_queue_added)
|
requireContext().showToast(R.string.lbl_queue_added)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
logW("Unknown menu item selected")
|
logEOrThrow("Unexpected menu item selected")
|
||||||
return@musicMenuImpl false
|
return@musicMenuImpl false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,6 +175,7 @@ abstract class MenuFragment<T : ViewBinding> : ViewBindingFragment<T>() {
|
||||||
|
|
||||||
protected fun menu(anchor: View, @MenuRes menuRes: Int, block: PopupMenu.() -> Unit) {
|
protected fun menu(anchor: View, @MenuRes menuRes: Int, block: PopupMenu.() -> Unit) {
|
||||||
if (currentMenu != null) {
|
if (currentMenu != null) {
|
||||||
|
logD("Menu already present, not launching")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ViewModel that handles complicated navigation situations.
|
* A ViewModel that handles complicated navigation situations.
|
||||||
|
@ -43,23 +44,35 @@ class NavigationViewModel : ViewModel() {
|
||||||
|
|
||||||
/** Notify MainFragment to navigate to the location outlined in [MainNavigationAction]. */
|
/** Notify MainFragment to navigate to the location outlined in [MainNavigationAction]. */
|
||||||
fun mainNavigateTo(action: MainNavigationAction) {
|
fun mainNavigateTo(action: MainNavigationAction) {
|
||||||
if (_mainNavigationAction.value != null) return
|
if (_mainNavigationAction.value != null) {
|
||||||
|
logD("Already navigating, not doing main action")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logD("Navigating with action $action")
|
||||||
_mainNavigationAction.value = action
|
_mainNavigationAction.value = action
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mark that the main navigation process is done. */
|
/** Mark that the main navigation process is done. */
|
||||||
fun finishMainNavigation() {
|
fun finishMainNavigation() {
|
||||||
|
logD("Finishing main navigation process")
|
||||||
_mainNavigationAction.value = null
|
_mainNavigationAction.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Navigate to an item's detail menu, whether a song/album/artist */
|
/** Navigate to an item's detail menu, whether a song/album/artist */
|
||||||
fun exploreNavigateTo(item: Music) {
|
fun exploreNavigateTo(item: Music) {
|
||||||
if (_exploreNavigationItem.value != null) return
|
if (_exploreNavigationItem.value != null) {
|
||||||
|
logD("Already navigation, not doing explore action")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
logD("Navigating to ${item.rawName}")
|
||||||
_exploreNavigationItem.value = item
|
_exploreNavigationItem.value = item
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mark that the item navigation process is done. */
|
/** Mark that the item navigation process is done. */
|
||||||
fun finishExploreNavigation() {
|
fun finishExploreNavigation() {
|
||||||
|
logD("Finishing explore navigation process")
|
||||||
_exploreNavigationItem.value = null
|
_exploreNavigationItem.value = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.Genre
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.util.logW
|
import org.oxycblt.auxio.util.logEOrThrow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A data class representing the sort modes used in Auxio.
|
* A data class representing the sort modes used in Auxio.
|
||||||
|
@ -74,19 +74,19 @@ sealed class Sort(open val isAscending: Boolean) {
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun songsInPlace(songs: MutableList<Song>) {
|
open fun songsInPlace(songs: MutableList<Song>) {
|
||||||
logW("This sort is not supported for songs")
|
logEOrThrow("This sort is not supported for songs")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun albumsInPlace(albums: MutableList<Album>) {
|
open fun albumsInPlace(albums: MutableList<Album>) {
|
||||||
logW("This sort is not supported for albums")
|
logEOrThrow("This sort is not supported for albums")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun artistsInPlace(artists: MutableList<Artist>) {
|
open fun artistsInPlace(artists: MutableList<Artist>) {
|
||||||
logW("This sort is not supported for artists")
|
logEOrThrow("This sort is not supported for artists")
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun genresInPlace(genres: MutableList<Genre>) {
|
open fun genresInPlace(genres: MutableList<Genre>) {
|
||||||
logW("This sort is not supported for genres")
|
logEOrThrow("This sort is not supported for genres")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -131,7 +131,7 @@ class Accent private constructor(val index: Int) {
|
||||||
companion object {
|
companion object {
|
||||||
fun from(index: Int): Accent {
|
fun from(index: Int): Accent {
|
||||||
if (index > (MAX - 1)) {
|
if (index > (MAX - 1)) {
|
||||||
logW("Account outside of bounds [idx: $index, max: $MAX")
|
logW("Account outside of bounds [idx: $index, max: $MAX]")
|
||||||
return Accent(5)
|
return Accent(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,6 @@ import org.oxycblt.auxio.R
|
||||||
*/
|
*/
|
||||||
fun View.disableDropShadowCompat() {
|
fun View.disableDropShadowCompat() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
logD("Disabling drop shadows")
|
|
||||||
val transparent = context.getColorSafe(android.R.color.transparent)
|
val transparent = context.getColorSafe(android.R.color.transparent)
|
||||||
outlineAmbientShadowColor = transparent
|
outlineAmbientShadowColor = transparent
|
||||||
outlineSpotShadowColor = transparent
|
outlineSpotShadowColor = transparent
|
||||||
|
|
|
@ -52,7 +52,7 @@ fun Any.logE(msg: String) = Log.e(autoTag, msg)
|
||||||
*/
|
*/
|
||||||
fun Any.logEOrThrow(msg: String) {
|
fun Any.logEOrThrow(msg: String) {
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
error("${autoTag}: $msg")
|
error(msg)
|
||||||
} else {
|
} else {
|
||||||
logE(msg)
|
logE(msg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.oxycblt.auxio.playback.state.PlaybackStateManager
|
||||||
import org.oxycblt.auxio.playback.state.RepeatMode
|
import org.oxycblt.auxio.playback.state.RepeatMode
|
||||||
import org.oxycblt.auxio.settings.SettingsManager
|
import org.oxycblt.auxio.settings.SettingsManager
|
||||||
import org.oxycblt.auxio.util.getDimenSizeSafe
|
import org.oxycblt.auxio.util.getDimenSizeSafe
|
||||||
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A wrapper around each [WidgetProvider] that plugs into the main Auxio process and updates the
|
* A wrapper around each [WidgetProvider] that plugs into the main Auxio process and updates the
|
||||||
|
@ -67,6 +68,7 @@ class WidgetComponent(private val context: Context) :
|
||||||
// possible.
|
// possible.
|
||||||
val song = playbackManager.song
|
val song = playbackManager.song
|
||||||
if (song == null) {
|
if (song == null) {
|
||||||
|
logD("No song, resetting widget")
|
||||||
widget.update(context, null)
|
widget.update(context, null)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -87,6 +89,8 @@ class WidgetComponent(private val context: Context) :
|
||||||
// - After Android 12, the widget has round edges, so we need to round out
|
// - After Android 12, the widget has round edges, so we need to round out
|
||||||
// the album art. I dislike this, but it's mainly for stylistic cohesion.
|
// the album art. I dislike this, but it's mainly for stylistic cohesion.
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
this@WidgetComponent.logD("Doing API 31 cover load")
|
||||||
|
|
||||||
val metrics = context.resources.displayMetrics
|
val metrics = context.resources.displayMetrics
|
||||||
|
|
||||||
// Use RoundedCornersTransformation. This is because our hack to get a 1:1
|
// Use RoundedCornersTransformation. This is because our hack to get a 1:1
|
||||||
|
@ -106,6 +110,7 @@ class WidgetComponent(private val context: Context) :
|
||||||
// bitmap on very large screens.
|
// bitmap on very large screens.
|
||||||
.size(minOf(metrics.widthPixels, metrics.heightPixels, 1024))
|
.size(minOf(metrics.widthPixels, metrics.heightPixels, 1024))
|
||||||
} else {
|
} else {
|
||||||
|
this@WidgetComponent.logD("Doing API 21 cover load")
|
||||||
// Note: Explicitly use the "original" size as without it the scaling logic
|
// Note: Explicitly use the "original" size as without it the scaling logic
|
||||||
// in coil breaks down and results in an error.
|
// in coil breaks down and results in an error.
|
||||||
builder.size(Size.ORIGINAL)
|
builder.size(Size.ORIGINAL)
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
app:liftOnScroll="true"
|
app:liftOnScroll="true"
|
||||||
app:liftOnScrollTargetViewId="@id/detail_recycler">
|
app:liftOnScrollTargetViewId="@id/detail_recycler">
|
||||||
|
|
||||||
<!-- FIXME: Not every detail view has actions -->
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/detail_toolbar"
|
android:id="@+id/detail_toolbar"
|
||||||
|
|
Loading…
Reference in a new issue