all: fix logging & anim unification

Can't bisect this without spending way too much time on it.
This commit is contained in:
Alexander Capehart 2024-10-18 16:09:32 -06:00
parent 7dfaea3a4b
commit 0f4702c4dd
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
118 changed files with 937 additions and 894 deletions

View file

@ -116,8 +116,7 @@ class AuxioService :
private fun getRootChildrenLimit(): Int {
return browserRootHints?.getInt(
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT, 4)
?: 4
MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT, 4) ?: 4
}
private fun Bundle.getPage(): MusicServiceFragment.Page? {

View file

@ -34,7 +34,7 @@ import org.oxycblt.auxio.playback.state.DeferredPlayback
import org.oxycblt.auxio.ui.UISettings
import org.oxycblt.auxio.util.isNight
import org.oxycblt.auxio.util.systemBarInsetsCompat
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Auxio's single [AppCompatActivity].
@ -62,7 +62,7 @@ class MainActivity : AppCompatActivity() {
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setupEdgeToEdge(binding.root)
T.d("Activity created")
L.d("Activity created")
}
override fun onResume() {
@ -90,10 +90,10 @@ class MainActivity : AppCompatActivity() {
// Apply the color scheme. The black theme requires it's own set of themes since
// it's not possible to modify the themes at run-time.
if (isNight && uiSettings.useBlackTheme) {
T.d("Applying black theme [accent ${uiSettings.accent}]")
L.d("Applying black theme [accent ${uiSettings.accent}]")
setTheme(uiSettings.accent.blackTheme)
} else {
T.d("Applying normal theme [accent ${uiSettings.accent}]")
L.d("Applying normal theme [accent ${uiSettings.accent}]")
setTheme(uiSettings.accent.theme)
}
}
@ -120,7 +120,7 @@ class MainActivity : AppCompatActivity() {
private fun startIntentAction(intent: Intent?): Boolean {
if (intent == null) {
// Nothing to do.
T.d("No intent to handle")
L.d("No intent to handle")
return false
}
@ -129,7 +129,7 @@ class MainActivity : AppCompatActivity() {
// This is because onStart can run multiple times, and thus we really don't
// want to return false and override the original delayed action with a
// RestoreState action.
T.d("Already used this intent")
L.d("Already used this intent")
return true
}
intent.putExtra(KEY_INTENT_USED, true)
@ -139,11 +139,11 @@ class MainActivity : AppCompatActivity() {
Intent.ACTION_VIEW -> DeferredPlayback.Open(intent.data ?: return false)
Auxio.INTENT_KEY_SHORTCUT_SHUFFLE -> DeferredPlayback.ShuffleAll
else -> {
T.w("Unexpected intent ${intent.action}")
L.w("Unexpected intent ${intent.action}")
return false
}
}
T.d("Translated intent to $action")
L.d("Translated intent to $action")
playbackModel.playDeferred(action)
return true
}

View file

@ -68,7 +68,7 @@ import org.oxycblt.auxio.util.getDimen
import org.oxycblt.auxio.util.lazyReflectedMethod
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A wrapper around the home fragment that shows the playback fragment and high-level navigation.
@ -145,13 +145,13 @@ class MainFragment :
if (queueSheetBehavior != null) {
// In portrait mode, set up click listeners on the stacked sheets.
T.d("Configuring stacked bottom sheets")
L.d("Configuring stacked bottom sheets")
unlikelyToBeNull(binding.queueHandleWrapper).setOnClickListener {
playbackModel.openQueue()
}
} else {
// Dual-pane mode, manually style the static queue sheet.
T.d("Configuring dual-pane bottom sheet")
L.d("Configuring dual-pane bottom sheet")
binding.queueSheet.apply {
// Emulate the elevated bottom sheet style.
background =
@ -367,11 +367,11 @@ class MainFragment :
override fun onActionSelected(actionItem: SpeedDialActionItem): Boolean {
when (actionItem.id) {
R.id.action_new_playlist -> {
T.d("Creating playlist")
L.d("Creating playlist")
musicModel.createPlaylist()
}
R.id.action_import_playlist -> {
T.d("Importing playlist")
L.d("Importing playlist")
musicModel.importPlaylist()
}
else -> {}
@ -402,7 +402,7 @@ class MainFragment :
// 1. Loading placeholder for item lists
// 2. Rework the "No Music" case to not be an error and instead result in a placeholder
if (state is IndexingState.Completed && state.error == null) {
T.d("Received ok response")
L.d("Received ok response")
val binding = requireBinding()
updateFabVisibility(
binding,
@ -427,7 +427,7 @@ class MainFragment :
// displaying the shuffle FAB makes no sense. We also don't want the fast scroll
// popup to overlap with the FAB, so we hide the FAB when fast scrolling too.
if (shouldHideAllFabs(binding, songs, isFastScrolling)) {
T.d("Hiding fab: [empty: ${songs.isEmpty()} scrolling: $isFastScrolling]")
L.d("Hiding fab: [empty: ${songs.isEmpty()} scrolling: $isFastScrolling]")
forceHideAllFabs()
} else {
if (tabType != MusicType.PLAYLISTS) {
@ -436,7 +436,7 @@ class MainFragment :
}
if (binding.homeNewPlaylistFab.mainFab.isOrWillBeShown) {
T.d("Animating transition")
L.d("Animating transition")
binding.homeNewPlaylistFab.hide(
object : FloatingActionButton.OnVisibilityChangedListener() {
override fun onHidden(fab: FloatingActionButton) {
@ -451,17 +451,17 @@ class MainFragment :
}
})
} else {
T.d("Showing immediately")
L.d("Showing immediately")
binding.homeShuffleFab.show()
}
} else {
T.d("Showing playlist button")
L.d("Showing playlist button")
if (binding.homeNewPlaylistFab.mainFab.isOrWillBeShown) {
return
}
if (binding.homeShuffleFab.isOrWillBeShown) {
T.d("Animating transition")
L.d("Animating transition")
binding.homeShuffleFab.hide(
object : FloatingActionButton.OnVisibilityChangedListener() {
override fun onHidden(fab: FloatingActionButton) {
@ -476,7 +476,7 @@ class MainFragment :
}
})
} else {
T.d("Showing immediately")
L.d("Showing immediately")
binding.homeNewPlaylistFab.show()
}
}
@ -551,7 +551,7 @@ class MainFragment :
private fun handlePanel(panel: OpenPanel?) {
if (panel == null) return
T.d("Trying to update panel to $panel")
L.d("Trying to update panel to $panel")
when (panel) {
OpenPanel.MAIN -> tryClosePlaybackPanel()
OpenPanel.PLAYBACK -> tryOpenPlaybackPanel()
@ -567,7 +567,7 @@ class MainFragment :
if (playbackSheetBehavior.targetState == BackportBottomSheetBehavior.STATE_COLLAPSED) {
// Playback sheet is not expanded and not hidden, we can expand it.
T.d("Expanding playback sheet")
L.d("Expanding playback sheet")
playbackSheetBehavior.state = BackportBottomSheetBehavior.STATE_EXPANDED
return
}
@ -578,7 +578,7 @@ class MainFragment :
queueSheetBehavior.targetState == BackportBottomSheetBehavior.STATE_EXPANDED) {
// Queue sheet and playback sheet is expanded, close the queue sheet so the
// playback panel can shown.
T.d("Collapsing queue sheet")
L.d("Collapsing queue sheet")
queueSheetBehavior.state = BackportBottomSheetBehavior.STATE_COLLAPSED
}
}
@ -589,7 +589,7 @@ class MainFragment :
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackBottomSheetBehavior
if (playbackSheetBehavior.targetState == BackportBottomSheetBehavior.STATE_EXPANDED) {
// Playback sheet (and possibly queue) needs to be collapsed.
T.d("Collapsing playback and queue sheets")
L.d("Collapsing playback and queue sheets")
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueBottomSheetBehavior?
playbackSheetBehavior.state = BackportBottomSheetBehavior.STATE_COLLAPSED
@ -615,7 +615,7 @@ class MainFragment :
val playbackSheetBehavior =
binding.playbackSheet.coordinatorLayoutBehavior as PlaybackBottomSheetBehavior
if (playbackSheetBehavior.targetState == BackportBottomSheetBehavior.STATE_HIDDEN) {
T.d("Unhiding and enabling playback sheet")
L.d("Unhiding and enabling playback sheet")
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueBottomSheetBehavior?
// Queue sheet behavior is either collapsed or expanded, no hiding needed
@ -636,7 +636,7 @@ class MainFragment :
val queueSheetBehavior =
binding.queueSheet.coordinatorLayoutBehavior as QueueBottomSheetBehavior?
T.d("Hiding and disabling playback and queue sheets")
L.d("Hiding and disabling playback and queue sheets")
// Make both bottom sheets non-draggable so the user can't halt the hiding event.
queueSheetBehavior?.apply {
@ -720,7 +720,7 @@ class MainFragment :
OnBackPressedCallback(false) {
override fun handleOnBackPressed() {
if (detailModel.dropPlaylistEdit()) {
T.d("Dropped playlist edits")
L.d("Dropped playlist edits")
}
}
@ -733,7 +733,7 @@ class MainFragment :
OnBackPressedCallback(false) {
override fun handleOnBackPressed() {
if (listModel.dropSelection()) {
T.d("Dropped selection")
L.d("Dropped selection")
}
}

View file

@ -44,7 +44,7 @@ import org.oxycblt.auxio.util.getPlural
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ListFragment] that shows information about an [Album].
@ -103,7 +103,7 @@ class AlbumDetailFragment : DetailFragment<Album, Song>() {
private fun updateAlbum(album: Album?) {
if (album == null) {
T.d("No album to show, navigating away")
L.d("No album to show, navigating away")
findNavController().navigateUp()
return
}
@ -153,7 +153,7 @@ class AlbumDetailFragment : DetailFragment<Album, Song>() {
val binding = requireBinding()
when (show) {
is Show.SongDetails -> {
T.d("Navigating to ${show.song}")
L.d("Navigating to ${show.song}")
findNavController()
.navigateSafe(AlbumDetailFragmentDirections.showSong(show.song.uid))
}
@ -162,11 +162,11 @@ class AlbumDetailFragment : DetailFragment<Album, Song>() {
// fragment should be launched otherwise.
is Show.SongAlbumDetails -> {
if (unlikelyToBeNull(detailModel.currentAlbum.value) == show.song.album) {
T.d("Navigating to a ${show.song} in this album")
L.d("Navigating to a ${show.song} in this album")
scrollToAlbumSong(show.song)
detailModel.toShow.consume()
} else {
T.d("Navigating to the album of ${show.song}")
L.d("Navigating to the album of ${show.song}")
findNavController()
.navigateSafe(AlbumDetailFragmentDirections.showAlbum(show.song.album.uid))
}
@ -176,27 +176,27 @@ class AlbumDetailFragment : DetailFragment<Album, Song>() {
// detail fragment.
is Show.AlbumDetails -> {
if (unlikelyToBeNull(detailModel.currentAlbum.value) == show.album) {
T.d("Navigating to the top of this album")
L.d("Navigating to the top of this album")
binding.detailRecycler.scrollToPosition(0)
detailModel.toShow.consume()
} else {
T.d("Navigating to ${show.album}")
L.d("Navigating to ${show.album}")
findNavController()
.navigateSafe(AlbumDetailFragmentDirections.showAlbum(show.album.uid))
}
}
is Show.ArtistDetails -> {
T.d("Navigating to ${show.artist}")
L.d("Navigating to ${show.artist}")
findNavController()
.navigateSafe(AlbumDetailFragmentDirections.showArtist(show.artist.uid))
}
is Show.SongArtistDecision -> {
T.d("Navigating to artist choices for ${show.song}")
L.d("Navigating to artist choices for ${show.song}")
findNavController()
.navigateSafe(AlbumDetailFragmentDirections.showArtistChoices(show.song.uid))
}
is Show.AlbumArtistDecision -> {
T.d("Navigating to artist choices for ${show.album}")
L.d("Navigating to artist choices for ${show.album}")
findNavController()
.navigateSafe(AlbumDetailFragmentDirections.showArtistChoices(show.album.uid))
}
@ -239,7 +239,7 @@ class AlbumDetailFragment : DetailFragment<Album, Song>() {
val directions =
when (decision) {
is PlaylistDecision.Add -> {
T.d("Adding ${decision.songs.size} songs to a playlist")
L.d("Adding ${decision.songs.size} songs to a playlist")
AlbumDetailFragmentDirections.addToPlaylist(
decision.songs.map { it.uid }.toTypedArray())
}
@ -268,11 +268,11 @@ class AlbumDetailFragment : DetailFragment<Album, Song>() {
val directions =
when (decision) {
is PlaybackDecision.PlayFromArtist -> {
T.d("Launching play from artist dialog for $decision")
L.d("Launching play from artist dialog for $decision")
AlbumDetailFragmentDirections.playFromArtist(decision.song.uid)
}
is PlaybackDecision.PlayFromGenre -> {
T.d("Launching play from artist dialog for $decision")
L.d("Launching play from artist dialog for $decision")
AlbumDetailFragmentDirections.playFromGenre(decision.song.uid)
}
}

View file

@ -44,7 +44,7 @@ import org.oxycblt.auxio.util.getPlural
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ListFragment] that shows information about an [Artist].
@ -111,7 +111,7 @@ class ArtistDetailFragment : DetailFragment<Artist, Music>() {
private fun updateArtist(artist: Artist?) {
if (artist == null) {
T.d("No artist to show, navigating away")
L.d("No artist to show, navigating away")
findNavController().navigateUp()
return
}
@ -154,7 +154,7 @@ class ArtistDetailFragment : DetailFragment<Artist, Music>() {
// The artist does not have any songs, so hide functionality that makes no sense.
// ex. Play and Shuffle, Song Counts, and Genre Information.
// Artists are always guaranteed to have albums however, so continue to show those.
T.d("Artist is empty, disabling genres and playback")
L.d("Artist is empty, disabling genres and playback")
binding.detailSubhead.isVisible = false
binding.detailPlayButton?.isEnabled = false
binding.detailShuffleButton?.isEnabled = false
@ -176,14 +176,14 @@ class ArtistDetailFragment : DetailFragment<Artist, Music>() {
val binding = requireBinding()
when (show) {
is Show.SongDetails -> {
T.d("Navigating to ${show.song}")
L.d("Navigating to ${show.song}")
findNavController()
.navigateSafe(ArtistDetailFragmentDirections.showSong(show.song.uid))
}
// Songs should be shown in their album, not in their artist.
is Show.SongAlbumDetails -> {
T.d("Navigating to the album of ${show.song}")
L.d("Navigating to the album of ${show.song}")
findNavController()
.navigateSafe(ArtistDetailFragmentDirections.showAlbum(show.song.album.uid))
}
@ -191,7 +191,7 @@ class ArtistDetailFragment : DetailFragment<Artist, Music>() {
// Launch a new detail view for an album, even if it is part of
// this artist.
is Show.AlbumDetails -> {
T.d("Navigating to ${show.album}")
L.d("Navigating to ${show.album}")
findNavController()
.navigateSafe(ArtistDetailFragmentDirections.showAlbum(show.album.uid))
}
@ -200,22 +200,22 @@ class ArtistDetailFragment : DetailFragment<Artist, Music>() {
// scroll back to the top. Otherwise launch a new detail view.
is Show.ArtistDetails -> {
if (show.artist == detailModel.currentArtist.value) {
T.d("Navigating to the top of this artist")
L.d("Navigating to the top of this artist")
binding.detailRecycler.scrollToPosition(0)
detailModel.toShow.consume()
} else {
T.d("Navigating to ${show.artist}")
L.d("Navigating to ${show.artist}")
findNavController()
.navigateSafe(ArtistDetailFragmentDirections.showArtist(show.artist.uid))
}
}
is Show.SongArtistDecision -> {
T.d("Navigating to artist choices for ${show.song}")
L.d("Navigating to artist choices for ${show.song}")
findNavController()
.navigateSafe(ArtistDetailFragmentDirections.showArtistChoices(show.song.uid))
}
is Show.AlbumArtistDecision -> {
T.d("Navigating to artist choices for ${show.album}")
L.d("Navigating to artist choices for ${show.album}")
findNavController()
.navigateSafe(ArtistDetailFragmentDirections.showArtistChoices(show.album.uid))
}
@ -259,7 +259,7 @@ class ArtistDetailFragment : DetailFragment<Artist, Music>() {
val directions =
when (decision) {
is PlaylistDecision.Add -> {
T.d("Adding ${decision.songs.size} songs to a playlist")
L.d("Adding ${decision.songs.size} songs to a playlist")
ArtistDetailFragmentDirections.addToPlaylist(
decision.songs.map { it.uid }.toTypedArray())
}
@ -300,7 +300,7 @@ class ArtistDetailFragment : DetailFragment<Artist, Music>() {
is PlaybackDecision.PlayFromArtist ->
error("Unexpected playback decision $decision")
is PlaybackDecision.PlayFromGenre -> {
T.d("Launching play from artist dialog for $decision")
L.d("Launching play from artist dialog for $decision")
ArtistDetailFragmentDirections.playFromGenre(decision.song.uid)
}
}

View file

@ -34,7 +34,7 @@ import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.info.Disc
import org.oxycblt.auxio.music.info.ReleaseType
import timber.log.Timber as T
import timber.log.Timber as L
interface DetailGenerator {
fun any(uid: Music.UID): Detail<out MusicParent>?
@ -159,7 +159,7 @@ private class DetailGeneratorImpl(
// groupByTo normally returns a mapping to a MutableList mapping. Since MutableList
// inherits list, we can cast upwards and save a copy by directly inserting the
// implicit album list into the mapping.
T.d("Implicit albums present, adding to list")
L.d("Implicit albums present, adding to list")
@Suppress("UNCHECKED_CAST")
(grouping as MutableMap<DetailSection.Albums.Category, Collection<Album>>)[
DetailSection.Albums.Category.APPEARANCES] = artist.implicitAlbums

View file

@ -55,7 +55,7 @@ import org.oxycblt.auxio.playback.PlaybackSettings
import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* [ViewModel] that manages the Song, Album, Artist, and Genre detail views. Keeps track of the
@ -301,7 +301,7 @@ constructor(
private fun showImpl(show: Show) {
val existing = toShow.flow.value
if (existing != null) {
T.d("Already have pending show command $existing, ignoring $show")
L.d("Already have pending show command $existing, ignoring $show")
return
}
_toShow.put(show)
@ -314,10 +314,10 @@ constructor(
* @param uid The UID of the [Song] to load. Must be valid.
*/
fun setSong(uid: Music.UID) {
T.d("Opening song $uid")
L.d("Opening song $uid")
_currentSong.value = musicRepository.deviceLibrary?.findSong(uid)?.also(::refreshAudioInfo)
if (_currentSong.value == null) {
T.w("Given song UID was invalid")
L.w("Given song UID was invalid")
}
}
@ -328,14 +328,14 @@ constructor(
* @param uid The [Music.UID] of the [Album] to update [currentAlbum] to. Must be valid.
*/
fun setAlbum(uid: Music.UID) {
T.d("Opening album $uid")
L.d("Opening album $uid")
if (uid === _currentAlbum.value?.uid) {
return
}
val album = detailGenerator.album(uid)
refreshDetail(album, _currentAlbum, _albumSongList, _albumSongInstructions, null)
if (_currentAlbum.value == null) {
T.w("Given album UID was invalid")
L.w("Given album UID was invalid")
}
}
@ -355,7 +355,7 @@ constructor(
* @param uid The [Music.UID] of the [Artist] to update [currentArtist] to. Must be valid.
*/
fun setArtist(uid: Music.UID) {
T.d("Opening artist $uid")
L.d("Opening artist $uid")
if (uid === _currentArtist.value?.uid) {
return
}
@ -379,7 +379,7 @@ constructor(
* @param uid The [Music.UID] of the [Genre] to update [currentGenre] to. Must be valid.
*/
fun setGenre(uid: Music.UID) {
T.d("Opening genre $uid")
L.d("Opening genre $uid")
if (uid === _currentGenre.value?.uid) {
return
}
@ -403,7 +403,7 @@ constructor(
* @param uid The [Music.UID] of the [Playlist] to update [currentPlaylist] to. Must be valid.
*/
fun setPlaylist(uid: Music.UID) {
T.d("Opening playlist $uid")
L.d("Opening playlist $uid")
if (uid === _currentPlaylist.value?.uid) {
return
}
@ -413,7 +413,7 @@ constructor(
/** Start a playlist editing session. Does nothing if a playlist is not being shown. */
fun startPlaylistEdit() {
val playlist = _currentPlaylist.value ?: return
T.d("Starting playlist edit")
L.d("Starting playlist edit")
_editedPlaylist.value = playlist.songs
refreshPlaylist(playlist.uid)
}
@ -425,7 +425,7 @@ constructor(
fun savePlaylistEdit() {
val playlist = _currentPlaylist.value ?: return
val editedPlaylist = _editedPlaylist.value ?: return
T.d("Committing playlist edits")
L.d("Committing playlist edits")
viewModelScope.launch {
musicRepository.rewritePlaylist(playlist, editedPlaylist)
// TODO: The user could probably press some kind of button if they were fast enough.
@ -478,7 +478,7 @@ constructor(
if (realFrom !in editedPlaylist.indices || realTo !in editedPlaylist.indices) {
return false
}
T.d("Moving playlist song from $realFrom [$from] to $realTo [$to]")
L.d("Moving playlist song from $realFrom [$from] to $realTo [$to]")
editedPlaylist.add(realFrom, editedPlaylist.removeAt(realTo))
_editedPlaylist.value = editedPlaylist
refreshPlaylist(playlist.uid, UpdateInstructions.Move(from, to))
@ -497,7 +497,7 @@ constructor(
if (realAt !in editedPlaylist.indices) {
return
}
T.d("Removing playlist song at $realAt [$at]")
L.d("Removing playlist song at $realAt [$at]")
editedPlaylist.removeAt(realAt)
_editedPlaylist.value = editedPlaylist
refreshPlaylist(
@ -505,13 +505,13 @@ constructor(
if (editedPlaylist.isNotEmpty()) {
UpdateInstructions.Remove(at, 1)
} else {
T.d("Playlist will be empty after removal, removing header")
L.d("Playlist will be empty after removal, removing header")
UpdateInstructions.Remove(at - 1, 3)
})
}
private fun refreshAudioInfo(song: Song) {
T.d("Refreshing audio info")
L.d("Refreshing audio info")
// Clear any previous job in order to avoid stale data from appearing in the UI.
currentSongJob?.cancel()
_songAudioProperties.value = null
@ -519,7 +519,7 @@ constructor(
viewModelScope.launch(Dispatchers.IO) {
val info = audioPropertiesFactory.extract(song)
yield()
T.d("Updating audio info to $info")
L.d("Updating audio info to $info")
_songAudioProperties.value = info
}
}
@ -586,7 +586,7 @@ constructor(
uid: Music.UID,
instructions: UpdateInstructions = UpdateInstructions.Diff
) {
T.d("Refreshing playlist list")
L.d("Refreshing playlist list")
val edited = editedPlaylist.value
if (edited == null) {
val playlist = detailGenerator.playlist(uid)

View file

@ -43,7 +43,7 @@ import org.oxycblt.auxio.util.getPlural
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ListFragment] that shows information for a particular [Genre].
@ -110,7 +110,7 @@ class GenreDetailFragment : DetailFragment<Genre, Music>() {
private fun updateGenre(genre: Genre?) {
if (genre == null) {
T.d("No genre to show, navigating away")
L.d("No genre to show, navigating away")
findNavController().navigateUp()
return
}
@ -144,7 +144,7 @@ class GenreDetailFragment : DetailFragment<Genre, Music>() {
private fun handleShow(show: Show?) {
when (show) {
is Show.SongDetails -> {
T.d("Navigating to ${show.song}")
L.d("Navigating to ${show.song}")
findNavController()
.navigateSafe(GenreDetailFragmentDirections.showSong(show.song.uid))
}
@ -152,7 +152,7 @@ class GenreDetailFragment : DetailFragment<Genre, Music>() {
// Songs should be scrolled to if the album matches, or a new detail
// fragment should be launched otherwise.
is Show.SongAlbumDetails -> {
T.d("Navigating to the album of ${show.song}")
L.d("Navigating to the album of ${show.song}")
findNavController()
.navigateSafe(GenreDetailFragmentDirections.showAlbum(show.song.album.uid))
}
@ -160,29 +160,29 @@ class GenreDetailFragment : DetailFragment<Genre, Music>() {
// If the album matches, no need to do anything. Otherwise launch a new
// detail fragment.
is Show.AlbumDetails -> {
T.d("Navigating to ${show.album}")
L.d("Navigating to ${show.album}")
findNavController()
.navigateSafe(GenreDetailFragmentDirections.showAlbum(show.album.uid))
}
// Always launch a new ArtistDetailFragment.
is Show.ArtistDetails -> {
T.d("Navigating to ${show.artist}")
L.d("Navigating to ${show.artist}")
findNavController()
.navigateSafe(GenreDetailFragmentDirections.showArtist(show.artist.uid))
}
is Show.SongArtistDecision -> {
T.d("Navigating to artist choices for ${show.song}")
L.d("Navigating to artist choices for ${show.song}")
findNavController()
.navigateSafe(GenreDetailFragmentDirections.showArtistChoices(show.song.uid))
}
is Show.AlbumArtistDecision -> {
T.d("Navigating to artist choices for ${show.album}")
L.d("Navigating to artist choices for ${show.album}")
findNavController()
.navigateSafe(GenreDetailFragmentDirections.showArtistChoices(show.album.uid))
}
is Show.GenreDetails -> {
T.d("Navigated to this genre")
L.d("Navigated to this genre")
detailModel.toShow.consume()
}
is Show.PlaylistDetails -> {
@ -223,7 +223,7 @@ class GenreDetailFragment : DetailFragment<Genre, Music>() {
val directions =
when (decision) {
is PlaylistDecision.Add -> {
T.d("Adding ${decision.songs.size} songs to a playlist")
L.d("Adding ${decision.songs.size} songs to a playlist")
GenreDetailFragmentDirections.addToPlaylist(
decision.songs.map { it.uid }.toTypedArray())
}
@ -262,7 +262,7 @@ class GenreDetailFragment : DetailFragment<Genre, Music>() {
val directions =
when (decision) {
is PlaybackDecision.PlayFromArtist -> {
T.d("Launching play from artist dialog for $decision")
L.d("Launching play from artist dialog for $decision")
GenreDetailFragmentDirections.playFromArtist(decision.song.uid)
}
is PlaybackDecision.PlayFromGenre -> error("Unexpected playback decision $decision")

View file

@ -52,7 +52,7 @@ import org.oxycblt.auxio.util.getPlural
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ListFragment] that shows information for a particular [Playlist].
@ -81,11 +81,11 @@ class PlaylistDetailFragment :
getContentLauncher =
registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
if (uri == null) {
T.w("No URI returned from file picker")
L.w("No URI returned from file picker")
return@registerForActivityResult
}
T.d("Received playlist URI $uri")
L.d("Received playlist URI $uri")
musicModel.importPlaylist(uri, pendingImportTarget)
}
@ -193,7 +193,7 @@ class PlaylistDetailFragment :
getString(R.string.fmt_editing, playlist.name.resolve(requireContext()))
if (editedPlaylist != null) {
T.d("Binding edited playlist image")
L.d("Binding edited playlist image")
binding.detailCover.bind(
editedPlaylist,
binding.context.getString(R.string.desc_playlist_image, playlist.name),
@ -222,7 +222,7 @@ class PlaylistDetailFragment :
val playable = playlist.songs.isNotEmpty() && editedPlaylist == null
if (!playable) {
T.d("Playlist is being edited or is empty, disabling playback options")
L.d("Playlist is being edited or is empty, disabling playback options")
}
binding.detailPlayButton?.apply {
@ -248,7 +248,7 @@ class PlaylistDetailFragment :
listModel.dropSelection()
if (editedPlaylist != null) {
T.d("Updating save button state")
L.d("Updating save button state")
requireBinding().detailEditToolbar.menu.findItem(R.id.action_save).apply {
isEnabled = editedPlaylist != detailModel.currentPlaylist.value?.songs
}
@ -260,38 +260,38 @@ class PlaylistDetailFragment :
private fun handleShow(show: Show?) {
when (show) {
is Show.SongDetails -> {
T.d("Navigating to ${show.song}")
L.d("Navigating to ${show.song}")
findNavController()
.navigateSafe(PlaylistDetailFragmentDirections.showSong(show.song.uid))
}
is Show.SongAlbumDetails -> {
T.d("Navigating to the album of ${show.song}")
L.d("Navigating to the album of ${show.song}")
findNavController()
.navigateSafe(PlaylistDetailFragmentDirections.showAlbum(show.song.album.uid))
}
is Show.AlbumDetails -> {
T.d("Navigating to ${show.album}")
L.d("Navigating to ${show.album}")
findNavController()
.navigateSafe(PlaylistDetailFragmentDirections.showAlbum(show.album.uid))
}
is Show.ArtistDetails -> {
T.d("Navigating to ${show.artist}")
L.d("Navigating to ${show.artist}")
findNavController()
.navigateSafe(PlaylistDetailFragmentDirections.showArtist(show.artist.uid))
}
is Show.SongArtistDecision -> {
T.d("Navigating to artist choices for ${show.song}")
L.d("Navigating to artist choices for ${show.song}")
findNavController()
.navigateSafe(PlaylistDetailFragmentDirections.showArtistChoices(show.song.uid))
}
is Show.AlbumArtistDecision -> {
T.d("Navigating to artist choices for ${show.album}")
L.d("Navigating to artist choices for ${show.album}")
findNavController()
.navigateSafe(
PlaylistDetailFragmentDirections.showArtistChoices(show.album.uid))
}
is Show.PlaylistDetails -> {
T.d("Navigated to this playlist")
L.d("Navigated to this playlist")
detailModel.toShow.consume()
}
is Show.GenreDetails -> {
@ -332,7 +332,7 @@ class PlaylistDetailFragment :
val directions =
when (decision) {
is PlaylistDecision.Import -> {
T.d("Importing playlist")
L.d("Importing playlist")
pendingImportTarget = decision.target
requireNotNull(getContentLauncher) {
"Content picker launcher was not available"
@ -342,7 +342,7 @@ class PlaylistDetailFragment :
return
}
is PlaylistDecision.Rename -> {
T.d("Renaming ${decision.playlist}")
L.d("Renaming ${decision.playlist}")
PlaylistDetailFragmentDirections.renamePlaylist(
decision.playlist.uid,
decision.template,
@ -350,15 +350,15 @@ class PlaylistDetailFragment :
decision.reason)
}
is PlaylistDecision.Export -> {
T.d("Exporting ${decision.playlist}")
L.d("Exporting ${decision.playlist}")
PlaylistDetailFragmentDirections.exportPlaylist(decision.playlist.uid)
}
is PlaylistDecision.Delete -> {
T.d("Deleting ${decision.playlist}")
L.d("Deleting ${decision.playlist}")
PlaylistDetailFragmentDirections.deletePlaylist(decision.playlist.uid)
}
is PlaylistDecision.Add -> {
T.d("Adding ${decision.songs.size} songs to a playlist")
L.d("Adding ${decision.songs.size} songs to a playlist")
PlaylistDetailFragmentDirections.addToPlaylist(
decision.songs.map { it.uid }.toTypedArray())
}
@ -384,11 +384,11 @@ class PlaylistDetailFragment :
val directions =
when (decision) {
is PlaybackDecision.PlayFromArtist -> {
T.d("Launching play from artist dialog for $decision")
L.d("Launching play from artist dialog for $decision")
PlaylistDetailFragmentDirections.playFromArtist(decision.song.uid)
}
is PlaybackDecision.PlayFromGenre -> {
T.d("Launching play from artist dialog for $decision")
L.d("Launching play from artist dialog for $decision")
PlaylistDetailFragmentDirections.playFromGenre(decision.song.uid)
}
}
@ -399,15 +399,15 @@ class PlaylistDetailFragment :
val id =
when {
detailModel.editedPlaylist.value != null -> {
T.d("Currently editing playlist, showing edit toolbar")
L.d("Currently editing playlist, showing edit toolbar")
R.id.detail_edit_toolbar
}
listModel.selected.value.isNotEmpty() -> {
T.d("Currently selecting, showing selection toolbar")
L.d("Currently selecting, showing selection toolbar")
R.id.detail_selection_toolbar
}
else -> {
T.d("Using normal toolbar")
L.d("Using normal toolbar")
R.id.detail_normal_toolbar
}
}

View file

@ -42,7 +42,7 @@ import org.oxycblt.auxio.playback.replaygain.formatDb
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.concatLocalized
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewBindingMaterialDialogFragment] that shows information about a Song.
@ -76,7 +76,7 @@ class SongDetailDialog : ViewBindingMaterialDialogFragment<DialogSongDetailBindi
private fun updateSong(song: Song?, info: AudioProperties?) {
if (song == null) {
T.d("No song to show, navigating away")
L.d("No song to show, navigating away")
findNavController().navigateUp()
return
}

View file

@ -29,7 +29,7 @@ import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.device.DeviceLibrary
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewModel] that stores choice information for [ShowArtistDialog], and possibly others in the
@ -59,7 +59,7 @@ class DetailPickerViewModel @Inject constructor(private val musicRepository: Mus
val deviceLibrary = musicRepository.deviceLibrary ?: return
// Need to sanitize different items depending on the current set of choices.
_artistChoices.value = _artistChoices.value?.sanitize(deviceLibrary)
T.d("Updated artist choices: ${_artistChoices.value}")
L.d("Updated artist choices: ${_artistChoices.value}")
}
/**
@ -68,20 +68,20 @@ class DetailPickerViewModel @Inject constructor(private val musicRepository: Mus
* @param itemUid The [Music.UID] of the item to show. Must be a [Song] or [Album].
*/
fun setArtistChoiceUid(itemUid: Music.UID) {
T.d("Opening navigation choices for $itemUid")
L.d("Opening navigation choices for $itemUid")
// Support Songs and Albums, which have parent artists.
_artistChoices.value =
when (val music = musicRepository.find(itemUid)) {
is Song -> {
T.d("Creating navigation choices for song")
L.d("Creating navigation choices for song")
ArtistShowChoices.FromSong(music)
}
is Album -> {
T.d("Creating navigation choices for album")
L.d("Creating navigation choices for album")
ArtistShowChoices.FromAlbum(music)
}
else -> {
T.w("Given song/album UID was invalid")
L.w("Given song/album UID was invalid")
null
}
}

View file

@ -35,7 +35,7 @@ import org.oxycblt.auxio.list.adapter.UpdateInstructions
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A picker [ViewBindingMaterialDialogFragment] intended for when the [Artist] to show is ambiguous.
@ -85,7 +85,7 @@ class ShowArtistDialog :
private fun updateChoices(choices: ArtistShowChoices?) {
if (choices == null) {
T.d("No choices to show, navigating away")
L.d("No choices to show, navigating away")
findNavController().navigateUp()
return
}

View file

@ -46,7 +46,7 @@ import org.oxycblt.auxio.music.resolveNames
import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.inflater
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [DetailListAdapter] implementing the header, sub-items, and editing state for the [Playlist]
@ -97,7 +97,7 @@ class PlaylistDetailListAdapter(private val listener: Listener) :
// Nothing to do.
return
}
T.d("Updating editing state [old: $isEditing new: $editing]")
L.d("Updating editing state [old: $isEditing new: $editing]")
this.isEditing = editing
notifyItemRangeChanged(0, currentList.size, PAYLOAD_EDITING_CHANGED)
}

View file

@ -28,7 +28,7 @@ import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.list.sort.SortDialog
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.util.collectImmediately
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [SortDialog] that controls the [Sort] of [DetailViewModel.albumSongSort].
@ -56,7 +56,7 @@ class AlbumSongSortDialog : SortDialog() {
private fun updateAlbum(album: Album?) {
if (album == null) {
T.d("No album to sort, navigating away")
L.d("No album to sort, navigating away")
findNavController().navigateUp()
}
}

View file

@ -28,7 +28,7 @@ import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.list.sort.SortDialog
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.util.collectImmediately
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [SortDialog] that controls the [Sort] of [DetailViewModel.artistSongSort].
@ -57,7 +57,7 @@ class ArtistSongSortDialog : SortDialog() {
private fun updateArtist(artist: Artist?) {
if (artist == null) {
T.d("No artist to sort, navigating away")
L.d("No artist to sort, navigating away")
findNavController().navigateUp()
}
}

View file

@ -28,7 +28,7 @@ import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.list.sort.SortDialog
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.util.collectImmediately
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [SortDialog] that controls the [Sort] of [DetailViewModel.genreSongSort].
@ -62,7 +62,7 @@ class GenreSongSortDialog : SortDialog() {
private fun updateGenre(genre: Genre?) {
if (genre == null) {
T.d("No genre to sort, navigating away")
L.d("No genre to sort, navigating away")
findNavController().navigateUp()
}
}

View file

@ -28,7 +28,7 @@ import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.list.sort.SortDialog
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.util.collectImmediately
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [SortDialog] that controls the [Sort] of [DetailViewModel.genreSongSort].
@ -62,7 +62,7 @@ class PlaylistSongSortDialog : SortDialog() {
private fun updatePlaylist(genre: Playlist?) {
if (genre == null) {
T.d("No genre to sort, navigating away")
L.d("No genre to sort, navigating away")
findNavController().navigateUp()
}
}

View file

@ -79,7 +79,7 @@ import org.oxycblt.auxio.util.lazyReflectedField
import org.oxycblt.auxio.util.lazyReflectedMethod
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.showToast
import timber.log.Timber as T
import timber.log.Timber as L
/**
* The starting [SelectionFragment] of Auxio. Shows the user's music library and enables navigation
@ -125,11 +125,11 @@ class HomeFragment :
getContentLauncher =
registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
if (uri == null) {
T.w("No URI returned from file picker")
L.w("No URI returned from file picker")
return@registerForActivityResult
}
T.d("Received playlist URI $uri")
L.d("Received playlist URI $uri")
musicModel.importPlaylist(uri, pendingImportTarget)
}
@ -220,17 +220,17 @@ class HomeFragment :
return when (item.itemId) {
// Handle main actions (Search, Settings, About)
R.id.action_search -> {
T.d("Navigating to search")
L.d("Navigating to search")
findNavController().navigateSafe(HomeFragmentDirections.search())
true
}
R.id.action_settings -> {
T.d("Navigating to preferences")
L.d("Navigating to preferences")
homeModel.showSettings()
true
}
R.id.action_about -> {
T.d("Navigating to about")
L.d("Navigating to about")
homeModel.showAbout()
true
}
@ -250,7 +250,7 @@ class HomeFragment :
true
}
else -> {
T.w("Unexpected menu item selected")
L.w("Unexpected menu item selected")
false
}
}
@ -264,7 +264,7 @@ class HomeFragment :
if (homeModel.currentTabTypes.size == 1) {
// A single tab makes the tab layout redundant, hide it and disable the collapsing
// behavior.
T.d("Single tab shown, disabling TabLayout")
L.d("Single tab shown, disabling TabLayout")
binding.homeTabs.isVisible = false
binding.homeAppbar.setExpanded(true, false)
toolbarParams.scrollFlags = 0
@ -302,7 +302,7 @@ class HomeFragment :
private fun handleRecreate(recreate: Unit?) {
if (recreate == null) return
val binding = requireBinding()
T.d("Recreating ViewPager")
L.d("Recreating ViewPager")
// Move back to position zero, as there must be a tab there.
binding.homePager.currentItem = 0
// Make sure tabs are set up to also follow the new ViewPager configuration.
@ -319,7 +319,7 @@ class HomeFragment :
is IndexingState.Completed -> setupCompleteState(binding, state.error)
is IndexingState.Indexing -> setupIndexingState(binding, state.progress)
null -> {
T.d("Indexer is in indeterminate state")
L.d("Indexer is in indeterminate state")
binding.homeIndexingContainer.visibility = View.INVISIBLE
}
}
@ -327,19 +327,19 @@ class HomeFragment :
private fun setupCompleteState(binding: FragmentHomeBinding, error: Exception?) {
if (error == null) {
T.d("Received ok response")
L.d("Received ok response")
binding.homeIndexingContainer.visibility = View.INVISIBLE
return
}
T.d("Received non-ok response")
L.d("Received non-ok response")
val context = requireContext()
binding.homeIndexingContainer.visibility = View.VISIBLE
binding.homeIndexingProgress.visibility = View.INVISIBLE
binding.homeIndexingActions.visibility = View.VISIBLE
when (error) {
is NoAudioPermissionException -> {
T.d("Showing permission prompt")
L.d("Showing permission prompt")
binding.homeIndexingStatus.setText(R.string.err_no_perms)
// Configure the action to act as a permission launcher.
binding.homeIndexingTry.apply {
@ -354,7 +354,7 @@ class HomeFragment :
binding.homeIndexingMore.visibility = View.GONE
}
is NoMusicException -> {
T.d("Showing no music error")
L.d("Showing no music error")
binding.homeIndexingStatus.setText(R.string.err_no_music)
// Configure the action to act as a reload trigger.
binding.homeIndexingTry.apply {
@ -365,7 +365,7 @@ class HomeFragment :
binding.homeIndexingMore.visibility = View.GONE
}
else -> {
T.d("Showing generic error")
L.d("Showing generic error")
binding.homeIndexingStatus.setText(R.string.err_index_failed)
// Configure the action to act as a reload trigger.
binding.homeIndexingTry.apply {
@ -411,14 +411,14 @@ class HomeFragment :
val directions =
when (decision) {
is PlaylistDecision.New -> {
T.d("Creating new playlist")
L.d("Creating new playlist")
HomeFragmentDirections.newPlaylist(
decision.songs.map { it.uid }.toTypedArray(),
decision.template,
decision.reason)
}
is PlaylistDecision.Import -> {
T.d("Importing playlist")
L.d("Importing playlist")
pendingImportTarget = decision.target
requireNotNull(getContentLauncher) {
"Content picker launcher was not available"
@ -428,7 +428,7 @@ class HomeFragment :
return
}
is PlaylistDecision.Rename -> {
T.d("Renaming ${decision.playlist}")
L.d("Renaming ${decision.playlist}")
HomeFragmentDirections.renamePlaylist(
decision.playlist.uid,
decision.template,
@ -436,15 +436,15 @@ class HomeFragment :
decision.reason)
}
is PlaylistDecision.Export -> {
T.d("Exporting ${decision.playlist}")
L.d("Exporting ${decision.playlist}")
HomeFragmentDirections.exportPlaylist(decision.playlist.uid)
}
is PlaylistDecision.Delete -> {
T.d("Deleting ${decision.playlist}")
L.d("Deleting ${decision.playlist}")
HomeFragmentDirections.deletePlaylist(decision.playlist.uid)
}
is PlaylistDecision.Add -> {
T.d("Adding ${decision.songs.size} to a playlist")
L.d("Adding ${decision.songs.size} to a playlist")
HomeFragmentDirections.addToPlaylist(
decision.songs.map { it.uid }.toTypedArray())
}
@ -475,38 +475,38 @@ class HomeFragment :
private fun handleShow(show: Show?) {
when (show) {
is Show.SongDetails -> {
T.d("Navigating to ${show.song}")
L.d("Navigating to ${show.song}")
findNavController().navigateSafe(HomeFragmentDirections.showSong(show.song.uid))
}
is Show.SongAlbumDetails -> {
T.d("Navigating to the album of ${show.song}")
L.d("Navigating to the album of ${show.song}")
findNavController()
.navigateSafe(HomeFragmentDirections.showAlbum(show.song.album.uid))
}
is Show.AlbumDetails -> {
T.d("Navigating to ${show.album}")
L.d("Navigating to ${show.album}")
findNavController().navigateSafe(HomeFragmentDirections.showAlbum(show.album.uid))
}
is Show.ArtistDetails -> {
T.d("Navigating to ${show.artist}")
L.d("Navigating to ${show.artist}")
findNavController().navigateSafe(HomeFragmentDirections.showArtist(show.artist.uid))
}
is Show.SongArtistDecision -> {
T.d("Navigating to artist choices for ${show.song}")
L.d("Navigating to artist choices for ${show.song}")
findNavController()
.navigateSafe(HomeFragmentDirections.showArtistChoices(show.song.uid))
}
is Show.AlbumArtistDecision -> {
T.d("Navigating to artist choices for ${show.album}")
L.d("Navigating to artist choices for ${show.album}")
findNavController()
.navigateSafe(HomeFragmentDirections.showArtistChoices(show.album.uid))
}
is Show.GenreDetails -> {
T.d("Navigating to ${show.genre}")
L.d("Navigating to ${show.genre}")
findNavController().navigateSafe(HomeFragmentDirections.showGenre(show.genre.uid))
}
is Show.PlaylistDetails -> {
T.d("Navigating to ${show.playlist}")
L.d("Navigating to ${show.playlist}")
findNavController()
.navigateSafe(HomeFragmentDirections.showPlaylist(show.playlist.uid))
}
@ -534,7 +534,7 @@ class HomeFragment :
binding.homeSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
if (binding.homeToolbar.setVisible(R.id.home_selection_toolbar)) {
// New selection started, show the AppBarLayout to indicate the new state.
T.d("Significant selection occurred, expanding AppBar")
L.d("Significant selection occurred, expanding AppBar")
binding.homeAppbar.expandWithScrollingRecycler()
}
} else {

View file

@ -29,7 +29,7 @@ import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicType
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import timber.log.Timber as T
import timber.log.Timber as L
interface HomeGenerator {
fun attach()
@ -89,7 +89,7 @@ private class HomeGeneratorImpl(
override fun onHideCollaboratorsChanged() {
// Changes in the hide collaborator setting will change the artist contents
// of the library, consider it a library update.
T.d("Collaborator setting changed, forwarding update")
L.d("Collaborator setting changed, forwarding update")
onMusicChanges(MusicRepository.Changes(deviceLibrary = true, userLibrary = false))
}
@ -121,7 +121,7 @@ private class HomeGeneratorImpl(
override fun onMusicChanges(changes: MusicRepository.Changes) {
val deviceLibrary = musicRepository.deviceLibrary
if (changes.deviceLibrary && deviceLibrary != null) {
T.d("Refreshing library")
L.d("Refreshing library")
// Get the each list of items in the library to use as our list data.
// Applying the preferred sorting to them.
invalidator.invalidateMusic(MusicType.SONGS, UpdateInstructions.Diff)
@ -132,7 +132,7 @@ private class HomeGeneratorImpl(
val userLibrary = musicRepository.userLibrary
if (changes.userLibrary && userLibrary != null) {
T.d("Refreshing playlists")
L.d("Refreshing playlists")
invalidator.invalidateMusic(MusicType.PLAYLISTS, UpdateInstructions.Diff)
}
}

View file

@ -27,7 +27,7 @@ import org.oxycblt.auxio.home.tabs.Tab
import org.oxycblt.auxio.music.MusicType
import org.oxycblt.auxio.settings.Settings
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* User configuration specific to the home UI.
@ -68,17 +68,17 @@ class HomeSettingsImpl @Inject constructor(@ApplicationContext context: Context)
override fun migrate() {
if (sharedPreferences.contains(OLD_KEY_LIB_TABS)) {
T.d("Migrating tab setting")
L.d("Migrating tab setting")
val oldTabs =
Tab.fromIntCode(sharedPreferences.getInt(OLD_KEY_LIB_TABS, Tab.SEQUENCE_DEFAULT))
?: unlikelyToBeNull(Tab.fromIntCode(Tab.SEQUENCE_DEFAULT))
T.d("Old tabs: $oldTabs")
L.d("Old tabs: $oldTabs")
// The playlist tab is now parsed, but it needs to be made visible.
val playlistIndex = oldTabs.indexOfFirst { it.type == MusicType.PLAYLISTS }
check(playlistIndex > -1) // This should exist, otherwise we are in big trouble
oldTabs[playlistIndex] = Tab.Visible(MusicType.PLAYLISTS)
T.d("New tabs: $oldTabs")
L.d("New tabs: $oldTabs")
sharedPreferences.edit {
putInt(getString(R.string.set_key_home_tabs), Tab.toIntCode(oldTabs))
@ -90,11 +90,11 @@ class HomeSettingsImpl @Inject constructor(@ApplicationContext context: Context)
override fun onSettingChanged(key: String, listener: HomeSettings.Listener) {
when (key) {
getString(R.string.set_key_home_tabs) -> {
T.d("Dispatching tab setting change")
L.d("Dispatching tab setting change")
listener.onTabsChanged()
}
getString(R.string.set_key_hide_collaborators) -> {
T.d("Dispatching collaborator setting change")
L.d("Dispatching collaborator setting change")
listener.onHideCollaboratorsChanged()
}
}

View file

@ -37,7 +37,7 @@ import org.oxycblt.auxio.playback.PlaySong
import org.oxycblt.auxio.playback.PlaybackSettings
import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent
import timber.log.Timber as T
import timber.log.Timber as L
/**
* The ViewModel for managing the tab data and lists of the home view.
@ -249,7 +249,7 @@ constructor(
* @param pagerPos The new position of the ViewPager2 instance.
*/
fun synchronizeTabPosition(pagerPos: Int) {
T.d("Updating current tab to ${currentTabTypes[pagerPos]}")
L.d("Updating current tab to ${currentTabTypes[pagerPos]}")
_currentTabType.value = currentTabTypes[pagerPos]
}
@ -259,7 +259,7 @@ constructor(
* @param isFastScrolling true if the user is currently fast scrolling, false otherwise.
*/
fun setFastScrolling(isFastScrolling: Boolean) {
T.d("Updating fast scrolling state: $isFastScrolling")
L.d("Updating fast scrolling state: $isFastScrolling")
_isFastScrolling.value = isFastScrolling
}

View file

@ -39,9 +39,6 @@ import androidx.core.os.BundleCompat
import androidx.core.view.setMargins
import androidx.core.view.updateLayoutParams
import androidx.core.widget.TextViewCompat
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.google.android.material.R as MR
import com.google.android.material.motion.MotionUtils
import com.google.android.material.shape.MaterialShapeDrawable
import com.leinardi.android.speeddial.FabWithLabelView
import com.leinardi.android.speeddial.SpeedDialActionItem
@ -49,6 +46,7 @@ import com.leinardi.android.speeddial.SpeedDialView
import kotlin.math.roundToInt
import kotlinx.parcelize.Parcelize
import org.oxycblt.auxio.R
import org.oxycblt.auxio.ui.StationaryAnim
import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.getDimen
import org.oxycblt.auxio.util.getDimenPixels
@ -80,12 +78,7 @@ class ThemedSpeedDialView : SpeedDialView {
@AttrRes defStyleAttr: Int
) : super(context, attrs, defStyleAttr)
private val matInterpolator =
MotionUtils.resolveThemeInterpolator(
context, MR.attr.motionEasingStandardInterpolator, FastOutSlowInInterpolator())
private val matDuration =
MotionUtils.resolveThemeDuration(context, MR.attr.motionDurationMedium2, 350)
private val inAnim = StationaryAnim.forMediumComponent(context)
init {
// Work around ripple bug on Android 12 when useCompatPadding = true.
@ -149,7 +142,7 @@ class ThemedSpeedDialView : SpeedDialView {
}
private fun createMainFabAnimator(isOpen: Boolean): Animator {
val totalDuration = matDuration.toLong()
val totalDuration = inAnim.duration
val partialDuration = totalDuration / 2 // This is half of the total duration
val delay = totalDuration / 4 // This is one fourth of the total duration
@ -181,7 +174,7 @@ class ThemedSpeedDialView : SpeedDialView {
val animatorSet =
AnimatorSet().apply {
playTogether(backgroundTintAnimator, imageTintAnimator, levelAnimator)
interpolator = matInterpolator
interpolator = inAnim.interpolator
}
animatorSet.start()
return animatorSet

View file

@ -31,15 +31,14 @@ import android.view.WindowInsets
import android.widget.FrameLayout
import androidx.annotation.AttrRes
import androidx.core.view.isInvisible
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.R as MR
import com.google.android.material.motion.MotionUtils
import kotlin.math.abs
import org.oxycblt.auxio.R
import org.oxycblt.auxio.list.recycler.AuxioRecyclerView
import org.oxycblt.auxio.ui.InAnim
import org.oxycblt.auxio.ui.OutAnim
import org.oxycblt.auxio.util.getDimenPixels
import org.oxycblt.auxio.util.getDrawableCompat
import org.oxycblt.auxio.util.isRtl
@ -85,23 +84,8 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
background = context.getDrawableCompat(R.drawable.ui_scroll_thumb)
}
private val thumbEnterInterpolator =
MotionUtils.resolveThemeInterpolator(
context,
MR.attr.motionEasingEmphasizedDecelerateInterpolator,
FastOutSlowInInterpolator())
private val thumbEnterDuration =
MotionUtils.resolveThemeDuration(context, MR.attr.motionDurationShort4, 300)
private val thumbExitInterpolator =
MotionUtils.resolveThemeInterpolator(
context,
MR.attr.motionEasingEmphasizedAccelerateInterpolator,
FastOutSlowInInterpolator())
private val thumbExitDuration =
MotionUtils.resolveThemeDuration(context, MR.attr.motionDurationShort2, 100)
private val thumbEnter = InAnim.forSmallComponent(context)
private val thumbExit = OutAnim.forSmallComponent(context)
private val thumbWidth = thumbView.background.intrinsicWidth
private val thumbHeight = thumbView.background.intrinsicHeight
@ -130,23 +114,8 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
}
}
private val popupEnterInterpolator =
MotionUtils.resolveThemeInterpolator(
context,
MR.attr.motionEasingEmphasizedDecelerateInterpolator,
FastOutSlowInInterpolator())
private val popupEnterDuration =
MotionUtils.resolveThemeDuration(context, MR.attr.motionDurationMedium1, 300)
private val popupExitInterpolator =
MotionUtils.resolveThemeInterpolator(
context,
MR.attr.motionEasingEmphasizedAccelerateInterpolator,
FastOutSlowInInterpolator())
private val popupExitDuration =
MotionUtils.resolveThemeDuration(context, MR.attr.motionDurationShort2, 100)
private val popupEnter = InAnim.forSmallComponent(context)
private val popupExit = OutAnim.forSmallComponent(context)
private var showingPopup = false
@ -460,8 +429,8 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
thumbView
.animate()
.scaleX(1f)
.setInterpolator(thumbEnterInterpolator)
.setDuration(thumbEnterDuration.toLong())
.setInterpolator(thumbEnter.interpolator)
.setDuration(thumbEnter.duration)
.start()
}
@ -474,8 +443,8 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
thumbView
.animate()
.scaleX(0f)
.setInterpolator(thumbExitInterpolator)
.setDuration(thumbExitDuration.toLong())
.setInterpolator(thumbExit.interpolator)
.setDuration(thumbExit.duration)
.start()
}
@ -493,8 +462,8 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
.animate()
.scaleX(1f)
.scaleY(1f)
.setInterpolator(popupEnterInterpolator)
.setDuration(popupEnterDuration.toLong())
.setInterpolator(popupEnter.interpolator)
.setDuration(popupEnter.duration)
.start()
}
@ -509,8 +478,8 @@ constructor(context: Context, attrs: AttributeSet? = null, @AttrRes defStyleAttr
.alpha(0f)
.scaleX(0.75f)
.scaleY(0.75f)
.setInterpolator(popupExitInterpolator)
.setDuration(popupExitDuration.toLong())
.setInterpolator(popupExit.interpolator)
.setDuration(popupExit.duration)
.start()
}

View file

@ -19,7 +19,7 @@
package org.oxycblt.auxio.home.tabs
import org.oxycblt.auxio.music.MusicType
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A representation of a library tab suitable for configuration.
@ -85,7 +85,7 @@ sealed class Tab(open val type: MusicType) {
// Like when deserializing, make sure there are no duplicate tabs for whatever reason.
val distinct = tabs.distinctBy { it.type }
if (tabs.size != distinct.size) {
T.w(
L.w(
"Tab sequences should not have duplicates [old: ${tabs.size} new: ${distinct.size}]")
}
@ -132,13 +132,13 @@ sealed class Tab(open val type: MusicType) {
// Make sure there are no duplicate tabs
val distinct = tabs.distinctBy { it.type }
if (tabs.size != distinct.size) {
T.w(
L.w(
"Tab sequences should not have duplicates [old: ${tabs.size} new: ${distinct.size}]")
}
// For safety, return null if we have an empty or larger-than-expected tab array.
if (distinct.isEmpty() || distinct.size < MAX_SEQUENCE_IDX) {
T.e("Sequence size was ${distinct.size}, which is invalid")
L.e("Sequence size was ${distinct.size}, which is invalid")
return null
}

View file

@ -28,7 +28,7 @@ import org.oxycblt.auxio.list.EditClickListListener
import org.oxycblt.auxio.list.recycler.DialogRecyclerView
import org.oxycblt.auxio.music.MusicType
import org.oxycblt.auxio.util.inflater
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [RecyclerView.Adapter] that displays an array of [Tab]s open for configuration.
@ -55,7 +55,7 @@ class TabAdapter(private val listener: EditClickListListener<Tab>) :
* @param newTabs The new array of tabs to show.
*/
fun submitTabs(newTabs: Array<Tab>) {
T.d("Force-updating tab information")
L.d("Force-updating tab information")
tabs = newTabs
@Suppress("NotifyDatasetChanged") notifyDataSetChanged()
}
@ -67,7 +67,7 @@ class TabAdapter(private val listener: EditClickListListener<Tab>) :
* @param tab The new tab.
*/
fun setTab(at: Int, tab: Tab) {
T.d("Updating tab [at: $at, tab: $tab]")
L.d("Updating tab [at: $at, tab: $tab]")
tabs[at] = tab
// Use a payload to avoid an item change animation.
notifyItemChanged(at, PAYLOAD_TAB_CHANGED)
@ -80,7 +80,7 @@ class TabAdapter(private val listener: EditClickListListener<Tab>) :
* @param b The position of the second tab to swap.
*/
fun swapTabs(a: Int, b: Int) {
T.d("Swapping tabs [a: $a, b: $b]")
L.d("Swapping tabs [a: $a, b: $b]")
val tmp = tabs[b]
tabs[b] = tabs[a]
tabs[a] = tmp

View file

@ -31,7 +31,7 @@ import org.oxycblt.auxio.databinding.DialogTabsBinding
import org.oxycblt.auxio.home.HomeSettings
import org.oxycblt.auxio.list.EditClickListListener
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewBindingMaterialDialogFragment] that allows the user to modify the home [Tab]
@ -52,7 +52,7 @@ class TabCustomizeDialog :
builder
.setTitle(R.string.set_lib_tabs)
.setPositiveButton(R.string.lbl_ok) { _, _ ->
T.d("Committing tab changes")
L.d("Committing tab changes")
homeSettings.homeTabs = tabAdapter.tabs
}
.setNegativeButton(R.string.lbl_cancel, null)
@ -99,7 +99,7 @@ class TabCustomizeDialog :
is Tab.Visible -> Tab.Invisible(old.type)
is Tab.Invisible -> Tab.Visible(old.type)
}
T.d("Flipping tab visibility [from: $old to: $new]")
L.d("Flipping tab visibility [from: $old to: $new]")
tabAdapter.setTab(index, new)
// Prevent the user from saving if all the tabs are Invisible, as that's an invalid state.

View file

@ -24,7 +24,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.Settings
import timber.log.Timber as T
import timber.log.Timber as L
/**
* User configuration specific to image loading.
@ -58,7 +58,7 @@ class ImageSettingsImpl @Inject constructor(@ApplicationContext context: Context
// Show album covers and Ignore MediaStore covers were unified in 3.0.0
if (sharedPreferences.contains(OLD_KEY_SHOW_COVERS) ||
sharedPreferences.contains(OLD_KEY_QUALITY_COVERS)) {
T.d("Migrating cover settings")
L.d("Migrating cover settings")
val mode =
when {
@ -79,7 +79,7 @@ class ImageSettingsImpl @Inject constructor(@ApplicationContext context: Context
override fun onSettingChanged(key: String, listener: ImageSettings.Listener) {
if (key == getString(R.string.set_key_cover_mode) ||
key == getString(R.string.set_key_square_covers)) {
T.d("Dispatching image setting change")
L.d("Dispatching image setting change")
listener.onImageSettingsChanged()
}
}

View file

@ -53,7 +53,7 @@ import okio.source
import org.oxycblt.auxio.image.CoverMode
import org.oxycblt.auxio.image.ImageSettings
import org.oxycblt.auxio.music.Song
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Provides functionality for extracting album cover information. Meant for internal use only.
@ -153,13 +153,14 @@ constructor(
}
}
} catch (e: Exception) {
T.e("Unable to extract album cover due to an error: $e")
L.e("Unable to extract album cover due to an error: $e")
null
}
private suspend fun extractQualityCover(cover: Cover.Embedded) =
extractExoplayerCover(cover)
?: extractAospMetadataCover(cover) ?: extractMediaStoreCover(cover)
?: extractAospMetadataCover(cover)
?: extractMediaStoreCover(cover)
private fun extractAospMetadataCover(cover: Cover.Embedded): InputStream? =
MediaMetadataRetriever().run {

View file

@ -36,7 +36,7 @@ import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaySong
import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewModel] that orchestrates menu dialogs and selection state.
@ -93,16 +93,16 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
*/
fun select(music: Music) {
if (music is MusicParent && music.songs.isEmpty()) {
T.d("Cannot select empty parent, ignoring operation")
L.d("Cannot select empty parent, ignoring operation")
return
}
val selected = _selected.value.toMutableList()
if (!selected.remove(music)) {
T.d("Adding $music to selection")
L.d("Adding $music to selection")
selected.add(music)
} else {
T.d("Removed $music from selection")
L.d("Removed $music from selection")
}
_selected.value = selected
@ -130,7 +130,7 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
* @return A list of [Song]s collated from each item selected.
*/
fun takeSelection(): List<Song> {
T.d("Taking selection")
L.d("Taking selection")
return peekSelection().also { _selected.value = listOf() }
}
@ -140,7 +140,7 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
* @return true if the prior selection was non-empty, false otherwise.
*/
fun dropSelection(): Boolean {
T.d("Dropping selection [empty=${_selected.value.isEmpty()}]")
L.d("Dropping selection [empty=${_selected.value.isEmpty()}]")
return _selected.value.isNotEmpty().also { _selected.value = listOf() }
}
@ -154,7 +154,7 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
* should do.
*/
fun openMenu(@MenuRes menuRes: Int, song: Song, playWith: PlaySong) {
T.d("Opening menu for $song")
L.d("Opening menu for $song")
openImpl(Menu.ForSong(menuRes, song, playWith))
}
@ -166,7 +166,7 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
* @param album The [Album] to show.
*/
fun openMenu(@MenuRes menuRes: Int, album: Album) {
T.d("Opening menu for $album")
L.d("Opening menu for $album")
openImpl(Menu.ForAlbum(menuRes, album))
}
@ -178,7 +178,7 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
* @param artist The [Artist] to show.
*/
fun openMenu(@MenuRes menuRes: Int, artist: Artist) {
T.d("Opening menu for $artist")
L.d("Opening menu for $artist")
openImpl(Menu.ForArtist(menuRes, artist))
}
@ -190,7 +190,7 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
* @param genre The [Genre] to show.
*/
fun openMenu(@MenuRes menuRes: Int, genre: Genre) {
T.d("Opening menu for $genre")
L.d("Opening menu for $genre")
openImpl(Menu.ForGenre(menuRes, genre))
}
@ -202,7 +202,7 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
* @param playlist The [Playlist] to show.
*/
fun openMenu(@MenuRes menuRes: Int, playlist: Playlist) {
T.d("Opening menu for $playlist")
L.d("Opening menu for $playlist")
openImpl(Menu.ForPlaylist(menuRes, playlist))
}
@ -214,14 +214,14 @@ constructor(private val listSettings: ListSettings, private val musicRepository:
* @param songs The [Song] selection to show.
*/
fun openMenu(@MenuRes menuRes: Int, songs: List<Song>) {
T.d("Opening menu for ${songs.size} songs")
L.d("Opening menu for ${songs.size} songs")
openImpl(Menu.ForSelection(menuRes, songs))
}
private fun openImpl(menu: Menu) {
val existing = _menu.flow.value
if (existing != null) {
T.w("Already opening $existing, ignoring $menu")
L.w("Already opening $existing, ignoring $menu")
return
}
_menu.put(menu)

View file

@ -25,6 +25,7 @@ import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import java.util.concurrent.Executor
import timber.log.Timber as L
/**
* A variant of ListDiffer with more flexible updates.
@ -56,7 +57,7 @@ abstract class FlexibleListAdapter<T, VH : RecyclerView.ViewHolder>(
instructions: UpdateInstructions?,
callback: (() -> Unit)? = null
) {
T.d("Updating list to ${newList.size} items with $instructions")
L.d("Updating list to ${newList.size} items with $instructions")
differ.update(newList, instructions, callback)
}
}
@ -170,7 +171,7 @@ private class FlexibleListDiffer<T>(
) {
// fast simple remove all
if (newList.isEmpty()) {
T.d("Short-circuiting diff to remove all")
L.d("Short-circuiting diff to remove all")
val countRemoved = oldList.size
currentList = emptyList()
// notify last, after list is updated
@ -181,7 +182,7 @@ private class FlexibleListDiffer<T>(
// fast simple first insert
if (oldList.isEmpty()) {
T.d("Short-circuiting diff to insert all")
L.d("Short-circuiting diff to insert all")
currentList = newList
// notify last, after list is updated
updateCallback.onInserted(0, newList.size)
@ -243,7 +244,7 @@ private class FlexibleListDiffer<T>(
mainThreadExecutor.execute {
if (maxScheduledGeneration == runGeneration) {
T.d("Applying calculated diff")
L.d("Applying calculated diff")
currentList = newList
result.dispatchUpdatesTo(updateCallback)
callback?.invoke()

View file

@ -21,6 +21,7 @@ package org.oxycblt.auxio.list.adapter
import android.view.View
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import timber.log.Timber as L
/**
* A [RecyclerView.Adapter] that supports indicating the playback status of a particular item.
@ -57,7 +58,7 @@ abstract class PlayingIndicatorAdapter<T, VH : RecyclerView.ViewHolder>(
* @param isPlaying Whether playback is ongoing or paused.
*/
fun setPlaying(item: T?, isPlaying: Boolean) {
T.d("Updating playing item [old: $currentItem new: $item]")
L.d("Updating playing item [old: $currentItem new: $item]")
var updatedItem = false
if (currentItem != item) {
@ -70,7 +71,7 @@ abstract class PlayingIndicatorAdapter<T, VH : RecyclerView.ViewHolder>(
if (pos > -1) {
notifyItemChanged(pos, PAYLOAD_PLAYING_INDICATOR_CHANGED)
} else {
T.w("oldItem was not in adapter data")
L.w("oldItem was not in adapter data")
}
}
@ -80,7 +81,7 @@ abstract class PlayingIndicatorAdapter<T, VH : RecyclerView.ViewHolder>(
if (pos > -1) {
notifyItemChanged(pos, PAYLOAD_PLAYING_INDICATOR_CHANGED)
} else {
T.w("newItem was not in adapter data")
L.w("newItem was not in adapter data")
}
}
@ -98,7 +99,7 @@ abstract class PlayingIndicatorAdapter<T, VH : RecyclerView.ViewHolder>(
if (pos > -1) {
notifyItemChanged(pos, PAYLOAD_PLAYING_INDICATOR_CHANGED)
} else {
T.w("newItem was not in adapter data")
L.w("newItem was not in adapter data")
}
}
}

View file

@ -22,6 +22,7 @@ import android.view.View
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.music.Music
import timber.log.Timber as L
/**
* A [PlayingIndicatorAdapter] that also supports indicating the selection status of a group of
@ -54,7 +55,7 @@ abstract class SelectionIndicatorAdapter<T, VH : RecyclerView.ViewHolder>(
// Nothing to do.
return
}
T.d("Updating selection [old=${oldSelectedItems.size} new=${newSelectedItems.size}")
L.d("Updating selection [old=${oldSelectedItems.size} new=${newSelectedItems.size}")
selectedItems = newSelectedItems
for (i in currentList.indices) {

View file

@ -33,7 +33,7 @@ import org.oxycblt.auxio.list.ListViewModel
import org.oxycblt.auxio.list.adapter.UpdateInstructions
import org.oxycblt.auxio.ui.ViewBindingBottomSheetDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewBindingBottomSheetDialogFragment] that displays basic music information and a series of
@ -102,7 +102,7 @@ abstract class MenuDialogFragment<M : Menu> :
private fun updateMenu(menu: Menu?) {
if (menu == null) {
T.d("No menu to show, navigating away")
L.d("No menu to show, navigating away")
findNavController().navigateUp()
return
}

View file

@ -26,7 +26,7 @@ import kotlinx.coroutines.flow.StateFlow
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.playback.PlaySong
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Manages the state information for [MenuDialogFragment] implementations.
@ -55,7 +55,7 @@ class MenuViewModel @Inject constructor(private val musicRepository: MusicReposi
fun setMenu(parcel: Menu.Parcel) {
_currentMenu.value = unpackParcel(parcel)
if (_currentMenu.value == null) {
T.w("Given menu parcel $parcel was invalid")
L.w("Given menu parcel $parcel was invalid")
}
}

View file

@ -34,7 +34,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.list.recycler.MaterialDragCallback.ViewHolder
import org.oxycblt.auxio.util.getDimen
import org.oxycblt.auxio.util.getInteger
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A highly customized [ItemTouchHelper.Callback] that enables some extra eye candy in editable UIs,
@ -94,7 +94,7 @@ abstract class MaterialDragCallback : ItemTouchHelper.Callback() {
// this is only done once when the item is initially picked up.
// TODO: I think this is possible to improve with a raw ValueAnimator.
if (shouldLift && isCurrentlyActive && actionState == ItemTouchHelper.ACTION_STATE_DRAG) {
T.d("Lifting ViewHolder")
L.d("Lifting ViewHolder")
val bg = holder.background
val elevation = recyclerView.context.getDimen(MR.dimen.m3_sys_elevation_level4)
@ -136,7 +136,7 @@ abstract class MaterialDragCallback : ItemTouchHelper.Callback() {
// This function can be called multiple times, so only start the animation when the view's
// translationZ is already non-zero.
if (holder.root.translationZ != 0f) {
T.d("Lifting ViewHolder")
L.d("Lifting ViewHolder")
val bg = holder.background
val elevation = recyclerView.context.getDimen(MR.dimen.m3_sys_elevation_level4)

View file

@ -22,6 +22,9 @@ import android.content.Context
import android.net.Uri
import android.os.Parcelable
import androidx.room.TypeConverter
import java.security.MessageDigest
import java.util.UUID
import kotlin.math.max
import kotlinx.parcelize.IgnoredOnParcel
import kotlinx.parcelize.Parcelize
import org.oxycblt.auxio.image.extractor.Cover
@ -36,9 +39,6 @@ import org.oxycblt.auxio.music.info.ReleaseType
import org.oxycblt.auxio.playback.replaygain.ReplayGainAdjustment
import org.oxycblt.auxio.util.concatLocalized
import org.oxycblt.auxio.util.toUuidOrNull
import java.security.MessageDigest
import java.util.UUID
import kotlin.math.max
/**
* Abstract music data. This contains universal information about all concrete music

View file

@ -44,7 +44,7 @@ import org.oxycblt.auxio.music.user.MutableUserLibrary
import org.oxycblt.auxio.music.user.UserLibrary
import org.oxycblt.auxio.util.DEFAULT_TIMEOUT
import org.oxycblt.auxio.util.forEachWithTimeout
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Primary manager of music information and loading.
@ -242,51 +242,51 @@ constructor(
@Synchronized
override fun addUpdateListener(listener: MusicRepository.UpdateListener) {
T.d("Adding $listener to update listeners")
L.d("Adding $listener to update listeners")
updateListeners.add(listener)
listener.onMusicChanges(MusicRepository.Changes(deviceLibrary = true, userLibrary = true))
}
@Synchronized
override fun removeUpdateListener(listener: MusicRepository.UpdateListener) {
T.d("Removing $listener to update listeners")
L.d("Removing $listener to update listeners")
if (!updateListeners.remove(listener)) {
T.w("Update listener $listener was not added prior, cannot remove")
L.w("Update listener $listener was not added prior, cannot remove")
}
}
@Synchronized
override fun addIndexingListener(listener: MusicRepository.IndexingListener) {
T.d("Adding $listener to indexing listeners")
L.d("Adding $listener to indexing listeners")
indexingListeners.add(listener)
listener.onIndexingStateChanged()
}
@Synchronized
override fun removeIndexingListener(listener: MusicRepository.IndexingListener) {
T.d("Removing $listener from indexing listeners")
L.d("Removing $listener from indexing listeners")
if (!indexingListeners.remove(listener)) {
T.w("Indexing listener $listener was not added prior, cannot remove")
L.w("Indexing listener $listener was not added prior, cannot remove")
}
}
@Synchronized
override fun registerWorker(worker: MusicRepository.IndexingWorker) {
if (indexingWorker != null) {
T.w("Worker is already registered")
L.w("Worker is already registered")
return
}
T.d("Registering worker $worker")
L.d("Registering worker $worker")
indexingWorker = worker
}
@Synchronized
override fun unregisterWorker(worker: MusicRepository.IndexingWorker) {
if (indexingWorker !== worker) {
T.w("Given worker did not match current worker")
L.w("Given worker did not match current worker")
return
}
T.d("Unregistering worker $worker")
L.d("Unregistering worker $worker")
indexingWorker = null
currentIndexingState = null
}
@ -298,42 +298,42 @@ constructor(
override suspend fun createPlaylist(name: String, songs: List<Song>) {
val userLibrary = synchronized(this) { userLibrary ?: return }
T.d("Creating playlist $name with ${songs.size} songs")
L.d("Creating playlist $name with ${songs.size} songs")
userLibrary.createPlaylist(name, songs)
withContext(Dispatchers.Main) { dispatchLibraryChange(device = false, user = true) }
}
override suspend fun renamePlaylist(playlist: Playlist, name: String) {
val userLibrary = synchronized(this) { userLibrary ?: return }
T.d("Renaming $playlist to $name")
L.d("Renaming $playlist to $name")
userLibrary.renamePlaylist(playlist, name)
withContext(Dispatchers.Main) { dispatchLibraryChange(device = false, user = true) }
}
override suspend fun deletePlaylist(playlist: Playlist) {
val userLibrary = synchronized(this) { userLibrary ?: return }
T.d("Deleting $playlist")
L.d("Deleting $playlist")
userLibrary.deletePlaylist(playlist)
withContext(Dispatchers.Main) { dispatchLibraryChange(device = false, user = true) }
}
override suspend fun addToPlaylist(songs: List<Song>, playlist: Playlist) {
val userLibrary = synchronized(this) { userLibrary ?: return }
T.d("Adding ${songs.size} songs to $playlist")
L.d("Adding ${songs.size} songs to $playlist")
userLibrary.addToPlaylist(playlist, songs)
withContext(Dispatchers.Main) { dispatchLibraryChange(device = false, user = true) }
}
override suspend fun rewritePlaylist(playlist: Playlist, songs: List<Song>) {
val userLibrary = synchronized(this) { userLibrary ?: return }
T.d("Rewriting $playlist with ${songs.size} songs")
L.d("Rewriting $playlist with ${songs.size} songs")
userLibrary.rewritePlaylist(playlist, songs)
withContext(Dispatchers.Main) { dispatchLibraryChange(device = false, user = true) }
}
@Synchronized
override fun requestIndex(withCache: Boolean) {
T.d("Requesting index operation [cache=$withCache]")
L.d("Requesting index operation [cache=$withCache]")
indexingWorker?.requestIndex(withCache)
}
@ -345,13 +345,13 @@ constructor(
indexImpl(context, scope, withCache)
} catch (e: CancellationException) {
// Got cancelled, propagate upwards to top-level co-routine.
T.d("Loading routine was cancelled")
L.d("Loading routine was cancelled")
throw e
} catch (e: Exception) {
// Music loading process failed due to something we have not handled.
// TODO: Still want to display this error eventually
T.e("Music indexing failed")
T.e(e.stackTraceToString())
L.e("Music indexing failed")
L.e(e.stackTraceToString())
emitIndexingCompletion(e)
}
}
@ -364,7 +364,7 @@ constructor(
// done at the UI level, but that intertwines logic and display too much.
if (ContextCompat.checkSelfPermission(context, PERMISSION_READ_AUDIO) ==
PackageManager.PERMISSION_DENIED) {
T.e("Permissions were not granted")
L.e("Permissions were not granted")
throw NoAudioPermissionException()
}
@ -383,7 +383,7 @@ constructor(
// to figure out what songs are (probably) on the device, and the latter will be needed
// for discovery (described later). These have no shared state, so they are done in
// parallel.
T.d("Starting MediaStore query")
L.d("Starting MediaStore query")
emitIndexingProgress(IndexingProgress.Indeterminate)
val mediaStoreQueryJob =
@ -404,18 +404,18 @@ constructor(
// identical to calling async.
val cache =
if (withCache) {
T.d("Reading cache")
L.d("Reading cache")
cacheRepository.readCache()
} else {
null
}
T.d("Awaiting MediaStore query")
L.d("Awaiting MediaStore query")
val query = mediaStoreQueryJob.await().getOrThrow()
// We now have all the information required to start the "discovery" process. This
// is the point at which Auxio starts scanning each file given from MediaStore and
// transforming it into a music library. MediaStore normally
T.d("Starting discovery")
L.d("Starting discovery")
val incompleteSongs = Channel<RawSong>(Channel.UNLIMITED) // Not fully populated w/metadata
val completeSongs = Channel<RawSong>(Channel.UNLIMITED) // Populated with quality metadata
val processedSongs = Channel<RawSong>(Channel.UNLIMITED) // Transformed into SongImpl
@ -423,7 +423,7 @@ constructor(
// MediaStoreExtractor discovers all music on the device, and forwards them to either
// DeviceLibrary if cached metadata exists for it, or TagExtractor if cached metadata
// does not exist. In the latter situation, it also applies it's own (inferior) metadata.
T.d("Starting MediaStore discovery")
L.d("Starting MediaStore discovery")
val mediaStoreJob =
scope.async {
try {
@ -432,7 +432,7 @@ constructor(
// To prevent a deadlock, we want to close the channel with an exception
// to cascade to and cancel all other routines before finally bubbling up
// to the main extractor loop.
T.e("MediaStore extraction failed: $e")
L.e("MediaStore extraction failed: $e")
incompleteSongs.close(
Exception("MediaStore extraction failed: ${e.stackTraceToString()}"))
return@async
@ -442,13 +442,13 @@ constructor(
// TagExtractor takes the incomplete songs from MediaStoreExtractor, parses up-to-date
// metadata for them, and then forwards it to DeviceLibrary.
T.d("Starting tag extraction")
L.d("Starting tag extraction")
val tagJob =
scope.async {
try {
tagExtractor.consume(incompleteSongs, completeSongs)
} catch (e: Exception) {
T.e("Tag extraction failed: $e")
L.e("Tag extraction failed: $e")
completeSongs.close(
Exception("Tag extraction failed: ${e.stackTraceToString()}"))
return@async
@ -458,7 +458,7 @@ constructor(
// DeviceLibrary constructs music parent instances as song information is provided,
// and then forwards them to the primary loading loop.
T.d("Starting DeviceLibrary creation")
L.d("Starting DeviceLibrary creation")
val deviceLibraryJob =
scope.async(Dispatchers.Default) {
val deviceLibrary =
@ -466,7 +466,7 @@ constructor(
deviceLibraryFactory.create(
completeSongs, processedSongs, separators, nameFactory)
} catch (e: Exception) {
T.e("DeviceLibrary creation failed: $e")
L.e("DeviceLibrary creation failed: $e")
processedSongs.close(
Exception("DeviceLibrary creation failed: ${e.stackTraceToString()}"))
return@async Result.failure(e)
@ -497,14 +497,14 @@ constructor(
// that the short-circuit occurs so quickly as to break the UI.
// TODO: Do not error, instead just wipe the entire library.
if (rawSongs.isEmpty()) {
T.e("Music library was empty")
L.e("Music library was empty")
throw NoMusicException()
}
// Now that the library is effectively loaded, we can start the finalization step, which
// involves writing new cache information and creating more music data that is derived
// from the library (e.g playlists)
T.d("Discovered ${rawSongs.size} songs, starting finalization")
L.d("Discovered ${rawSongs.size} songs, starting finalization")
// We have no idea how long the cache will take, and the playlist construction
// will be too fast to indicate, so switch back to an indeterminate state.
@ -513,7 +513,7 @@ constructor(
// The UserLibrary job is split into a query and construction step, a la MediaStore.
// This way, we can start working on playlists even as DeviceLibrary might still be
// working on parent information.
T.d("Starting UserLibrary query")
L.d("Starting UserLibrary query")
val userLibraryQueryJob =
scope.async {
val rawPlaylists =
@ -530,20 +530,20 @@ constructor(
// since the playlist read will probably take some time.
// TODO: Read/write from the cache incrementally instead of in bulk?
if (cache == null || cache.invalidated) {
T.d("Writing cache [why=${cache?.invalidated}]")
L.d("Writing cache [why=${cache?.invalidated}]")
cacheRepository.writeCache(rawSongs)
}
// Create UserLibrary once we finally get the required components for it.
T.d("Awaiting UserLibrary query")
L.d("Awaiting UserLibrary query")
val rawPlaylists = userLibraryQueryJob.await().getOrThrow()
T.d("Awaiting DeviceLibrary creation")
L.d("Awaiting DeviceLibrary creation")
val deviceLibrary = deviceLibraryJob.await().getOrThrow()
T.d("Starting UserLibrary creation")
L.d("Starting UserLibrary creation")
val userLibrary = userLibraryFactory.create(rawPlaylists, deviceLibrary, nameFactory)
// Loading process is functionally done, indicate such
T.d(
L.d(
"Successfully indexed music library [device=$deviceLibrary " +
"user=$userLibrary time=${System.currentTimeMillis() - start}]")
emitIndexingCompletion(null)
@ -559,7 +559,7 @@ constructor(
deviceLibraryChanged = this.deviceLibrary != deviceLibrary
userLibraryChanged = this.userLibrary != userLibrary
if (!deviceLibraryChanged && !userLibraryChanged) {
T.d("Library has not changed, skipping update")
L.d("Library has not changed, skipping update")
return
}
@ -589,7 +589,7 @@ constructor(
synchronized(this) {
previousCompletedState = IndexingState.Completed(error)
currentIndexingState = null
T.d("Dispatching completion state [error=$error]")
L.d("Dispatching completion state [error=$error]")
for (listener in indexingListeners) {
listener.onIndexingStateChanged()
}
@ -599,7 +599,7 @@ constructor(
@Synchronized
private fun dispatchLibraryChange(device: Boolean, user: Boolean) {
val changes = MusicRepository.Changes(device, user)
T.d("Dispatching library change [changes=$changes]")
L.d("Dispatching library change [changes=$changes]")
for (listener in updateListeners) {
listener.onMusicChanges(changes)
}

View file

@ -26,7 +26,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.dirs.MusicDirectories
import org.oxycblt.auxio.music.fs.DocumentPathFactory
import org.oxycblt.auxio.settings.Settings
import timber.log.Timber as T
import timber.log.Timber as L
/**
* User configuration specific to music system.
@ -108,11 +108,11 @@ constructor(
getString(R.string.set_key_music_dirs_include),
getString(R.string.set_key_separators),
getString(R.string.set_key_auto_sort_names) -> {
T.d("Dispatching indexing setting change for $key")
L.d("Dispatching indexing setting change for $key")
listener.onIndexingSettingChanged()
}
getString(R.string.set_key_observing) -> {
T.d("Dispatching observing setting change")
L.d("Dispatching observing setting change")
listener.onObservingChanged()
}
}

View file

@ -33,7 +33,7 @@ import org.oxycblt.auxio.music.external.ExportConfig
import org.oxycblt.auxio.music.external.ExternalPlaylistManager
import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewModel] providing data specific to the music loading process.
@ -93,7 +93,7 @@ constructor(
deviceLibrary.artists.size,
deviceLibrary.genres.size,
deviceLibrary.songs.sumOf { it.durationMs })
T.d("Updated statistics: ${_statistics.value}")
L.d("Updated statistics: ${_statistics.value}")
}
override fun onIndexingStateChanged() {
@ -102,13 +102,13 @@ constructor(
/** Requests that the music library should be re-loaded while leveraging the cache. */
fun refresh() {
T.d("Refreshing library")
L.d("Refreshing library")
musicRepository.requestIndex(true)
}
/** Requests that the music library be re-loaded without the cache. */
fun rescan() {
T.d("Rescanning library")
L.d("Rescanning library")
musicRepository.requestIndex(false)
}
@ -126,7 +126,7 @@ constructor(
reason: PlaylistDecision.New.Reason = PlaylistDecision.New.Reason.NEW
) {
if (name != null) {
T.d("Creating $name with ${songs.size} songs]")
L.d("Creating $name with ${songs.size} songs]")
viewModelScope.launch(Dispatchers.IO) {
musicRepository.createPlaylist(name, songs)
val message =
@ -138,7 +138,7 @@ constructor(
_playlistMessage.put(message)
}
} else {
T.d("Launching creation dialog for ${songs.size} songs")
L.d("Launching creation dialog for ${songs.size} songs")
_playlistDecision.put(PlaylistDecision.New(songs, null, reason))
}
}
@ -157,7 +157,7 @@ constructor(
viewModelScope.launch(Dispatchers.IO) {
val importedPlaylist = externalPlaylistManager.import(uri)
if (importedPlaylist == null) {
T.e("Could not import playlist")
L.e("Could not import playlist")
_playlistMessage.put(PlaylistMessage.ImportFailed)
return@launch
}
@ -169,7 +169,7 @@ constructor(
}
if (songs.isEmpty()) {
T.e("No songs found")
L.e("No songs found")
_playlistMessage.put(PlaylistMessage.ImportFailed)
return@launch
}
@ -193,7 +193,7 @@ constructor(
}
}
} else {
T.d("Launching import picker")
L.d("Launching import picker")
_playlistDecision.put(PlaylistDecision.Import(target))
}
}
@ -206,7 +206,7 @@ constructor(
*/
fun exportPlaylist(playlist: Playlist, uri: Uri? = null, config: ExportConfig? = null) {
if (uri != null && config != null) {
T.d("Exporting playlist to $uri")
L.d("Exporting playlist to $uri")
viewModelScope.launch(Dispatchers.IO) {
if (externalPlaylistManager.export(playlist, uri, config)) {
_playlistMessage.put(PlaylistMessage.ExportSuccess)
@ -215,7 +215,7 @@ constructor(
}
}
} else {
T.d("Launching export dialog")
L.d("Launching export dialog")
_playlistDecision.put(PlaylistDecision.Export(playlist))
}
}
@ -237,7 +237,7 @@ constructor(
reason: PlaylistDecision.Rename.Reason = PlaylistDecision.Rename.Reason.ACTION
) {
if (name != null) {
T.d("Renaming $playlist to $name")
L.d("Renaming $playlist to $name")
viewModelScope.launch(Dispatchers.IO) {
musicRepository.renamePlaylist(playlist, name)
if (applySongs.isNotEmpty()) {
@ -251,7 +251,7 @@ constructor(
_playlistMessage.put(message)
}
} else {
T.d("Launching rename dialog for $playlist")
L.d("Launching rename dialog for $playlist")
_playlistDecision.put(PlaylistDecision.Rename(playlist, null, applySongs, reason))
}
}
@ -266,13 +266,13 @@ constructor(
*/
fun deletePlaylist(playlist: Playlist, rude: Boolean = false) {
if (rude) {
T.d("Deleting $playlist")
L.d("Deleting $playlist")
viewModelScope.launch(Dispatchers.IO) {
musicRepository.deletePlaylist(playlist)
_playlistMessage.put(PlaylistMessage.DeleteSuccess)
}
} else {
T.d("Launching deletion dialog for $playlist")
L.d("Launching deletion dialog for $playlist")
_playlistDecision.put(PlaylistDecision.Delete(playlist))
}
}
@ -284,7 +284,7 @@ constructor(
* @param playlist The [Playlist] to add to. If null, the user will be prompted for one.
*/
fun addToPlaylist(song: Song, playlist: Playlist? = null) {
T.d("Adding $song to playlist")
L.d("Adding $song to playlist")
addToPlaylist(listOf(song), playlist)
}
@ -295,7 +295,7 @@ constructor(
* @param playlist The [Playlist] to add to. If null, the user will be prompted for one.
*/
fun addToPlaylist(album: Album, playlist: Playlist? = null) {
T.d("Adding $album to playlist")
L.d("Adding $album to playlist")
addToPlaylist(listSettings.albumSongSort.songs(album.songs), playlist)
}
@ -306,7 +306,7 @@ constructor(
* @param playlist The [Playlist] to add to. If null, the user will be prompted for one.
*/
fun addToPlaylist(artist: Artist, playlist: Playlist? = null) {
T.d("Adding $artist to playlist")
L.d("Adding $artist to playlist")
addToPlaylist(listSettings.artistSongSort.songs(artist.songs), playlist)
}
@ -317,7 +317,7 @@ constructor(
* @param playlist The [Playlist] to add to. If null, the user will be prompted for one.
*/
fun addToPlaylist(genre: Genre, playlist: Playlist? = null) {
T.d("Adding $genre to playlist")
L.d("Adding $genre to playlist")
addToPlaylist(listSettings.genreSongSort.songs(genre.songs), playlist)
}
@ -329,13 +329,13 @@ constructor(
*/
fun addToPlaylist(songs: List<Song>, playlist: Playlist? = null) {
if (playlist != null) {
T.d("Adding ${songs.size} songs to $playlist")
L.d("Adding ${songs.size} songs to $playlist")
viewModelScope.launch(Dispatchers.IO) {
musicRepository.addToPlaylist(songs, playlist)
_playlistMessage.put(PlaylistMessage.AddSuccess)
}
} else {
T.d("Launching addition dialog for songs=${songs.size}")
L.d("Launching addition dialog for songs=${songs.size}")
_playlistDecision.put(PlaylistDecision.Add(songs))
}
}

View file

@ -20,7 +20,7 @@ package org.oxycblt.auxio.music.cache
import javax.inject.Inject
import org.oxycblt.auxio.music.device.RawSong
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A repository allowing access to cached metadata obtained in prior music loading operations.
@ -50,11 +50,11 @@ class CacheRepositoryImpl @Inject constructor(private val cachedSongsDao: Cached
// Faster to load the whole database into memory than do a query on each
// populate call.
val songs = cachedSongsDao.readSongs()
T.d("Successfully read ${songs.size} songs from cache")
L.d("Successfully read ${songs.size} songs from cache")
CacheImpl(songs)
} catch (e: Exception) {
T.e("Unable to load cache database.")
T.e(e.stackTraceToString())
L.e("Unable to load cache database.")
L.e(e.stackTraceToString())
null
}
@ -62,12 +62,12 @@ class CacheRepositoryImpl @Inject constructor(private val cachedSongsDao: Cached
try {
// Still write out whatever data was extracted.
cachedSongsDao.nukeSongs()
T.d("Successfully deleted old cache")
L.d("Successfully deleted old cache")
cachedSongsDao.insertSongs(rawSongs.map(CachedSong::fromRaw))
T.d("Successfully wrote ${rawSongs.size} songs to cache")
L.d("Successfully wrote ${rawSongs.size} songs to cache")
} catch (e: Exception) {
T.e("Unable to save cache database.")
T.e(e.stackTraceToString())
L.e("Unable to save cache database.")
L.e(e.stackTraceToString())
}
}
}

View file

@ -37,7 +37,7 @@ import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.navigateSafe
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A dialog that allows the user to pick a specific playlist to add song(s) to.
@ -105,7 +105,7 @@ class AddToPlaylistDialog :
private fun updatePendingSongs(songs: List<Song>?) {
if (songs == null) {
T.d("No songs to show choices for, navigating away")
L.d("No songs to show choices for, navigating away")
findNavController().navigateUp()
}
}

View file

@ -33,7 +33,7 @@ import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewBindingMaterialDialogFragment] that asks the user to confirm the deletion of a [Playlist].
@ -76,7 +76,7 @@ class DeletePlaylistDialog : ViewBindingMaterialDialogFragment<DialogDeletePlayl
private fun updatePlaylistToDelete(playlist: Playlist?) {
if (playlist == null) {
T.d("No playlist to delete, navigating away")
L.d("No playlist to delete, navigating away")
findNavController().navigateUp()
return
}

View file

@ -37,7 +37,7 @@ import org.oxycblt.auxio.music.external.M3U
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A dialog that allows the user to configure how a playlist will be exported to a file.
@ -72,18 +72,18 @@ class ExportPlaylistDialog : ViewBindingMaterialDialogFragment<DialogPlaylistExp
registerForActivityResult(ActivityResultContracts.CreateDocument(M3U.MIME_TYPE)) { uri
->
if (uri == null) {
T.w("No URI returned from file picker")
L.w("No URI returned from file picker")
return@registerForActivityResult
}
val playlist = pickerModel.currentPlaylistToExport.value
if (playlist == null) {
T.w("No playlist to export")
L.w("No playlist to export")
findNavController().navigateUp()
return@registerForActivityResult
}
T.d("Received playlist URI $uri")
L.d("Received playlist URI $uri")
musicModel.exportPlaylist(playlist, uri, pickerModel.currentExportConfig.value)
findNavController().navigateUp()
}
@ -128,7 +128,7 @@ class ExportPlaylistDialog : ViewBindingMaterialDialogFragment<DialogPlaylistExp
private fun updatePlaylistToExport(playlist: Playlist?) {
if (playlist == null) {
T.d("No playlist to export, leaving")
L.d("No playlist to export, leaving")
findNavController().navigateUp()
return
}

View file

@ -35,7 +35,7 @@ import org.oxycblt.auxio.music.PlaylistDecision
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A dialog allowing the name of a new playlist to be chosen before committing it to the database.
@ -98,7 +98,7 @@ class NewPlaylistDialog : ViewBindingMaterialDialogFragment<DialogPlaylistNameBi
private fun updatePendingPlaylist(pendingNewPlaylist: PendingNewPlaylist?) {
if (pendingNewPlaylist == null) {
T.d("No playlist to create, leaving")
L.d("No playlist to create, leaving")
findNavController().navigateUp()
return
}

View file

@ -33,7 +33,7 @@ import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.PlaylistDecision
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.external.ExportConfig
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewModel] managing the state of the playlist picker dialogs.
@ -99,7 +99,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
pendingPlaylist.template,
pendingPlaylist.reason)
}
T.d("Updated pending playlist: ${_currentPendingNewPlaylist.value?.preferredName}")
L.d("Updated pending playlist: ${_currentPendingNewPlaylist.value?.preferredName}")
_currentSongsToAdd.value =
_currentSongsToAdd.value?.let { pendingSongs ->
@ -108,7 +108,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
.ifEmpty { null }
.also { refreshChoicesWith = it }
}
T.d("Updated songs to add: ${_currentSongsToAdd.value?.size} songs")
L.d("Updated songs to add: ${_currentSongsToAdd.value?.size} songs")
}
val chosenName = _chosenName.value
@ -120,7 +120,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
// Nothing to do.
}
}
T.d("Updated chosen name to $chosenName")
L.d("Updated chosen name to $chosenName")
refreshChoicesWith = refreshChoicesWith ?: _currentSongsToAdd.value
// TODO: Add music syncing for other playlist states here
@ -129,7 +129,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
_currentPlaylistToExport.value?.let { playlist ->
musicRepository.userLibrary?.findPlaylist(playlist.uid)
}
T.d("Updated playlist to export to ${_currentPlaylistToExport.value}")
L.d("Updated playlist to export to ${_currentPlaylistToExport.value}")
}
refreshChoicesWith?.let(::refreshPlaylistChoices)
@ -152,7 +152,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
template: String?,
reason: PlaylistDecision.New.Reason
) {
T.d("Opening ${songUids.size} songs to create a playlist from")
L.d("Opening ${songUids.size} songs to create a playlist from")
val userLibrary = musicRepository.userLibrary ?: return
val songs =
musicRepository.deviceLibrary
@ -166,10 +166,10 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
var possibleName: String
do {
possibleName = context.getString(R.string.fmt_def_playlist, i)
T.d("Trying $possibleName as a playlist name")
L.d("Trying $possibleName as a playlist name")
++i
} while (userLibrary.playlists.any { it.name.resolve(context) == possibleName })
T.d("$possibleName is unique, using it as the playlist name")
L.d("$possibleName is unique, using it as the playlist name")
possibleName
}
@ -177,7 +177,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
if (possibleName != null && songs != null) {
PendingNewPlaylist(possibleName, songs, template, reason)
} else {
T.w("Given song UIDs to create were invalid")
L.w("Given song UIDs to create were invalid")
null
}
}
@ -193,7 +193,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
template: String?,
reason: PlaylistDecision.Rename.Reason
) {
T.d("Opening playlist $playlistUid to rename")
L.d("Opening playlist $playlistUid to rename")
val playlist = musicRepository.userLibrary?.findPlaylist(playlistUid)
val applySongs =
musicRepository.deviceLibrary?.let { applySongUids.mapNotNull(it::findSong) }
@ -202,7 +202,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
if (playlist != null && applySongs != null) {
PendingRenamePlaylist(playlist, applySongs, template, reason)
} else {
T.w("Given playlist UID to rename was invalid")
L.w("Given playlist UID to rename was invalid")
null
}
}
@ -213,12 +213,12 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
* @param playlistUid The [Music.UID] of the [Playlist] to export.
*/
fun setPlaylistToExport(playlistUid: Music.UID) {
T.d("Opening playlist $playlistUid to export")
L.d("Opening playlist $playlistUid to export")
// TODO: Add this guard to the rest of the methods here
if (_currentPlaylistToExport.value?.uid == playlistUid) return
_currentPlaylistToExport.value = musicRepository.userLibrary?.findPlaylist(playlistUid)
if (_currentPlaylistToExport.value == null) {
T.w("Given playlist UID to export was invalid")
L.w("Given playlist UID to export was invalid")
} else {
_currentExportConfig.value = DEFAULT_EXPORT_CONFIG
}
@ -230,7 +230,7 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
* @param exportConfig The new [ExportConfig] to use.
*/
fun setExportConfig(exportConfig: ExportConfig) {
T.d("Setting export config to $exportConfig")
L.d("Setting export config to $exportConfig")
_currentExportConfig.value = exportConfig
}
@ -240,10 +240,10 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
* @param playlistUid The [Music.UID] of the [Playlist] to delete.
*/
fun setPlaylistToDelete(playlistUid: Music.UID) {
T.d("Opening playlist $playlistUid to delete")
L.d("Opening playlist $playlistUid to delete")
_currentPlaylistToDelete.value = musicRepository.userLibrary?.findPlaylist(playlistUid)
if (_currentPlaylistToDelete.value == null) {
T.w("Given playlist UID to delete was invalid")
L.w("Given playlist UID to delete was invalid")
}
}
@ -253,25 +253,25 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
* @param name The new user-inputted name, or null if not present.
*/
fun updateChosenName(name: String?) {
T.d("Updating chosen name to $name")
L.d("Updating chosen name to $name")
_chosenName.value =
when {
name.isNullOrEmpty() -> {
T.e("Chosen name is empty")
L.e("Chosen name is empty")
ChosenName.Empty
}
name.isBlank() -> {
T.e("Chosen name is blank")
L.e("Chosen name is blank")
ChosenName.Blank
}
else -> {
val trimmed = name.trim()
val userLibrary = musicRepository.userLibrary
if (userLibrary != null && userLibrary.findPlaylist(trimmed) == null) {
T.d("Chosen name is valid")
L.d("Chosen name is valid")
ChosenName.Valid(trimmed)
} else {
T.d("Chosen name already exists in library")
L.d("Chosen name already exists in library")
ChosenName.AlreadyExists(trimmed)
}
}
@ -284,19 +284,19 @@ class PlaylistPickerViewModel @Inject constructor(private val musicRepository: M
* @param songUids The [Music.UID]s of songs to add to a playlist.
*/
fun setSongsToAdd(songUids: Array<Music.UID>) {
T.d("Opening ${songUids.size} songs to add to a playlist")
L.d("Opening ${songUids.size} songs to add to a playlist")
_currentSongsToAdd.value =
musicRepository.deviceLibrary
?.let { songUids.mapNotNull(it::findSong).ifEmpty { null } }
?.also(::refreshPlaylistChoices)
if (_currentSongsToAdd.value == null || songUids.size != _currentSongsToAdd.value?.size) {
T.w("Given song UIDs to add were (partially) invalid")
L.w("Given song UIDs to add were (partially) invalid")
}
}
private fun refreshPlaylistChoices(songs: List<Song>) {
val userLibrary = musicRepository.userLibrary ?: return
T.d("Refreshing playlist choices")
L.d("Refreshing playlist choices")
_playlistAddChoices.value =
Sort(Sort.Mode.ByName, Sort.Direction.ASCENDING).playlists(userLibrary.playlists).map {
val songSet = it.songs.toSet()

View file

@ -33,7 +33,7 @@ import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A dialog allowing the name of a new playlist to be chosen before committing it to the database.
@ -94,7 +94,7 @@ class RenamePlaylistDialog : ViewBindingMaterialDialogFragment<DialogPlaylistNam
val default =
pendingRenamePlaylist.template
?: pendingRenamePlaylist.playlist.name.resolve(requireContext())
T.d("Name input is not initialized, setting to $default")
L.d("Name input is not initialized, setting to $default")
requireBinding().playlistName.setText(default)
initializedField = true
}

View file

@ -37,7 +37,7 @@ import org.oxycblt.auxio.music.metadata.Separators
import org.oxycblt.auxio.util.forEachWithTimeout
import org.oxycblt.auxio.util.sendWithTimeout
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Organized music library information obtained from device storage.
@ -147,7 +147,7 @@ class DeviceLibraryFactoryImpl @Inject constructor() : DeviceLibrary.Factory {
// UID is sufficient for something like this, and also prevents collisions from
// causing severe issues elsewhere.
if (songGrouping.containsKey(song.uid)) {
T.w(
L.w(
"Duplicate song found: ${song.path} " +
"collides with ${unlikelyToBeNull(songGrouping[song.uid]).path}")
// We still want to say that we "processed" the song so that the user doesn't

View file

@ -125,8 +125,7 @@ class SongImpl(
.toSongCoverUri(),
uri,
it)
}
?: Cover.External(requireNotNull(rawSong.albumMediaStoreId).toAlbumCoverUri())
} ?: Cover.External(requireNotNull(rawSong.albumMediaStoreId).toAlbumCoverUri())
/**
* The [RawAlbum] instances collated by the [Song]. This can be used to group [Song]s into an

View file

@ -26,7 +26,7 @@ import org.oxycblt.auxio.list.recycler.DialogRecyclerView
import org.oxycblt.auxio.music.fs.Path
import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.inflater
import timber.log.Timber as T
import timber.log.Timber as L
/**
* [RecyclerView.Adapter] that manages a list of [Path] music directory instances.
@ -55,7 +55,7 @@ class DirectoryAdapter(private val listener: Listener) :
*/
fun add(path: Path) {
if (_dirs.contains(path)) return
T.d("Adding $path")
L.d("Adding $path")
_dirs.add(path)
notifyItemInserted(_dirs.lastIndex)
}
@ -66,7 +66,7 @@ class DirectoryAdapter(private val listener: Listener) :
* @param path The [Path] instances to add.
*/
fun addAll(path: List<Path>) {
T.d("Adding ${path.size} directories")
L.d("Adding ${path.size} directories")
val oldLastIndex = path.lastIndex
_dirs.addAll(path)
notifyItemRangeInserted(oldLastIndex, path.size)
@ -78,7 +78,7 @@ class DirectoryAdapter(private val listener: Listener) :
* @param path The [Path] to remove. Must exist in the list.
*/
fun remove(path: Path) {
T.d("Removing $path")
L.d("Removing $path")
val idx = _dirs.indexOf(path)
_dirs.removeAt(idx)
notifyItemRemoved(idx)

View file

@ -37,7 +37,7 @@ import org.oxycblt.auxio.music.fs.DocumentPathFactory
import org.oxycblt.auxio.music.fs.Path
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.showToast
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Dialog that manages the music dirs setting.
@ -62,7 +62,7 @@ class MusicDirsDialog :
.setPositiveButton(R.string.lbl_save) { _, _ ->
val newDirs = MusicDirectories(dirAdapter.dirs, isUiModeInclude(requireBinding()))
if (musicSettings.musicDirs != newDirs) {
T.d("Committing changes")
L.d("Committing changes")
musicSettings.musicDirs = newDirs
}
}
@ -76,7 +76,7 @@ class MusicDirsDialog :
binding.dirsAdd.apply {
ViewCompat.setTooltipText(this, contentDescription)
setOnClickListener {
T.d("Opening launcher")
L.d("Opening launcher")
val launcher =
requireNotNull(openDocumentTreeLauncher) {
"Document tree launcher was not available"
@ -150,7 +150,7 @@ class MusicDirsDialog :
private fun addDocumentTreeUriToDirs(uri: Uri?) {
if (uri == null) {
// A null URI means that the user left the file picker without picking a directory
T.d("No URI given (user closed the dialog)")
L.d("No URI given (user closed the dialog)")
return
}

View file

@ -27,7 +27,7 @@ import org.oxycblt.auxio.music.fs.Components
import org.oxycblt.auxio.music.fs.DocumentPathFactory
import org.oxycblt.auxio.music.fs.Path
import org.oxycblt.auxio.music.fs.contentResolverSafe
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Generic playlist file importing abstraction.
@ -108,7 +108,7 @@ constructor(
return ImportedPlaylist(newName, imported.paths)
}
} catch (e: Exception) {
T.e("Failed to import playlist: $e")
L.e("Failed to import playlist: $e")
null
}
}
@ -124,7 +124,7 @@ constructor(
return try {
val outputStream = context.contentResolverSafe.openOutputStream(uri)
if (outputStream == null) {
T.e("Failed to export playlist: Could not open output stream")
L.e("Failed to export playlist: Could not open output stream")
return false
}
outputStream.use {
@ -132,7 +132,7 @@ constructor(
true
}
} catch (e: Exception) {
T.e("Failed to export playlist: $e")
L.e("Failed to export playlist: $e")
false
}
}

View file

@ -34,7 +34,7 @@ import org.oxycblt.auxio.music.fs.VolumeManager
import org.oxycblt.auxio.music.metadata.correctWhitespace
import org.oxycblt.auxio.music.resolveNames
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Minimal M3U file format implementation.
@ -116,7 +116,7 @@ constructor(
}
if (path == null) {
T.e("Expected a path, instead got an EOF")
L.e("Expected a path, instead got an EOF")
break@consumeFile
}
@ -261,7 +261,7 @@ constructor(
}
commonIndex == components.size -> {
// The working directory is deeper in the path, backtrack.
for (i in 0..<workingDirectory.components.size - commonIndex) {
for (i in 0 ..< workingDirectory.components.size - commonIndex) {
relativeComponents = relativeComponents.child("..")
}
}
@ -272,7 +272,7 @@ constructor(
}
else -> {
// The paths are siblings. Backtrack and append as needed.
for (i in 0..<workingDirectory.components.size - commonIndex) {
for (i in 0 ..< workingDirectory.components.size - commonIndex) {
relativeComponents = relativeComponents.child("..")
}
relativeComponents = relativeComponents.child(depth(commonIndex))

View file

@ -33,7 +33,7 @@ import org.oxycblt.auxio.music.info.Date
import org.oxycblt.auxio.music.metadata.parseId3v2PositionField
import org.oxycblt.auxio.music.metadata.transformPositionField
import org.oxycblt.auxio.util.sendWithTimeout
import timber.log.Timber as T
import timber.log.Timber as L
/**
* The layer that loads music from the [MediaStore] database. This is an intermediate step in the
@ -127,7 +127,7 @@ private class MediaStoreExtractorImpl(
// Filter out audio that is not music, if enabled.
if (constraints.excludeNonMusic) {
T.d("Excluding non-music")
L.d("Excluding non-music")
uniSelector += " AND ${MediaStore.Audio.AudioColumns.IS_MUSIC}=1"
}
@ -136,10 +136,10 @@ private class MediaStoreExtractorImpl(
val pathSelector =
mediaStorePathInterpreterFactory.createSelector(constraints.musicDirs.dirs)
if (pathSelector != null) {
T.d("Must select for directories")
L.d("Must select for directories")
uniSelector += " AND "
if (!constraints.musicDirs.shouldInclude) {
T.d("Excluding directories in selector")
L.d("Excluding directories in selector")
// Without a NOT, the query will be restricted to the specified paths, resulting
// in the "Include" mode. With a NOT, the specified paths will not be included,
// resulting in the "Exclude" mode.
@ -151,7 +151,7 @@ private class MediaStoreExtractorImpl(
}
// Now we can actually query MediaStore.
T.d(
L.d(
"Starting song query [proj=${projection.toList()}, selector=$uniSelector, args=$uniArgs]")
val cursor =
context.contentResolverSafe.safeQuery(
@ -159,7 +159,7 @@ private class MediaStoreExtractorImpl(
projection,
uniSelector,
uniArgs.toTypedArray())
T.d("Successfully queried for ${cursor.count} songs")
L.d("Successfully queried for ${cursor.count} songs")
val genreNamesMap = mutableMapOf<Long, String>()
@ -194,8 +194,8 @@ private class MediaStoreExtractorImpl(
}
}
T.d("Read ${genreNamesMap.values.distinct().size} genres from MediaStore")
T.d("Finished initialization in ${System.currentTimeMillis() - start}ms")
L.d("Read ${genreNamesMap.values.distinct().size} genres from MediaStore")
L.d("Finished initialization in ${System.currentTimeMillis() - start}ms")
return QueryImpl(
cursor,
mediaStorePathInterpreterFactory.wrap(cursor),

View file

@ -21,7 +21,7 @@ package org.oxycblt.auxio.music.fs
import android.database.Cursor
import android.os.Build
import android.provider.MediaStore
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Wrapper around a [Cursor] that interprets path information on a per-API/manufacturer basis.
@ -112,7 +112,7 @@ private constructor(private val cursor: Cursor, volumeManager: VolumeManager) :
}
}
T.e("Could not find volume for $data [tried: ${volumes.map { it.components }}]")
L.e("Could not find volume for $data [tried: ${volumes.map { it.components }}]")
return null
}
@ -181,7 +181,7 @@ private constructor(private val cursor: Cursor, volumeManager: VolumeManager) :
val displayName = cursor.getString(displayNameIndex)
val volume = volumes.find { it.mediaStoreName == volumeName }
if (volume == null) {
T.e(
L.e(
"Could not find volume for $volumeName:$relativePath/$displayName [tried: ${volumes.map { it.mediaStoreName }}]")
return null
}

View file

@ -25,7 +25,7 @@ import kotlin.math.max
import org.oxycblt.auxio.R
import org.oxycblt.auxio.util.inRangeOrNull
import org.oxycblt.auxio.util.positiveOrNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* An ISO-8601/RFC 3339 Date.
@ -64,7 +64,7 @@ class Date private constructor(private val tokens: List<Int>) : Comparable<Date>
try {
format.parse("$year-$month")
} catch (e: ParseException) {
T.e("Unable to parse fine-grained date: $e")
L.e("Unable to parse fine-grained date: $e")
return null
}

View file

@ -62,8 +62,7 @@ sealed interface Name : Comparable<Name> {
sortTokens
.firstOrNull()
?.run { collationKey.sourceString.firstOrNull() }
?.let { if (it.isDigit()) "#" else it.uppercase() }
?: "?"
?.let { if (it.isDigit()) "#" else it.uppercase() } ?: "?"
final override fun resolve(context: Context) = raw

View file

@ -25,7 +25,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.fs.MimeType
import timber.log.Timber as T
import timber.log.Timber as L
/**
* The properties of a [Song]'s file.
@ -73,8 +73,8 @@ constructor(@ApplicationContext private val context: Context) : AudioProperties.
// Can feasibly fail with invalid file formats. Note that this isn't considered
// an error condition in the UI, as there is still plenty of other song information
// that we can show.
T.w("Unable to extract song attributes.")
T.w(e.stackTraceToString())
L.w("Unable to extract song attributes.")
L.w(e.stackTraceToString())
return AudioProperties(null, null, song.mimeType)
}
@ -90,7 +90,7 @@ constructor(@ApplicationContext private val context: Context) : AudioProperties.
// Convert bytes-per-second to kilobytes-per-second.
format.getInteger(MediaFormat.KEY_BIT_RATE) / 1000
} catch (e: NullPointerException) {
T.d("Unable to extract bit rate field")
L.d("Unable to extract bit rate field")
null
}
@ -98,7 +98,7 @@ constructor(@ApplicationContext private val context: Context) : AudioProperties.
try {
format.getInteger(MediaFormat.KEY_SAMPLE_RATE)
} catch (e: NullPointerException) {
T.e("Unable to extract sample rate field")
L.e("Unable to extract sample rate field")
null
}
@ -108,13 +108,13 @@ constructor(@ApplicationContext private val context: Context) : AudioProperties.
try {
format.getString(MediaFormat.KEY_MIME)
} catch (e: NullPointerException) {
T.e("Unable to extract mime type field")
L.e("Unable to extract mime type field")
null
}
extractor.release()
T.d("Finished extracting audio properties")
L.d("Finished extracting audio properties")
return AudioProperties(
bitrate,

View file

@ -30,7 +30,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.DialogSeparatorsBinding
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewBindingMaterialDialogFragment] that allows the user to configure the separator characters
@ -76,7 +76,7 @@ class SeparatorsDialog : ViewBindingMaterialDialogFragment<DialogSeparatorsBindi
Separators.SLASH -> binding.separatorSlash.isChecked = true
Separators.PLUS -> binding.separatorPlus.isChecked = true
Separators.AND -> binding.separatorAnd.isChecked = true
else -> T.w("Unexpected separator in settings data")
else -> L.w("Unexpected separator in settings data")
}
}
}

View file

@ -42,7 +42,7 @@ import org.oxycblt.auxio.music.device.RawSong
import org.oxycblt.auxio.music.fs.toAudioUri
import org.oxycblt.auxio.util.forEachWithTimeout
import org.oxycblt.auxio.util.sendWithTimeout
import timber.log.Timber as T
import timber.log.Timber as L
class TagExtractor
@Inject
@ -66,7 +66,7 @@ constructor(private val mediaSourceFactory: Factory, private val tagInterpreter:
songsIn++
}
T.d("All incomplete songs exhausted, starting cleanup loop")
L.d("All incomplete songs exhausted, starting cleanup loop")
while (!worker.idle()) {
val completeRawSong = worker.pull()
if (completeRawSong != null) {
@ -152,8 +152,8 @@ private class MetadataWorker(
try {
tagInterpreter.interpret(job.rawSong, job.future.get())
} catch (e: Exception) {
T.e("Failed to extract metadata")
T.e(e.stackTraceToString())
L.e("Failed to extract metadata")
L.e(e.stackTraceToString())
}
jobs[i] = null
return job.rawSong
@ -176,7 +176,7 @@ private class MetadataWorker(
mediaSource = currentMediaSource
mediaSourceCaller = currentMediaSourceCaller
} else {
T.d("new media source yahoo")
L.d("new media source yahoo")
mediaSource = mediaSourceFactory.createMediaSource(job.mediaItem)
mediaSourceCaller = MediaSourceCaller(job)
mediaSource.prepareSource(
@ -193,8 +193,8 @@ private class MetadataWorker(
mediaPeriod.maybeThrowPrepareError()
}
} catch (e: Exception) {
T.e("Failed to extract MediaSource")
T.e(e.stackTraceToString())
L.e("Failed to extract MediaSource")
L.e(e.stackTraceToString())
job.mediaPeriod?.let(mediaSource::releasePeriod)
mediaSource.releaseSource(mediaSourceCaller)
job.future.setException(e)
@ -247,7 +247,7 @@ private class MetadataWorker(
// Ignore dynamic updates.
return
}
T.d("yay source created")
L.d("yay source created")
mediaPeriodCreated = true
val mediaPeriod =
source.createPeriod(

View file

@ -27,7 +27,7 @@ import org.oxycblt.auxio.image.extractor.CoverExtractor
import org.oxycblt.auxio.music.device.RawSong
import org.oxycblt.auxio.music.info.Date
import org.oxycblt.auxio.util.nonZeroOrNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* An processing abstraction over the [MetadataRetriever] and [TextTags] workflow that operates on
@ -82,19 +82,19 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
// val gain =
// (((header[16]).toInt() and 0xFF) or ((header[17].toInt() shl 8)))
// .R128ToLUFS18()
// T.d("Obtained opus base gain: $gain dB")
// L.d("Obtained opus base gain: $gain dB")
// if (gain != 0f) {
// T.d("Applying opus base gain")
// L.d("Applying opus base gain")
// rawSong.replayGainTrackAdjustment =
// (rawSong.replayGainTrackAdjustment ?: 0f) + gain
// rawSong.replayGainAlbumAdjustment =
// (rawSong.replayGainAlbumAdjustment ?: 0f) + gain
// } else {
// T.d("Ignoring opus base gain")
// L.d("Ignoring opus base gain")
// }
// }
} else {
T.d("No metadata could be extracted for ${rawSong.name}")
L.d("No metadata could be extracted for ${rawSong.name}")
}
}
@ -127,8 +127,8 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
// isn't known?
(textFrames["TDOR"]?.run { Date.from(first()) }
?: textFrames["TDRC"]?.run { Date.from(first()) }
?: textFrames["TDRL"]?.run { Date.from(first()) }
?: parseId3v23Date(textFrames))
?: textFrames["TDRL"]?.run { Date.from(first()) }
?: parseId3v23Date(textFrames))
?.let { rawSong.date = it }
// Album
@ -138,7 +138,8 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
textFrames["TALB"]?.let { rawSong.albumName = it.first() }
textFrames["TSOA"]?.let { rawSong.albumSortName = it.first() }
(textFrames["TXXX:musicbrainz album type"]
?: textFrames["TXXX:releasetype"] ?:
?: textFrames["TXXX:releasetype"]
?:
// This is a non-standard iTunes extension
textFrames["GRP1"])
?.let { rawSong.releaseTypes = it }
@ -151,9 +152,11 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
rawSong.artistNames = it
}
(textFrames["TXXX:artistssort"]
?: textFrames["TXXX:artists_sort"] ?: textFrames["TXXX:artists sort"]
?: textFrames["TSOP"] ?: textFrames["artistsort"]
?: textFrames["TXXX:artist sort"])
?: textFrames["TXXX:artists_sort"]
?: textFrames["TXXX:artists sort"]
?: textFrames["TSOP"]
?: textFrames["artistsort"]
?: textFrames["TXXX:artist sort"])
?.let { rawSong.artistSortNames = it }
// Album artist
@ -161,15 +164,19 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
?: textFrames["TXXX:musicbrainz_albumartistid"])
?.let { rawSong.albumArtistMusicBrainzIds = it }
(textFrames["TXXX:albumartists"]
?: textFrames["TXXX:album_artists"] ?: textFrames["TXXX:album artists"]
?: textFrames["TPE2"] ?: textFrames["TXXX:albumartist"]
?: textFrames["TXXX:album artist"])
?: textFrames["TXXX:album_artists"]
?: textFrames["TXXX:album artists"]
?: textFrames["TPE2"]
?: textFrames["TXXX:albumartist"]
?: textFrames["TXXX:album artist"])
?.let { rawSong.albumArtistNames = it }
(textFrames["TXXX:albumartistssort"]
?: textFrames["TXXX:albumartists_sort"] ?: textFrames["TXXX:albumartists sort"]
?: textFrames["TXXX:albumartistsort"]
?: textFrames["TXXX:albumartists_sort"]
?: textFrames["TXXX:albumartists sort"]
?: textFrames["TXXX:albumartistsort"]
// This is a non-standard iTunes extension
?: textFrames["TSO2"] ?: textFrames["TXXX:album artist sort"])
?: textFrames["TSO2"]
?: textFrames["TXXX:album artist sort"])
?.let { rawSong.albumArtistSortNames = it }
// Genre
@ -177,7 +184,7 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
// Compilation Flag
(textFrames["TCMP"] // This is a non-standard itunes extension
?: textFrames["TXXX:compilation"] ?: textFrames["TXXX:itunescompilation"])
?: textFrames["TXXX:compilation"] ?: textFrames["TXXX:itunescompilation"])
?.let {
// Ignore invalid instances of this tag
if (it.size != 1 || it[0] != "1") return@let
@ -201,7 +208,8 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
// is present.
val year =
textFrames["TORY"]?.run { first().toIntOrNull() }
?: textFrames["TYER"]?.run { first().toIntOrNull() } ?: return null
?: textFrames["TYER"]?.run { first().toIntOrNull() }
?: return null
val tdat = textFrames["TDAT"]
return if (tdat != null && tdat.first().length == 4 && tdat.first().isDigitsOnly()) {
@ -258,7 +266,7 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
// date tag that android supports, so it must be 15 years old or more!)
(comments["originaldate"]?.run { Date.from(first()) }
?: comments["date"]?.run { Date.from(first()) }
?: comments["year"]?.run { Date.from(first()) })
?: comments["year"]?.run { Date.from(first()) })
?.let { rawSong.date = it }
// Album
@ -277,8 +285,10 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
}
(comments["artists"] ?: comments["artist"])?.let { rawSong.artistNames = it }
(comments["artistssort"]
?: comments["artists_sort"] ?: comments["artists sort"] ?: comments["artistsort"]
?: comments["artist sort"])
?: comments["artists_sort"]
?: comments["artists sort"]
?: comments["artistsort"]
?: comments["artist sort"])
?.let { rawSong.artistSortNames = it }
// Album artist
@ -286,12 +296,16 @@ class TagInterpreterImpl @Inject constructor(private val coverExtractor: CoverEx
rawSong.albumArtistMusicBrainzIds = it
}
(comments["albumartists"]
?: comments["album_artists"] ?: comments["album artists"] ?: comments["albumartist"]
?: comments["album artist"])
?: comments["album_artists"]
?: comments["album artists"]
?: comments["albumartist"]
?: comments["album artist"])
?.let { rawSong.albumArtistNames = it }
(comments["albumartistssort"]
?: comments["albumartists_sort"] ?: comments["albumartists sort"]
?: comments["albumartistsort"] ?: comments["album artist sort"])
?: comments["albumartists_sort"]
?: comments["albumartists sort"]
?: comments["albumartistsort"]
?: comments["album artist sort"])
?.let { rawSong.albumArtistSortNames = it }
// Genre

View file

@ -170,8 +170,8 @@ private fun String.parseId3v1Genre(): String? {
// try to index the genre table with such.
val numeric =
toIntOrNull()
// Not a numeric value, try some other fixed values.
?: return when (this) {
// Not a numeric value, try some other fixed values.
?: return when (this) {
// CR and RX are not technically ID3v1, but are formatted similarly to a plain
// number.
"CR" -> "Cover"

View file

@ -33,7 +33,7 @@ import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.util.getSystemServiceCompat
import timber.log.Timber as T
import timber.log.Timber as L
class Indexer
private constructor(
@ -117,7 +117,7 @@ private constructor(
}
} else if (musicSettings.shouldBeObserving) {
// Not observing and done loading, exit foreground.
T.d("Exiting foreground")
L.d("Exiting foreground")
post(observingNotification)
} else {
post(null)
@ -125,7 +125,7 @@ private constructor(
}
override fun requestIndex(withCache: Boolean) {
T.d("Starting new indexing job (previous=${currentIndexJob?.hashCode()})")
L.d("Starting new indexing job (previous=${currentIndexJob?.hashCode()})")
// Cancel the previous music loading job.
currentIndexJob?.cancel()
// Start a new music loading job on a co-routine.
@ -146,7 +146,7 @@ private constructor(
override fun onMusicChanges(changes: MusicRepository.Changes) {
val deviceLibrary = musicRepository.deviceLibrary ?: return
T.d("Music changed, updating shared objects")
L.d("Music changed, updating shared objects")
// Wipe possibly-invalidated outdated covers
imageLoader.memoryCache?.clear()
// Clear invalid models from PlaybackStateManager. This is not connected
@ -175,7 +175,7 @@ private constructor(
// setting changed. In such a case, the state will still be updated when
// the music loading process ends.
if (musicRepository.indexingState == null) {
T.d("Not loading, updating idle session")
L.d("Not loading, updating idle session")
foregroundListener.updateForeground(ForegroundListener.Change.INDEXER)
}
}
@ -184,7 +184,7 @@ private constructor(
private fun PowerManager.WakeLock.acquireSafe() {
// Avoid unnecessary acquire calls.
if (!wakeLock.isHeld) {
T.d("Acquiring wake lock")
L.d("Acquiring wake lock")
// Time out after a minute, which is the average music loading time for a medium-sized
// library. If this runs out, we will re-request the lock, and if music loading is
// shorter than the timeout, it will be released early.
@ -196,7 +196,7 @@ private constructor(
private fun PowerManager.WakeLock.releaseSafe() {
// Avoid unnecessary release calls.
if (wakeLock.isHeld) {
T.d("Releasing wake lock")
L.d("Releasing wake lock")
release()
}
}

View file

@ -27,7 +27,7 @@ import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.IndexingProgress
import org.oxycblt.auxio.util.newMainPendingIntent
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A dynamic [ForegroundServiceNotification] that shows the current music loading state.
@ -66,7 +66,7 @@ class IndexingNotification(private val context: Context) :
// Indeterminate state, use a vaguer description and in-determinate progress.
// These events are not very frequent, and thus we don't need to safeguard
// against rate limiting.
T.d("Updating state to $progress")
L.d("Updating state to $progress")
lastUpdateTime = -1
setContentText(context.getString(R.string.lng_indexing))
setProgress(0, 0, true)
@ -81,7 +81,7 @@ class IndexingNotification(private val context: Context) :
return false
}
lastUpdateTime = SystemClock.elapsedRealtime()
T.d("Updating state to $progress")
L.d("Updating state to $progress")
setContentText(
context.getString(R.string.fmt_indexing, progress.current, progress.total))
setProgress(progress.total, progress.current, false)

View file

@ -119,8 +119,7 @@ private constructor(
is MediaSessionUID.SingleItem ->
musicRepository.find(uid.uid)?.let { musicRepository.find(it.uid) }
null -> null
}
?: return null
} ?: return null
return when (music) {
is Album -> music.toMediaItem(context)

View file

@ -23,6 +23,7 @@ import android.os.Bundle
import android.support.v4.media.MediaBrowserCompat.MediaItem
import androidx.media.MediaBrowserServiceCompat.BrowserRoot
import androidx.media.MediaBrowserServiceCompat.Result
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -30,7 +31,7 @@ import kotlinx.coroutines.launch
import org.oxycblt.auxio.ForegroundListener
import org.oxycblt.auxio.ForegroundServiceNotification
import org.oxycblt.auxio.music.MusicRepository
import javax.inject.Inject
import timber.log.Timber as L
class MusicServiceFragment
@Inject
@ -122,11 +123,11 @@ constructor(
try {
val result = body()
if (result == null) {
T.w("Result is null")
L.w("Result is null")
}
sendResult(result)
} catch (e: Exception) {
T.d("Error while dispatching: $e")
L.d("Error while dispatching: $e")
sendResult(null)
}
}
@ -137,11 +138,11 @@ constructor(
try {
val result = body()
if (result == null) {
T.w("Result is null")
L.w("Result is null")
}
sendResult(result)
} catch (e: Exception) {
T.d("Error while dispatching: $e")
L.d("Error while dispatching: $e")
sendResult(null)
}
}

View file

@ -28,7 +28,7 @@ import javax.inject.Inject
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.MusicSettings
import org.oxycblt.auxio.music.fs.contentResolverSafe
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ContentObserver] that observes the [MediaStore] music database for changes, a behavior known
@ -68,7 +68,7 @@ constructor(
// Check here if we should even start a reindex. This is much less bug-prone than
// registering and de-registering this component as this setting changes.
if (musicSettings.shouldBeObserving) {
T.d("MediaStore changed, starting re-index")
L.d("MediaStore changed, starting re-index")
musicRepository.requestIndex(true)
}
}

View file

@ -26,7 +26,7 @@ import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.device.DeviceLibrary
import org.oxycblt.auxio.music.info.Name
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Organized library information controlled by the user.
@ -143,10 +143,10 @@ class UserLibraryFactoryImpl @Inject constructor(private val playlistDao: Playli
override suspend fun query() =
try {
val rawPlaylists = playlistDao.readRawPlaylists()
T.d("Successfully read ${rawPlaylists.size} playlists")
L.d("Successfully read ${rawPlaylists.size} playlists")
rawPlaylists
} catch (e: Exception) {
T.e("Unable to read playlists: $e")
L.e("Unable to read playlists: $e")
listOf()
}
@ -192,11 +192,11 @@ private class UserLibraryImpl(
return try {
playlistDao.insertPlaylist(rawPlaylist)
T.d("Successfully created playlist $name with ${songs.size} songs")
L.d("Successfully created playlist $name with ${songs.size} songs")
playlistImpl
} catch (e: Exception) {
T.e("Unable to create playlist $name with ${songs.size} songs")
T.e(e.stackTraceToString())
L.e("Unable to create playlist $name with ${songs.size} songs")
L.e(e.stackTraceToString())
synchronized(this) { playlistMap.remove(playlistImpl.uid) }
null
}
@ -211,11 +211,11 @@ private class UserLibraryImpl(
return try {
playlistDao.replacePlaylistInfo(PlaylistInfo(playlist.uid, name))
T.d("Successfully renamed $playlist to $name")
L.d("Successfully renamed $playlist to $name")
true
} catch (e: Exception) {
T.e("Unable to rename $playlist to $name: $e")
T.e(e.stackTraceToString())
L.e("Unable to rename $playlist to $name: $e")
L.e(e.stackTraceToString())
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
false
}
@ -230,11 +230,11 @@ private class UserLibraryImpl(
return try {
playlistDao.deletePlaylist(playlist.uid)
T.d("Successfully deleted $playlist")
L.d("Successfully deleted $playlist")
true
} catch (e: Exception) {
T.e("Unable to delete $playlist: $e")
T.e(e.stackTraceToString())
L.e("Unable to delete $playlist: $e")
L.e(e.stackTraceToString())
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
false
}
@ -249,11 +249,11 @@ private class UserLibraryImpl(
return try {
playlistDao.insertPlaylistSongs(playlist.uid, songs.map { PlaylistSong(it.uid) })
T.d("Successfully added ${songs.size} songs to $playlist")
L.d("Successfully added ${songs.size} songs to $playlist")
true
} catch (e: Exception) {
T.e("Unable to add ${songs.size} songs to $playlist: $e")
T.e(e.stackTraceToString())
L.e("Unable to add ${songs.size} songs to $playlist: $e")
L.e(e.stackTraceToString())
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
false
}
@ -268,11 +268,11 @@ private class UserLibraryImpl(
return try {
playlistDao.replacePlaylistSongs(playlist.uid, songs.map { PlaylistSong(it.uid) })
T.d("Successfully rewrote $playlist with ${songs.size} songs")
L.d("Successfully rewrote $playlist with ${songs.size} songs")
true
} catch (e: Exception) {
T.e("Unable to rewrite $playlist with ${songs.size} songs: $e")
T.e(e.stackTraceToString())
L.e("Unable to rewrite $playlist with ${songs.size} songs: $e")
L.e(e.stackTraceToString())
synchronized(this) { playlistMap[playlistImpl.uid] = playlistImpl }
false
}

View file

@ -33,7 +33,7 @@ import org.oxycblt.auxio.ui.ViewBindingFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.getColorCompat
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewBindingFragment] that shows the current playback state in a compact manner.
@ -128,7 +128,7 @@ class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
val binding = requireBinding()
when (actionMode) {
ActionMode.NEXT -> {
T.d("Using skip next action")
L.d("Using skip next action")
binding.playbackSecondaryAction.apply {
if (tag != actionMode) {
setIconResource(R.drawable.ic_skip_next_24)
@ -140,7 +140,7 @@ class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
}
}
ActionMode.REPEAT -> {
T.d("Using repeat mode action")
L.d("Using repeat mode action")
binding.playbackSecondaryAction.apply {
if (tag != actionMode) {
contentDescription = getString(R.string.desc_change_repeat)
@ -153,7 +153,7 @@ class PlaybackBarFragment : ViewBindingFragment<FragmentPlaybackBarBinding>() {
}
}
ActionMode.SHUFFLE -> {
T.d("Using shuffle action")
L.d("Using shuffle action")
binding.playbackSecondaryAction.apply {
if (tag != actionMode) {
setIconResource(R.drawable.sel_shuffle_state_24)

View file

@ -45,7 +45,7 @@ import org.oxycblt.auxio.ui.ViewBindingFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.showToast
import org.oxycblt.auxio.util.systemBarInsetsCompat
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewBindingFragment] more information about the currently playing song, alongside all
@ -179,7 +179,7 @@ class PlaybackPanelFragment :
override fun onMenuItemClick(item: MenuItem): Boolean {
if (item.itemId == R.id.action_open_equalizer) {
// Launch the system equalizer app, if possible.
T.d("Launching equalizer")
L.d("Launching equalizer")
val equalizerIntent =
Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL)
// Provide audio session ID so the equalizer can show options for this app
@ -220,7 +220,7 @@ class PlaybackPanelFragment :
val binding = requireBinding()
val context = requireContext()
T.d("Updating song display: $song")
L.d("Updating song display: $song")
binding.playbackCover.bind(song)
binding.playbackSong.text = song.name.resolve(context)
binding.playbackArtist.text = song.artists.resolveNames(context)

View file

@ -27,7 +27,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.playback.replaygain.ReplayGainMode
import org.oxycblt.auxio.playback.replaygain.ReplayGainPreAmp
import org.oxycblt.auxio.settings.Settings
import timber.log.Timber as T
import timber.log.Timber as L
/**
* User configuration specific to the playback system.
@ -146,7 +146,7 @@ class PlaybackSettingsImpl @Inject constructor(@ApplicationContext context: Cont
}
if (sharedPreferences.contains(OLD_KEY_LIB_MUSIC_PLAYBACK_MODE)) {
T.d("Migrating $OLD_KEY_LIB_MUSIC_PLAYBACK_MODE")
L.d("Migrating $OLD_KEY_LIB_MUSIC_PLAYBACK_MODE")
val mode =
sharedPreferences
@ -162,7 +162,7 @@ class PlaybackSettingsImpl @Inject constructor(@ApplicationContext context: Cont
}
if (sharedPreferences.contains(OLD_KEY_DETAIL_MUSIC_PLAYBACK_MODE)) {
T.d("Migrating $OLD_KEY_DETAIL_MUSIC_PLAYBACK_MODE")
L.d("Migrating $OLD_KEY_DETAIL_MUSIC_PLAYBACK_MODE")
val mode =
sharedPreferences
@ -183,19 +183,19 @@ class PlaybackSettingsImpl @Inject constructor(@ApplicationContext context: Cont
getString(R.string.set_key_replay_gain),
getString(R.string.set_key_pre_amp_with),
getString(R.string.set_key_pre_amp_without) -> {
T.d("Dispatching ReplayGain setting change")
L.d("Dispatching ReplayGain setting change")
listener.onReplayGainSettingsChanged()
}
getString(R.string.set_key_notif_action) -> {
T.d("Dispatching notification setting change")
L.d("Dispatching notification setting change")
listener.onNotificationActionChanged()
}
getString(R.string.set_key_bar_action) -> {
T.d("Dispatching bar action change")
L.d("Dispatching bar action change")
listener.onBarActionChanged()
}
getString(R.string.set_key_repeat_pause) -> {
T.d("Dispatching pause on repeat change")
L.d("Dispatching pause on repeat change")
listener.onPauseOnRepeatChanged()
}
}

View file

@ -43,7 +43,7 @@ import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.playback.state.ShuffleMode
import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent
import timber.log.Timber as T
import timber.log.Timber as L
/**
* An [ViewModel] that provides a safe UI frontend for the current playback state.
@ -129,20 +129,20 @@ constructor(
}
override fun onIndexMoved(index: Int) {
T.d("Index moved, updating current song")
L.d("Index moved, updating current song")
_song.value = playbackManager.currentSong
}
override fun onQueueChanged(queue: List<Song>, index: Int, change: QueueChange) {
// Other types of queue changes preserve the current song.
if (change.type == QueueChange.Type.SONG) {
T.d("Queue changed, updating current song")
L.d("Queue changed, updating current song")
_song.value = playbackManager.currentSong
}
}
override fun onQueueReordered(queue: List<Song>, index: Int, isShuffled: Boolean) {
T.d("Queue completely changed, updating current song")
L.d("Queue completely changed, updating current song")
_isShuffled.value = isShuffled
}
@ -152,14 +152,14 @@ constructor(
index: Int,
isShuffled: Boolean
) {
T.d("New playback started, updating playback information")
L.d("New playback started, updating playback information")
_song.value = playbackManager.currentSong
_parent.value = parent
_isShuffled.value = isShuffled
}
override fun onProgressionChanged(progression: Progression) {
T.d("Player state changed, starting new position polling")
L.d("Player state changed, starting new position polling")
_isPlaying.value = progression.isPlaying
// Still need to update the position now due to co-routine launch delays
_positionDs.value = progression.calculateElapsedPositionMs().msToDs()
@ -187,7 +187,7 @@ constructor(
// --- PLAYING FUNCTIONS ---
fun play(song: Song, with: PlaySong) {
T.d("Playing $song with $with")
L.d("Playing $song with $with")
playWithImpl(song, with, ShuffleMode.IMPLICIT)
}
@ -201,7 +201,7 @@ constructor(
/** Shuffle all songs in the music library. */
fun shuffleAll() {
T.d("Shuffling all songs")
L.d("Shuffling all songs")
playFromAllImpl(null, ShuffleMode.ON)
}
@ -257,7 +257,7 @@ constructor(
}
private fun playFromAlbumImpl(song: Song, shuffle: ShuffleMode) {
T.d("Playing $song from album")
L.d("Playing $song from album")
playImpl(commandFactory.songFromAlbum(song, shuffle))
}
@ -267,7 +267,7 @@ constructor(
playbackManager.play(params)
return
}
T.d(
L.d(
"Cannot use given artist parameter for $song [$artist from ${song.artists}], showing choice dialog")
startPlaybackDecision(PlaybackDecision.PlayFromArtist(song))
}
@ -278,20 +278,20 @@ constructor(
playbackManager.play(params)
return
}
T.d(
L.d(
"Cannot use given genre parameter for $song [$genre from ${song.genres}], showing choice dialog")
startPlaybackDecision(PlaybackDecision.PlayFromArtist(song))
}
private fun playFromPlaylistImpl(song: Song, playlist: Playlist, shuffle: ShuffleMode) {
T.d("Playing $song from $playlist")
L.d("Playing $song from $playlist")
playImpl(commandFactory.songFromPlaylist(song, playlist, shuffle))
}
private fun startPlaybackDecision(decision: PlaybackDecision) {
val existing = _playbackDecision.flow.value
if (existing != null) {
T.d("Already handling decision $existing, ignoring $decision")
L.d("Already handling decision $existing, ignoring $decision")
return
}
_playbackDecision.put(decision)
@ -303,7 +303,7 @@ constructor(
* @param album The [Album] to play.
*/
fun play(album: Album) {
T.d("Playing $album")
L.d("Playing $album")
playImpl(commandFactory.album(album, ShuffleMode.OFF))
}
@ -313,7 +313,7 @@ constructor(
* @param album The [Album] to shuffle.
*/
fun shuffle(album: Album) {
T.d("Shuffling $album")
L.d("Shuffling $album")
playImpl(commandFactory.album(album, ShuffleMode.ON))
}
@ -323,7 +323,7 @@ constructor(
* @param artist The [Artist] to play.
*/
fun play(artist: Artist) {
T.d("Playing $artist")
L.d("Playing $artist")
playImpl(commandFactory.artist(artist, ShuffleMode.OFF))
}
@ -333,7 +333,7 @@ constructor(
* @param artist The [Artist] to shuffle.
*/
fun shuffle(artist: Artist) {
T.d("Shuffling $artist")
L.d("Shuffling $artist")
playImpl(commandFactory.artist(artist, ShuffleMode.ON))
}
@ -343,7 +343,7 @@ constructor(
* @param genre The [Genre] to play.
*/
fun play(genre: Genre) {
T.d("Playing $genre")
L.d("Playing $genre")
playImpl(commandFactory.genre(genre, ShuffleMode.OFF))
}
@ -353,7 +353,7 @@ constructor(
* @param genre The [Genre] to shuffle.
*/
fun shuffle(genre: Genre) {
T.d("Shuffling $genre")
L.d("Shuffling $genre")
playImpl(commandFactory.genre(genre, ShuffleMode.ON))
}
@ -363,7 +363,7 @@ constructor(
* @param playlist The [Playlist] to play.
*/
fun play(playlist: Playlist) {
T.d("Playing $playlist")
L.d("Playing $playlist")
playImpl(commandFactory.playlist(playlist, ShuffleMode.OFF))
}
@ -373,7 +373,7 @@ constructor(
* @param playlist The [Playlist] to shuffle.
*/
fun shuffle(playlist: Playlist) {
T.d("Shuffling $playlist")
L.d("Shuffling $playlist")
playImpl(commandFactory.playlist(playlist, ShuffleMode.ON))
}
@ -383,7 +383,7 @@ constructor(
* @param songs The [Song]s to play.
*/
fun play(songs: List<Song>) {
T.d("Playing ${songs.size} songs")
L.d("Playing ${songs.size} songs")
playImpl(commandFactory.songs(songs, ShuffleMode.OFF))
}
@ -393,7 +393,7 @@ constructor(
* @param songs The [Song]s to shuffle.
*/
fun shuffle(songs: List<Song>) {
T.d("Shuffling ${songs.size} songs")
L.d("Shuffling ${songs.size} songs")
playImpl(commandFactory.songs(songs, ShuffleMode.ON))
}
@ -408,7 +408,7 @@ constructor(
* @param action The [DeferredPlayback] to perform eventually.
*/
fun playDeferred(action: DeferredPlayback) {
T.d("Starting action $action")
L.d("Starting action $action")
playbackManager.playDeferred(action)
}
@ -420,7 +420,7 @@ constructor(
* @param positionDs The position to seek to, in deci-seconds (1/10th of a second).
*/
fun seekTo(positionDs: Long) {
T.d("Seeking to ${positionDs}ds")
L.d("Seeking to ${positionDs}ds")
playbackManager.seekTo(positionDs.dsToMs())
}
@ -428,13 +428,13 @@ constructor(
/** Skip to the next [Song]. */
fun next() {
T.d("Skipping to next song")
L.d("Skipping to next song")
playbackManager.next()
}
/** Skip to the previous [Song]. */
fun prev() {
T.d("Skipping to previous song")
L.d("Skipping to previous song")
playbackManager.prev()
}
@ -444,7 +444,7 @@ constructor(
* @param song The [Song] to add.
*/
fun playNext(song: Song) {
T.d("Playing $song next")
L.d("Playing $song next")
playbackManager.playNext(song)
}
@ -454,7 +454,7 @@ constructor(
* @param album The [Album] to add.
*/
fun playNext(album: Album) {
T.d("Playing $album next")
L.d("Playing $album next")
playbackManager.playNext(listSettings.albumSongSort.songs(album.songs))
}
@ -464,7 +464,7 @@ constructor(
* @param artist The [Artist] to add.
*/
fun playNext(artist: Artist) {
T.d("Playing $artist next")
L.d("Playing $artist next")
playbackManager.playNext(listSettings.artistSongSort.songs(artist.songs))
}
@ -474,7 +474,7 @@ constructor(
* @param genre The [Genre] to add.
*/
fun playNext(genre: Genre) {
T.d("Playing $genre next")
L.d("Playing $genre next")
playbackManager.playNext(listSettings.genreSongSort.songs(genre.songs))
}
@ -484,7 +484,7 @@ constructor(
* @param playlist The [Playlist] to add.
*/
fun playNext(playlist: Playlist) {
T.d("Playing $playlist next")
L.d("Playing $playlist next")
playbackManager.playNext(playlist.songs)
}
@ -494,7 +494,7 @@ constructor(
* @param songs The [Song]s to add.
*/
fun playNext(songs: List<Song>) {
T.d("Playing ${songs.size} songs next")
L.d("Playing ${songs.size} songs next")
playbackManager.playNext(songs)
}
@ -504,7 +504,7 @@ constructor(
* @param song The [Song] to add.
*/
fun addToQueue(song: Song) {
T.d("Adding $song to queue")
L.d("Adding $song to queue")
playbackManager.addToQueue(song)
}
@ -514,7 +514,7 @@ constructor(
* @param album The [Album] to add.
*/
fun addToQueue(album: Album) {
T.d("Adding $album to queue")
L.d("Adding $album to queue")
playbackManager.addToQueue(listSettings.albumSongSort.songs(album.songs))
}
@ -524,7 +524,7 @@ constructor(
* @param artist The [Artist] to add.
*/
fun addToQueue(artist: Artist) {
T.d("Adding $artist to queue")
L.d("Adding $artist to queue")
playbackManager.addToQueue(listSettings.artistSongSort.songs(artist.songs))
}
@ -534,7 +534,7 @@ constructor(
* @param genre The [Genre] to add.
*/
fun addToQueue(genre: Genre) {
T.d("Adding $genre to queue")
L.d("Adding $genre to queue")
playbackManager.addToQueue(listSettings.genreSongSort.songs(genre.songs))
}
@ -544,7 +544,7 @@ constructor(
* @param playlist The [Playlist] to add.
*/
fun addToQueue(playlist: Playlist) {
T.d("Adding $playlist to queue")
L.d("Adding $playlist to queue")
playbackManager.addToQueue(playlist.songs)
}
@ -554,7 +554,7 @@ constructor(
* @param songs The [Song]s to add.
*/
fun addToQueue(songs: List<Song>) {
T.d("Adding ${songs.size} songs to queue")
L.d("Adding ${songs.size} songs to queue")
playbackManager.addToQueue(songs)
}
@ -562,13 +562,13 @@ constructor(
/** Toggle [isPlaying] (i.e from playing to paused) */
fun togglePlaying() {
T.d("Toggling playing state")
L.d("Toggling playing state")
playbackManager.playing(!playbackManager.progression.isPlaying)
}
/** Toggle [isShuffled] (ex. from on to off) */
fun toggleShuffled() {
T.d("Toggling shuffled state")
L.d("Toggling shuffled state")
playbackManager.shuffled(!playbackManager.isShuffled)
}
@ -578,7 +578,7 @@ constructor(
* @see RepeatMode.increment
*/
fun toggleRepeatMode() {
T.d("Toggling repeat mode")
L.d("Toggling repeat mode")
playbackManager.repeatMode(playbackManager.repeatMode.increment())
}
@ -599,7 +599,7 @@ constructor(
private fun openImpl(panel: OpenPanel) {
val existing = openPanel.flow.value
if (existing != null) {
T.d("Already opening $existing, ignoring opening $panel")
L.d("Already opening $existing, ignoring opening $panel")
return
}
_openPanel.put(panel)

View file

@ -37,7 +37,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A picker [ViewBindingMaterialDialogFragment] intended for when [Artist] playback is ambiguous.
@ -88,7 +88,7 @@ class PlayFromArtistDialog :
private fun updateSong(song: Song?) {
if (song == null) {
T.d("No song to show choices for, navigating away")
L.d("No song to show choices for, navigating away")
findNavController().navigateUp()
return
}

View file

@ -37,7 +37,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import org.oxycblt.auxio.util.collectImmediately
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A picker [ViewBindingMaterialDialogFragment] intended for when [Genre] playback is ambiguous.
@ -88,7 +88,7 @@ class PlayFromGenreDialog :
private fun updateSong(song: Song?) {
if (song == null) {
T.d("No song to show choices for, navigating away")
L.d("No song to show choices for, navigating away")
findNavController().navigateUp()
return
}

View file

@ -27,7 +27,7 @@ import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.Song
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewModel] that stores the choices shown in the playback picker dialogs.
@ -63,10 +63,10 @@ class PlaybackPickerViewModel @Inject constructor(private val musicRepository: M
* @param uid The [Music.UID] of the item to show. Must be a [Song].
*/
fun setPickerSongUid(uid: Music.UID) {
T.d("Opening picker for song $uid")
L.d("Opening picker for song $uid")
_currentPickerSong.value = musicRepository.deviceLibrary?.findSong(uid)
if (_currentPickerSong.value != null) {
T.w("Given song UID was invalid")
L.w("Given song UID was invalid")
}
}
}

View file

@ -22,7 +22,7 @@ import javax.inject.Inject
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Manages the persisted playback state in a structured manner.
@ -59,8 +59,8 @@ constructor(
heapItems = queueDao.getHeap()
mappingItems = queueDao.getShuffledMapping()
} catch (e: Exception) {
T.e("Unable read playback state")
T.e(e.stackTraceToString())
L.e("Unable read playback state")
L.e(e.stackTraceToString())
return null
}
@ -84,12 +84,12 @@ constructor(
queueDao.nukeHeap()
queueDao.nukeShuffledMapping()
} catch (e: Exception) {
T.e("Unable to clear previous state")
T.e(e.stackTraceToString())
L.e("Unable to clear previous state")
L.e(e.stackTraceToString())
return false
}
T.d("Successfully cleared previous state")
L.d("Successfully cleared previous state")
if (state != null) {
// Transform saved state into raw state, which can then be written to the database.
val playbackState =
@ -113,12 +113,12 @@ constructor(
queueDao.insertHeap(heap)
queueDao.insertShuffledMapping(shuffledMapping)
} catch (e: Exception) {
T.e("Unable to write new state")
T.e(e.stackTraceToString())
L.e("Unable to write new state")
L.e(e.stackTraceToString())
return false
}
T.d("Successfully wrote new state")
L.d("Successfully wrote new state")
}
return true

View file

@ -37,7 +37,7 @@ import org.oxycblt.auxio.music.resolveNames
import org.oxycblt.auxio.util.context
import org.oxycblt.auxio.util.getAttrColorCompat
import org.oxycblt.auxio.util.inflater
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [RecyclerView.Adapter] that shows an editable list of queue items.
@ -80,7 +80,7 @@ class QueueAdapter(private val listener: EditClickListListener<Song>) :
* @param isPlaying Whether playback is ongoing or paused.
*/
fun setPosition(index: Int, isPlaying: Boolean) {
T.d("Updating index")
L.d("Updating index")
val lastIndex = currentIndex
currentIndex = index
@ -89,10 +89,10 @@ class QueueAdapter(private val listener: EditClickListListener<Song>) :
// TODO: Optimize this by only updating the range between old and new indices?
// TODO: Don't update when the index has not moved.
if (currentIndex < lastIndex) {
T.d("Moved backwards, must update items above last index")
L.d("Moved backwards, must update items above last index")
notifyItemRangeChanged(0, lastIndex + 1, PAYLOAD_UPDATE_POSITION)
} else {
T.d("Moved forwards, update items after index")
L.d("Moved forwards, update items after index")
notifyItemRangeChanged(0, currentIndex + 1, PAYLOAD_UPDATE_POSITION)
}

View file

@ -34,7 +34,7 @@ import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.ViewBindingFragment
import org.oxycblt.auxio.util.collectImmediately
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewBindingFragment] that displays an editable queue.
@ -122,14 +122,14 @@ class QueueFragment : ViewBindingFragment<FragmentQueueBinding>(), EditClickList
// dependent on where we have to scroll to get to the currently playing song.
if (notInitialized || scrollTo < start) {
// We need to scroll upwards, or initialize the scroll, no need to offset
T.d("Not scrolling downwards, no offset needed")
L.d("Not scrolling downwards, no offset needed")
binding.queueRecycler.scrollToPosition(scrollTo)
} else if (scrollTo > end) {
// We need to scroll downwards, we need to offset by a screen of songs.
// This does have some error due to how many completely visible items on-screen
// can vary. This is considered okay.
val offset = scrollTo + (end - start)
T.d("Scrolling downwards, offsetting by $offset")
L.d("Scrolling downwards, offsetting by $offset")
binding.queueRecycler.scrollToPosition(min(queue.lastIndex, offset))
}
}

View file

@ -30,7 +30,7 @@ import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.playback.state.QueueChange
import org.oxycblt.auxio.util.Event
import org.oxycblt.auxio.util.MutableEvent
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [ViewModel] that manages the current queue state and allows navigation through the queue.
@ -62,26 +62,26 @@ class QueueViewModel @Inject constructor(private val playbackManager: PlaybackSt
}
override fun onIndexMoved(index: Int) {
T.d("Index moved, synchronizing and scrolling to new position")
L.d("Index moved, synchronizing and scrolling to new position")
_scrollTo.put(index)
_index.value = index
}
override fun onQueueChanged(queue: List<Song>, index: Int, change: QueueChange) {
// Queue changed trivially due to item mo -> Diff queue, stay at current index.
T.d("Updating queue display")
L.d("Updating queue display")
_queueInstructions.put(change.instructions)
_queue.value = queue
if (change.type != QueueChange.Type.MAPPING) {
// Index changed, make sure it remains updated without actually scrolling to it.
T.d("Index changed with queue, synchronizing new position")
L.d("Index changed with queue, synchronizing new position")
_index.value = index
}
}
override fun onQueueReordered(queue: List<Song>, index: Int, isShuffled: Boolean) {
// Queue changed completely -> Replace queue, update index
T.d("Queue changed completely, replacing queue and position")
L.d("Queue changed completely, replacing queue and position")
_queueInstructions.put(UpdateInstructions.Replace(0))
_scrollTo.put(index)
_queue.value = queue
@ -95,7 +95,7 @@ class QueueViewModel @Inject constructor(private val playbackManager: PlaybackSt
isShuffled: Boolean
) {
// Entirely new queue -> Replace queue, update index
T.d("New playback, replacing queue and position")
L.d("New playback, replacing queue and position")
_queueInstructions.put(UpdateInstructions.Replace(0))
_scrollTo.put(index)
_queue.value = queue
@ -117,7 +117,7 @@ class QueueViewModel @Inject constructor(private val playbackManager: PlaybackSt
if (adapterIndex !in queue.value.indices) {
return
}
T.d("Going to position $adapterIndex in queue")
L.d("Going to position $adapterIndex in queue")
playbackManager.goto(adapterIndex)
}
@ -131,7 +131,7 @@ class QueueViewModel @Inject constructor(private val playbackManager: PlaybackSt
if (adapterIndex !in queue.value.indices) {
return
}
T.d("Removing item $adapterIndex in queue")
L.d("Removing item $adapterIndex in queue")
playbackManager.removeQueueItem(adapterIndex)
}
@ -146,7 +146,7 @@ class QueueViewModel @Inject constructor(private val playbackManager: PlaybackSt
if (adapterFrom !in queue.value.indices || adapterTo !in queue.value.indices) {
return false
}
T.d("Moving $adapterFrom to $adapterFrom in queue")
L.d("Moving $adapterFrom to $adapterFrom in queue")
playbackManager.moveQueueItem(adapterFrom, adapterTo)
return true
}

View file

@ -28,7 +28,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.DialogPreAmpBinding
import org.oxycblt.auxio.playback.PlaybackSettings
import org.oxycblt.auxio.ui.ViewBindingMaterialDialogFragment
import timber.log.Timber as T
import timber.log.Timber as L
/**
* aa [ViewBindingMaterialDialogFragment] that allows user configuration of the current
@ -62,7 +62,7 @@ class PreAmpCustomizeDialog : ViewBindingMaterialDialogFragment<DialogPreAmpBind
// settings. After this, the sliders save their own state, so we do not need to
// do any restore behavior.
val preAmp = playbackSettings.replayGainPreAmp
T.d("Initializing from $preAmp")
L.d("Initializing from $preAmp")
binding.withTagsSlider.value = preAmp.with
binding.withoutTagsSlider.value = preAmp.without
}

View file

@ -32,7 +32,7 @@ import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackSettings
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.playback.state.QueueChange
import timber.log.Timber as T
import timber.log.Timber as L
/**
* An [AudioProcessor] that handles ReplayGain values and their amplification of the audio stream.
@ -71,7 +71,7 @@ constructor(
// --- OVERRIDES ---
override fun onIndexMoved(index: Int) {
T.d("Index moved, updating current song")
L.d("Index moved, updating current song")
applyReplayGain(playbackManager.currentSong)
}
@ -88,7 +88,7 @@ constructor(
index: Int,
isShuffled: Boolean
) {
T.d("New playback started, updating playback information")
L.d("New playback started, updating playback information")
applyReplayGain(playbackManager.currentSong)
}
@ -106,12 +106,12 @@ constructor(
*/
private fun applyReplayGain(song: Song?) {
if (song == null) {
T.d("Nothing playing, disabling adjustment")
L.d("Nothing playing, disabling adjustment")
volume = 1f
return
}
T.d("Applying ReplayGain adjustment for $song")
L.d("Applying ReplayGain adjustment for $song")
val gain = song.replayGainAdjustment
val preAmp = playbackSettings.replayGainPreAmp
@ -121,44 +121,43 @@ constructor(
when (playbackSettings.replayGainMode) {
// User wants no adjustment.
ReplayGainMode.OFF -> {
T.d("ReplayGain is off")
L.d("ReplayGain is off")
null
}
// User wants track gain to be preferred. Default to album gain only if
// there is no track gain.
ReplayGainMode.TRACK -> {
T.d("Using track strategy")
L.d("Using track strategy")
gain.track ?: gain.album
}
// User wants album gain to be preferred. Default to track gain only if
// here is no album gain.
ReplayGainMode.ALBUM -> {
T.d("Using album strategy")
L.d("Using album strategy")
gain.album ?: gain.track
}
// User wants album gain to be used when in an album, track gain otherwise.
ReplayGainMode.DYNAMIC -> {
T.d("Using dynamic strategy")
L.d("Using dynamic strategy")
gain.album?.takeIf {
playbackManager.parent is Album &&
playbackManager.currentSong?.album == playbackManager.parent
}
?: gain.track
} ?: gain.track
}
}
val amplifiedAdjustment =
if (resolvedAdjustment != null) {
// Successfully resolved an adjustment, apply the corresponding pre-amp
T.d("Applying with pre-amp")
L.d("Applying with pre-amp")
resolvedAdjustment + preAmp.with
} else {
// No adjustment found, use the corresponding user-defined pre-amp
T.d("Applying without pre-amp")
L.d("Applying without pre-amp")
preAmp.without
}
T.d("Applying ReplayGain adjustment ${amplifiedAdjustment}db")
L.d("Applying ReplayGain adjustment ${amplifiedAdjustment}db")
// Final adjustment along the volume curve.
volume = 10f.pow(amplifiedAdjustment / 20f)

View file

@ -59,7 +59,7 @@ import org.oxycblt.auxio.playback.state.RawQueue
import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.playback.state.ShuffleMode
import org.oxycblt.auxio.playback.state.StateAck
import timber.log.Timber as T
import timber.log.Timber as L
class ExoPlaybackStateHolder(
private val context: Context,
@ -130,8 +130,8 @@ class ExoPlaybackStateHolder(
override fun resolveQueue(): RawQueue {
val deviceLibrary =
musicRepository.deviceLibrary
// No library, cannot do anything.
?: return RawQueue(emptyList(), emptyList(), 0)
// No library, cannot do anything.
?: return RawQueue(emptyList(), emptyList(), 0)
val heap = (0 until player.mediaItemCount).map { player.getMediaItemAt(it) }
val shuffledMapping =
if (player.shuffleModeEnabled) {
@ -145,13 +145,13 @@ class ExoPlaybackStateHolder(
override fun handleDeferred(action: DeferredPlayback): Boolean {
val deviceLibrary =
musicRepository.deviceLibrary
// No library, cannot do anything.
?: return false
// No library, cannot do anything.
?: return false
when (action) {
// Restore state -> Start a new restoreState job
is DeferredPlayback.RestoreState -> {
T.d("Restoring playback state")
L.d("Restoring playback state")
restoreScope.launch {
val state = persistenceRepository.readState()
withContext(Dispatchers.Main) {
@ -170,7 +170,7 @@ class ExoPlaybackStateHolder(
}
// Shuffle all -> Start new playback from all songs
is DeferredPlayback.ShuffleAll -> {
T.d("Shuffling all tracks")
L.d("Shuffling all tracks")
playbackManager.play(
requireNotNull(commandFactory.all(ShuffleMode.ON)) {
"Invalid playback parameters"
@ -178,7 +178,7 @@ class ExoPlaybackStateHolder(
}
// Open -> Try to find the Song for the given file and then play it from all songs
is DeferredPlayback.Open -> {
T.d("Opening specified file")
L.d("Opening specified file")
deviceLibrary.findSongForUri(context, action.uri)?.let { song ->
playbackManager.play(
requireNotNull(commandFactory.song(song, ShuffleMode.IMPLICIT)) {
@ -427,18 +427,18 @@ class ExoPlaybackStateHolder(
if (player.playWhenReady) {
// Mark that we have started playing so that the notification can now be posted.
T.d("Player has started playing")
L.d("Player has started playing")
sessionOngoing = true
if (!openAudioEffectSession) {
// Convention to start an audioeffect session on play/pause rather than
// start/stop
T.d("Opening audio effect session")
L.d("Opening audio effect session")
broadcastAudioEffectAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION)
openAudioEffectSession = true
}
} else if (openAudioEffectSession) {
// Make sure to close the audio session when we stop playback.
T.d("Closing audio effect session")
L.d("Closing audio effect session")
broadcastAudioEffectAction(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)
openAudioEffectSession = false
}
@ -470,7 +470,7 @@ class ExoPlaybackStateHolder(
Player.EVENT_PLAY_WHEN_READY_CHANGED,
Player.EVENT_IS_PLAYING_CHANGED,
Player.EVENT_POSITION_DISCONTINUITY)) {
T.d("Player state changed, must synchronize state")
L.d("Player state changed, must synchronize state")
playbackManager.ack(this, StateAck.ProgressionChanged)
}
}
@ -478,13 +478,13 @@ class ExoPlaybackStateHolder(
override fun onPlayerError(error: PlaybackException) {
// TODO: Replace with no skipping and a notification instead
// If there's any issue, just go to the next song.
T.e("Player error occurred")
T.e(error.stackTraceToString())
L.e("Player error occurred")
L.e(error.stackTraceToString())
playbackManager.next()
}
private fun broadcastAudioEffectAction(event: String) {
T.d("Broadcasting AudioEffect event: $event")
L.d("Broadcasting AudioEffect event: $event")
context.sendBroadcast(
Intent(event)
.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
@ -497,7 +497,7 @@ class ExoPlaybackStateHolder(
override fun onMusicChanges(changes: MusicRepository.Changes) {
if (changes.deviceLibrary && musicRepository.deviceLibrary != null) {
// We now have a library, see if we have anything we need to do.
T.d("Library obtained, requesting action")
L.d("Library obtained, requesting action")
playbackManager.requestAction(this)
}
}
@ -523,17 +523,17 @@ class ExoPlaybackStateHolder(
private fun deferSave() {
saveJob {
T.d("Waiting for save buffer")
L.d("Waiting for save buffer")
delay(SAVE_BUFFER)
yield()
T.d("Committing saved state")
L.d("Committing saved state")
persistenceRepository.saveState(playbackManager.toSavedState())
}
}
private fun saveJob(block: suspend () -> Unit) {
currentSaveJob?.let {
T.d("Discarding prior save job")
L.d("Discarding prior save job")
it.cancel()
}
currentSaveJob = saveScope.launch { block() }

View file

@ -27,7 +27,7 @@ import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
import org.oxycblt.auxio.AuxioService
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [BroadcastReceiver] that forwards [Intent.ACTION_MEDIA_BUTTON] [Intent]s to
@ -47,7 +47,7 @@ class MediaButtonReceiver : BroadcastReceiver() {
// stupid this is with the state of foreground services on modern android. One
// wrong action at the wrong time will result in the app crashing, and there is
// nothing I can do about it.
T.d("Delivering media button intent $intent")
L.d("Delivering media button intent $intent")
intent.component = ComponentName(context, AuxioService::class.java)
ContextCompat.startForegroundService(context, intent)
}

View file

@ -49,7 +49,7 @@ import org.oxycblt.auxio.playback.state.QueueChange
import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.util.newBroadcastPendingIntent
import org.oxycblt.auxio.util.newMainPendingIntent
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A component that mirrors the current playback state into the [MediaSessionCompat] and
@ -210,10 +210,10 @@ private constructor(
* playback is currently occuring from all songs.
*/
private fun updateMediaMetadata(song: Song?, parent: MusicParent?) {
T.d("Updating media metadata to $song with $parent")
L.d("Updating media metadata to $song with $parent")
if (song == null) {
// Nothing playing, reset the MediaSession and close the notification.
T.d("Nothing playing, resetting media session")
L.d("Nothing playing, resetting media session")
mediaSession.setMetadata(emptyMetadata)
return
}
@ -252,15 +252,15 @@ private constructor(
MediaSessionUID.SingleItem(song.album.uid).toString())
// These fields are nullable and so we must check first before adding them to the fields.
song.track?.let {
T.d("Adding track information")
L.d("Adding track information")
builder.putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, it.toLong())
}
song.disc?.let {
T.d("Adding disc information")
L.d("Adding disc information")
builder.putLong(MediaMetadataCompat.METADATA_KEY_DISC_NUMBER, it.number.toLong())
}
song.date?.let {
T.d("Adding date information")
L.d("Adding date information")
builder.putString(MediaMetadataCompat.METADATA_KEY_DATE, it.toString())
builder.putLong(MediaMetadataCompat.METADATA_KEY_YEAR, it.year.toLong())
}
@ -272,7 +272,7 @@ private constructor(
song,
object : BitmapProvider.Target {
override fun onCompleted(bitmap: Bitmap?) {
T.d("Bitmap loaded, applying media session and posting notification")
L.d("Bitmap loaded, applying media session and posting notification")
if (bitmap != null) {
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ART, bitmap)
builder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap)
@ -300,13 +300,13 @@ private constructor(
// playback state.
MediaSessionCompat.QueueItem(description, i.toLong())
}
T.d("Uploading ${queueItems.size} songs to MediaSession queue")
L.d("Uploading ${queueItems.size} songs to MediaSession queue")
mediaSession.setQueue(queueItems)
}
/** Invalidate the current [MediaSessionCompat]'s [PlaybackStateCompat]. */
private fun invalidateSessionState() {
T.d("Updating media session playback state")
L.d("Updating media session playback state")
val state =
// InternalPlayer.State handles position/state information.
@ -322,7 +322,7 @@ private constructor(
val secondaryAction =
when (playbackSettings.notificationAction) {
ActionMode.SHUFFLE -> {
T.d("Using shuffle MediaSession action")
L.d("Using shuffle MediaSession action")
PlaybackStateCompat.CustomAction.Builder(
PlaybackActions.ACTION_INVERT_SHUFFLE,
context.getString(R.string.desc_shuffle),
@ -333,7 +333,7 @@ private constructor(
})
}
else -> {
T.d("Using repeat mode MediaSession action")
L.d("Using repeat mode MediaSession action")
PlaybackStateCompat.CustomAction.Builder(
PlaybackActions.ACTION_INC_REPEAT_MODE,
context.getString(R.string.desc_change_repeat),
@ -356,22 +356,22 @@ private constructor(
/** Invalidate the "secondary" action (i.e shuffle/repeat mode). */
private fun invalidateSecondaryAction() {
T.d("Invalidating secondary action")
L.d("Invalidating secondary action")
invalidateSessionState()
when (playbackSettings.notificationAction) {
ActionMode.SHUFFLE -> {
T.d("Using shuffle notification action")
L.d("Using shuffle notification action")
_notification.updateShuffled(playbackManager.isShuffled)
}
else -> {
T.d("Using repeat mode notification action")
L.d("Using repeat mode notification action")
_notification.updateRepeatMode(playbackManager.repeatMode)
}
}
if (!bitmapProvider.isBusy) {
T.d("Not loading a bitmap, post the notification")
L.d("Not loading a bitmap, post the notification")
foregroundListener.updateForeground(ForegroundListener.Change.MEDIA_SESSION)
}
}
@ -423,7 +423,7 @@ private class PlaybackNotification(
* @param metadata The [MediaMetadataCompat] to display in this notification.
*/
fun updateMetadata(metadata: MediaMetadataCompat) {
T.d("Updating shown metadata")
L.d("Updating shown metadata")
setLargeIcon(metadata.getBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART))
setContentTitle(metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE))
setContentText(metadata.getText(MediaMetadataCompat.METADATA_KEY_ARTIST))
@ -436,7 +436,7 @@ private class PlaybackNotification(
* @param isPlaying Whether playback should be indicated as ongoing or paused.
*/
fun updatePlaying(isPlaying: Boolean) {
T.d("Updating playing state: $isPlaying")
L.d("Updating playing state: $isPlaying")
mActions[2] = buildPlayPauseAction(context, isPlaying)
}
@ -446,7 +446,7 @@ private class PlaybackNotification(
* @param repeatMode The current [RepeatMode].
*/
fun updateRepeatMode(repeatMode: RepeatMode) {
T.d("Applying repeat mode action: $repeatMode")
L.d("Applying repeat mode action: $repeatMode")
mActions[0] = buildRepeatAction(context, repeatMode)
}
@ -456,7 +456,7 @@ private class PlaybackNotification(
* @param isShuffled Whether the queue is currently shuffled or not.
*/
fun updateShuffled(isShuffled: Boolean) {
T.d("Applying shuffle action: $isShuffled")
L.d("Applying shuffle action: $isShuffled")
mActions[0] = buildShuffleAction(context, isShuffled)
}

View file

@ -20,7 +20,6 @@ package org.oxycblt.auxio.playback.service
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.support.v4.media.MediaDescriptionCompat
@ -47,7 +46,7 @@ import org.oxycblt.auxio.playback.state.PlaybackCommand
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.playback.state.RepeatMode
import org.oxycblt.auxio.playback.state.ShuffleMode
import timber.log.Timber as T
import timber.log.Timber as L
class MediaSessionInterface
@Inject
@ -82,7 +81,7 @@ constructor(
val parentUid =
extras?.getString(MusicBrowser.KEY_CHILD_OF)?.let { MediaSessionUID.fromString(it) }
val command = expandUidIntoCommand(uid, parentUid)
T.d(extras?.getString(MusicBrowser.KEY_CHILD_OF))
L.d(extras?.getString(MusicBrowser.KEY_CHILD_OF))
playbackManager.play(requireNotNull(command) { "Invalid playback configuration" })
}
@ -295,9 +294,11 @@ constructor(
private fun expandSongIntoCommand(music: Song, parent: MusicParent?) =
when (parent) {
is Album -> commandFactory.songFromAlbum(music, ShuffleMode.IMPLICIT)
is Artist -> commandFactory.songFromArtist(music, parent, ShuffleMode.IMPLICIT)
is Artist ->
commandFactory.songFromArtist(music, parent, ShuffleMode.IMPLICIT)
?: commandFactory.songFromArtist(music, music.artists[0], ShuffleMode.IMPLICIT)
is Genre -> commandFactory.songFromGenre(music, parent, ShuffleMode.IMPLICIT)
is Genre ->
commandFactory.songFromGenre(music, parent, ShuffleMode.IMPLICIT)
?: commandFactory.songFromGenre(music, music.genres[0], ShuffleMode.IMPLICIT)
is Playlist -> commandFactory.songFromPlaylist(music, parent, ShuffleMode.IMPLICIT)
null -> commandFactory.songFromAll(music, ShuffleMode.IMPLICIT)

View file

@ -28,7 +28,7 @@ import org.oxycblt.auxio.IntegerTable
import org.oxycblt.auxio.playback.state.DeferredPlayback
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.widgets.WidgetComponent
import timber.log.Timber as T
import timber.log.Timber as L
class PlaybackServiceFragment
private constructor(
@ -86,7 +86,7 @@ private constructor(
fun start(startedBy: Int) {
// At minimum we want to ensure an active playback state.
// TODO: Possibly also force to go foreground?
T.d("Handling non-native start.")
L.d("Handling non-native start.")
val action =
when (startedBy) {
IntegerTable.START_ID_ACTIVITY -> null
@ -97,7 +97,7 @@ private constructor(
else -> DeferredPlayback.RestoreState(play = false)
}
if (action != null) {
T.d("Initing service fragment using action $action")
L.d("Initing service fragment using action $action")
playbackManager.playDeferred(action)
}
}

View file

@ -29,7 +29,7 @@ import org.oxycblt.auxio.playback.PlaybackSettings
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.widgets.WidgetComponent
import org.oxycblt.auxio.widgets.WidgetProvider
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A [BroadcastReceiver] for receiving playback-specific [Intent]s from the system that require an
@ -76,7 +76,7 @@ private constructor(
// 3. Some internal framework thing that also handles bluetooth headsets
// Just use ACTION_HEADSET_PLUG.
AudioManager.ACTION_HEADSET_PLUG -> {
T.d("Received headset plug event")
L.d("Received headset plug event")
when (intent.getIntExtra("state", -1)) {
0 -> pauseFromHeadsetPlug()
1 -> playFromHeadsetPlug()
@ -85,37 +85,37 @@ private constructor(
initialHeadsetPlugEventHandled = true
}
AudioManager.ACTION_AUDIO_BECOMING_NOISY -> {
T.d("Received Headset noise event")
L.d("Received Headset noise event")
pauseFromHeadsetPlug()
}
// --- AUXIO EVENTS ---
PlaybackActions.ACTION_PLAY_PAUSE -> {
T.d("Received play event")
L.d("Received play event")
playbackManager.playing(!playbackManager.progression.isPlaying)
}
PlaybackActions.ACTION_INC_REPEAT_MODE -> {
T.d("Received repeat mode event")
L.d("Received repeat mode event")
playbackManager.repeatMode(playbackManager.repeatMode.increment())
}
PlaybackActions.ACTION_INVERT_SHUFFLE -> {
T.d("Received shuffle event")
L.d("Received shuffle event")
playbackManager.shuffled(!playbackManager.isShuffled)
}
PlaybackActions.ACTION_SKIP_PREV -> {
T.d("Received skip previous event")
L.d("Received skip previous event")
playbackManager.prev()
}
PlaybackActions.ACTION_SKIP_NEXT -> {
T.d("Received skip next event")
L.d("Received skip next event")
playbackManager.next()
}
PlaybackActions.ACTION_EXIT -> {
T.d("Received exit event")
L.d("Received exit event")
playbackManager.endSession()
}
WidgetProvider.ACTION_WIDGET_UPDATE -> {
T.d("Received widget update event")
L.d("Received widget update event")
widgetComponent.update()
}
}
@ -128,14 +128,14 @@ private constructor(
if (playbackSettings.headsetAutoplay &&
playbackManager.currentSong != null &&
initialHeadsetPlugEventHandled) {
T.d("Device connected, resuming")
L.d("Device connected, resuming")
playbackManager.playing(true)
}
}
private fun pauseFromHeadsetPlug() {
if (playbackManager.currentSong != null) {
T.d("Device disconnected, pausing")
L.d("Device disconnected, pausing")
playbackManager.playing(false)
}
}

View file

@ -18,6 +18,7 @@
package org.oxycblt.auxio.playback.state
import javax.inject.Inject
import org.oxycblt.auxio.list.ListSettings
import org.oxycblt.auxio.list.sort.Sort
import org.oxycblt.auxio.music.Album
@ -28,7 +29,6 @@ import org.oxycblt.auxio.music.MusicRepository
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackSettings
import javax.inject.Inject
/**
* A playback command that can be passed to [PlaybackStateManager] to start new playback.

View file

@ -25,7 +25,7 @@ import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.PlaybackStateManager.Listener
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Core playback state controller class.
@ -387,11 +387,11 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun addListener(listener: Listener) {
T.d("Adding $listener to listeners")
L.d("Adding $listener to listeners")
listeners.add(listener)
if (isInitialized) {
T.d("Sending initial state to $listener")
L.d("Sending initial state to $listener")
listener.onNewPlayback(
stateMirror.parent, stateMirror.queue, stateMirror.index, stateMirror.isShuffled)
listener.onProgressionChanged(stateMirror.progression)
@ -401,16 +401,16 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun removeListener(listener: Listener) {
T.d("Removing $listener from listeners")
L.d("Removing $listener from listeners")
if (!listeners.remove(listener)) {
T.w("Listener $listener was not added prior, cannot remove")
L.w("Listener $listener was not added prior, cannot remove")
}
}
@Synchronized
override fun registerStateHolder(stateHolder: PlaybackStateHolder) {
if (this.stateHolder != null) {
T.w("Internal player is already registered")
L.w("Internal player is already registered")
return
}
@ -429,11 +429,11 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun unregisterStateHolder(stateHolder: PlaybackStateHolder) {
if (this.stateHolder !== stateHolder) {
T.w("Given internal player did not match current internal player")
L.w("Given internal player did not match current internal player")
return
}
T.d("Unregistering internal player $stateHolder")
L.d("Unregistering internal player $stateHolder")
this.stateHolder = null
}
@ -443,7 +443,7 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun play(command: PlaybackCommand) {
val stateHolder = stateHolder ?: return
T.d("Playing $command")
L.d("Playing $command")
// Played something, so we are initialized now
isInitialized = true
stateHolder.newPlayback(command)
@ -454,32 +454,32 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun next() {
val stateHolder = stateHolder ?: return
T.d("Going to next song")
L.d("Going to next song")
stateHolder.next()
}
@Synchronized
override fun prev() {
val stateHolder = stateHolder ?: return
T.d("Going to previous song")
L.d("Going to previous song")
stateHolder.prev()
}
@Synchronized
override fun goto(index: Int) {
val stateHolder = stateHolder ?: return
T.d("Going to index $index")
L.d("Going to index $index")
stateHolder.goto(index)
}
@Synchronized
override fun playNext(songs: List<Song>) {
if (currentSong == null) {
T.d("Nothing playing, short-circuiting to new playback")
L.d("Nothing playing, short-circuiting to new playback")
play(QueueCommand(songs))
} else {
val stateHolder = stateHolder ?: return
T.d("Adding ${songs.size} songs to start of queue")
L.d("Adding ${songs.size} songs to start of queue")
stateHolder.playNext(songs, StateAck.PlayNext(stateMirror.index + 1, songs.size))
}
}
@ -487,11 +487,11 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun addToQueue(songs: List<Song>) {
if (currentSong == null) {
T.d("Nothing playing, short-circuiting to new playback")
L.d("Nothing playing, short-circuiting to new playback")
play(QueueCommand(songs))
} else {
val stateHolder = stateHolder ?: return
T.d("Adding ${songs.size} songs to end of queue")
L.d("Adding ${songs.size} songs to end of queue")
stateHolder.addToQueue(songs, StateAck.AddToQueue(queue.size, songs.size))
}
}
@ -505,21 +505,21 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun moveQueueItem(src: Int, dst: Int) {
val stateHolder = stateHolder ?: return
T.d("Moving item $src to position $dst")
L.d("Moving item $src to position $dst")
stateHolder.move(src, dst, StateAck.Move(src, dst))
}
@Synchronized
override fun removeQueueItem(at: Int) {
val stateHolder = stateHolder ?: return
T.d("Removing item at $at")
L.d("Removing item at $at")
stateHolder.remove(at, StateAck.Remove(at))
}
@Synchronized
override fun shuffled(shuffled: Boolean) {
val stateHolder = stateHolder ?: return
T.d("Reordering queue [shuffled=$shuffled]")
L.d("Reordering queue [shuffled=$shuffled]")
stateHolder.shuffled(shuffled)
}
@ -529,7 +529,7 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
override fun playDeferred(action: DeferredPlayback) {
val stateHolder = stateHolder
if (stateHolder == null || !stateHolder.handleDeferred(action)) {
T.d("Internal player not present or did not consume action, waiting")
L.d("Internal player not present or did not consume action, waiting")
pendingDeferredPlayback = action
}
}
@ -537,12 +537,12 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun requestAction(stateHolder: PlaybackStateHolder) {
if (BuildConfig.DEBUG && this.stateHolder !== stateHolder) {
T.w("Given internal player did not match current internal player")
L.w("Given internal player did not match current internal player")
return
}
if (pendingDeferredPlayback?.let(stateHolder::handleDeferred) == true) {
T.d("Pending action consumed")
L.d("Pending action consumed")
pendingDeferredPlayback = null
}
}
@ -550,35 +550,35 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Synchronized
override fun playing(isPlaying: Boolean) {
val stateHolder = stateHolder ?: return
T.d("Updating playing state to $isPlaying")
L.d("Updating playing state to $isPlaying")
stateHolder.playing(isPlaying)
}
@Synchronized
override fun repeatMode(repeatMode: RepeatMode) {
val stateHolder = stateHolder ?: return
T.d("Updating repeat mode to $repeatMode")
L.d("Updating repeat mode to $repeatMode")
stateHolder.repeatMode(repeatMode)
}
@Synchronized
override fun seekTo(positionMs: Long) {
val stateHolder = stateHolder ?: return
T.d("Seeking to ${positionMs}ms")
L.d("Seeking to ${positionMs}ms")
stateHolder.seekTo(positionMs)
}
@Synchronized
override fun endSession() {
val stateHolder = stateHolder ?: return
T.d("Ending session")
L.d("Ending session")
stateHolder.endSession()
}
@Synchronized
override fun ack(stateHolder: PlaybackStateHolder, ack: StateAck) {
if (BuildConfig.DEBUG && this.stateHolder !== stateHolder) {
T.w("Given internal player did not match current internal player")
L.w("Given internal player did not match current internal player")
return
}
@ -729,7 +729,7 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
destructive: Boolean
) {
if (isInitialized && !destructive) {
T.w("Already initialized, cannot apply saved state")
L.w("Already initialized, cannot apply saved state")
return
}
@ -751,7 +751,7 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
}
}
T.d("Created adjustment mapping [max shift=$currentShift]")
L.d("Created adjustment mapping [max shift=$currentShift]")
val shuffledMapping =
savedState.shuffledMapping.mapNotNullTo(mutableListOf()) { index ->
@ -775,7 +775,7 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
index--
}
T.d("Corrected index: ${savedState.index} -> $index")
L.d("Corrected index: ${savedState.index} -> $index")
check(shuffledMapping.all { it in heap.indices }) {
"Queue inconsistency detected: Shuffled mapping indices out of heap bounds"

View file

@ -21,12 +21,10 @@ package org.oxycblt.auxio.playback.ui
import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.google.android.material.R as MR
import com.google.android.material.button.MaterialButton
import com.google.android.material.motion.MotionUtils
import org.oxycblt.auxio.ui.RippleFixMaterialButton
import timber.log.Timber as T
import org.oxycblt.auxio.ui.StationaryAnim
import timber.log.Timber as L
/**
* A [MaterialButton] that automatically morphs from a circle to a squircle shape appearance when
@ -47,13 +45,7 @@ class AnimatedMaterialButton : RippleFixMaterialButton {
private var currentCornerRadiusRatio = 0f
private var animator: ValueAnimator? = null
private val matInterpolator =
MotionUtils.resolveThemeInterpolator(
context, MR.attr.motionEasingStandardInterpolator, FastOutSlowInInterpolator())
private val matDuration =
MotionUtils.resolveThemeDuration(context, MR.attr.motionDurationMedium2, 300)
private val anim = StationaryAnim.forMediumComponent(context)
override fun setActivated(activated: Boolean) {
super.setActivated(activated)
@ -62,20 +54,17 @@ class AnimatedMaterialButton : RippleFixMaterialButton {
val targetRadius = if (activated) 0.3f else 0.5f
if (!isLaidOut) {
// Not laid out, initialize it without animation before drawing.
T.d("Not laid out, immediately updating corner radius")
L.d("Not laid out, immediately updating corner radius")
updateCornerRadiusRatio(targetRadius)
return
}
T.d("Starting corner radius animation")
L.d("Starting corner radius animation")
animator?.cancel()
animator =
ValueAnimator.ofFloat(currentCornerRadiusRatio, targetRadius).apply {
duration = matDuration.toLong()
interpolator = matInterpolator
addUpdateListener { updateCornerRadiusRatio(animatedValue as Float) }
start()
}
anim
.genericFloat(currentCornerRadiusRatio, targetRadius, ::updateCornerRadiusRatio)
.also { it.start() }
}
private fun updateCornerRadiusRatio(ratio: Float) {

View file

@ -25,7 +25,7 @@ import kotlin.math.max
import org.oxycblt.auxio.databinding.ViewSeekBarBinding
import org.oxycblt.auxio.playback.formatDurationDs
import org.oxycblt.auxio.util.inflater
import timber.log.Timber as T
import timber.log.Timber as L
/**
* A wrapper around [Slider] that shows position and duration values and sanitizes input to reduce
@ -81,11 +81,11 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
// zero, use 1 instead and disable the SeekBar.
val to = max(value, 1)
isEnabled = value > 0
T.d("Value sanitization finished [to=$to, enabled=$isEnabled]")
L.d("Value sanitization finished [to=$to, enabled=$isEnabled]")
// 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.
if (positionDs > to) {
T.d("Clamping invalid position [current: $positionDs new max: $to]")
L.d("Clamping invalid position [current: $positionDs new max: $to]")
binding.seekBarSlider.value = to.toFloat()
}
binding.seekBarSlider.valueTo = to.toFloat()
@ -93,14 +93,14 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
}
override fun onStartTrackingTouch(slider: Slider) {
T.d("Starting seek mode")
L.d("Starting seek mode")
// 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.
isActivated = true
}
override fun onStopTrackingTouch(slider: Slider) {
T.d("Confirming seek")
L.d("Confirming seek")
// End of seek event, send off new value to listener.
isActivated = false
listener?.onSeekConfirmed(slider.value.toLong())

View file

@ -29,7 +29,7 @@ import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.Playlist
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.info.Name
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Implements the fuzzy-ish searching algorithm used in the search view.
@ -67,7 +67,7 @@ interface SearchEngine {
class SearchEngineImpl @Inject constructor(@ApplicationContext private val context: Context) :
SearchEngine {
override suspend fun search(items: SearchEngine.Items, query: String): SearchEngine.Items {
T.d("Launching search for $query")
L.d("Launching search for $query")
return SearchEngine.Items(
songs =
items.songs?.searchListImpl(query) { q, song ->

View file

@ -64,7 +64,7 @@ import org.oxycblt.auxio.util.getSystemServiceCompat
import org.oxycblt.auxio.util.navigateSafe
import org.oxycblt.auxio.util.setFullWidthLookup
import org.oxycblt.auxio.util.showToast
import timber.log.Timber as T
import timber.log.Timber as L
/**
* The [ListFragment] providing search functionality for the music library.
@ -108,11 +108,11 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
getContentLauncher =
registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
if (uri == null) {
T.w("No URI returned from file picker")
L.w("No URI returned from file picker")
return@registerForActivityResult
}
T.d("Received playlist URI $uri")
L.d("Received playlist URI $uri")
musicModel.importPlaylist(uri, pendingImportTarget)
}
@ -139,7 +139,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
if (!launchedKeyboard) {
// Auto-open the keyboard when this view is shown
T.d("Keyboard is not shown yet")
L.d("Keyboard is not shown yet")
showKeyboard(this)
launchedKeyboard = true
}
@ -184,7 +184,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
if (item.itemId != R.id.submenu_filtering) {
// Is a change in filter mode and not just a junk submenu click, update
// the filtering within SearchViewModel.
T.d("Filter mode selected")
L.d("Filter mode selected")
item.isChecked = true
searchModel.setFilterOptionId(item.itemId)
return true
@ -222,7 +222,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
// I would make it so that the position is only scrolled back to the top when
// the query actually changes instead of once every re-creation event, but sadly
// that doesn't seem possible.
T.d("Update finished, scrolling to top")
L.d("Update finished, scrolling to top")
binding.searchRecycler.scrollToPosition(0)
}
}
@ -230,39 +230,39 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
private fun handleShow(show: Show?) {
when (show) {
is Show.SongDetails -> {
T.d("Navigating to ${show.song}")
L.d("Navigating to ${show.song}")
findNavController().navigateSafe(SearchFragmentDirections.showSong(show.song.uid))
}
is Show.SongAlbumDetails -> {
T.d("Navigating to the album of ${show.song}")
L.d("Navigating to the album of ${show.song}")
findNavController()
.navigateSafe(SearchFragmentDirections.showAlbum(show.song.album.uid))
}
is Show.AlbumDetails -> {
T.d("Navigating to ${show.album}")
L.d("Navigating to ${show.album}")
findNavController().navigateSafe(SearchFragmentDirections.showAlbum(show.album.uid))
}
is Show.ArtistDetails -> {
T.d("Navigating to ${show.artist}")
L.d("Navigating to ${show.artist}")
findNavController()
.navigateSafe(SearchFragmentDirections.showArtist(show.artist.uid))
}
is Show.SongArtistDecision -> {
T.d("Navigating to artist choices for ${show.song}")
L.d("Navigating to artist choices for ${show.song}")
findNavController()
.navigateSafe(SearchFragmentDirections.showArtistChoices(show.song.uid))
}
is Show.AlbumArtistDecision -> {
T.d("Navigating to artist choices for ${show.album}")
L.d("Navigating to artist choices for ${show.album}")
findNavController()
.navigateSafe(SearchFragmentDirections.showArtistChoices(show.album.uid))
}
is Show.GenreDetails -> {
T.d("Navigating to ${show.genre}")
L.d("Navigating to ${show.genre}")
findNavController().navigateSafe(SearchFragmentDirections.showGenre(show.genre.uid))
}
is Show.PlaylistDetails -> {
T.d("Navigating to ${show.playlist}")
L.d("Navigating to ${show.playlist}")
findNavController()
.navigateSafe(SearchFragmentDirections.showPlaylist(show.playlist.uid))
}
@ -296,7 +296,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
binding.searchSelectionToolbar.title = getString(R.string.fmt_selected, selected.size)
if (binding.searchToolbar.setVisible(R.id.search_selection_toolbar)) {
// New selection started, show the keyboard to make selection easier.
T.d("Significant selection occurred, hiding keyboard")
L.d("Significant selection occurred, hiding keyboard")
hideKeyboard()
}
} else {
@ -309,7 +309,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
val directions =
when (decision) {
is PlaylistDecision.Import -> {
T.d("Importing playlist")
L.d("Importing playlist")
pendingImportTarget = decision.target
requireNotNull(getContentLauncher) {
"Content picker launcher was not available"
@ -319,7 +319,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
return
}
is PlaylistDecision.Rename -> {
T.d("Renaming ${decision.playlist}")
L.d("Renaming ${decision.playlist}")
SearchFragmentDirections.renamePlaylist(
decision.playlist.uid,
decision.template,
@ -327,15 +327,15 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
decision.reason)
}
is PlaylistDecision.Delete -> {
T.d("Deleting ${decision.playlist}")
L.d("Deleting ${decision.playlist}")
SearchFragmentDirections.deletePlaylist(decision.playlist.uid)
}
is PlaylistDecision.Export -> {
T.d("Exporting ${decision.playlist}")
L.d("Exporting ${decision.playlist}")
SearchFragmentDirections.exportPlaylist(decision.playlist.uid)
}
is PlaylistDecision.Add -> {
T.d("Adding ${decision.songs.size} to a playlist")
L.d("Adding ${decision.songs.size} to a playlist")
SearchFragmentDirections.addToPlaylist(
decision.songs.map { it.uid }.toTypedArray())
}
@ -361,11 +361,11 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
val directions =
when (decision) {
is PlaybackDecision.PlayFromArtist -> {
T.d("Launching play from artist dialog for $decision")
L.d("Launching play from artist dialog for $decision")
SearchFragmentDirections.playFromArtist(decision.song.uid)
}
is PlaybackDecision.PlayFromGenre -> {
T.d("Launching play from artist dialog for $decision")
L.d("Launching play from artist dialog for $decision")
SearchFragmentDirections.playFromGenre(decision.song.uid)
}
}
@ -378,7 +378,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
* @param view The [View] to focus the keyboard on.
*/
private fun showKeyboard(view: View) {
T.d("Launching keyboard")
L.d("Launching keyboard")
view.apply {
requestFocus()
postDelayed(200) {
@ -390,7 +390,7 @@ class SearchFragment : ListFragment<Music, FragmentSearchBinding>() {
/** Safely hide the keyboard from this view. */
private fun hideKeyboard() {
T.d("Hiding keyboard")
L.d("Hiding keyboard")
requireNotNull(imm) { "InputMethodManager was not available" }
.hideSoftInputFromWindow(requireView().windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}

View file

@ -40,7 +40,7 @@ import org.oxycblt.auxio.music.device.DeviceLibrary
import org.oxycblt.auxio.music.user.UserLibrary
import org.oxycblt.auxio.playback.PlaySong
import org.oxycblt.auxio.playback.PlaybackSettings
import timber.log.Timber as T
import timber.log.Timber as L
/**
* An [ViewModel] that keeps performs search operations and tracks their results.
@ -79,7 +79,7 @@ constructor(
override fun onMusicChanges(changes: MusicRepository.Changes) {
if (changes.deviceLibrary || changes.userLibrary) {
T.d("Music changed, re-searching library")
L.d("Music changed, re-searching library")
search(lastQuery)
}
}
@ -98,13 +98,13 @@ constructor(
val deviceLibrary = musicRepository.deviceLibrary
val userLibrary = musicRepository.userLibrary
if (query.isNullOrEmpty() || deviceLibrary == null || userLibrary == null) {
T.d("Cannot search for the current query, aborting")
L.d("Cannot search for the current query, aborting")
_searchResults.value = listOf()
return
}
// Searching is time-consuming, so do it in the background.
T.d("Searching music library for $query")
L.d("Searching music library for $query")
currentSearchJob =
viewModelScope.launch {
_searchResults.value =
@ -122,7 +122,7 @@ constructor(
val items =
if (filter == null) {
// A nulled filter type means to not filter anything.
T.d("No filter specified, using entire library")
L.d("No filter specified, using entire library")
SearchEngine.Items(
deviceLibrary.songs,
deviceLibrary.albums,
@ -130,7 +130,7 @@ constructor(
deviceLibrary.genres,
userLibrary.playlists)
} else {
T.d("Filter specified, reducing library")
L.d("Filter specified, reducing library")
SearchEngine.Items(
songs = if (filter == MusicType.SONGS) deviceLibrary.songs else null,
albums = if (filter == MusicType.ALBUMS) deviceLibrary.albums else null,
@ -143,13 +143,13 @@ constructor(
return buildList {
results.artists?.let {
T.d("Adding ${it.size} artists to search results")
L.d("Adding ${it.size} artists to search results")
val header = BasicHeader(R.string.lbl_artists)
add(header)
addAll(SORT.artists(it))
}
results.albums?.let {
T.d("Adding ${it.size} albums to search results")
L.d("Adding ${it.size} albums to search results")
val header = BasicHeader(R.string.lbl_albums)
if (isNotEmpty()) {
add(PlainDivider(header))
@ -159,7 +159,7 @@ constructor(
addAll(SORT.albums(it))
}
results.playlists?.let {
T.d("Adding ${it.size} playlists to search results")
L.d("Adding ${it.size} playlists to search results")
val header = BasicHeader(R.string.lbl_playlists)
if (isNotEmpty()) {
add(PlainDivider(header))
@ -169,7 +169,7 @@ constructor(
addAll(SORT.playlists(it))
}
results.genres?.let {
T.d("Adding ${it.size} genres to search results")
L.d("Adding ${it.size} genres to search results")
val header = BasicHeader(R.string.lbl_genres)
if (isNotEmpty()) {
add(PlainDivider(header))
@ -179,7 +179,7 @@ constructor(
addAll(SORT.genres(it))
}
results.songs?.let {
T.d("Adding ${it.size} songs to search results")
L.d("Adding ${it.size} songs to search results")
val header = BasicHeader(R.string.lbl_songs)
if (isNotEmpty()) {
add(PlainDivider(header))
@ -225,7 +225,7 @@ constructor(
R.id.option_filter_all -> null
else -> error("Invalid option ID provided")
}
T.d("Updating filter type to $newFilter")
L.d("Updating filter type to $newFilter")
searchSettings.filterTo = newFilter
search(lastQuery)
}

View file

@ -38,7 +38,7 @@ import org.oxycblt.auxio.settings.ui.IntListPreferenceDialog
import org.oxycblt.auxio.settings.ui.PreferenceHeaderItemDecoration
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.util.systemBarInsetsCompat
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Shared [PreferenceFragmentCompat] used across all preference screens.
@ -82,7 +82,7 @@ abstract class BasePreferenceFragment(@XmlRes private val screen: Int) :
preferenceManager.onDisplayPreferenceDialogListener = this
preferenceScreen.children.forEach(::setupPreference)
T.d("Fragment created")
L.d("Fragment created")
}
override fun onCreateRecyclerView(

View file

@ -30,7 +30,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.MusicViewModel
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.util.navigateSafe
import timber.log.Timber as T
import timber.log.Timber as L
/**
* The [PreferenceFragmentCompat] that displays the root settings list.
@ -62,21 +62,21 @@ class RootPreferenceFragment : BasePreferenceFragment(R.xml.preferences_root) {
// do one.
when (preference.key) {
getString(R.string.set_key_ui) -> {
T.d("Navigating to UI preferences")
L.d("Navigating to UI preferences")
findNavController().navigateSafe(RootPreferenceFragmentDirections.uiPreferences())
}
getString(R.string.set_key_personalize) -> {
T.d("Navigating to personalization preferences")
L.d("Navigating to personalization preferences")
findNavController()
.navigateSafe(RootPreferenceFragmentDirections.personalizePreferences())
}
getString(R.string.set_key_music) -> {
T.d("Navigating to music preferences")
L.d("Navigating to music preferences")
findNavController()
.navigateSafe(RootPreferenceFragmentDirections.musicPreferences())
}
getString(R.string.set_key_audio) -> {
T.d("Navigating to audio preferences")
L.d("Navigating to audio preferences")
findNavController().navigateSafe(RootPreferenceFragmentDirections.audioPeferences())
}
getString(R.string.set_key_reindex) -> musicModel.refresh()

View file

@ -23,7 +23,7 @@ import android.content.SharedPreferences
import androidx.annotation.StringRes
import androidx.preference.PreferenceManager
import org.oxycblt.auxio.util.unlikelyToBeNull
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Abstract user configuration information. This interface has no functionality whatsoever. Concrete
@ -73,19 +73,19 @@ interface Settings<L> {
override fun registerListener(listener: L) {
if (this.listener == null) {
// Registering a listener when it was null prior, attach the callback.
T.d("Registering shared preference listener")
L.d("Registering shared preference listener")
sharedPreferences.registerOnSharedPreferenceChangeListener(this)
}
T.d("Registering listener $listener")
L.d("Registering listener $listener")
this.listener = listener
}
override fun unregisterListener(listener: L) {
if (this.listener !== listener) {
T.w("Given listener was not the current listener.")
L.w("Given listener was not the current listener.")
return
}
T.d("Unregistering listener $listener")
L.d("Unregistering listener $listener")
this.listener = null
// No longer have a listener, detach from the preferences instance.
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this)
@ -96,7 +96,7 @@ interface Settings<L> {
key: String?
) {
// FIXME: Settings initialization firing the listener.
T.d("Dispatching settings change $key")
L.d("Dispatching settings change $key")
onSettingChanged(unlikelyToBeNull(key), unlikelyToBeNull(listener))
}

View file

@ -23,7 +23,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.BasePreferenceFragment
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.util.navigateSafe
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Audio settings interface.
@ -34,7 +34,7 @@ class AudioPreferenceFragment : BasePreferenceFragment(R.xml.preferences_audio)
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_pre_amp)) {
T.d("Navigating to pre-amp dialog")
L.d("Navigating to pre-amp dialog")
findNavController().navigateSafe(AudioPreferenceFragmentDirections.preAmpSettings())
}
}

View file

@ -27,7 +27,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.BasePreferenceFragment
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.util.navigateSafe
import timber.log.Timber as T
import timber.log.Timber as L
/**
* "Content" settings.
@ -40,7 +40,7 @@ class MusicPreferenceFragment : BasePreferenceFragment(R.xml.preferences_music)
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_separators)) {
T.d("Navigating to separator dialog")
L.d("Navigating to separator dialog")
findNavController().navigateSafe(MusicPreferenceFragmentDirections.separatorsSettings())
}
}
@ -48,10 +48,10 @@ class MusicPreferenceFragment : BasePreferenceFragment(R.xml.preferences_music)
override fun onSetupPreference(preference: Preference) {
if (preference.key == getString(R.string.set_key_cover_mode) ||
preference.key == getString(R.string.set_key_square_covers)) {
T.d("Configuring cover mode setting")
L.d("Configuring cover mode setting")
preference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, _ ->
T.d("Cover mode changed, resetting image memory cache")
L.d("Cover mode changed, resetting image memory cache")
imageLoader.memoryCache?.clear()
true
}

View file

@ -23,7 +23,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.settings.BasePreferenceFragment
import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.util.navigateSafe
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Personalization settings interface.
@ -33,7 +33,7 @@ import timber.log.Timber as T
class PersonalizePreferenceFragment : BasePreferenceFragment(R.xml.preferences_personalize) {
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_home_tabs)) {
T.d("Navigating to home tab dialog")
L.d("Navigating to home tab dialog")
findNavController().navigateSafe(PersonalizePreferenceFragmentDirections.tabSettings())
}
}

View file

@ -29,7 +29,7 @@ import org.oxycblt.auxio.settings.ui.WrappedDialogPreference
import org.oxycblt.auxio.ui.UISettings
import org.oxycblt.auxio.util.isNight
import org.oxycblt.auxio.util.navigateSafe
import timber.log.Timber as T
import timber.log.Timber as L
/**
* Display preferences.
@ -42,7 +42,7 @@ class UIPreferenceFragment : BasePreferenceFragment(R.xml.preferences_ui) {
override fun onOpenDialogPreference(preference: WrappedDialogPreference) {
if (preference.key == getString(R.string.set_key_accent)) {
T.d("Navigating to accent dialog")
L.d("Navigating to accent dialog")
findNavController().navigateSafe(UIPreferenceFragmentDirections.accentSettings())
}
}
@ -50,25 +50,25 @@ class UIPreferenceFragment : BasePreferenceFragment(R.xml.preferences_ui) {
override fun onSetupPreference(preference: Preference) {
when (preference.key) {
getString(R.string.set_key_theme) -> {
T.d("Configuring theme setting")
L.d("Configuring theme setting")
preference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, value ->
T.d("Theme changed, recreating")
L.d("Theme changed, recreating")
AppCompatDelegate.setDefaultNightMode(value as Int)
true
}
}
getString(R.string.set_key_accent) -> {
T.d("Configuring accent setting")
L.d("Configuring accent setting")
preference.summary = getString(uiSettings.accent.name)
}
getString(R.string.set_key_black_theme) -> {
T.d("Configuring black theme setting")
L.d("Configuring black theme setting")
preference.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, _ ->
val activity = requireActivity()
if (activity.isNight) {
T.d("Black theme changed in night mode, recreating")
L.d("Black theme changed in night mode, recreating")
activity.recreate()
}

Some files were not shown because too many files have changed in this diff Show more