Minor changes

Change some minor things across the app.
This commit is contained in:
OxygenCobalt 2020-11-24 15:39:09 -07:00
parent 034f073bac
commit 6ce8c854a9
27 changed files with 112 additions and 104 deletions

View file

@ -1,7 +1,7 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs" apply plugin: 'androidx.navigation.safeargs'
android { android {
compileSdkVersion 30 compileSdkVersion 30
@ -22,6 +22,10 @@ android {
} }
buildTypes { buildTypes {
debug {
applicationIdSuffix = '.debug'
versionNameSuffix = "-DEBUG"
}
release { release {
minifyEnabled true minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

View file

@ -11,9 +11,8 @@ import org.oxycblt.auxio.ui.accent
// FIXME: Fix bug where fast navigation will break the animations and // FIXME: Fix bug where fast navigation will break the animations and
// lead to nothing being displayed [Possibly Un-fixable] // lead to nothing being displayed [Possibly Un-fixable]
// FIXME: Compat issues with Versions 5/6 that cause recyclerview // TODO: Landscape UI layouts
// dividers not to show and for progress bars to look wonky // FIXME: Compat issue with Versions 5 that leads to progress bar looking off
// FIXME: Navigation memory leak that is really confusing
class MainActivity : AppCompatActivity(R.layout.activity_main) { class MainActivity : AppCompatActivity(R.layout.activity_main) {
override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? { override fun onCreateView(name: String, context: Context, attrs: AttributeSet): View? {

View file

@ -59,9 +59,9 @@ class MainFragment : Fragment() {
) )
val navController = ( val navController = (
childFragmentManager.findFragmentById(R.id.explore_nav_host) childFragmentManager.findFragmentById(R.id.explore_nav_host)
as NavHostFragment? as NavHostFragment?
)?.findNavController() )?.findNavController()
// --- UI SETUP --- // --- UI SETUP ---
@ -97,11 +97,11 @@ class MainFragment : Fragment() {
if (it) { if (it) {
if (binding.navBar.selectedItemId != R.id.library_fragment || if (binding.navBar.selectedItemId != R.id.library_fragment ||
( (
navController!!.currentDestination?.id == R.id.album_detail_fragment && navController!!.currentDestination?.id == R.id.album_detail_fragment &&
detailModel.currentAlbum.value == null || detailModel.currentAlbum.value == null ||
detailModel.currentAlbum.value?.id detailModel.currentAlbum.value?.id
!= playbackModel.song.value!!.album.id != playbackModel.song.value!!.album.id
) || ) ||
navController.currentDestination?.id == R.id.artist_detail_fragment || navController.currentDestination?.id == R.id.artist_detail_fragment ||
navController.currentDestination?.id == R.id.genre_detail_fragment navController.currentDestination?.id == R.id.genre_detail_fragment
) { ) {

View file

@ -15,6 +15,7 @@ import android.util.Log
*/ */
class PlaybackStateDatabase(context: Context) : class PlaybackStateDatabase(context: Context) :
SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) { SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
override fun onCreate(db: SQLiteDatabase) { override fun onCreate(db: SQLiteDatabase) {
createTable(db, TABLE_NAME_STATE) createTable(db, TABLE_NAME_STATE)
createTable(db, TABLE_NAME_QUEUE) createTable(db, TABLE_NAME_QUEUE)
@ -111,7 +112,7 @@ class PlaybackStateDatabase(context: Context) :
/** /**
* Read the stored [PlaybackState] from the database, if there is one. * Read the stored [PlaybackState] from the database, if there is one.
* @return The stored [PlaybackState], null if there isnt one,. * @return The stored [PlaybackState], null if there isn't one,.
* @author OxygenCobalt * @author OxygenCobalt
*/ */
fun readState(): PlaybackState? { fun readState(): PlaybackState? {
@ -121,7 +122,11 @@ class PlaybackStateDatabase(context: Context) :
var stateCursor: Cursor? = null var stateCursor: Cursor? = null
try { try {
stateCursor = database.query(TABLE_NAME_STATE, null, null, null, null, null, null) stateCursor = database.query(
TABLE_NAME_STATE,
null, null, null,
null, null, null
)
stateCursor?.use { cursor -> stateCursor?.use { cursor ->
// Don't bother if the cursor [and therefore database] has nothing in it. // Don't bother if the cursor [and therefore database] has nothing in it.
@ -227,7 +232,10 @@ class PlaybackStateDatabase(context: Context) :
var queueCursor: Cursor? = null var queueCursor: Cursor? = null
try { try {
queueCursor = database.query(TABLE_NAME_QUEUE, null, null, null, null, null, null) queueCursor = database.query(
TABLE_NAME_QUEUE, null, null,
null, null, null, null
)
queueCursor?.use { cursor -> queueCursor?.use { cursor ->
if (cursor.count == 0) return@use if (cursor.count == 0) return@use

View file

@ -131,7 +131,7 @@ class AlbumDetailFragment : DetailFragment() {
binding.albumSongRecycler.post { binding.albumSongRecycler.post {
// Only scroll after UI creation // Only scroll after UI creation
val y = binding.albumSongRecycler.y + val y = binding.albumSongRecycler.y +
binding.albumSongRecycler.getChildAt(pos).y binding.albumSongRecycler.getChildAt(pos).y
binding.nestedScroll.smoothScrollBy(0, y.toInt()) binding.nestedScroll.smoothScrollBy(0, y.toInt())
} }

View file

@ -11,7 +11,8 @@ import androidx.navigation.fragment.findNavController
* A Base [Fragment] implementing a [OnBackPressedCallback] so that Auxio will navigate upwards * A Base [Fragment] implementing a [OnBackPressedCallback] so that Auxio will navigate upwards
* instead of out of the app if a Detail Fragment is currently open. Also carries the * instead of out of the app if a Detail Fragment is currently open. Also carries the
* multi-navigation fix. * multi-navigation fix.
* // TODO: Merge headers with recyclerview [if possible] * TODO: Implement a system where the Toolbar will update with some info when
* the main detail header is obscured.
* @author OxygenCobalt * @author OxygenCobalt
*/ */
abstract class DetailFragment : Fragment() { abstract class DetailFragment : Fragment() {
@ -32,6 +33,7 @@ abstract class DetailFragment : Fragment() {
super.onPause() super.onPause()
callback.isEnabled = false callback.isEnabled = false
} }
private val callback = object : OnBackPressedCallback(false) { private val callback = object : OnBackPressedCallback(false) {
override fun handleOnBackPressed() { override fun handleOnBackPressed() {

View file

@ -9,9 +9,6 @@ import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.recycler.SortMode import org.oxycblt.auxio.recycler.SortMode
// ViewModel for the Detail Fragments. // ViewModel for the Detail Fragments.
// TODO:
// - Implement a system where the Toolbar will update with some info when
// the main detail header is obscured.
class DetailViewModel : ViewModel() { class DetailViewModel : ViewModel() {
private var mIsNavigating = false private var mIsNavigating = false
val isNavigating: Boolean get() = mIsNavigating val isNavigating: Boolean get() = mIsNavigating

View file

@ -4,6 +4,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import org.oxycblt.auxio.databinding.ItemArtistAlbumBinding import org.oxycblt.auxio.databinding.ItemArtistAlbumBinding
import org.oxycblt.auxio.music.Album import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.recycler.DiffCallback import org.oxycblt.auxio.recycler.DiffCallback
@ -11,17 +12,19 @@ import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
class DetailAlbumAdapter( class DetailAlbumAdapter(
private val doOnClick: (data: Album) -> Unit, private val doOnClick: (data: Album) -> Unit,
private val doOnLongClick: (data: Album, view: View) -> Unit private val doOnLongClick: (data: Album, view: View) -> Unit,
) : ListAdapter<Album, DetailAlbumAdapter.AlbumViewHolder>(DiffCallback()) { ) : ListAdapter<Album, RecyclerView.ViewHolder>(DiffCallback()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return AlbumViewHolder( return AlbumViewHolder(
ItemArtistAlbumBinding.inflate(LayoutInflater.from(parent.context)) ItemArtistAlbumBinding.inflate(LayoutInflater.from(parent.context))
) )
} }
override fun onBindViewHolder(holder: AlbumViewHolder, position: Int) { override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder.bind(getItem(position)) when (val item = getItem(position)) {
is Album -> (holder as AlbumViewHolder).bind(item)
}
} }
// Generic ViewHolder for a detail album // Generic ViewHolder for a detail album

View file

@ -44,7 +44,7 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
val binding = FragmentLibraryBinding.inflate(inflater) val binding = FragmentLibraryBinding.inflate(inflater)
val musicStore = MusicStore.getInstance() val musicStore = MusicStore.getInstance()

View file

@ -107,5 +107,5 @@ class MosaicFetcher(private val context: Context) : Fetcher<List<Uri>> {
) )
} }
override fun key(data: List<Uri>): String? = data.toString() override fun key(data: List<Uri>): String = data.toString()
} }

View file

@ -6,7 +6,7 @@ import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageButton
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels import androidx.fragment.app.activityViewModels
@ -27,8 +27,6 @@ import org.oxycblt.auxio.ui.createToast
class CompactPlaybackFragment : Fragment() { class CompactPlaybackFragment : Fragment() {
private val playbackModel: PlaybackViewModel by activityViewModels() private val playbackModel: PlaybackViewModel by activityViewModels()
private var playbackControls: ImageView? = null
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@ -77,9 +75,6 @@ class CompactPlaybackFragment : Fragment() {
binding.playbackProgress.progress = it binding.playbackProgress.progress = it
} }
// Use the playback control ImageView for later.
playbackControls = binding.playbackControls
Log.d(this::class.simpleName, "Fragment Created") Log.d(this::class.simpleName, "Fragment Created")
return binding.root return binding.root
@ -90,6 +85,10 @@ class CompactPlaybackFragment : Fragment() {
playbackModel.disableAnimation() playbackModel.disableAnimation()
// Use the caveman method of getting a view as storing the binding will cause a memory
// leak.
val playbackControls = requireView().findViewById<ImageButton>(R.id.playback_controls)
// Observe the changes to isPlaying for // Observe the changes to isPlaying for
val iconPauseToPlay = ContextCompat.getDrawable( val iconPauseToPlay = ContextCompat.getDrawable(
requireContext(), R.drawable.ic_pause_to_play requireContext(), R.drawable.ic_pause_to_play
@ -122,10 +121,4 @@ class CompactPlaybackFragment : Fragment() {
} }
} }
} }
override fun onDestroy() {
super.onDestroy()
playbackControls = null
}
} }

View file

@ -32,7 +32,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
val binding = FragmentPlaybackBinding.inflate(inflater) val binding = FragmentPlaybackBinding.inflate(inflater)
// TODO: Add a swipe-to-next-track function using a ViewPager // TODO: Add a swipe-to-next-track function using a ViewPager
@ -84,7 +84,6 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
} }
// Make marquee scroll work // Make marquee scroll work
// TODO: Add nav here as well
binding.playbackSong.isSelected = true binding.playbackSong.isSelected = true
binding.playbackSeekBar.setOnSeekBarChangeListener(this) binding.playbackSeekBar.setOnSeekBarChangeListener(this)

View file

@ -1,6 +1,7 @@
package org.oxycblt.auxio.playback.queue package org.oxycblt.auxio.playback.queue
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent import android.view.MotionEvent
@ -54,7 +55,7 @@ class QueueAdapter(
ItemQueueSongBinding.inflate(LayoutInflater.from(parent.context)) ItemQueueSongBinding.inflate(LayoutInflater.from(parent.context))
) )
USER_QUEUE_HEADER_ITEM_tYPE -> UserQueueHeaderViewHolder( USER_QUEUE_HEADER_ITEM_tYPE -> UserQueueHeaderViewHolder(
ItemActionHeaderBinding.inflate(LayoutInflater.from(parent.context)) parent.context, ItemActionHeaderBinding.inflate(LayoutInflater.from(parent.context))
) )
else -> error("Someone messed with the ViewHolder item types.") else -> error("Someone messed with the ViewHolder item types.")
} }
@ -97,6 +98,7 @@ class QueueAdapter(
// Check for two things: // Check for two things:
// If the data from the next queue is now entirely empty [Signified by a header at the end] // If the data from the next queue is now entirely empty [Signified by a header at the end]
// Or if the data from the last queue is now entirely empty [Signified by there being 2 headers with no items in between] // Or if the data from the last queue is now entirely empty [Signified by there being 2 headers with no items in between]
// If so, remove that item and the removed item in a range. Otherwise just remove the item.
if (data[data.lastIndex] is Header) { if (data[data.lastIndex] is Header) {
val lastIndex = data.lastIndex val lastIndex = data.lastIndex
@ -146,8 +148,16 @@ class QueueAdapter(
} }
inner class UserQueueHeaderViewHolder( inner class UserQueueHeaderViewHolder(
context: Context,
private val binding: ItemActionHeaderBinding private val binding: ItemActionHeaderBinding
) : BaseViewHolder<Header>(binding, null, null) { ) : BaseViewHolder<Header>(binding, null, null) {
init {
binding.headerButton.contentDescription = context.getString(
R.string.description_clear_user_queue
)
}
override fun onBind(data: Header) { override fun onBind(data: Header) {
binding.header = data binding.header = data
binding.headerButton.apply { binding.headerButton.apply {

View file

@ -28,7 +28,7 @@ class QueueFragment : Fragment() {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
val binding = FragmentQueueBinding.inflate(inflater) val binding = FragmentQueueBinding.inflate(inflater)
val callback = QueueDragCallback(playbackModel) val callback = QueueDragCallback(playbackModel)

View file

@ -560,12 +560,12 @@ class PlaybackStateManager private constructor() {
// Traverse albums and then album songs instead of just the songs, as its faster. // Traverse albums and then album songs instead of just the songs, as its faster.
musicStore.albums.find { it.id == item.albumId } musicStore.albums.find { it.id == item.albumId }
?.songs?.find { it.id == item.songId }?.let { ?.songs?.find { it.id == item.songId }?.let {
if (item.isUserQueue) { if (item.isUserQueue) {
mUserQueue.add(it) mUserQueue.add(it)
} else { } else {
mQueue.add(it) mQueue.add(it)
}
} }
}
} }
// Get a more accurate index [At least if were not in the user queue] // Get a more accurate index [At least if were not in the user queue]

View file

@ -3,8 +3,6 @@ package org.oxycblt.auxio.recycler.viewholders
import android.content.Context import android.content.Context
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import androidx.annotation.DrawableRes
import org.oxycblt.auxio.databinding.ItemActionHeaderBinding
import org.oxycblt.auxio.databinding.ItemAlbumBinding import org.oxycblt.auxio.databinding.ItemAlbumBinding
import org.oxycblt.auxio.databinding.ItemArtistBinding import org.oxycblt.auxio.databinding.ItemArtistBinding
import org.oxycblt.auxio.databinding.ItemGenreBinding import org.oxycblt.auxio.databinding.ItemGenreBinding
@ -149,20 +147,3 @@ class HeaderViewHolder(
} }
} }
} }
abstract class ActionHeaderViewHolder(
protected val binding: ItemActionHeaderBinding,
@DrawableRes private val iconRes: Int
) : BaseViewHolder<Header>(binding, null, null) {
override fun onBind(data: Header) {
binding.header = data
binding.headerButton.apply {
setImageResource(iconRes)
setOnClickListener {
onActionClick()
}
}
}
abstract fun onActionClick()
}

View file

@ -22,7 +22,7 @@ class SongsFragment : Fragment() {
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View {
val binding = FragmentSongsBinding.inflate(inflater) val binding = FragmentSongsBinding.inflate(inflater)
val musicStore = MusicStore.getInstance() val musicStore = MusicStore.getInstance()

View file

@ -1,3 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!--
Animated icons derived from noice
https://github.com/ashutoshgngwr/noice/
-->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt" xmlns:aapt="http://schemas.android.com/aapt"
android:drawable="@drawable/ic_pause_large"> android:drawable="@drawable/ic_pause_large">

View file

@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<vector android:width="32dp" <vector android:width="32dp"
android:height="32dp" android:height="32dp"
android:tint="@color/control_color" android:tint="@color/control_color"

View file

@ -1,3 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!--
Animated icons derived from noice
https://github.com/ashutoshgngwr/noice/
-->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" <animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt" xmlns:aapt="http://schemas.android.com/aapt"
android:drawable="@drawable/ic_play_large"> android:drawable="@drawable/ic_play_large">

View file

@ -9,7 +9,7 @@ https://stackoverflow.com/a/61157571/14143986
android:top="-2dp"> android:top="-2dp">
<shape android:shape="rectangle"> <shape android:shape="rectangle">
<stroke <stroke
android:width="0.5dp" android:width="1dp"
android:color="@color/divider_color" /> android:color="@color/divider_color" />
</shape> </shape>
</item> </item>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/selection_color"
android:radius="@dimen/size_divider_ripple" />

View file

@ -111,23 +111,23 @@
android:id="@+id/album_song_header" android:id="@+id/album_song_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="@dimen/padding_medium" android:layout_marginTop="@dimen/margin_medium"
android:background="@drawable/ui_header_dividers" android:background="@drawable/ui_header_dividers"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@font/inter_semibold" android:fontFamily="@font/inter_semibold"
android:paddingStart="@dimen/padding_medium" android:paddingStart="@dimen/padding_medium"
android:paddingTop="@dimen/padding_small" android:paddingTop="@dimen/padding_small"
android:paddingEnd="@dimen/padding_small" android:paddingEnd="@dimen/padding_small"
android:paddingBottom="@dimen/padding_small" android:paddingBottom="@dimen/padding_small"
android:text="@string/label_songs" android:text="@string/label_songs"
android:textColor="?android:attr/textColorPrimary"
android:textSize="19sp" android:textSize="19sp"
app:layout_constraintTop_toBottomOf="@+id/album_details" /> app:layout_constraintTop_toBottomOf="@+id/album_details"
app:layout_constraintStart_toStartOf="parent" />
<ImageButton <ImageButton
android:id="@+id/album_sort_button" android:id="@+id/album_sort_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="@dimen/margin_medium"
android:background="@drawable/ui_header_dividers" android:background="@drawable/ui_header_dividers"
android:contentDescription="@string/description_sort_button" android:contentDescription="@string/description_sort_button"
android:onClick="@{() -> detailModel.incrementAlbumSortMode()}" android:onClick="@{() -> detailModel.incrementAlbumSortMode()}"
@ -135,9 +135,9 @@
android:paddingTop="@dimen/padding_small" android:paddingTop="@dimen/padding_small"
android:paddingEnd="@dimen/margin_medium" android:paddingEnd="@dimen/margin_medium"
android:paddingBottom="@dimen/padding_small" android:paddingBottom="@dimen/padding_small"
app:layout_constraintBottom_toTopOf="@+id/album_song_recycler" app:layout_constraintBottom_toBottomOf="@+id/album_song_header"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/album_details" app:layout_constraintTop_toTopOf="@+id/album_song_header"
tools:src="@drawable/ic_sort_numeric_down" /> tools:src="@drawable/ic_sort_numeric_down" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView

View file

@ -104,15 +104,15 @@
android:id="@+id/artist_album_header" android:id="@+id/artist_album_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="@dimen/padding_medium" android:layout_marginTop="@dimen/margin_medium"
android:background="@drawable/ui_header_dividers" android:background="@drawable/ui_header_dividers"
android:textColor="?android:attr/textColorPrimary"
android:fontFamily="@font/inter_semibold" android:fontFamily="@font/inter_semibold"
android:paddingStart="@dimen/padding_medium" android:paddingStart="@dimen/padding_medium"
android:paddingTop="@dimen/padding_small" android:paddingTop="@dimen/padding_small"
android:paddingEnd="@dimen/padding_small" android:paddingEnd="@dimen/padding_small"
android:paddingBottom="@dimen/padding_small" android:paddingBottom="@dimen/padding_small"
android:text="@string/label_albums" android:text="@string/label_albums"
android:textColor="?android:attr/textColorPrimary"
android:textSize="19sp" android:textSize="19sp"
app:layout_constraintTop_toBottomOf="@+id/artist_counts" /> app:layout_constraintTop_toBottomOf="@+id/artist_counts" />
@ -120,7 +120,6 @@
android:id="@+id/artist_sort_button" android:id="@+id/artist_sort_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="@dimen/margin_medium"
android:background="@drawable/ui_header_dividers" android:background="@drawable/ui_header_dividers"
android:contentDescription="@string/description_sort_button" android:contentDescription="@string/description_sort_button"
android:onClick="@{() -> detailModel.incrementArtistSortMode()}" android:onClick="@{() -> detailModel.incrementArtistSortMode()}"
@ -128,9 +127,9 @@
android:paddingTop="@dimen/padding_small" android:paddingTop="@dimen/padding_small"
android:paddingEnd="@dimen/margin_medium" android:paddingEnd="@dimen/margin_medium"
android:paddingBottom="@dimen/padding_small" android:paddingBottom="@dimen/padding_small"
app:layout_constraintBottom_toTopOf="@+id/artist_album_recycler" app:layout_constraintBottom_toBottomOf="@+id/artist_album_header"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/artist_counts" app:layout_constraintTop_toTopOf="@+id/artist_album_header"
tools:src="@drawable/ic_sort_numeric_down" /> tools:src="@drawable/ic_sort_numeric_down" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView

View file

@ -121,18 +121,17 @@
android:id="@+id/genre_sort_button" android:id="@+id/genre_sort_button"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginTop="@dimen/margin_medium"
android:background="@drawable/ui_header_dividers" android:background="@drawable/ui_header_dividers"
android:contentDescription="@string/description_sort_button" android:contentDescription="@string/description_sort_button"
android:onClick="@{() -> detailModel.incrementGenreSortMode()}"
android:paddingStart="@dimen/padding_medium" android:paddingStart="@dimen/padding_medium"
android:paddingTop="@dimen/padding_small" android:paddingTop="@dimen/padding_small"
android:paddingEnd="@dimen/margin_medium" android:paddingEnd="@dimen/margin_medium"
android:paddingBottom="@dimen/padding_small" android:paddingBottom="@dimen/padding_small"
android:onClick="@{() -> detailModel.incrementGenreSortMode()}" app:layout_constraintBottom_toBottomOf="@+id/genre_artist_header"
tools:src="@drawable/ic_sort_alpha_down" app:layout_constraintTop_toTopOf="@+id/genre_artist_header"
app:layout_constraintBottom_toTopOf="@+id/genre_artist_recycler" tools:layout_editor_absoluteX="355dp"
app:layout_constraintEnd_toEndOf="parent" tools:src="@drawable/ic_sort_alpha_down" />
app:layout_constraintTop_toBottomOf="@+id/genre_song_count" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/genre_artist_recycler" android:id="@+id/genre_artist_recycler"

View file

@ -13,37 +13,38 @@
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="wrap_content"
android:background="@drawable/ui_header_dividers">
<TextView <TextView
android:id="@+id/header_text" android:id="@+id/header_title"
android:layout_width="0dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginTop="@dimen/padding_medium"
android:fontFamily="@font/inter_semibold" android:fontFamily="@font/inter_semibold"
android:paddingStart="@dimen/padding_medium" android:paddingStart="@dimen/padding_medium"
android:paddingTop="@dimen/padding_small" android:paddingTop="@dimen/padding_small"
android:paddingEnd="@dimen/padding_small" android:paddingEnd="@dimen/padding_small"
android:paddingBottom="@dimen/padding_small" android:paddingBottom="@dimen/padding_small"
android:text="@{header.name}" android:text="@{header.name}"
tools:text="Songs"
android:textColor="?android:attr/textColorPrimary" android:textColor="?android:attr/textColorPrimary"
android:textSize="19sp" android:textSize="19sp"
app:layout_constraintEnd_toStartOf="@+id/header_button" app:layout_constraintStart_toStartOf="parent" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:background="@drawable/ui_header_dividers"
tools:text="Songs" />
<ImageButton <ImageButton
android:id="@+id/header_button" android:id="@+id/header_button"
style="@style/Widget.AppCompat.Button.Borderless" android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:background="@drawable/ui_header_dividers" android:contentDescription="@string/description_sort_button"
android:tint="?android:attr/colorPrimary" android:paddingStart="@dimen/padding_medium"
app:layout_constraintDimensionRatio="1:1" android:paddingTop="@dimen/padding_small"
android:background="@drawable/ui_small_unbounded_ripple"
android:paddingEnd="@dimen/margin_medium"
android:paddingBottom="@dimen/padding_small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="@+id/header_title"
tools:src="@drawable/ic_clear" tools:src="@drawable/ic_sort_numeric_down" />
tools:ignore="ContentDescription" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</layout> </layout>

View file

@ -25,7 +25,6 @@
<string name="label_queue_add">Add to queue</string> <string name="label_queue_add">Add to queue</string>
<string name="label_queue_added">Added to queue</string> <string name="label_queue_added">Added to queue</string>
<string name="label_next_user_queue">Next in Queue</string> <string name="label_next_user_queue">Next in Queue</string>
<string name="label_clear_user_queue">Clear queue</string>
<string name="label_channel">Music Playback</string> <string name="label_channel">Music Playback</string>
<string name="label_service_playback">The music playback service for Auxio.</string> <string name="label_service_playback">The music playback service for Auxio.</string>
@ -50,6 +49,7 @@
<string name="description_sort_none">Default Sort Order</string> <string name="description_sort_none">Default Sort Order</string>
<string name="description_sort_alpha_down">Sort from A to Z</string> <string name="description_sort_alpha_down">Sort from A to Z</string>
<string name="description_sort_alpha_up">Sort from Z to A</string> <string name="description_sort_alpha_up">Sort from Z to A</string>
<string name="description_clear_user_queue">Clear queue</string>
<string name="description_play">Play</string> <string name="description_play">Play</string>
<string name="description_pause">Pause</string> <string name="description_pause">Pause</string>
<string name="description_skip_next">Skip to next song</string> <string name="description_skip_next">Skip to next song</string>