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 * [BaseModel] variant that denotes that this object is a parent of other data objects, such
* as an [Album] or [Artist] * 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]. * The data object for a song. Inherits [BaseModel].
@ -47,6 +50,9 @@ data class Song(
val genre: Genre? get() = mGenre val genre: Genre? get() = mGenre
val album: Album get() = requireNotNull(mAlbum) val album: Album get() = requireNotNull(mAlbum)
val seconds = duration / 1000
val formattedDuration: String = seconds.toDuration()
fun linkAlbum(album: Album) { fun linkAlbum(album: Album) {
if (mAlbum == null) { if (mAlbum == null) {
mAlbum = album mAlbum = album
@ -58,9 +64,6 @@ data class Song(
mGenre = genre mGenre = genre
} }
} }
val seconds = duration / 1000
val formattedDuration: String = seconds.toDuration()
} }
/** /**
@ -119,7 +122,7 @@ data class Artist(
} }
val genre: Genre? by lazy { 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 { val songs: List<Song> by lazy {
@ -130,17 +133,14 @@ data class Artist(
/** /**
* The data object for a genre. Inherits [Parent] * The data object for a genre. Inherits [Parent]
* @property songs The list of all [Song]s in this genre. * @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 * @author OxygenCobalt
*/ */
data class Genre( data class Genre(
override val id: Long = -1, override val id: Long = -1,
override val name: String, override val name: String,
) : Parent() { ) : Parent() {
private val mSongs = mutableListOf<Song>() val resolvedName: String by lazy {
val songs: List<Song> get() = mSongs
val displayName: String by lazy {
if (name.contains(Regex("[0123456789)]"))) { if (name.contains(Regex("[0123456789)]"))) {
name.toNamedGenre() ?: name name.toNamedGenre() ?: name
} else { } 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() val totalDuration: String get() = songs.sumOf { it.seconds }.toDuration()
fun linkSong(song: Song) { fun linkSong(song: Song) {

View file

@ -113,7 +113,7 @@ fun Int.toYear(context: Context): String {
*/ */
@BindingAdapter("artistGenre") @BindingAdapter("artistGenre")
fun TextView.bindArtistGenre(artist: Artist) { 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") logD("Fragment Created")
return binding.root return binding.root

View file

@ -32,14 +32,8 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
playbackSong.isSelected = false playbackSong.isSelected = false
} }
// Colors private lateinit var accentColor: ColorStateList
private val accentColor: ColorStateList by lazy { private lateinit var controlColor: ColorStateList
Accent.get().getStateList(requireContext())
}
private val controlColor: ColorStateList by lazy {
R.color.control_color.toStateList(requireContext())
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
@ -50,12 +44,14 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
// Would require writing my own variant though to avoid index updates // Would require writing my own variant though to avoid index updates
val normalTextColor = binding.playbackDurationCurrent.currentTextColor 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. // Can't set the tint of a MenuItem below Android 8, so use icons instead.
val iconQueueActive = R.drawable.ic_queue.toDrawable(requireContext()) val iconQueueActive = R.drawable.ic_queue.toDrawable(requireContext())
val iconQueueInactive = R.drawable.ic_queue_inactive.toDrawable(requireContext()) val iconQueueInactive = R.drawable.ic_queue_inactive.toDrawable(requireContext())
val queueMenuItem: MenuItem val queueItem: MenuItem
// --- UI SETUP --- // --- UI SETUP ---
@ -77,7 +73,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
} else false } else false
} }
queueMenuItem = menu.findItem(R.id.action_queue) queueItem = menu.findItem(R.id.action_queue)
} }
// Make marquee of song title work // Make marquee of song title work
@ -100,12 +96,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
} }
playbackModel.isShuffling.observe(viewLifecycleOwner) { playbackModel.isShuffling.observe(viewLifecycleOwner) {
// Highlight the shuffle button if Playback is shuffled, and revert it if not. binding.playbackShuffle.imageTintList = if (it) accentColor else controlColor
if (it) {
binding.playbackShuffle.imageTintList = accentColor
} else {
binding.playbackShuffle.imageTintList = controlColor
}
} }
playbackModel.loopMode.observe(viewLifecycleOwner) { playbackModel.loopMode.observe(viewLifecycleOwner) {
@ -114,10 +105,12 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
binding.playbackLoop.imageTintList = controlColor binding.playbackLoop.imageTintList = controlColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop) binding.playbackLoop.setImageResource(R.drawable.ic_loop)
} }
LoopMode.ONCE -> { LoopMode.ONCE -> {
binding.playbackLoop.imageTintList = accentColor binding.playbackLoop.imageTintList = accentColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop_one) binding.playbackLoop.setImageResource(R.drawable.ic_loop_one)
} }
LoopMode.INFINITE -> { LoopMode.INFINITE -> {
binding.playbackLoop.imageTintList = accentColor binding.playbackLoop.imageTintList = accentColor
binding.playbackLoop.setImageResource(R.drawable.ic_loop) binding.playbackLoop.setImageResource(R.drawable.ic_loop)
@ -128,7 +121,6 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
} }
playbackModel.isSeeking.observe(viewLifecycleOwner) { playbackModel.isSeeking.observe(viewLifecycleOwner) {
// Highlight the current duration if the user is seeking, and revert it if not.
if (it) { if (it) {
binding.playbackDurationCurrent.setTextColor(accentColor) binding.playbackDurationCurrent.setTextColor(accentColor)
} else { } 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) { playbackModel.positionAsProgress.observe(viewLifecycleOwner) {
if (!playbackModel.isSeeking.value!!) { if (!playbackModel.isSeeking.value!!) {
binding.playbackSeekBar.progress = it binding.playbackSeekBar.progress = it
} }
} }
playbackModel.nextItemsInQueue.observe(viewLifecycleOwner) { playbackModel.nextItemsInQueue.observe(viewLifecycleOwner) { nextQueue ->
// Disable the option to open the queue if there's nothing in it. val userQueue = playbackModel.userQueue.value!!
if (it.isEmpty() && playbackModel.userQueue.value!!.isEmpty()) {
queueMenuItem.isEnabled = false if (userQueue.isEmpty() && nextQueue.isEmpty()) {
queueMenuItem.icon = iconQueueInactive queueItem.icon = iconQueueInactive
queueItem.isEnabled = false
} else { } else {
queueMenuItem.isEnabled = true queueItem.icon = iconQueueActive
queueMenuItem.icon = iconQueueActive queueItem.isEnabled = true
} }
} }
playbackModel.userQueue.observe(viewLifecycleOwner) { playbackModel.userQueue.observe(viewLifecycleOwner) { userQueue ->
if (it.isEmpty() && playbackModel.nextItemsInQueue.value!!.isEmpty()) { val nextQueue = playbackModel.nextItemsInQueue.value!!
queueMenuItem.isEnabled = false
queueMenuItem.icon = iconQueueInactive if (userQueue.isEmpty() && nextQueue.isEmpty()) {
queueItem.icon = iconQueueInactive
queueItem.isEnabled = false
} else { } else {
queueMenuItem.isEnabled = true queueItem.icon = iconQueueActive
queueMenuItem.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.R
import org.oxycblt.auxio.databinding.FragmentQueueBinding import org.oxycblt.auxio.databinding.FragmentQueueBinding
import org.oxycblt.auxio.music.BaseModel import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Header import org.oxycblt.auxio.music.Header
import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.playback.shouldHandleFileIntent import org.oxycblt.auxio.playback.shouldHandleFileIntent
import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.ui.isEdgeOn import org.oxycblt.auxio.ui.isEdgeOn
import org.oxycblt.auxio.ui.isIrregularLandscape import org.oxycblt.auxio.ui.isIrregularLandscape
@ -145,15 +143,6 @@ class QueueFragment : Fragment() {
} }
private fun getParentName(): String { private fun getParentName(): String {
return if (playbackModel.mode.value == PlaybackMode.ALL_SONGS) { return playbackModel.parent.value?.displayName ?: getString(R.string.label_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
}
}
} }
} }

View file

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

View file

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

View file

@ -31,11 +31,11 @@ enum class SortMode(@DrawableRes val iconRes: Int) {
fun getSortedGenreList(genres: List<Genre>): List<Genre> { fun getSortedGenreList(genres: List<Genre>): List<Genre> {
return when (this) { return when (this) {
ALPHA_UP -> genres.sortedWith( ALPHA_UP -> genres.sortedWith(
compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.displayName } compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.resolvedName }
) )
ALPHA_DOWN -> genres.sortedWith( ALPHA_DOWN -> genres.sortedWith(
compareBy(String.CASE_INSENSITIVE_ORDER) { it.displayName } compareBy(String.CASE_INSENSITIVE_ORDER) { it.resolvedName }
) )
else -> genres 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 { companion object {
@Volatile @Volatile
private var INSTANCE: SettingsManager? = null 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.") 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_width="match_parent"
android:layout_height="@dimen/height_compact_progress" android:layout_height="@dimen/height_compact_progress"
android:clickable="false" android:clickable="false"
android:progress="@{playbackModel.positionAsProgress}"
android:progressBackgroundTint="?attr/colorControlNormal" android:progressBackgroundTint="?attr/colorControlNormal"
android:progressTint="?attr/colorPrimary" android:progressTint="?attr/colorPrimary"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"

View file

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

View file

@ -43,7 +43,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium" android:layout_marginStart="@dimen/margin_medium"
android:layout_marginEnd="@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_constraintBottom_toTopOf="@+id/genre_song_count"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"

View file

@ -43,7 +43,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_medium" android:layout_marginStart="@dimen/margin_medium"
android:layout_marginEnd="@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_constraintBottom_toTopOf="@+id/genre_song_count"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5" app:layout_constraintHorizontal_bias="0.5"

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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