Update codebase

Do a variety of small things across the codebase.
This commit is contained in:
OxygenCobalt 2021-02-23 13:22:09 -07:00
parent 8c107d66a0
commit f04ffdb59b
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
24 changed files with 137 additions and 199 deletions

View file

@ -18,8 +18,11 @@ sealed class BaseModel {
/**
* [BaseModel] variant that denotes that this object is a parent of other data objects, such
* as an [Album] or [Artist]
* @property displayName Name that handles the usage of [Genre.resolvedName] and the normal [BaseModel.name]
*/
sealed class Parent : BaseModel()
sealed class Parent : BaseModel() {
val displayName: String get() = if (this is Genre) resolvedName else name
}
/**
* The data object for a song. Inherits [BaseModel].
@ -47,6 +50,9 @@ data class Song(
val genre: Genre? get() = mGenre
val album: Album get() = requireNotNull(mAlbum)
val seconds = duration / 1000
val formattedDuration: String = seconds.toDuration()
fun linkAlbum(album: Album) {
if (mAlbum == null) {
mAlbum = album
@ -58,9 +64,6 @@ data class Song(
mGenre = genre
}
}
val seconds = duration / 1000
val formattedDuration: String = seconds.toDuration()
}
/**
@ -119,7 +122,7 @@ data class Artist(
}
val genre: Genre? by lazy {
songs.map { it.genre }.maxByOrNull { it?.songs?.size ?: 0 }
songs.groupBy { it.genre }.entries.maxByOrNull { it.value.size }?.key
}
val songs: List<Song> by lazy {
@ -130,17 +133,14 @@ data class Artist(
/**
* The data object for a genre. Inherits [Parent]
* @property songs The list of all [Song]s in this genre.
* @property displayName A name that can be displayed without it showing up as an integer. ***USE THIS INSTEAD OF [name]!!!!***
* @property resolvedName A name that has been resolved from its int-genre form to its named form.
* @author OxygenCobalt
*/
data class Genre(
override val id: Long = -1,
override val name: String,
) : Parent() {
private val mSongs = mutableListOf<Song>()
val songs: List<Song> get() = mSongs
val displayName: String by lazy {
val resolvedName: String by lazy {
if (name.contains(Regex("[0123456789)]"))) {
name.toNamedGenre() ?: name
} else {
@ -148,6 +148,9 @@ data class Genre(
}
}
private val mSongs = mutableListOf<Song>()
val songs: List<Song> get() = mSongs
val totalDuration: String get() = songs.sumOf { it.seconds }.toDuration()
fun linkSong(song: Song) {

View file

@ -113,7 +113,7 @@ fun Int.toYear(context: Context): String {
*/
@BindingAdapter("artistGenre")
fun TextView.bindArtistGenre(artist: Artist) {
text = artist.genre?.displayName ?: context.getString(R.string.placeholder_genre)
text = artist.genre?.resolvedName ?: context.getString(R.string.placeholder_genre)
}
/**

View file

@ -63,10 +63,6 @@ class CompactPlaybackFragment : Fragment() {
}
}
playbackModel.positionAsProgress.observe(viewLifecycleOwner) {
binding.playbackProgress.progress = it
}
logD("Fragment Created")
return binding.root

View file

@ -32,14 +32,8 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
playbackSong.isSelected = false
}
// Colors
private val accentColor: ColorStateList by lazy {
Accent.get().getStateList(requireContext())
}
private val controlColor: ColorStateList by lazy {
R.color.control_color.toStateList(requireContext())
}
private lateinit var accentColor: ColorStateList
private lateinit var controlColor: ColorStateList
override fun onCreateView(
inflater: LayoutInflater,
@ -50,12 +44,14 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
// Would require writing my own variant though to avoid index updates
val normalTextColor = binding.playbackDurationCurrent.currentTextColor
accentColor = Accent.get().getStateList(requireContext())
controlColor = R.color.control_color.toStateList(requireContext())
// Can't set the tint of a MenuItem below Android 8, so use icons instead.
val iconQueueActive = R.drawable.ic_queue.toDrawable(requireContext())
val iconQueueInactive = R.drawable.ic_queue_inactive.toDrawable(requireContext())
val queueMenuItem: MenuItem
val queueItem: MenuItem
// --- UI SETUP ---
@ -77,7 +73,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
} else false
}
queueMenuItem = menu.findItem(R.id.action_queue)
queueItem = menu.findItem(R.id.action_queue)
}
// Make marquee of song title work
@ -100,12 +96,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
}
playbackModel.isShuffling.observe(viewLifecycleOwner) {
// Highlight the shuffle button if Playback is shuffled, and revert it if not.
if (it) {
binding.playbackShuffle.imageTintList = accentColor
} else {
binding.playbackShuffle.imageTintList = controlColor
}
binding.playbackShuffle.imageTintList = if (it) accentColor else controlColor
}
playbackModel.loopMode.observe(viewLifecycleOwner) {
@ -114,10 +105,12 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
binding.playbackLoop.imageTintList = controlColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop)
}
LoopMode.ONCE -> {
binding.playbackLoop.imageTintList = accentColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop_one)
}
LoopMode.INFINITE -> {
binding.playbackLoop.imageTintList = accentColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop)
@ -128,7 +121,6 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
}
playbackModel.isSeeking.observe(viewLifecycleOwner) {
// Highlight the current duration if the user is seeking, and revert it if not.
if (it) {
binding.playbackDurationCurrent.setTextColor(accentColor)
} else {
@ -136,35 +128,33 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
}
}
// Updates for the current duration TextView/SeekBar
playbackModel.formattedPosition.observe(viewLifecycleOwner) {
binding.playbackDurationCurrent.text = it
}
playbackModel.positionAsProgress.observe(viewLifecycleOwner) {
if (!playbackModel.isSeeking.value!!) {
binding.playbackSeekBar.progress = it
}
}
playbackModel.nextItemsInQueue.observe(viewLifecycleOwner) {
// Disable the option to open the queue if there's nothing in it.
if (it.isEmpty() && playbackModel.userQueue.value!!.isEmpty()) {
queueMenuItem.isEnabled = false
queueMenuItem.icon = iconQueueInactive
playbackModel.nextItemsInQueue.observe(viewLifecycleOwner) { nextQueue ->
val userQueue = playbackModel.userQueue.value!!
if (userQueue.isEmpty() && nextQueue.isEmpty()) {
queueItem.icon = iconQueueInactive
queueItem.isEnabled = false
} else {
queueMenuItem.isEnabled = true
queueMenuItem.icon = iconQueueActive
queueItem.icon = iconQueueActive
queueItem.isEnabled = true
}
}
playbackModel.userQueue.observe(viewLifecycleOwner) {
if (it.isEmpty() && playbackModel.nextItemsInQueue.value!!.isEmpty()) {
queueMenuItem.isEnabled = false
queueMenuItem.icon = iconQueueInactive
playbackModel.userQueue.observe(viewLifecycleOwner) { userQueue ->
val nextQueue = playbackModel.nextItemsInQueue.value!!
if (userQueue.isEmpty() && nextQueue.isEmpty()) {
queueItem.icon = iconQueueInactive
queueItem.isEnabled = false
} else {
queueMenuItem.isEnabled = true
queueMenuItem.icon = iconQueueActive
queueItem.icon = iconQueueActive
queueItem.isEnabled = true
}
}

View file

@ -14,11 +14,9 @@ import androidx.recyclerview.widget.ItemTouchHelper
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentQueueBinding
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Header
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.shouldHandleFileIntent
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.ui.isEdgeOn
import org.oxycblt.auxio.ui.isIrregularLandscape
@ -145,15 +143,6 @@ class QueueFragment : Fragment() {
}
private fun getParentName(): String {
return if (playbackModel.mode.value == PlaybackMode.ALL_SONGS) {
getString(R.string.label_all_songs)
} else {
if (playbackModel.parent.value is Genre) {
// Use display name for Genres so that numbers dont show up
(playbackModel.parent.value as Genre).displayName
} else {
playbackModel.parent.value!!.name
}
}
return playbackModel.parent.value?.displayName ?: getString(R.string.label_all_songs)
}
}

View file

@ -14,7 +14,6 @@ import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.MainActivity
import org.oxycblt.auxio.R
import org.oxycblt.auxio.coil.loadBitmap
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Parent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.state.LoopMode
@ -119,17 +118,8 @@ class PlaybackNotification private constructor(
return
}
if (parent == null) {
// A blank parent always means that the mode is ALL_SONGS
setSubText(context.getString(R.string.label_all_songs))
} else {
if (parent is Genre) {
// Use display name for genre
setSubText(parent.displayName)
} else {
setSubText(parent.name)
}
}
// A blank parent always means that the mode is ALL_SONGS
setSubText(parent?.displayName ?: context.getString(R.string.label_all_songs))
}
// --- NOTIFICATION ACTION BUILDERS ---

View file

@ -412,9 +412,7 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
)
} else {
startForeground(
PlaybackNotification.NOTIFICATION_ID, notification.build()
)
startForeground(PlaybackNotification.NOTIFICATION_ID, notification.build())
}
} else {
// If we are already in foreground just update the notification
@ -486,51 +484,45 @@ class PlaybackService : Service(), Player.EventListener, PlaybackStateManager.Ca
*/
private inner class SystemEventReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
when (intent.action) {
PlaybackNotification.ACTION_PLAY_PAUSE -> playbackManager.setPlaying(
!playbackManager.isPlaying
)
action?.let {
when (it) {
// --- NOTIFICATION CASES ---
PlaybackNotification.ACTION_LOOP -> playbackManager.setLoopMode(
playbackManager.loopMode.increment()
)
PlaybackNotification.ACTION_PLAY_PAUSE -> playbackManager.setPlaying(
!playbackManager.isPlaying
)
PlaybackNotification.ACTION_SHUFFLE -> playbackManager.setShuffling(
!playbackManager.isShuffling, keepSong = true
)
PlaybackNotification.ACTION_LOOP -> playbackManager.setLoopMode(
playbackManager.loopMode.increment()
)
PlaybackNotification.ACTION_SKIP_PREV -> playbackManager.prev()
PlaybackNotification.ACTION_SKIP_NEXT -> playbackManager.next()
PlaybackNotification.ACTION_SHUFFLE -> playbackManager.setShuffling(
!playbackManager.isShuffling, keepSong = true
)
PlaybackNotification.ACTION_EXIT -> {
playbackManager.setPlaying(false)
stopForegroundAndNotification()
}
PlaybackNotification.ACTION_SKIP_PREV -> playbackManager.prev()
PlaybackNotification.ACTION_SKIP_NEXT -> playbackManager.next()
// --- HEADSET CASES ---
PlaybackNotification.ACTION_EXIT -> {
playbackManager.setPlaying(false)
stopForegroundAndNotification()
BluetoothDevice.ACTION_ACL_CONNECTED -> resumeFromPlug()
BluetoothDevice.ACTION_ACL_DISCONNECTED -> pauseFromPlug()
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED -> {
when (intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1)) {
AudioManager.SCO_AUDIO_STATE_CONNECTED -> resumeFromPlug()
AudioManager.SCO_AUDIO_STATE_DISCONNECTED -> pauseFromPlug()
}
}
// --- HEADSET CASES ---
AudioManager.ACTION_AUDIO_BECOMING_NOISY -> pauseFromPlug()
BluetoothDevice.ACTION_ACL_CONNECTED -> resumeFromPlug()
BluetoothDevice.ACTION_ACL_DISCONNECTED -> pauseFromPlug()
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED -> {
when (intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1)) {
AudioManager.SCO_AUDIO_STATE_CONNECTED -> resumeFromPlug()
AudioManager.SCO_AUDIO_STATE_DISCONNECTED -> pauseFromPlug()
}
}
AudioManager.ACTION_AUDIO_BECOMING_NOISY -> pauseFromPlug()
Intent.ACTION_HEADSET_PLUG -> {
when (intent.getIntExtra("state", -1)) {
CONNECTED -> resumeFromPlug()
DISCONNECTED -> pauseFromPlug()
}
Intent.ACTION_HEADSET_PLUG -> {
when (intent.getIntExtra("state", -1)) {
CONNECTED -> resumeFromPlug()
DISCONNECTED -> pauseFromPlug()
}
}
}

View file

@ -31,11 +31,11 @@ enum class SortMode(@DrawableRes val iconRes: Int) {
fun getSortedGenreList(genres: List<Genre>): List<Genre> {
return when (this) {
ALPHA_UP -> genres.sortedWith(
compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.displayName }
compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.resolvedName }
)
ALPHA_DOWN -> genres.sortedWith(
compareBy(String.CASE_INSENSITIVE_ORDER) { it.displayName }
compareBy(String.CASE_INSENSITIVE_ORDER) { it.resolvedName }
)
else -> genres

View file

@ -197,6 +197,57 @@ class SettingsManager private constructor(context: Context) :
}
}
/** SharedPreferences keys. */
object Keys {
const val KEY_THEME = "KEY_THEME"
const val KEY_ACCENT = "KEY_ACCENT"
const val KEY_EDGE_TO_EDGE = "KEY_EDGE"
const val KEY_LIBRARY_DISPLAY_MODE = "KEY_LIBRARY_DISPLAY_MODE"
const val KEY_SHOW_COVERS = "KEY_SHOW_COVERS"
const val KEY_QUALITY_COVERS = "KEY_QUALITY_COVERS"
const val KEY_COLORIZE_NOTIFICATION = "KEY_COLOR_NOTIF"
const val KEY_USE_ALT_NOTIFICATION_ACTION = "KEY_ALT_NOTIF_ACTION"
const val KEY_AUDIO_FOCUS = "KEY_AUDIO_FOCUS"
const val KEY_PLUG_MANAGEMENT = "KEY_PLUG_MGT"
const val KEY_SONG_PLAYBACK_MODE = "KEY_SONG_PLAY_MODE"
const val KEY_AT_END = "KEY_AT_END"
const val KEY_KEEP_SHUFFLE = "KEY_KEEP_SHUFFLE"
const val KEY_PREV_REWIND = "KEY_PREV_REWIND"
const val KEY_LIBRARY_SORT_MODE = "KEY_LIBRARY_SORT_MODE"
const val KEY_SEARCH_FILTER_MODE = "KEY_SEARCH"
const val KEY_DEBUG_SAVE = "KEY_SAVE_STATE"
}
/** Values for some settings entries that cant be enums/ints.*/
object EntryValues {
const val THEME_AUTO = "AUTO"
const val THEME_LIGHT = "LIGHT"
const val THEME_DARK = "DARK"
/** Pause and loop at the end. Similar to Spotify. */
const val AT_END_LOOP_PAUSE = "LOOP_PAUSE"
/** Loop at the end. Similar to Music Player GO. */
const val AT_END_LOOP = "LOOP"
/** Stop at the end. */
const val AT_END_STOP = "STOP"
}
/**
* An interface for receiving some preference updates. Use/Extend this instead of
* [SharedPreferences.OnSharedPreferenceChangeListener] if possible, as it doesn't require a
* context.
*/
interface Callback {
fun onColorizeNotifUpdate(doColorize: Boolean) {}
fun onNotifActionUpdate(useAltAction: Boolean) {}
fun onLibDisplayModeUpdate(displayMode: DisplayMode) {}
fun onShowCoverUpdate(showCovers: Boolean) {}
fun onQualityCoverUpdate(doQualityCovers: Boolean) {}
}
companion object {
@Volatile
private var INSTANCE: SettingsManager? = null
@ -228,65 +279,4 @@ class SettingsManager private constructor(context: Context) :
error("SettingsManager must be initialized with init() before getting its instance.")
}
}
/**
* SharedPreferences keys.
*/
object Keys {
const val KEY_THEME = "KEY_THEME"
const val KEY_ACCENT = "KEY_ACCENT"
const val KEY_EDGE_TO_EDGE = "KEY_EDGE"
const val KEY_LIBRARY_DISPLAY_MODE = "KEY_LIBRARY_DISPLAY_MODE"
const val KEY_SHOW_COVERS = "KEY_SHOW_COVERS"
const val KEY_QUALITY_COVERS = "KEY_QUALITY_COVERS"
const val KEY_COLORIZE_NOTIFICATION = "KEY_COLOR_NOTIF"
const val KEY_USE_ALT_NOTIFICATION_ACTION = "KEY_ALT_NOTIF_ACTION"
const val KEY_AUDIO_FOCUS = "KEY_AUDIO_FOCUS"
const val KEY_PLUG_MANAGEMENT = "KEY_PLUG_MGT"
const val KEY_SONG_PLAYBACK_MODE = "KEY_SONG_PLAY_MODE"
const val KEY_AT_END = "KEY_AT_END"
const val KEY_KEEP_SHUFFLE = "KEY_KEEP_SHUFFLE"
const val KEY_PREV_REWIND = "KEY_PREV_REWIND"
const val KEY_LIBRARY_SORT_MODE = "KEY_LIBRARY_SORT_MODE"
const val KEY_SEARCH_FILTER_MODE = "KEY_SEARCH"
const val KEY_DEBUG_SAVE = "KEY_SAVE_STATE"
}
/**
* Values for some settings entries that cant be enums/ints.
*/
object EntryValues {
const val THEME_AUTO = "AUTO"
const val THEME_LIGHT = "LIGHT"
const val THEME_DARK = "DARK"
/**
* Pause and loop at the end. Similar to Spotify.
*/
const val AT_END_LOOP_PAUSE = "LOOP_PAUSE"
/**
* Loop at the end. Similar to Music Player GO.
*/
const val AT_END_LOOP = "LOOP"
/**
* Stop at the end. Similar to Phonograph.
*/
const val AT_END_STOP = "STOP"
}
/**
* An interface for receiving some preference updates. Use/Extend this instead of
* [SharedPreferences.OnSharedPreferenceChangeListener] if possible, as it doesn't require a
* context.
*/
interface Callback {
fun onColorizeNotifUpdate(doColorize: Boolean) {}
fun onNotifActionUpdate(useAltAction: Boolean) {}
fun onLibDisplayModeUpdate(displayMode: DisplayMode) {}
fun onShowCoverUpdate(showCovers: Boolean) {}
fun onQualityCoverUpdate(doQualityCovers: Boolean) {}
}
}

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M4 6H2v16h16v-2H4V6zm18-4H6v16h16V2zm-3 9h-4v4h-2v-4H9V9h4V5h2v4h4v2z" />
</vector>

View file

@ -96,6 +96,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/height_compact_progress"
android:clickable="false"
android:progress="@{playbackModel.positionAsProgress}"
android:progressBackgroundTint="?attr/colorControlNormal"
android:progressTint="?attr/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent"

View file

@ -145,6 +145,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_mid_large"
android:text="@{playbackModel.formattedPosition}"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"

View file

@ -43,7 +43,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium"
android:layout_marginEnd="@dimen/margin_medium"
android:text="@{genre.displayName}"
android:text="@{genre.resolvedName}"
app:layout_constraintBottom_toTopOf="@+id/genre_song_count"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"

View file

@ -43,7 +43,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium"
android:layout_marginEnd="@dimen/margin_medium"
android:text="@{genre.displayName}"
android:text="@{genre.resolvedName}"
app:layout_constraintBottom_toTopOf="@+id/genre_song_count"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"

View file

@ -147,6 +147,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_mid_large"
android:text="@{playbackModel.formattedPosition}"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toEndOf="@+id/playback_cover"
app:layout_constraintTop_toBottomOf="@+id/playback_seek_bar"

View file

@ -132,6 +132,7 @@
android:id="@+id/playback_duration_current"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{playbackModel.formattedPosition}"
android:layout_marginStart="@dimen/margin_mid_huge"
android:layout_marginBottom="@dimen/margin_medium"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"

View file

@ -30,6 +30,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/height_compact_progress"
android:clickable="false"
android:progress="@{playbackModel.positionAsProgress}"
android:progressBackgroundTint="?attr/colorControlNormal"
android:progressTint="?attr/colorPrimary"
app:layout_constraintStart_toStartOf="parent"

View file

@ -134,6 +134,7 @@
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_mid_large"
android:layout_marginBottom="@dimen/margin_medium"
android:text="@{playbackModel.formattedPosition}"
app:layout_constraintBottom_toTopOf="@+id/playback_play_pause"
app:layout_constraintStart_toStartOf="parent"
tools:text="11:38" />

View file

@ -27,7 +27,7 @@
<TextView
android:id="@+id/genre_name"
style="@style/ItemText.Primary"
android:text="@{genre.displayName}"
android:text="@{genre.resolvedName}"
app:layout_constraintBottom_toTopOf="@+id/genre_count"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/genre_image"

View file

@ -46,7 +46,7 @@
android:layout_marginStart="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_medium"
android:layout_marginEnd="@dimen/margin_medium"
android:text="@{genre.displayName}"
android:text="@{genre.resolvedName}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"

View file

@ -3,7 +3,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_queue_add"
android:icon="@drawable/ic_queue_add"
android:title="@string/label_queue_add"
app:showAsAction="never" />
</menu>

View file

@ -3,17 +3,14 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_play"
android:icon="@drawable/ic_play"
android:title="@string/label_play"
app:showAsAction="ifRoom" />
app:showAsAction="never" />
<item
android:id="@+id/action_shuffle"
android:icon="@drawable/ic_shuffle"
android:title="@string/label_shuffle"
app:showAsAction="never" />
<item
android:id="@+id/action_queue_add"
android:icon="@drawable/ic_queue_add"
android:title="@string/label_queue_add"
app:showAsAction="never" />
</menu>

View file

@ -2,10 +2,8 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_play"
android:icon="@drawable/ic_play"
android:title="@string/label_play" />
<item
android:id="@+id/action_shuffle"
android:icon="@drawable/ic_shuffle"
android:title="@string/label_shuffle" />
</menu>

View file

@ -2,7 +2,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_queue_add"
android:icon="@drawable/ic_queue_add"
android:title="@string/label_queue_add" />
<item
android:id="@+id/action_go_artist"