all: reformat code
This commit is contained in:
parent
00401430f7
commit
affe5c482b
17 changed files with 82 additions and 45 deletions
|
@ -15,7 +15,7 @@
|
||||||
- Added setting to hide "collaborator" artists
|
- Added setting to hide "collaborator" artists
|
||||||
- Upgraded music ID management:
|
- Upgraded music ID management:
|
||||||
- Added support for MusicBrainz IDs (MBIDs)
|
- Added support for MusicBrainz IDs (MBIDs)
|
||||||
- Use the more unique MD5 hash of metadata when MBIDs can't be used
|
- Use a more unique hash of metadata when MBIDs can't be used
|
||||||
- Genres now display a list of artists
|
- Genres now display a list of artists
|
||||||
- Added toggle to load non-music (Such as podcasts)
|
- Added toggle to load non-music (Such as podcasts)
|
||||||
- Music loader now caches parsed metadata for faster load times
|
- Music loader now caches parsed metadata for faster load times
|
||||||
|
|
|
@ -121,3 +121,7 @@ spotless {
|
||||||
licenseHeaderFile("NOTICE")
|
licenseHeaderFile("NOTICE")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
preDebugBuild.dependsOn spotlessApply
|
||||||
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
||||||
import org.oxycblt.auxio.list.selection.SelectionViewModel
|
import org.oxycblt.auxio.list.selection.SelectionViewModel
|
||||||
import org.oxycblt.auxio.music.Artist
|
|
||||||
import org.oxycblt.auxio.music.Music
|
import org.oxycblt.auxio.music.Music
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.playback.PlaybackBottomSheetBehavior
|
import org.oxycblt.auxio.playback.PlaybackBottomSheetBehavior
|
||||||
|
|
|
@ -292,7 +292,7 @@ class HomeFragment :
|
||||||
// Check the ascending option and corresponding sort option to align with
|
// Check the ascending option and corresponding sort option to align with
|
||||||
// the current sort of the tab.
|
// the current sort of the tab.
|
||||||
if (option.itemId == toHighlight.mode.itemId ||
|
if (option.itemId == toHighlight.mode.itemId ||
|
||||||
(option.itemId == R.id.option_sort_asc && toHighlight.isAscending)) {
|
(option.itemId == R.id.option_sort_asc && toHighlight.isAscending)) {
|
||||||
option.isChecked = true
|
option.isChecked = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,8 @@ object Covers {
|
||||||
@Suppress("BlockingMethodInNonBlockingContext")
|
@Suppress("BlockingMethodInNonBlockingContext")
|
||||||
private suspend fun fetchMediaStoreCovers(context: Context, album: Album): InputStream? {
|
private suspend fun fetchMediaStoreCovers(context: Context, album: Album): InputStream? {
|
||||||
// Eliminate any chance that this blocking call might mess up the loading process
|
// Eliminate any chance that this blocking call might mess up the loading process
|
||||||
return withContext(Dispatchers.IO) { context.contentResolver.openInputStream(album.coverUri) }
|
return withContext(Dispatchers.IO) {
|
||||||
|
context.contentResolver.openInputStream(album.coverUri)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -387,8 +387,7 @@ private class CacheDatabase(context: Context) :
|
||||||
* @return A list of strings corresponding to the delimited values present within the original
|
* @return A list of strings corresponding to the delimited values present within the original
|
||||||
* string. Escaped delimiters are converted back into their normal forms.
|
* string. Escaped delimiters are converted back into their normal forms.
|
||||||
*/
|
*/
|
||||||
private fun String.parseSQLMultiValue() =
|
private fun String.parseSQLMultiValue() = splitEscaped { it == ';' }.correctWhitespace()
|
||||||
splitEscaped { it == ';' }.correctWhitespace()
|
|
||||||
|
|
||||||
/** Defines the columns used in this database. */
|
/** Defines the columns used in this database. */
|
||||||
private object Columns {
|
private object Columns {
|
||||||
|
|
|
@ -17,11 +17,9 @@
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.extractor
|
package org.oxycblt.auxio.music.extractor
|
||||||
|
|
||||||
import androidx.core.text.isDigitsOnly
|
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import org.oxycblt.auxio.music.Date
|
import org.oxycblt.auxio.music.Date
|
||||||
import org.oxycblt.auxio.settings.Settings
|
import org.oxycblt.auxio.settings.Settings
|
||||||
import org.oxycblt.auxio.util.logD
|
|
||||||
import org.oxycblt.auxio.util.nonZeroOrNull
|
import org.oxycblt.auxio.util.nonZeroOrNull
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -117,8 +115,8 @@ inline fun String.splitEscaped(selector: (Char) -> Boolean): List<String> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fix trailing whitespace or blank contents in a [String].
|
* Fix trailing whitespace or blank contents in a [String].
|
||||||
* @return A string with trailing whitespace remove,d or null if the [String] was all whitespace
|
* @return A string with trailing whitespace remove,d or null if the [String] was all whitespace or
|
||||||
* or empty.
|
* empty.
|
||||||
*/
|
*/
|
||||||
fun String.correctWhitespace() = trim().ifBlank { null }
|
fun String.correctWhitespace() = trim().ifBlank { null }
|
||||||
|
|
||||||
|
@ -197,12 +195,15 @@ private fun String.parseId3v1Genre(): String? {
|
||||||
// ID3v1 genres are a plain integer value without formatting, so in that case
|
// ID3v1 genres are a plain integer value without formatting, so in that case
|
||||||
// try to index the genre table with such. If this fails, then try to compare it
|
// try to index the genre table with such. If this fails, then try to compare it
|
||||||
// to some other hard-coded values.
|
// to some other hard-coded values.
|
||||||
val numeric = toIntOrNull() ?: return when (this) {
|
val numeric =
|
||||||
// CR and RX are not technically ID3v1, but are formatted similarly to a plain number.
|
toIntOrNull()
|
||||||
"CR" -> "Cover"
|
?: return when (this) {
|
||||||
"RX" -> "Remix"
|
// CR and RX are not technically ID3v1, but are formatted similarly to a plain
|
||||||
else -> null
|
// number.
|
||||||
}
|
"CR" -> "Cover"
|
||||||
|
"RX" -> "Remix"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
return GENRE_TABLE.getOrNull(numeric)
|
return GENRE_TABLE.getOrNull(numeric)
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,16 +61,17 @@ class SeparatorsDialog : ViewBindingDialogFragment<DialogSeparatorsBinding>() {
|
||||||
// More efficient to do one iteration through the separator list and initialize
|
// More efficient to do one iteration through the separator list and initialize
|
||||||
// the corresponding CheckBox for each character instead of doing an iteration
|
// the corresponding CheckBox for each character instead of doing an iteration
|
||||||
// through the separator list for each CheckBox.
|
// through the separator list for each CheckBox.
|
||||||
(savedInstanceState?.getString(KEY_PENDING_SEPARATORS) ?: settings.musicSeparators)?.forEach {
|
(savedInstanceState?.getString(KEY_PENDING_SEPARATORS) ?: settings.musicSeparators)
|
||||||
when (it) {
|
?.forEach {
|
||||||
SEPARATOR_COMMA -> binding.separatorComma.isChecked = true
|
when (it) {
|
||||||
SEPARATOR_SEMICOLON -> binding.separatorSemicolon.isChecked = true
|
SEPARATOR_COMMA -> binding.separatorComma.isChecked = true
|
||||||
SEPARATOR_SLASH -> binding.separatorSlash.isChecked = true
|
SEPARATOR_SEMICOLON -> binding.separatorSemicolon.isChecked = true
|
||||||
SEPARATOR_PLUS -> binding.separatorPlus.isChecked = true
|
SEPARATOR_SLASH -> binding.separatorSlash.isChecked = true
|
||||||
SEPARATOR_AND -> binding.separatorAnd.isChecked = true
|
SEPARATOR_PLUS -> binding.separatorPlus.isChecked = true
|
||||||
else -> error("Unexpected separator in settings data")
|
SEPARATOR_AND -> binding.separatorAnd.isChecked = true
|
||||||
|
else -> error("Unexpected separator in settings data")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSaveInstanceState(outState: Bundle) {
|
override fun onSaveInstanceState(outState: Bundle) {
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Auxio Project
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.picker
|
package org.oxycblt.auxio.music.picker
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Auxio Project
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.oxycblt.auxio.music.picker
|
package org.oxycblt.auxio.music.picker
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -21,7 +38,8 @@ import org.oxycblt.auxio.util.collectImmediately
|
||||||
* A picker [ViewBindingDialogFragment] intended for when [Genre] playback is ambiguous.
|
* A picker [ViewBindingDialogFragment] intended for when [Genre] playback is ambiguous.
|
||||||
* @author Alexander Capehart (OxygenCobalt)
|
* @author Alexander Capehart (OxygenCobalt)
|
||||||
*/
|
*/
|
||||||
class GenrePlaybackPickerDialog : ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener {
|
class GenrePlaybackPickerDialog :
|
||||||
|
ViewBindingDialogFragment<DialogMusicPickerBinding>(), ClickableListListener {
|
||||||
private val pickerModel: PickerViewModel by viewModels()
|
private val pickerModel: PickerViewModel by viewModels()
|
||||||
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
private val playbackModel: PlaybackViewModel by androidActivityViewModels()
|
||||||
// Information about what Song to show choices for is initially within the navigation arguments
|
// Information about what Song to show choices for is initially within the navigation arguments
|
||||||
|
@ -63,4 +81,4 @@ class GenrePlaybackPickerDialog : ViewBindingDialogFragment<DialogMusicPickerBin
|
||||||
check(song is Song) { "Unexpected datatype: ${item::class.simpleName}" }
|
check(song is Song) { "Unexpected datatype: ${item::class.simpleName}" }
|
||||||
playbackModel.playFromGenre(song, item)
|
playbackModel.playFromGenre(song, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,8 @@ class PickerViewModel : ViewModel(), MusicStore.Callback {
|
||||||
|
|
||||||
private val _currentItem = MutableStateFlow<Music?>(null)
|
private val _currentItem = MutableStateFlow<Music?>(null)
|
||||||
/** The current item whose artists should be shown in the picker. Null if there is no item. */
|
/** The current item whose artists should be shown in the picker. Null if there is no item. */
|
||||||
val currentItem: StateFlow<Music?> get() = _currentItem
|
val currentItem: StateFlow<Music?>
|
||||||
|
get() = _currentItem
|
||||||
|
|
||||||
private val _artistChoices = MutableStateFlow<List<Artist>>(listOf())
|
private val _artistChoices = MutableStateFlow<List<Artist>>(listOf())
|
||||||
/** The current [Artist] choices. Empty if no item is shown in the picker. */
|
/** The current [Artist] choices. Empty if no item is shown in the picker. */
|
||||||
|
@ -75,5 +76,4 @@ class PickerViewModel : ViewModel(), MusicStore.Callback {
|
||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,10 @@
|
||||||
package org.oxycblt.auxio.music.storage
|
package org.oxycblt.auxio.music.storage
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.media.MediaExtractor
|
|
||||||
import android.media.MediaFormat
|
import android.media.MediaFormat
|
||||||
import android.os.storage.StorageManager
|
import android.os.storage.StorageManager
|
||||||
import android.os.storage.StorageVolume
|
import android.os.storage.StorageVolume
|
||||||
import android.webkit.MimeTypeMap
|
import android.webkit.MimeTypeMap
|
||||||
import com.google.android.exoplayer2.util.MimeTypes
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,8 @@ class PlaybackViewModel(application: Application) :
|
||||||
|
|
||||||
private val _artistPlaybackPickerSong = MutableStateFlow<Song?>(null)
|
private val _artistPlaybackPickerSong = MutableStateFlow<Song?>(null)
|
||||||
/**
|
/**
|
||||||
* Flag signaling to open a picker dialog in order to resolve an ambiguous choice when
|
* Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing a
|
||||||
* playing a [Song] from one of it's [Artist]s.
|
* [Song] from one of it's [Artist]s.
|
||||||
* @see playFromArtist
|
* @see playFromArtist
|
||||||
*/
|
*/
|
||||||
val artistPickerSong: StateFlow<Song?>
|
val artistPickerSong: StateFlow<Song?>
|
||||||
|
@ -79,8 +79,8 @@ class PlaybackViewModel(application: Application) :
|
||||||
|
|
||||||
private val _genrePlaybackPickerSong = MutableStateFlow<Song?>(null)
|
private val _genrePlaybackPickerSong = MutableStateFlow<Song?>(null)
|
||||||
/**
|
/**
|
||||||
* Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing
|
* Flag signaling to open a picker dialog in order to resolve an ambiguous choice when playing a
|
||||||
* a [Song] from one of it's [Genre]s.
|
* [Song] from one of it's [Genre]s.
|
||||||
*/
|
*/
|
||||||
val genrePickerSong: StateFlow<Song?>
|
val genrePickerSong: StateFlow<Song?>
|
||||||
get() = _genrePlaybackPickerSong
|
get() = _genrePlaybackPickerSong
|
||||||
|
|
|
@ -165,9 +165,7 @@ class Settings(private val context: Context, private val callback: Callback? = n
|
||||||
unlikelyToBeNull(callback).onSettingChanged(key)
|
unlikelyToBeNull(callback).onSettingChanged(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** Simplified callback for settings changes. */
|
||||||
* Simplified callback for settings changes.
|
|
||||||
*/
|
|
||||||
interface Callback {
|
interface Callback {
|
||||||
// TODO: Refactor this lifecycle
|
// TODO: Refactor this lifecycle
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -92,8 +92,8 @@ class NavigationViewModel : ViewModel() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigate to one of the parent [Artist]'s of the given [Song].
|
* Navigate to one of the parent [Artist]'s of the given [Song].
|
||||||
* @param song The [Song] to navigate with. If there are multiple parent [Artist]s,
|
* @param song The [Song] to navigate with. If there are multiple parent [Artist]s, a picker
|
||||||
* a picker dialog will be shown.
|
* dialog will be shown.
|
||||||
*/
|
*/
|
||||||
fun exploreNavigateToParentArtist(song: Song) {
|
fun exploreNavigateToParentArtist(song: Song) {
|
||||||
exploreNavigateToParentArtistImpl(song, song.artists)
|
exploreNavigateToParentArtistImpl(song, song.artists)
|
||||||
|
@ -101,8 +101,8 @@ class NavigationViewModel : ViewModel() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigate to one of the parent [Artist]'s of the given [Album].
|
* Navigate to one of the parent [Artist]'s of the given [Album].
|
||||||
* @param album The [Album] to navigate with. If there are multiple parent [Artist]s,
|
* @param album The [Album] to navigate with. If there are multiple parent [Artist]s, a picker
|
||||||
* a picker dialog will be shown.
|
* dialog will be shown.
|
||||||
*/
|
*/
|
||||||
fun exploreNavigateToParentArtist(album: Album) {
|
fun exploreNavigateToParentArtist(album: Album) {
|
||||||
exploreNavigateToParentArtistImpl(album, album.artists)
|
exploreNavigateToParentArtistImpl(album, album.artists)
|
||||||
|
|
|
@ -80,8 +80,8 @@ fun RemoteViews.setLayoutDirection(@IdRes viewId: Int, layoutDirection: Int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the app widget layouts corresponding to the given [WidgetProvider] [ComponentName] with
|
* Update the app widget layouts corresponding to the given [WidgetProvider] [ComponentName] with an
|
||||||
* an adaptive layout, in a version-compatible manner.
|
* adaptive layout, in a version-compatible manner.
|
||||||
* @param context [Context] required to backport adaptive layout behavior.
|
* @param context [Context] required to backport adaptive layout behavior.
|
||||||
* @param component [ComponentName] of the app widget layout to update.
|
* @param component [ComponentName] of the app widget layout to update.
|
||||||
* @param views Mapping between different size classes and [RemoteViews] instances.
|
* @param views Mapping between different size classes and [RemoteViews] instances.
|
||||||
|
|
|
@ -60,7 +60,7 @@ if os.getenv("ANDROID_HOME") is None and os.getenv("ANDROID_SDK_ROOT") is None:
|
||||||
"ANDROID_HOME/ANDROID_SDK_ROOT before continuing.")
|
"ANDROID_HOME/ANDROID_SDK_ROOT before continuing.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
ndk_path = os.getenv("NDK_PATH")
|
ndk_path = os.getenv("ANDROID_NDK_HOME")
|
||||||
if ndk_path is None or not os.path.isfile(os.path.join(ndk_path, "ndk-build")):
|
if ndk_path is None or not os.path.isfile(os.path.join(ndk_path, "ndk-build")):
|
||||||
# We don't have a proper path. Do some digging on the Android SDK directory
|
# We don't have a proper path. Do some digging on the Android SDK directory
|
||||||
# to see if we can find it.
|
# to see if we can find it.
|
||||||
|
|
Loading…
Reference in a new issue