diff --git a/README.md b/README.md
index a958860ac..097c58cbb 100644
--- a/README.md
+++ b/README.md
@@ -21,8 +21,6 @@ Auxio is a local music player with a fast, reliable UI/UX without the many usele
I primarily built Auxio for myself, but you can use it too, I guess.
-**Note: Auxio is in a point that I am largely satisfied with. The app is still maintained, but feature additions will be slow.**
-
## Screenshots
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/AndroidUtils.kt b/app/src/main/java/org/oxycblt/auxio/AuxioUtils.kt
similarity index 86%
rename from app/src/main/java/org/oxycblt/auxio/ui/AndroidUtils.kt
rename to app/src/main/java/org/oxycblt/auxio/AuxioUtils.kt
index abdca58b8..ec7e23766 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/AndroidUtils.kt
+++ b/app/src/main/java/org/oxycblt/auxio/AuxioUtils.kt
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2021 Auxio Project
- * AndroidUtils.kt is part of Auxio.
+ * AuxioUtils.kt is part of Auxio.
*
* 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
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.ui
+package org.oxycblt.auxio
import android.app.Activity
import android.app.PendingIntent
@@ -46,9 +46,6 @@ import androidx.annotation.PluralsRes
import androidx.annotation.StringRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
-import org.oxycblt.auxio.MainActivity
-import org.oxycblt.auxio.R
-import org.oxycblt.auxio.logE
import kotlin.reflect.KClass
const val INTENT_REQUEST_CODE = 0xA0A0
@@ -60,7 +57,7 @@ const val INTENT_REQUEST_CODE = 0xA0A0
*/
fun ImageButton.disable() {
if (isEnabled) {
- imageTintList = R.color.inactive.toStateList(context)
+ imageTintList = R.color.inactive.resolveStateList(context)
isEnabled = false
}
}
@@ -69,9 +66,24 @@ fun ImageButton.disable() {
* Set a [TextView] text color, without having to resolve the resource.
*/
fun TextView.setTextColorResource(@ColorRes color: Int) {
- setTextColor(color.toColor(context))
+ setTextColor(color.resolveColor(context))
}
+/**
+ * Get the span count for most RecyclerViews. These probably work right on most displays. Trust me.
+ */
+val RecyclerView.spans: Int get() =
+ if (context.isLandscape()) {
+ if (context.isXLTablet()) 3 else 2
+ } else {
+ if (context.isXLTablet()) 2 else 1
+ }
+
+/**
+ * Returns whether a recyclerview can scroll.
+ */
+fun RecyclerView.canScroll(): Boolean = computeVerticalScrollRange() > height
+
// --- CONVENIENCE ---
/**
@@ -80,14 +92,12 @@ fun TextView.setTextColorResource(@ColorRes color: Int) {
val Context.inflater: LayoutInflater get() = LayoutInflater.from(this)
/**
- * Convenience method for getting a plural.
- * @param pluralsRes Resource for the plural
- * @param value Int value for the plural.
- * @return The formatted string requested
+ * Returns whether the current UI is in night mode or not. This will work if the theme is
+ * automatic as well.
*/
-fun Context.getPlural(@PluralsRes pluralsRes: Int, value: Int): String {
- return resources.getQuantityString(pluralsRes, value, value)
-}
+val Context.isNight: Boolean get() =
+ resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
+ Configuration.UI_MODE_NIGHT_YES
/**
* Convenience method for getting a system service without nullability issues.
@@ -102,80 +112,6 @@ fun Context.getSystemServiceSafe(serviceClass: KClass): T {
}
}
-/**
- * Returns whether the current UI is in night mode or not. This will work if the theme is
- * automatic as well.
- */
-fun Context.isNight(): Boolean {
- return resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
- Configuration.UI_MODE_NIGHT_YES
-}
-
-/**
- * Resolve a color.
- * @param context [Context] required
- * @return The resolved color, black if the resolving process failed.
- */
-@ColorInt
-fun @receiver:ColorRes Int.toColor(context: Context): Int {
- return try {
- ContextCompat.getColor(context, this)
- } catch (e: Resources.NotFoundException) {
- logE("Attempted color load failed: ${e.stackTraceToString()}")
-
- // Default to the emergency color [Black] if the loading fails.
- ContextCompat.getColor(context, android.R.color.black)
- }
-}
-
-/**
- * Resolve a color and turn it into a [ColorStateList]
- * @param context [Context] required
- * @return The resolved color as a [ColorStateList]
- * @see toColor
- */
-fun @receiver:ColorRes Int.toStateList(context: Context) =
- ColorStateList.valueOf(toColor(context))
-
-/**
- * Resolve a drawable resource into a [Drawable]
- */
-fun @receiver:DrawableRes Int.toDrawable(context: Context) =
- ContextCompat.getDrawable(context, this)
-
-/**
- * Resolve a drawable resource into an [AnimatedVectorDrawable]
- * @see toDrawable
- */
-fun @receiver:DrawableRes Int.toAnimDrawable(context: Context) =
- toDrawable(context) as AnimatedVectorDrawable
-
-/**
- * Resolve this int into a color as if it was an attribute
- */
-@ColorInt
-fun @receiver:AttrRes Int.resolveAttr(context: Context): Int {
- // Convert the attribute into its color
- val resolvedAttr = TypedValue()
- context.theme.resolveAttribute(this, resolvedAttr, true)
-
- // Then convert it to a proper color
- val color = if (resolvedAttr.resourceId != 0) {
- resolvedAttr.resourceId
- } else {
- resolvedAttr.data
- }
-
- return color.toColor(context)
-}
-
-/**
- * Create a toast using the provided string resource.
- */
-fun Context.showToast(@StringRes str: Int) {
- Toast.makeText(applicationContext, getString(str), Toast.LENGTH_SHORT).show()
-}
-
/**
* Create a broadcast [PendingIntent]
*/
@@ -200,6 +136,81 @@ fun Context.newMainIntent(): PendingIntent {
)
}
+/**
+ * Create a toast using the provided string resource.
+ */
+fun Context.showToast(@StringRes str: Int) {
+ Toast.makeText(applicationContext, getString(str), Toast.LENGTH_SHORT).show()
+}
+
+/**
+ * Convenience method for getting a plural.
+ * @param pluralsRes Resource for the plural
+ * @param value Int value for the plural.
+ * @return The formatted string requested
+ */
+fun Context.getPlural(@PluralsRes pluralsRes: Int, value: Int): String {
+ return resources.getQuantityString(pluralsRes, value, value)
+}
+
+/**
+ * Resolve a color.
+ * @param context [Context] required
+ * @return The resolved color, black if the resolving process failed.
+ */
+@ColorInt
+fun @receiver:ColorRes Int.resolveColor(context: Context): Int {
+ return try {
+ ContextCompat.getColor(context, this)
+ } catch (e: Resources.NotFoundException) {
+ logE("Attempted color load failed: ${e.stackTraceToString()}")
+
+ // Default to the emergency color [Black] if the loading fails.
+ ContextCompat.getColor(context, android.R.color.black)
+ }
+}
+
+/**
+ * Resolve a color and turn it into a [ColorStateList]
+ * @param context [Context] required
+ * @return The resolved color as a [ColorStateList]
+ * @see resolveColor
+ */
+fun @receiver:ColorRes Int.resolveStateList(context: Context) =
+ ColorStateList.valueOf(resolveColor(context))
+
+/**
+ * Resolve a drawable resource into a [Drawable]
+ */
+fun @receiver:DrawableRes Int.resolveDrawable(context: Context) =
+ requireNotNull(ContextCompat.getDrawable(context, this))
+
+/**
+ * Resolve a drawable resource into an [AnimatedVectorDrawable]
+ * @see resolveDrawable
+ */
+fun @receiver:DrawableRes Int.toAnimDrawable(context: Context) =
+ resolveDrawable(context) as AnimatedVectorDrawable
+
+/**
+ * Resolve this int into a color as if it was an attribute
+ */
+@ColorInt
+fun @receiver:AttrRes Int.resolveAttr(context: Context): Int {
+ // Convert the attribute into its color
+ val resolvedAttr = TypedValue()
+ context.theme.resolveAttribute(this, resolvedAttr, true)
+
+ // Then convert it to a proper color
+ val color = if (resolvedAttr.resourceId != 0) {
+ resolvedAttr.resourceId
+ } else {
+ resolvedAttr.data
+ }
+
+ return color.resolveColor(context)
+}
+
/**
* Shortcut for querying all items in a database and running [block] with the cursor returned.
* Will not run if the cursor is null.
@@ -235,16 +246,15 @@ fun isEdgeOn(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1
/**
* Determine if the device is currently in landscape.
- * @param resources [Resources] required
*/
-fun isLandscape(resources: Resources): Boolean {
+fun Context.isLandscape(): Boolean {
return resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
}
/**
* Determine if we are in tablet mode or not
*/
-fun isTablet(resources: Resources): Boolean {
+fun Context.isTablet(): Boolean {
val layout = resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK
return layout == Configuration.SCREENLAYOUT_SIZE_XLARGE ||
@@ -254,35 +264,19 @@ fun isTablet(resources: Resources): Boolean {
/**
* Determine if the tablet is XLARGE, ignoring normal tablets.
*/
-fun isXLTablet(resources: Resources): Boolean {
+fun Context.isXLTablet(): Boolean {
val layout = resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK
return layout == Configuration.SCREENLAYOUT_SIZE_XLARGE
}
-/**
- * Get the span count for most RecyclerViews. These probably work right on most displays. Trust me.
- */
-fun RecyclerView.getSpans(): Int {
- return if (isLandscape(resources)) {
- if (isXLTablet(resources)) 3 else 2
- } else {
- if (isXLTablet(resources)) 2 else 1
- }
-}
-
-/**
- * Returns whether a recyclerview can scroll.
- */
-fun RecyclerView.canScroll() = computeVerticalScrollRange() > height
-
/**
* Check if we are in the "Irregular" landscape mode (e.g landscape, but nav bar is on the sides)
* Used to disable most of edge-to-edge if that's the case, as I cant get it to work on this mode.
* @return True if we are in the irregular landscape mode, false if not.
*/
fun Activity.isIrregularLandscape(): Boolean {
- return isLandscape(resources) && !isSystemBarOnBottom(this)
+ return isLandscape() && !isSystemBarOnBottom(this)
}
/**
diff --git a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
index f5c25ae11..7030a611c 100644
--- a/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
+++ b/app/src/main/java/org/oxycblt/auxio/MainActivity.kt
@@ -27,13 +27,11 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.databinding.DataBindingUtil
+import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.databinding.ActivityMainBinding
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.system.PlaybackService
import org.oxycblt.auxio.settings.SettingsManager
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.isEdgeOn
-import org.oxycblt.auxio.ui.isNight
/**
* The single [AppCompatActivity] for Auxio.
@@ -66,22 +64,6 @@ class MainActivity : AppCompatActivity() {
onNewIntent(intent)
}
- private fun setupTheme() {
- // Update the current accent and theme
- val settingsManager = SettingsManager.getInstance()
- AppCompatDelegate.setDefaultNightMode(settingsManager.theme)
-
- val newAccent = Accent.set(settingsManager.accent)
-
- // The black theme has a completely separate set of styles since style attributes cannot
- // be modified at runtime.
- if (isNight() && settingsManager.useBlackTheme) {
- setTheme(newAccent.blackTheme)
- } else {
- setTheme(newAccent.theme)
- }
- }
-
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
@@ -102,6 +84,22 @@ class MainActivity : AppCompatActivity() {
}
}
+ private fun setupTheme() {
+ // Update the current accent and theme
+ val settingsManager = SettingsManager.getInstance()
+ AppCompatDelegate.setDefaultNightMode(settingsManager.theme)
+
+ val newAccent = Accent.set(settingsManager.accent)
+
+ // The black theme has a completely separate set of styles since style attributes cannot
+ // be modified at runtime.
+ if (isNight && settingsManager.useBlackTheme) {
+ setTheme(newAccent.blackTheme)
+ } else {
+ setTheme(newAccent.theme)
+ }
+ }
+
private fun setupEdgeToEdge(binding: ActivityMainBinding) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// Do modern edge to edge, which happens to be around twice the size of the
diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
index b73bc9c99..ccf032694 100644
--- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt
@@ -32,15 +32,11 @@ import androidx.navigation.NavOptions
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomnavigation.BottomNavigationView
+import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.databinding.FragmentMainBinding
import org.oxycblt.auxio.detail.DetailViewModel
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.isLandscape
-import org.oxycblt.auxio.ui.isTablet
-import org.oxycblt.auxio.ui.resolveAttr
-import org.oxycblt.auxio.ui.toColor
/**
* The primary "Home" [Fragment] for Auxio.
@@ -56,7 +52,7 @@ class MainFragment : Fragment() {
): View {
val binding = FragmentMainBinding.inflate(inflater)
- val colorActive = Accent.get().color.toColor(requireContext())
+ val colorActive = Accent.get().color.resolveColor(requireContext())
val colorInactive = ColorUtils.setAlphaComponent(colorActive, 150)
// Set up the tints for the navigation icons + text
@@ -86,7 +82,7 @@ class MainFragment : Fragment() {
itemIconTintList = navTints
itemTextColor = navTints
- if (isTablet(resources) && !isLandscape(resources)) {
+ if (requireContext().isTablet() && !requireContext().isLandscape()) {
labelVisibilityMode = BottomNavigationView.LABEL_VISIBILITY_LABELED
}
@@ -160,7 +156,7 @@ class MainFragment : Fragment() {
if (song == null) {
logD("Hiding CompactPlaybackFragment since no song is being played.")
- binding.compactPlayback.visibility = if (isLandscape(resources)) {
+ binding.compactPlayback.visibility = if (requireContext().isLandscape()) {
View.INVISIBLE
} else {
View.GONE
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/Accent.kt b/app/src/main/java/org/oxycblt/auxio/accent/Accent.kt
similarity index 96%
rename from app/src/main/java/org/oxycblt/auxio/ui/Accent.kt
rename to app/src/main/java/org/oxycblt/auxio/accent/Accent.kt
index b8136ac56..3959a0f4a 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/Accent.kt
+++ b/app/src/main/java/org/oxycblt/auxio/accent/Accent.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.ui
+package org.oxycblt.auxio.accent
import android.annotation.SuppressLint
import android.content.Context
@@ -27,6 +27,7 @@ import androidx.annotation.StringRes
import androidx.annotation.StyleRes
import androidx.core.text.HtmlCompat
import org.oxycblt.auxio.R
+import org.oxycblt.auxio.resolveStateList
/**
* A list of all possible accents.
@@ -94,7 +95,7 @@ data class Accent(
/**
* Get a [ColorStateList] of the accent
*/
- fun getStateList(context: Context) = color.toStateList(context)
+ fun getStateList(context: Context) = color.resolveStateList(context)
/**
* Get the name (in bold) and the hex value of a accent.
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/accent/AccentAdapter.kt b/app/src/main/java/org/oxycblt/auxio/accent/AccentAdapter.kt
similarity index 90%
rename from app/src/main/java/org/oxycblt/auxio/settings/accent/AccentAdapter.kt
rename to app/src/main/java/org/oxycblt/auxio/accent/AccentAdapter.kt
index 8153c4ac0..a2b2b1d83 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/accent/AccentAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/accent/AccentAdapter.kt
@@ -16,17 +16,15 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.settings.accent
+package org.oxycblt.auxio.accent
import android.view.ViewGroup
import androidx.appcompat.widget.TooltipCompat
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.ItemAccentBinding
-import org.oxycblt.auxio.ui.ACCENTS
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.inflater
-import org.oxycblt.auxio.ui.toStateList
+import org.oxycblt.auxio.inflater
+import org.oxycblt.auxio.resolveStateList
/**
* An adapter that displays the list of all possible accents, and highlights the current one.
@@ -84,9 +82,9 @@ class AccentAdapter(
selectedViewHolder?.setSelected(false)
selectedViewHolder = this
- R.color.surface.toStateList(context)
+ R.color.surface.resolveStateList(context)
} else {
- android.R.color.transparent.toStateList(context)
+ android.R.color.transparent.resolveStateList(context)
}
}
}
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/accent/AccentDialog.kt b/app/src/main/java/org/oxycblt/auxio/accent/AccentDialog.kt
similarity index 93%
rename from app/src/main/java/org/oxycblt/auxio/settings/accent/AccentDialog.kt
rename to app/src/main/java/org/oxycblt/auxio/accent/AccentDialog.kt
index 20b25a314..b617ff1df 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/accent/AccentDialog.kt
+++ b/app/src/main/java/org/oxycblt/auxio/accent/AccentDialog.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.settings.accent
+package org.oxycblt.auxio.accent
import android.os.Bundle
import android.view.LayoutInflater
@@ -27,11 +27,9 @@ import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.DialogAccentBinding
import org.oxycblt.auxio.logD
+import org.oxycblt.auxio.resolveColor
import org.oxycblt.auxio.settings.SettingsManager
import org.oxycblt.auxio.settings.ui.LifecycleDialog
-import org.oxycblt.auxio.ui.ACCENTS
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.toColor
/**
* Dialog responsible for showing the list of accents to select.
@@ -93,7 +91,7 @@ class AccentDialog : LifecycleDialog() {
}
private fun updateAccent() {
- val accentColor = pendingAccent.color.toColor(requireContext())
+ val accentColor = pendingAccent.color.resolveColor(requireContext())
(requireDialog() as AlertDialog).apply {
getButton(AlertDialog.BUTTON_POSITIVE)?.setTextColor(accentColor)
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/accent/AutoGridLayoutManager.kt b/app/src/main/java/org/oxycblt/auxio/accent/AutoGridLayoutManager.kt
similarity index 98%
rename from app/src/main/java/org/oxycblt/auxio/settings/accent/AutoGridLayoutManager.kt
rename to app/src/main/java/org/oxycblt/auxio/accent/AutoGridLayoutManager.kt
index 61c583447..ab853c447 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/accent/AutoGridLayoutManager.kt
+++ b/app/src/main/java/org/oxycblt/auxio/accent/AutoGridLayoutManager.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.settings.accent
+package org.oxycblt.auxio.accent
import android.content.Context
import android.util.AttributeSet
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt
index e220ecce6..64cad21c3 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt
@@ -25,6 +25,7 @@ import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import org.oxycblt.auxio.R
+import org.oxycblt.auxio.canScroll
import org.oxycblt.auxio.detail.adapters.AlbumDetailAdapter
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.Album
@@ -34,10 +35,9 @@ import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.recycler.CenterSmoothScroller
+import org.oxycblt.auxio.showToast
import org.oxycblt.auxio.ui.ActionMenu
-import org.oxycblt.auxio.ui.canScroll
import org.oxycblt.auxio.ui.newMenu
-import org.oxycblt.auxio.ui.showToast
/**
* The [DetailFragment] for an album.
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
index 6db31c87c..23adc169e 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt
@@ -28,8 +28,8 @@ import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.databinding.FragmentDetailBinding
+import org.oxycblt.auxio.isLandscape
import org.oxycblt.auxio.playback.PlaybackViewModel
-import org.oxycblt.auxio.ui.isLandscape
import org.oxycblt.auxio.ui.memberBinding
/**
@@ -95,7 +95,7 @@ abstract class DetailFragment : Fragment() {
setHasFixedSize(true)
// Set up a grid if the mode is landscape
- if (isLandscape(resources)) {
+ if (requireContext().isLandscape()) {
layoutManager = GridLayoutManager(requireContext(), 2).also {
it.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt
index 6c8d1456d..4bfea26a6 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/AlbumDetailAdapter.kt
@@ -23,9 +23,12 @@ import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.databinding.ItemAlbumHeaderBinding
import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
import org.oxycblt.auxio.detail.DetailViewModel
+import org.oxycblt.auxio.disable
+import org.oxycblt.auxio.inflater
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Song
@@ -33,10 +36,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.recycler.viewholders.Highlightable
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.disable
-import org.oxycblt.auxio.ui.inflater
-import org.oxycblt.auxio.ui.setTextColorResource
+import org.oxycblt.auxio.setTextColorResource
/**
* An adapter for displaying the details and [Song]s of an [Album]
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt
index 58420b517..4e2d59e66 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/ArtistDetailAdapter.kt
@@ -22,11 +22,14 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.databinding.ItemActionHeaderBinding
import org.oxycblt.auxio.databinding.ItemArtistAlbumBinding
import org.oxycblt.auxio.databinding.ItemArtistHeaderBinding
import org.oxycblt.auxio.databinding.ItemArtistSongBinding
import org.oxycblt.auxio.detail.DetailViewModel
+import org.oxycblt.auxio.disable
+import org.oxycblt.auxio.inflater
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
@@ -37,10 +40,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.recycler.viewholders.Highlightable
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.disable
-import org.oxycblt.auxio.ui.inflater
-import org.oxycblt.auxio.ui.setTextColorResource
+import org.oxycblt.auxio.setTextColorResource
/**
* An adapter for displaying the [Album]s and [Song]s of an artist.
diff --git a/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt b/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt
index 2ff65f73a..e8f345dc3 100644
--- a/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/detail/adapters/GenreDetailAdapter.kt
@@ -23,9 +23,12 @@ import android.view.ViewGroup
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
+import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.databinding.ItemGenreHeaderBinding
import org.oxycblt.auxio.databinding.ItemGenreSongBinding
import org.oxycblt.auxio.detail.DetailViewModel
+import org.oxycblt.auxio.disable
+import org.oxycblt.auxio.inflater
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song
@@ -33,10 +36,7 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.recycler.viewholders.Highlightable
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.disable
-import org.oxycblt.auxio.ui.inflater
-import org.oxycblt.auxio.ui.setTextColorResource
+import org.oxycblt.auxio.setTextColorResource
/**
* An adapter for displaying the [Song]s of a genre.
diff --git a/app/src/main/java/org/oxycblt/auxio/music/BlacklistDatabase.kt b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDatabase.kt
similarity index 87%
rename from app/src/main/java/org/oxycblt/auxio/music/BlacklistDatabase.kt
rename to app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDatabase.kt
index df80b10c0..0d15ce5e1 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/BlacklistDatabase.kt
+++ b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDatabase.kt
@@ -16,24 +16,24 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.music
+package org.oxycblt.auxio.excluded
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import androidx.core.database.sqlite.transaction
+import org.oxycblt.auxio.assertBackgroundThread
import org.oxycblt.auxio.logD
-import org.oxycblt.auxio.ui.assertBackgroundThread
-import org.oxycblt.auxio.ui.queryAll
+import org.oxycblt.auxio.queryAll
/**
- * Database for storing blacklisted paths.
+ * Database for storing excluded directories.
* Note that the paths stored here will not work with MediaStore unless you append a "%" at the end.
* Yes. I know Room exists. But that would needlessly bloat my app and has crippling bugs.
* @author OxygenCobalt
*/
-class BlacklistDatabase(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
+class ExcludedDatabase(context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE IF NOT EXISTS $TABLE_NAME ($COLUMN_PATH TEXT NOT NULL)")
}
@@ -94,12 +94,12 @@ class BlacklistDatabase(context: Context) : SQLiteOpenHelper(context, DB_NAME, n
const val COLUMN_PATH = "COLUMN_PATH"
@Volatile
- private var INSTANCE: BlacklistDatabase? = null
+ private var INSTANCE: ExcludedDatabase? = null
/**
* Get/Instantiate the single instance of [PlaybackStateDatabase].
*/
- fun getInstance(context: Context): BlacklistDatabase {
+ fun getInstance(context: Context): ExcludedDatabase {
val currentInstance = INSTANCE
if (currentInstance != null) {
@@ -107,7 +107,7 @@ class BlacklistDatabase(context: Context) : SQLiteOpenHelper(context, DB_NAME, n
}
synchronized(this) {
- val newInstance = BlacklistDatabase(context.applicationContext)
+ val newInstance = ExcludedDatabase(context.applicationContext)
INSTANCE = newInstance
return newInstance
}
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistDialog.kt b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDialog.kt
similarity index 94%
rename from app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistDialog.kt
rename to app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDialog.kt
index 97810ac2b..ede0a3fca 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistDialog.kt
+++ b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedDialog.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.settings.blacklist
+package org.oxycblt.auxio.excluded
import android.content.Intent
import android.net.Uri
@@ -37,16 +37,16 @@ import org.oxycblt.auxio.databinding.DialogBlacklistBinding
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.settings.ui.LifecycleDialog
-import org.oxycblt.auxio.ui.showToast
+import org.oxycblt.auxio.showToast
import kotlin.system.exitProcess
/**
* Dialog that manages the currently excluded directories.
* @author OxygenCobalt
*/
-class BlacklistDialog : LifecycleDialog() {
- private val blacklistModel: BlacklistViewModel by viewModels {
- BlacklistViewModel.Factory(requireContext())
+class ExcludedDialog : LifecycleDialog() {
+ private val blacklistModel: ExcludedViewModel by viewModels {
+ ExcludedViewModel.Factory(requireContext())
}
private val playbackModel: PlaybackViewModel by activityViewModels()
@@ -58,7 +58,7 @@ class BlacklistDialog : LifecycleDialog() {
): View {
val binding = DialogBlacklistBinding.inflate(inflater)
- val adapter = BlacklistEntryAdapter { path ->
+ val adapter = ExcludedEntryAdapter { path ->
blacklistModel.removePath(path)
}
@@ -123,6 +123,7 @@ class BlacklistDialog : LifecycleDialog() {
if (path != null) {
blacklistModel.addPath(path)
} else {
+ // TODO: Tolerate this once the excluded system is modernized
requireContext().showToast(R.string.err_bad_dir)
}
}
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistEntryAdapter.kt b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedEntryAdapter.kt
similarity index 92%
rename from app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistEntryAdapter.kt
rename to app/src/main/java/org/oxycblt/auxio/excluded/ExcludedEntryAdapter.kt
index ce8f18bc3..b6c28a181 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistEntryAdapter.kt
+++ b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedEntryAdapter.kt
@@ -16,21 +16,21 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.settings.blacklist
+package org.oxycblt.auxio.excluded
import android.annotation.SuppressLint
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.databinding.ItemBlacklistEntryBinding
-import org.oxycblt.auxio.ui.inflater
+import org.oxycblt.auxio.inflater
/**
* Adapter that shows the blacklist entries and their "Clear" button.
* @author OxygenCobalt
*/
-class BlacklistEntryAdapter(
+class ExcludedEntryAdapter(
private val onClear: (String) -> Unit
-) : RecyclerView.Adapter() {
+) : RecyclerView.Adapter() {
private var paths = mutableListOf()
override fun getItemCount() = paths.size
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistViewModel.kt b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedViewModel.kt
similarity index 86%
rename from app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistViewModel.kt
rename to app/src/main/java/org/oxycblt/auxio/excluded/ExcludedViewModel.kt
index 5a11aea71..8fb1ffaa8 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/blacklist/BlacklistViewModel.kt
+++ b/app/src/main/java/org/oxycblt/auxio/excluded/ExcludedViewModel.kt
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-package org.oxycblt.auxio.settings.blacklist
+package org.oxycblt.auxio.excluded
import android.content.Context
import androidx.lifecycle.LiveData
@@ -27,18 +27,17 @@ import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
-import org.oxycblt.auxio.music.BlacklistDatabase
/**
- * ViewModel that acts as a wrapper around [BlacklistDatabase], allowing for the addition/removal
+ * ViewModel that acts as a wrapper around [ExcludedDatabase], allowing for the addition/removal
* of paths. Use [Factory] to instantiate this.
* @author OxygenCobalt
*/
-class BlacklistViewModel(context: Context) : ViewModel() {
+class ExcludedViewModel(context: Context) : ViewModel() {
private val mPaths = MutableLiveData(mutableListOf())
val paths: LiveData> get() = mPaths
- private val blacklistDatabase = BlacklistDatabase.getInstance(context)
+ private val blacklistDatabase = ExcludedDatabase.getInstance(context)
private var dbPaths = listOf()
init {
@@ -97,12 +96,12 @@ class BlacklistViewModel(context: Context) : ViewModel() {
class Factory(private val context: Context) : ViewModelProvider.Factory {
override fun create(modelClass: Class): T {
- check(modelClass.isAssignableFrom(BlacklistViewModel::class.java)) {
+ check(modelClass.isAssignableFrom(ExcludedViewModel::class.java)) {
"BlacklistViewModel.Factory does not support this class"
}
@Suppress("UNCHECKED_CAST")
- return BlacklistViewModel(context) as T
+ return ExcludedViewModel(context) as T
}
}
}
diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
index 99d853e90..0c2f4774d 100644
--- a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
@@ -36,7 +36,7 @@ import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Parent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.recycler.sliceArticle
-import org.oxycblt.auxio.ui.getSpans
+import org.oxycblt.auxio.spans
import org.oxycblt.auxio.ui.newMenu
/**
@@ -78,7 +78,6 @@ class LibraryFragment : Fragment() {
adapter = libraryAdapter
setHasFixedSize(true)
- val spans = getSpans()
if (spans != 1) {
layoutManager = GridLayoutManager(requireContext(), spans)
}
diff --git a/app/src/main/java/org/oxycblt/auxio/loading/LoadingFragment.kt b/app/src/main/java/org/oxycblt/auxio/loading/LoadingFragment.kt
index e84566a3f..c5b64b81e 100644
--- a/app/src/main/java/org/oxycblt/auxio/loading/LoadingFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/loading/LoadingFragment.kt
@@ -33,7 +33,6 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentLoadingBinding
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.MusicStore
-import org.oxycblt.auxio.ui.isLandscape
/**
* Fragment that handles what to display during the loading process.
@@ -62,10 +61,6 @@ class LoadingFragment : Fragment() {
binding.lifecycleOwner = viewLifecycleOwner
binding.loadingModel = loadingModel
- // The loading panel shouldn't fit the system window on landscape as that will cause it
- // to be mis-aligned with the Auxio icon.
- binding.loadingPanel.fitsSystemWindows = !isLandscape(resources)
-
// --- VIEWMODEL SETUP ---
loadingModel.doGrant.observe(viewLifecycleOwner) { doGrant ->
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 71018a132..13b416ae0 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/MusicLoader.kt
@@ -27,6 +27,7 @@ import android.provider.MediaStore.Audio.Genres
import android.provider.MediaStore.Audio.Media
import androidx.core.database.getStringOrNull
import org.oxycblt.auxio.R
+import org.oxycblt.auxio.excluded.ExcludedDatabase
import org.oxycblt.auxio.logD
/**
@@ -69,7 +70,7 @@ class MusicLoader(private val context: Context) {
@Suppress("DEPRECATION")
private fun buildSelector() {
// TODO: Upgrade this to be compatible with Android Q.
- val blacklistDatabase = BlacklistDatabase.getInstance(context)
+ val blacklistDatabase = ExcludedDatabase.getInstance(context)
val paths = blacklistDatabase.readPaths()
diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt
index e387c5493..17b753714 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt
@@ -27,7 +27,7 @@ import android.widget.TextView
import androidx.core.text.isDigitsOnly
import androidx.databinding.BindingAdapter
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.ui.getPlural
+import org.oxycblt.auxio.getPlural
/**
* A complete array of all the hardcoded genre values for ID3
if (cursor.count == 0) return@queryAll
- val songIndex = cursor.getColumnIndexOrThrow(PlaybackState.COLUMN_SONG_HASH)
- val posIndex = cursor.getColumnIndexOrThrow(PlaybackState.COLUMN_POSITION)
- val parentIndex = cursor.getColumnIndexOrThrow(PlaybackState.COLUMN_PARENT_HASH)
- val indexIndex = cursor.getColumnIndexOrThrow(PlaybackState.COLUMN_INDEX)
- val modeIndex = cursor.getColumnIndexOrThrow(PlaybackState.COLUMN_MODE)
- val shuffleIndex = cursor.getColumnIndexOrThrow(PlaybackState.COLUMN_IS_SHUFFLING)
- val loopModeIndex = cursor.getColumnIndexOrThrow(PlaybackState.COLUMN_LOOP_MODE)
+ val songIndex = cursor.getColumnIndexOrThrow(DatabaseState.COLUMN_SONG_HASH)
+ val posIndex = cursor.getColumnIndexOrThrow(DatabaseState.COLUMN_POSITION)
+ val parentIndex = cursor.getColumnIndexOrThrow(DatabaseState.COLUMN_PARENT_HASH)
+ val indexIndex = cursor.getColumnIndexOrThrow(DatabaseState.COLUMN_INDEX)
+ val modeIndex = cursor.getColumnIndexOrThrow(DatabaseState.COLUMN_MODE)
+ val shuffleIndex = cursor.getColumnIndexOrThrow(DatabaseState.COLUMN_IS_SHUFFLING)
+ val loopModeIndex = cursor.getColumnIndexOrThrow(DatabaseState.COLUMN_LOOP_MODE)
val inUserQueueIndex = cursor.getColumnIndexOrThrow(
- PlaybackState.COLUMN_IN_USER_QUEUE
+ DatabaseState.COLUMN_IN_USER_QUEUE
)
cursor.moveToFirst()
- state = PlaybackState(
+ state = DatabaseState(
songHash = cursor.getInt(songIndex),
position = cursor.getLong(posIndex),
parentHash = cursor.getInt(parentIndex),
@@ -174,7 +174,7 @@ class PlaybackStateDatabase(context: Context) :
/**
* Write a list of [queueItems] to the database, clearing the previous queue present.
*/
- fun writeQueue(queueItems: List) {
+ fun writeQueue(queueItems: List) {
assertBackgroundThread()
val database = writableDatabase
@@ -197,10 +197,10 @@ class PlaybackStateDatabase(context: Context) :
i++
val itemData = ContentValues(4).apply {
- put(QueueItem.COLUMN_ID, item.id)
- put(QueueItem.COLUMN_SONG_HASH, item.songHash)
- put(QueueItem.COLUMN_ALBUM_HASH, item.albumHash)
- put(QueueItem.COLUMN_IS_USER_QUEUE, item.isUserQueue)
+ put(DatabaseQueueItem.COLUMN_ID, item.id)
+ put(DatabaseQueueItem.COLUMN_SONG_HASH, item.songHash)
+ put(DatabaseQueueItem.COLUMN_ALBUM_HASH, item.albumHash)
+ put(DatabaseQueueItem.COLUMN_IS_USER_QUEUE, item.isUserQueue)
}
insert(TABLE_NAME_QUEUE, null, itemData)
@@ -216,24 +216,24 @@ class PlaybackStateDatabase(context: Context) :
}
/**
- * Read the database for any [QueueItem]s.
- * @return A list of any stored [QueueItem]s.
+ * Read the database for any [DatabaseQueueItem]s.
+ * @return A list of any stored [DatabaseQueueItem]s.
*/
- fun readQueue(): List {
+ fun readQueue(): List {
assertBackgroundThread()
- val queueItems = mutableListOf()
+ val queueItems = mutableListOf()
readableDatabase.queryAll(TABLE_NAME_QUEUE) { cursor ->
if (cursor.count == 0) return@queryAll
- val idIndex = cursor.getColumnIndexOrThrow(QueueItem.COLUMN_ID)
- val songIdIndex = cursor.getColumnIndexOrThrow(QueueItem.COLUMN_SONG_HASH)
- val albumIdIndex = cursor.getColumnIndexOrThrow(QueueItem.COLUMN_ALBUM_HASH)
- val isUserQueueIndex = cursor.getColumnIndexOrThrow(QueueItem.COLUMN_IS_USER_QUEUE)
+ val idIndex = cursor.getColumnIndexOrThrow(DatabaseQueueItem.COLUMN_ID)
+ val songIdIndex = cursor.getColumnIndexOrThrow(DatabaseQueueItem.COLUMN_SONG_HASH)
+ val albumIdIndex = cursor.getColumnIndexOrThrow(DatabaseQueueItem.COLUMN_ALBUM_HASH)
+ val isUserQueueIndex = cursor.getColumnIndexOrThrow(DatabaseQueueItem.COLUMN_IS_USER_QUEUE)
while (cursor.moveToNext()) {
- queueItems += QueueItem(
+ queueItems += DatabaseQueueItem(
id = cursor.getLong(idIndex),
songHash = cursor.getInt(songIdIndex),
albumHash = cursor.getInt(albumIdIndex),
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 25cb08a58..36c6aaeb9 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
@@ -581,8 +581,8 @@ class PlaybackStateManager private constructor() {
logD("Getting state from DB.")
val start: Long
- val playbackState: PlaybackState?
- val queueItems: List
+ val playbackState: DatabaseState?
+ val queueItems: List
withContext(Dispatchers.IO) {
start = System.currentTimeMillis()
@@ -609,11 +609,11 @@ class PlaybackStateManager private constructor() {
}
/**
- * Pack the current state into a [PlaybackState] to be saved.
- * @return A [PlaybackState] reflecting the current state.
+ * Pack the current state into a [DatabaseState] to be saved.
+ * @return A [DatabaseState] reflecting the current state.
*/
- private fun packToPlaybackState(): PlaybackState {
- return PlaybackState(
+ private fun packToPlaybackState(): DatabaseState {
+ return DatabaseState(
songHash = mSong?.hash ?: Int.MIN_VALUE,
position = mPosition,
parentHash = mParent?.hash ?: Int.MIN_VALUE,
@@ -628,7 +628,7 @@ class PlaybackStateManager private constructor() {
/**
* Unpack a [playbackState] into this instance.
*/
- private fun unpackFromPlaybackState(playbackState: PlaybackState) {
+ private fun unpackFromPlaybackState(playbackState: DatabaseState) {
// Turn the simplified information from PlaybackState into usable data.
// Do queue setup first
@@ -646,21 +646,21 @@ class PlaybackStateManager private constructor() {
}
/**
- * Pack the queue into a list of [QueueItem]s to be saved.
+ * Pack the queue into a list of [DatabaseQueueItem]s to be saved.
* @return A list of packed queue items.
*/
- private fun packQueue(): List {
- val unified = mutableListOf()
+ private fun packQueue(): List {
+ val unified = mutableListOf()
var queueItemId = 0L
mUserQueue.forEach { song ->
- unified.add(QueueItem(queueItemId, song.hash, song.album.hash, true))
+ unified.add(DatabaseQueueItem(queueItemId, song.hash, song.album.hash, true))
queueItemId++
}
mQueue.forEach { song ->
- unified.add(QueueItem(queueItemId, song.hash, song.album.hash, false))
+ unified.add(DatabaseQueueItem(queueItemId, song.hash, song.album.hash, false))
queueItemId++
}
@@ -669,9 +669,9 @@ class PlaybackStateManager private constructor() {
/**
* Unpack a list of queue items into a queue & user queue.
- * @param queueItems The list of [QueueItem]s to unpack.
+ * @param queueItems The list of [DatabaseQueueItem]s to unpack.
*/
- private fun unpackQueue(queueItems: List) {
+ private fun unpackQueue(queueItems: List) {
for (item in queueItems) {
musicStore.findSongFast(item.songHash, item.albumHash)?.let { song ->
if (item.isUserQueue) {
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/AudioReactor.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/AudioReactor.kt
index c06fc6a0c..e80d3b100 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/system/AudioReactor.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/system/AudioReactor.kt
@@ -25,10 +25,10 @@ import androidx.core.animation.addListener
import androidx.media.AudioFocusRequestCompat
import androidx.media.AudioManagerCompat
import com.google.android.exoplayer2.SimpleExoPlayer
+import org.oxycblt.auxio.getSystemServiceSafe
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.settings.SettingsManager
-import org.oxycblt.auxio.ui.getSystemServiceSafe
/**
* Object that manages the AudioFocus state.
diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt
index 39cd9c399..5a17b0e72 100644
--- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt
+++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackNotification.kt
@@ -31,10 +31,10 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.coil.loadBitmap
import org.oxycblt.auxio.music.Parent
import org.oxycblt.auxio.music.Song
+import org.oxycblt.auxio.newBroadcastIntent
+import org.oxycblt.auxio.newMainIntent
import org.oxycblt.auxio.playback.state.LoopMode
import org.oxycblt.auxio.settings.SettingsManager
-import org.oxycblt.auxio.ui.newBroadcastIntent
-import org.oxycblt.auxio.ui.newMainIntent
/**
* The unified notification for [PlaybackService]. This is not self-sufficient, updates have
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 25f82464c..177f87bc2 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
@@ -52,6 +52,7 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.launch
import org.oxycblt.auxio.BuildConfig
+import org.oxycblt.auxio.getSystemServiceSafe
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.Parent
import org.oxycblt.auxio.music.Song
@@ -59,7 +60,6 @@ import org.oxycblt.auxio.music.toURI
import org.oxycblt.auxio.playback.state.LoopMode
import org.oxycblt.auxio.playback.state.PlaybackStateManager
import org.oxycblt.auxio.settings.SettingsManager
-import org.oxycblt.auxio.ui.getSystemServiceSafe
import org.oxycblt.auxio.widgets.WidgetController
import org.oxycblt.auxio.widgets.WidgetProvider
diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/FastScrollView.kt b/app/src/main/java/org/oxycblt/auxio/recycler/FastScrollView.kt
index 331e311c6..e80750fca 100644
--- a/app/src/main/java/org/oxycblt/auxio/recycler/FastScrollView.kt
+++ b/app/src/main/java/org/oxycblt/auxio/recycler/FastScrollView.kt
@@ -33,13 +33,13 @@ import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
+import org.oxycblt.auxio.accent.Accent
+import org.oxycblt.auxio.canScroll
import org.oxycblt.auxio.databinding.ViewFastScrollBinding
+import org.oxycblt.auxio.inflater
import org.oxycblt.auxio.logD
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.canScroll
-import org.oxycblt.auxio.ui.inflater
-import org.oxycblt.auxio.ui.resolveAttr
-import org.oxycblt.auxio.ui.toColor
+import org.oxycblt.auxio.resolveAttr
+import org.oxycblt.auxio.resolveColor
import kotlin.math.ceil
import kotlin.math.min
import kotlin.math.roundToInt
@@ -49,6 +49,8 @@ import kotlin.math.roundToInt
* fast-scrollers, this one displays indicators and a thumb instead of simply a scroll bar.
* This code is fundamentally an adaptation of Reddit's IndicatorFastScroll, albeit specialized
* towards Auxio. The original library is here: https://github.com/reddit/IndicatorFastScroll/
+ * TODO: Replace this with something similar to AndroidFastScroll [but optimized for Auxio],
+ * since this thumb view is a blocker to a better sort system.
* @author OxygenCobalt
*/
class FastScrollView @JvmOverloads constructor(
@@ -97,7 +99,7 @@ class FastScrollView @JvmOverloads constructor(
private data class Indicator(val char: Char, val pos: Int)
private var indicators = listOf()
- private val activeColor = Accent.get().color.toColor(context)
+ private val activeColor = Accent.get().color.resolveColor(context)
private val inactiveColor = android.R.attr.textColorSecondary.resolveAttr(context)
// --- STATE ---
diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ModelHolders.kt b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ModelHolders.kt
index 7b029ba37..6882aeb77 100644
--- a/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ModelHolders.kt
+++ b/app/src/main/java/org/oxycblt/auxio/recycler/viewholders/ModelHolders.kt
@@ -25,12 +25,12 @@ import org.oxycblt.auxio.databinding.ItemArtistBinding
import org.oxycblt.auxio.databinding.ItemGenreBinding
import org.oxycblt.auxio.databinding.ItemHeaderBinding
import org.oxycblt.auxio.databinding.ItemSongBinding
+import org.oxycblt.auxio.inflater
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Header
import org.oxycblt.auxio.music.Song
-import org.oxycblt.auxio.ui.inflater
/**
* The Shared ViewHolder for a [Song]. Instantiation should be done with [from].
diff --git a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt
index 8ae0ee32b..cc80aade9 100644
--- a/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/search/SearchFragment.kt
@@ -40,7 +40,7 @@ import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Header
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
-import org.oxycblt.auxio.ui.getSpans
+import org.oxycblt.auxio.spans
import org.oxycblt.auxio.ui.newMenu
/**
@@ -90,7 +90,9 @@ class SearchFragment : Fragment() {
binding.searchRecycler.apply {
adapter = searchAdapter
- val spans = getSpans()
+
+ // It's expensive to calculate the spans for each position in the list, so cache it.
+ val spans = spans
if (spans != -1) {
layoutManager = GridLayoutManager(requireContext(), spans).apply {
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/AboutFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/AboutFragment.kt
index a32305267..2829389ed 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/AboutFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/AboutFragment.kt
@@ -34,7 +34,7 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentAboutBinding
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.MusicStore
-import org.oxycblt.auxio.ui.showToast
+import org.oxycblt.auxio.showToast
/**
* A [BottomSheetDialogFragment] that shows Auxio's about screen.
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 f79779dea..74db3de55 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsCompat.kt
@@ -21,10 +21,10 @@ package org.oxycblt.auxio.settings
import android.content.SharedPreferences
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.content.edit
+import org.oxycblt.auxio.accent.ACCENTS
+import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.recycler.DisplayMode
-import org.oxycblt.auxio.ui.ACCENTS
-import org.oxycblt.auxio.ui.Accent
// A couple of utils for migrating from old settings values to the new
// formats used in 1.3.2 & 1.4.0
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
index 0488f20e4..f40a75aa5 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsListFragment.kt
@@ -28,16 +28,16 @@ import androidx.preference.PreferenceFragmentCompat
import androidx.preference.children
import coil.Coil
import org.oxycblt.auxio.R
+import org.oxycblt.auxio.accent.Accent
+import org.oxycblt.auxio.accent.AccentDialog
+import org.oxycblt.auxio.excluded.ExcludedDialog
+import org.oxycblt.auxio.isNight
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.DisplayMode
-import org.oxycblt.auxio.settings.accent.AccentDialog
-import org.oxycblt.auxio.settings.blacklist.BlacklistDialog
import org.oxycblt.auxio.settings.ui.IntListPrefDialog
import org.oxycblt.auxio.settings.ui.IntListPreference
-import org.oxycblt.auxio.ui.Accent
-import org.oxycblt.auxio.ui.isNight
-import org.oxycblt.auxio.ui.showToast
+import org.oxycblt.auxio.showToast
/**
* The actual fragment containing the settings menu. Inherits [PreferenceFragmentCompat].
@@ -103,7 +103,7 @@ class SettingsListFragment : PreferenceFragmentCompat() {
SettingsManager.KEY_BLACK_THEME -> {
onPreferenceClickListener = Preference.OnPreferenceClickListener {
- if (requireContext().isNight()) {
+ if (requireContext().isNight) {
requireActivity().recreate()
}
@@ -168,7 +168,7 @@ class SettingsListFragment : PreferenceFragmentCompat() {
SettingsManager.KEY_BLACKLIST -> {
onPreferenceClickListener = Preference.OnPreferenceClickListener {
- BlacklistDialog().show(childFragmentManager, BlacklistDialog.TAG)
+ ExcludedDialog().show(childFragmentManager, ExcludedDialog.TAG)
true
}
}
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 509d70fcf..729b2c039 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/SettingsManager.kt
@@ -22,11 +22,11 @@ import android.content.Context
import android.content.SharedPreferences
import androidx.core.content.edit
import androidx.preference.PreferenceManager
+import org.oxycblt.auxio.accent.ACCENTS
+import org.oxycblt.auxio.accent.Accent
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.recycler.DisplayMode
import org.oxycblt.auxio.recycler.SortMode
-import org.oxycblt.auxio.ui.ACCENTS
-import org.oxycblt.auxio.ui.Accent
/**
* Wrapper around the [SharedPreferences] class that writes & reads values without a context.
diff --git a/app/src/main/java/org/oxycblt/auxio/settings/ui/LifecycleDialog.kt b/app/src/main/java/org/oxycblt/auxio/settings/ui/LifecycleDialog.kt
index 5dc7e45c5..1d6dd1bd4 100644
--- a/app/src/main/java/org/oxycblt/auxio/settings/ui/LifecycleDialog.kt
+++ b/app/src/main/java/org/oxycblt/auxio/settings/ui/LifecycleDialog.kt
@@ -27,7 +27,7 @@ import androidx.core.graphics.drawable.toDrawable
import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.oxycblt.auxio.R
-import org.oxycblt.auxio.ui.resolveAttr
+import org.oxycblt.auxio.resolveAttr
/**
* A wrapper around [DialogFragment] that allows the usage of the standard Auxio lifecycle
diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt
index 4185cca48..a9c53f4fc 100644
--- a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt
@@ -31,7 +31,7 @@ import org.oxycblt.auxio.logD
import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.recycler.sliceArticle
-import org.oxycblt.auxio.ui.getSpans
+import org.oxycblt.auxio.spans
import org.oxycblt.auxio.ui.newMenu
/**
@@ -66,7 +66,6 @@ class SongsFragment : Fragment() {
adapter = songAdapter
setHasFixedSize(true)
- val spans = getSpans()
if (spans != 1) {
layoutManager = GridLayoutManager(requireContext(), spans)
}
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 3a8c3a85c..645bb4732 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/ActionMenu.kt
@@ -33,6 +33,7 @@ import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.PlaybackViewModel
+import org.oxycblt.auxio.showToast
/**
* Extension method for creating and showing a new [ActionMenu].
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/MemberBinder.kt b/app/src/main/java/org/oxycblt/auxio/ui/MemberBinder.kt
index dac290503..0dc191aa0 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/MemberBinder.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/MemberBinder.kt
@@ -26,6 +26,8 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
+import org.oxycblt.auxio.assertMainThread
+import org.oxycblt.auxio.inflater
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty
diff --git a/app/src/main/java/org/oxycblt/auxio/ui/SlideLinearLayout.kt b/app/src/main/java/org/oxycblt/auxio/ui/SlideLinearLayout.kt
index 0a01efb93..b1e91346a 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/SlideLinearLayout.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/SlideLinearLayout.kt
@@ -55,7 +55,7 @@ class SlideLinearLayout @JvmOverloads constructor(
it.isAccessible = true
}
} catch (e: NoSuchFieldException) {
- logE("Could not get mDisappearingChildren.")
+ logE("Could not get mDisappearingChildren. This is very ungood.")
null
}
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 7eaab084e..69efb2a93 100644
--- a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt
+++ b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt
@@ -22,10 +22,10 @@ import android.content.Context
import android.widget.RemoteViews
import androidx.annotation.LayoutRes
import org.oxycblt.auxio.R
+import org.oxycblt.auxio.newBroadcastIntent
+import org.oxycblt.auxio.newMainIntent
import org.oxycblt.auxio.playback.state.LoopMode
import org.oxycblt.auxio.playback.system.PlaybackService
-import org.oxycblt.auxio.ui.newBroadcastIntent
-import org.oxycblt.auxio.ui.newMainIntent
private fun createViews(
context: Context,
@@ -41,7 +41,7 @@ private fun createViews(
return views
}
-private fun RemoteViews.applyMeta(context: Context, state: WidgetState) {
+private fun RemoteViews.applyMeta(state: WidgetState) {
setTextViewText(R.id.widget_song, state.song.name)
setTextViewText(R.id.widget_artist, state.song.album.artist.name)
}
@@ -96,20 +96,20 @@ fun createDefaultWidget(context: Context): RemoteViews {
fun createMiniWidget(context: Context, state: WidgetState): RemoteViews {
val views = createViews(context, R.layout.widget_mini)
- views.applyMeta(context, state)
+ views.applyMeta(state)
return views
}
fun createCompactWidget(context: Context, state: WidgetState): RemoteViews {
val views = createViews(context, R.layout.widget_compact)
- views.applyMeta(context, state)
+ views.applyMeta(state)
views.applyCover(context, state)
return views
}
fun createSmallWidget(context: Context, state: WidgetState): RemoteViews {
val views = createViews(context, R.layout.widget_small)
- views.applyMeta(context, state)
+ views.applyMeta(state)
views.applyCover(context, state)
views.applyControls(context, state)
return views
@@ -117,7 +117,7 @@ fun createSmallWidget(context: Context, state: WidgetState): RemoteViews {
fun createFullWidget(context: Context, state: WidgetState): RemoteViews {
val views = createViews(context, R.layout.widget_full)
- views.applyMeta(context, state)
+ views.applyMeta(state)
views.applyCover(context, state)
views.applyControls(context, state)
diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt
index 1a167c66f..a10ca8ff0 100644
--- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt
+++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt
@@ -30,9 +30,9 @@ import android.util.SizeF
import android.widget.RemoteViews
import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.coil.loadBitmap
+import org.oxycblt.auxio.isLandscape
import org.oxycblt.auxio.logD
import org.oxycblt.auxio.playback.state.PlaybackStateManager
-import org.oxycblt.auxio.ui.isLandscape
/**
* Auxio's one and only appwidget. This widget follows a more unorthodox approach, effectively
@@ -167,7 +167,7 @@ class WidgetProvider : AppWidgetProvider() {
var height: Int
// Landscape/Portrait modes use different dimen bounds
- if (isLandscape(context.resources)) {
+ if (context.isLandscape()) {
width = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH)
height = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
} else {
diff --git a/app/src/main/res/layout/dialog_accent.xml b/app/src/main/res/layout/dialog_accent.xml
index eb9cf294f..9c0c8d3c4 100644
--- a/app/src/main/res/layout/dialog_accent.xml
+++ b/app/src/main/res/layout/dialog_accent.xml
@@ -9,7 +9,7 @@
android:layout_height="match_parent"
android:overScrollMode="never"
android:paddingTop="@dimen/spacing_small"
- app:layoutManager="org.oxycblt.auxio.settings.accent.AutoGridLayoutManager"
+ app:layoutManager=".accent.AutoGridLayoutManager"
app:layout_constraintBottom_toTopOf="@+id/accent_cancel"
app:layout_constraintTop_toBottomOf="@+id/accent_header"
tools:itemCount="18"
diff --git a/info/ARCHITECTURE.md b/info/ARCHITECTURE.md
index 57513dcca..6fb237b96 100644
--- a/info/ARCHITECTURE.md
+++ b/info/ARCHITECTURE.md
@@ -87,8 +87,10 @@ To prevent any strange bugs, all integer representations must be unique. A table
Auxio's package structure is mostly based around the features, and then any sub-features or components involved with that. There are some shared packages however. A diagram of the package structure is shown below:
```
-org.oxycblt.auxio # Main UI's and logging utilities
+org.oxycblt.auxio # Main UI's and utilities
+├──.accent # Accent UI + Systems
├──.coil # Fetchers and utilities for Coil, contains binding adapters than be used in the user interface.
+├──.blacklist # Excluded Directories UI/Systems
├──.database # Databases and their items for Auxio
├──.detail # UIs for more album/artist/genre details
│ └──.adapters # RecyclerView adapters for the detail UIs, which display the header information and items
@@ -103,8 +105,6 @@ org.oxycblt.auxio # Main UI's and logging utilities
│ └──.viewholders # Shared ViewHolders and ViewHolder utilities
├──.search # Search UI
├──.settings # Settings UI and systems
-│ ├──.blacklist # Excluded Directories UI/Systems
-│ ├──.accent # Accent UI + Systems
│ └──.ui # Settings-Related UIs
├──.songs # Songs UI
├──.ui # Shared user interface utilities