Update codebase
Do a variety of small things across the codebase.
This commit is contained in:
parent
8c107d66a0
commit
f04ffdb59b
24 changed files with 137 additions and 199 deletions
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -63,10 +63,6 @@ class CompactPlaybackFragment : Fragment() {
|
|||
}
|
||||
}
|
||||
|
||||
playbackModel.positionAsProgress.observe(viewLifecycleOwner) {
|
||||
binding.playbackProgress.progress = it
|
||||
}
|
||||
|
||||
logD("Fragment Created")
|
||||
|
||||
return binding.root
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ---
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue