diff --git a/README.md b/README.md index 49bd4f1d5..ebdbf9a85 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ I primarily built Auxio for myself, but you can use it too, I guess. - Search Functionality - Audio/Headset focus - Completely private and offline -- No rounded album covers +- No rounded album covers (Unless you want them. Then you can.) ## To possibly come in the future: diff --git a/app/build.gradle b/app/build.gradle index 628532ca4..e7a25566b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,8 +4,8 @@ apply plugin: "kotlin-kapt" apply plugin: "androidx.navigation.safeargs.kotlin" android { - compileSdkVersion 31 - buildToolsVersion "31.0.0" + compileSdkVersion 32 + buildToolsVersion "32.0.0" defaultConfig { applicationId "org.oxycblt.auxio" @@ -13,7 +13,7 @@ android { versionCode 10 minSdkVersion 21 - targetSdkVersion 31 + targetSdkVersion 32 buildFeatures { dataBinding true diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3e8f565a2..36c208036 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,13 @@ + + + android:theme="@style/Theme.Auxio.App" + android:dataExtractionRules="@xml/data_extraction_rules" + tools:ignore="UnusedAttribute"> item.id == song.id && item is Song } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt index f77ebbdd1..30cfa5a54 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/recycler/GenreDetailAdapter.kt @@ -71,7 +71,7 @@ class GenreDetailAdapter( ActionHeaderViewHolder.ITEM_TYPE -> ActionHeaderViewHolder.from(parent.context) - else -> error("Bad viewholder item type $viewType") + else -> error("Bad ViewHolder item type $viewType") } } @@ -102,9 +102,9 @@ class GenreDetailAdapter( * @param recycler The recyclerview the highlighting should act on. */ fun highlightSong(song: Song?, recycler: RecyclerView) { - if (song == currentSong) return // Already highlighting this viewholder + if (song == currentSong) return // Already highlighting this ViewHolder - // Clear the current viewholder since it's invalid + // Clear the current ViewHolder since it's invalid currentHolder?.setHighlighted(false) currentHolder = null currentSong = song diff --git a/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDialog.kt b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDialog.kt index 7e3671af1..5949a5d47 100644 --- a/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDialog.kt @@ -105,7 +105,7 @@ class ExcludedDialog : LifecycleDialog() { override fun onConfigDialog(builder: AlertDialog.Builder) { builder.setTitle(R.string.set_excluded) - // Dont set the click listener here, we do some custom black magic in onCreateView instead. + // Don't set the click listener here, we do some custom black magic in onCreateView instead. builder.setNeutralButton(R.string.lbl_add, null) builder.setPositiveButton(R.string.lbl_save, null) builder.setNegativeButton(android.R.string.cancel, null) @@ -136,9 +136,9 @@ class ExcludedDialog : LifecycleDialog() { // Turn it into a semi-usable path val typeAndPath = DocumentsContract.getTreeDocumentId(docUri).split(":") - // Only the main drive is supported, since thats all we can get from MediaColumns.DATA - // Unless I change the system to use the drive/directory system, but thats limited to - // Android 10 + // Only the main drive is supported, since that's all we can get from MediaColumns.DATA + // Unless I change the system to use the drive/directory system, that is. But there's no + // demand for that. if (typeAndPath[0] == "primary") { return getRootPath() + "/" + typeAndPath.last() } diff --git a/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedViewModel.kt b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedViewModel.kt index cb91c1fa6..504cb4f73 100644 --- a/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedViewModel.kt @@ -49,7 +49,7 @@ class ExcludedViewModel(private val excludedDatabase: ExcludedDatabase) : ViewMo } /** - * Add a path to this viewmodel. It will not write the path to the database unless + * Add a path to this ViewModel. It will not write the path to the database unless * [save] is called. */ fun addPath(path: String) { @@ -60,7 +60,7 @@ class ExcludedViewModel(private val excludedDatabase: ExcludedDatabase) : ViewMo } /** - * Remove a path from this viewmodel, it will not remove this path from the database unless + * Remove a path from this ViewModel, it will not remove this path from the database unless * [save] is called. */ fun removePath(path: String) { diff --git a/app/src/main/java/org/oxycblt/auxio/home/AdaptiveFloatingActionButton.kt b/app/src/main/java/org/oxycblt/auxio/home/AdaptiveFloatingActionButton.kt index 4fec30a73..61a7afe11 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/AdaptiveFloatingActionButton.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/AdaptiveFloatingActionButton.kt @@ -5,6 +5,7 @@ import android.util.AttributeSet import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.R as MaterialR +@Suppress("PrivateResource") class AdaptiveFloatingActionButton @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, diff --git a/app/src/main/java/org/oxycblt/auxio/home/tabs/TabCustomizeDialog.kt b/app/src/main/java/org/oxycblt/auxio/home/tabs/TabCustomizeDialog.kt index 2183b275b..5dfa61a1f 100644 --- a/app/src/main/java/org/oxycblt/auxio/home/tabs/TabCustomizeDialog.kt +++ b/app/src/main/java/org/oxycblt/auxio/home/tabs/TabCustomizeDialog.kt @@ -63,7 +63,7 @@ class TabCustomizeDialog : LifecycleDialog() { getTabs = { pendingTabs }, onTabSwitch = { tab -> // Don't find the specific tab [Which might be outdated due to the nature - // of how viewholders are bound], but instead simply look for the mode in + // of how ViewHolders are bound], but instead simply look for the mode in // the list of pending tabs and update that instead. val index = pendingTabs.indexOfFirst { it.mode == tab.mode } diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt index 968a37ca6..540cfcb65 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt @@ -18,7 +18,7 @@ import org.oxycblt.auxio.excluded.ExcludedDatabase * * You think that if you wanted to query a song's genre from a media database, you could just * put "genre" in the query and it would return it, right? But not with MediaStore! No, that's - * too straightfoward for this class that was dropped on it's head as a baby. So instead, you + * too straightforward for this class that was dropped on it's head as a baby. So instead, you * have to query for each genre, query all the songs in each genre, and then iterate through those * songs to link every song with their genre. This is not documented anywhere, and the * O(mom im scared) algorithm you have to run to get it working single-handedly DOUBLES Auxio's @@ -28,7 +28,7 @@ import org.oxycblt.auxio.excluded.ExcludedDatabase * * It's not even ergonomics that makes this API bad. It's base implementation is completely borked * as well. Did you know that MediaStore doesn't accept dates that aren't from ID3v2.3 MP3 files? - * I sure didn't, until I decided to upgrade my music collection to ID3v2.4 and Xiph only to see + * I sure didn't, until I decided to upgrade my music collection to ID3v2.4 and FLAC only to see * that their metadata parser has a brain aneurysm the moment it stumbles upon a dreaded TRDC or * DATE tag. Once again, this is because internally android uses an ancient in-house metadata * parser to get everything indexed, and so far they have not bothered to modernize this parser @@ -36,7 +36,7 @@ import org.oxycblt.auxio.excluded.ExcludedDatabase * been around for 21 years. It can drink now. All of my what. * * Not to mention all the other infuriating quirks. Album artists can't be accessed from the albums - * table, so we have to go for the less efficent "make a big query on all the songs lol" method + * table, so we have to go for the less efficient "make a big query on all the songs lol" method * so that songs don't end up fragmented across artists. Pretty much every OEM has added some * extension or quirk to MediaStore that I cannot reproduce, with some OEMs (COUGHSAMSUNGCOUGH) * crippling the normal tables so that you're railroaded into their music app. The way I do @@ -67,6 +67,7 @@ import org.oxycblt.auxio.excluded.ExcludedDatabase * * @author OxygenCobalt */ +@Suppress("InlinedApi") class MusicLoader { data class Library( val genres: List, @@ -273,10 +274,11 @@ class MusicLoader { } private fun linkGenre(context: Context, genre: Genre, songs: List) { + // Don't even bother blacklisting here as useless iterations are less expensive than IO val songCursor = context.contentResolver.query( MediaStore.Audio.Genres.Members.getContentUri("external", genre.id), arrayOf(MediaStore.Audio.Genres.Members._ID), - null, null, null // Dont even bother blacklisting here as useless iters are less expensive than IO + null, null, null ) songCursor?.use { cursor -> diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicStore.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicStore.kt index be38b942a..0ca70a191 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicStore.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicStore.kt @@ -96,7 +96,7 @@ class MusicStore private constructor() { /** * Find a song for a [uri], this is similar to [findSongFast], but with some kind of content uri. - * @return The corresponding [Song] for this [uri], null if there isnt one. + * @return The corresponding [Song] for this [uri], null if there isn't one. */ fun findSongForUri(uri: Uri, resolver: ContentResolver): Song? { val cur = resolver.query(uri, arrayOf(OpenableColumns.DISPLAY_NAME), null, null, null) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt index afa67d5e9..bb02d6102 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt @@ -544,10 +544,10 @@ class PlaybackLayout @JvmOverloads constructor( // playback menu's toolbar properly as PlaybackFragment will apply it's window insets. // Therefore, we slowly increase the bar view's margins so that it fully disappears // near the toolbar instead of in the system bars, which just looks nicer. - // The reason why we can't pad the bar is that it might result in the padding desyncing - // [reminder that this view also applies the bottom window inset] and we can't - // apply padding to the whole container layout since that would adjust the size - // of the playback view. This seems to be the least obtrusive way to do this. + // The reason why we can't pad the bar is that it might result in the padding + // desynchronizing [reminder that this view also applies the bottom window inset] + // and we can't apply padding to the whole container layout since that would adjust + // the size of the playback view. This seems to be the least obtrusive way to do this. lastInsets?.systemBarInsetsCompat?.let { bars -> val params = layoutParams as FrameLayout.LayoutParams val oldTopMargin = params.topMargin diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSeekBar.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSeekBar.kt index 3a3adc684..4e219388e 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSeekBar.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackSeekBar.kt @@ -18,6 +18,7 @@ package org.oxycblt.auxio.playback +import android.annotation.SuppressLint import android.content.Context import android.content.res.ColorStateList import android.util.AttributeSet @@ -36,6 +37,7 @@ import org.oxycblt.auxio.util.resolveAttr * still not having gobs of whitespace everywhere. * @author OxygenCobalt */ +@SuppressLint("RestrictedApi") class PlaybackSeekBar @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, @@ -68,7 +70,7 @@ class PlaybackSeekBar @JvmOverloads constructor( fun setDuration(seconds: Long) { if (seconds == 0L) { - // One of two things occured: + // One of two things occurred: // - Android couldn't get the total duration of the song // - The duration of the song was so low as to be rounded to zero when converted // to seconds. diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt index 8d665e511..ccecc8a41 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt @@ -73,7 +73,7 @@ class QueueAdapter( HeaderViewHolder.ITEM_TYPE -> HeaderViewHolder.from(parent.context) ActionHeaderViewHolder.ITEM_TYPE -> ActionHeaderViewHolder.from(parent.context) - else -> error("Invalid viewholder item type $viewType.") + else -> error("Invalid ViewHolder item type $viewType.") } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt index 67e2528ef..4cffd8bb9 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueDragCallback.kt @@ -112,7 +112,8 @@ class QueueDragCallback(private val playbackModel: PlaybackViewModel) : ItemTouc // lag behind the body view, resulting in a noticeable pixel offset when dragging. To fix // this, we make this a separate view and make this view invisible whenever the item is // not being swiped. We cannot merge this view with the FrameLayout, as that will cause - // another weird pixel desync issue that is less visible but still incredibly annoying. + // another weird pixel desynchronization issue that is less visible but still incredibly + // annoying. if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { holder.backgroundView.isInvisible = dX == 0f } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/LoopMode.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/LoopMode.kt index dba0a3fa3..b9e336d75 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/LoopMode.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/LoopMode.kt @@ -54,7 +54,7 @@ enum class LoopMode { private const val INT_TRACK = 0xA102 /** - * Convert an int [constant] into a LoopMode, or null if it isnt valid. + * Convert an int [constant] into a LoopMode, or null if it isn't valid. */ fun fromInt(constant: Int): LoopMode? { return when (constant) { diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index 307285400..fb9cf3092 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -153,7 +153,7 @@ class PlaybackStateManager private constructor() { PlaybackMode.IN_GENRE -> { val genre = song.genre - // Dont do this if the genre is null + // Don't do this if the genre is null if (genre != null) { mParent = genre mQueue = genre.songs.toMutableList() @@ -366,7 +366,7 @@ class PlaybackStateManager private constructor() { /** * Set whether this instance is [shuffled]. Updates the queue accordingly. - * @param keepSong Whether the current song should be kept as the queue is shuffled/unshuffled + * @param keepSong Whether the current song should be kept as the queue is shuffled/un-shuffled */ fun setShuffling(shuffled: Boolean, keepSong: Boolean) { mIsShuffling = shuffled @@ -403,7 +403,7 @@ class PlaybackStateManager private constructor() { /** * Reset the queue to its normal, ordered state. - * @param keepSong Whether the current song should be kept as the queue is unshuffled + * @param keepSong Whether the current song should be kept as the queue is un-shuffled */ private fun resetShuffle(keepSong: Boolean) { val musicStore = MusicStore.maybeGetInstance() ?: return diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt index 7ef8d0a3e..0e65af8f7 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt @@ -146,7 +146,7 @@ class PlaybackService : Service(), Player.Listener, PlaybackStateManager.Callbac connector = PlaybackSessionConnector(this, player, mediaSession) - // Then the notif/headset callbacks + // Then the notification/headset callbacks IntentFilter().apply { addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED) addAction(AudioManager.ACTION_AUDIO_BECOMING_NOISY) diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchAdapter.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchAdapter.kt index 999143278..8104c55a0 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchAdapter.kt @@ -77,7 +77,7 @@ class SearchAdapter( HeaderViewHolder.ITEM_TYPE -> HeaderViewHolder.from(parent.context) - else -> error("Invalid viewholder item type.") + else -> error("Invalid ViewHolder item type.") } } diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt index edc753671..4f9604edc 100644 --- a/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/search/SearchViewModel.kt @@ -152,7 +152,7 @@ class SearchViewModel : ViewModel() { name.normalized().contains(value, ignoreCase = true) } - return if (filtered.isNotEmpty()) filtered else null + return filtered.ifEmpty { null } } private fun String.normalized(): String { diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt index bccd305ca..d7b2e46dd 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt @@ -69,7 +69,7 @@ fun handleAccentCompat(prefs: SharedPreferences): Accent { accent = 16 } - // If there are still any issues with indices, just correct them so a crash doesnt occur. + // If there are still any issues with indices, just correct them so a crash doesn't occur. if (accent >= ACCENT_COUNT) { accent = ACCENT_COUNT - 1 } diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt index 51851e8bf..b97534df2 100644 --- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt @@ -39,7 +39,7 @@ class SettingsManager private constructor(context: Context) : private val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context) init { - // Poke the song playback mode pref so that it migrates [if it hasnt already] + // Poke the song playback mode pref so that it migrates [if it hasn't already] handleSongPlayModeCompat(sharedPrefs) sharedPrefs.registerOnSharedPreferenceChangeListener(this) diff --git a/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt b/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt index 99a831e2b..d38095891 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt @@ -64,7 +64,7 @@ class ActionMenu( ) : PopupMenu(activity, anchor) { private val context = activity.applicationContext - // Get viewmodels using the activity as the store owner + // Get ViewModels using the activity as the store owner private val detailModel: DetailViewModel by lazy { ViewModelProvider(activity)[DetailViewModel::class.java] } diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt index 82a1b7798..f27166176 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt @@ -179,7 +179,7 @@ private fun RemoteViews.applyFullControls(context: Context, state: WidgetState): ) // While it is technically possible to use the setColorFilter to tint these buttons, its - // actually less efficent than using duplicate drawables. + // actually less efficient than using duplicate drawables. // And no, we can't control state drawables with RemoteViews. Because of course we can't. val shuffleRes = when { diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index c450cfbc3..2ecf0dee8 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -139,11 +139,11 @@ "%d skladba" "%d skladby" - "%d skladeb" + "%d skladeb" "%d album" "%d alba" - "%d alb" + "%d alb" diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 6bbe18804..5b46d6e1d 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -86,11 +86,11 @@ %s Titre - %s Titres + %s Titres %s Album - %s Albums + %s Albums \ No newline at end of file diff --git a/app/src/main/res/values-night-v31/styles_core.xml b/app/src/main/res/values-night-v31/styles_core.xml index 6f16649ed..c94c7b362 100644 --- a/app/src/main/res/values-night-v31/styles_core.xml +++ b/app/src/main/res/values-night-v31/styles_core.xml @@ -1,5 +1,6 @@ - +>