Improve semantics
Remove some useless TODOs, update naming in places.
This commit is contained in:
parent
00667151dc
commit
2811c83543
20 changed files with 89 additions and 76 deletions
|
@ -89,7 +89,6 @@ class MainFragment : Fragment() {
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
|
||||||
// TODO: Add a slide animation to this
|
|
||||||
// Change CompactPlaybackFragment's visibility here so that an animation occurs.
|
// Change CompactPlaybackFragment's visibility here so that an animation occurs.
|
||||||
playbackModel.currentSong.observe(viewLifecycleOwner) {
|
playbackModel.currentSong.observe(viewLifecycleOwner) {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
|
|
|
@ -86,7 +86,6 @@ class AlbumDetailFragment : Fragment() {
|
||||||
|
|
||||||
// Observe playback model to update the play button
|
// Observe playback model to update the play button
|
||||||
// TODO: Make these icons animated
|
// TODO: Make these icons animated
|
||||||
// TODO: Shuffle button/option, unsure of which one
|
|
||||||
playbackModel.currentMode.observe(viewLifecycleOwner) {
|
playbackModel.currentMode.observe(viewLifecycleOwner) {
|
||||||
updatePlayButton(it, binding)
|
updatePlayButton(it, binding)
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,6 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.theme.applyDivider
|
import org.oxycblt.auxio.theme.applyDivider
|
||||||
import org.oxycblt.auxio.theme.disable
|
import org.oxycblt.auxio.theme.disable
|
||||||
|
|
||||||
// TODO: Add media controls to DetailFragments [Play, Shuffle]
|
|
||||||
// TODO: Implement a system where if the main info [Name, Parent, Counts] scrolls off of
|
|
||||||
// the screen, then update the toolbar to show that info w/the media controls
|
|
||||||
class ArtistDetailFragment : Fragment() {
|
class ArtistDetailFragment : Fragment() {
|
||||||
|
|
||||||
private val args: ArtistDetailFragmentArgs by navArgs()
|
private val args: ArtistDetailFragmentArgs by navArgs()
|
||||||
|
|
|
@ -8,7 +8,6 @@ import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.recycler.DiffCallback
|
import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
|
|
||||||
// TODO: Add ability to highlight currently playing songs
|
|
||||||
class DetailAlbumAdapter(
|
class DetailAlbumAdapter(
|
||||||
private val doOnClick: (Album) -> Unit
|
private val doOnClick: (Album) -> Unit
|
||||||
) : ListAdapter<Album, DetailAlbumAdapter.ViewHolder>(DiffCallback()) {
|
) : ListAdapter<Album, DetailAlbumAdapter.ViewHolder>(DiffCallback()) {
|
||||||
|
@ -25,7 +24,7 @@ class DetailAlbumAdapter(
|
||||||
|
|
||||||
// Generic ViewHolder for a detail album
|
// Generic ViewHolder for a detail album
|
||||||
inner class ViewHolder(
|
inner class ViewHolder(
|
||||||
private val binding: ItemArtistAlbumBinding
|
private val binding: ItemArtistAlbumBinding,
|
||||||
) : BaseViewHolder<Album>(binding, doOnClick) {
|
) : BaseViewHolder<Album>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Album) {
|
override fun onBind(model: Album) {
|
||||||
|
|
|
@ -2,18 +2,24 @@ package org.oxycblt.auxio.detail.adapters
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import androidx.annotation.ColorInt
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
|
import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.recycler.DiffCallback
|
import org.oxycblt.auxio.recycler.DiffCallback
|
||||||
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
|
||||||
|
import org.oxycblt.auxio.theme.accent
|
||||||
|
import org.oxycblt.auxio.theme.toColor
|
||||||
|
|
||||||
class DetailSongAdapter(
|
class DetailSongAdapter(
|
||||||
private val doOnClick: (Song) -> Unit
|
private val doOnClick: (Song) -> Unit
|
||||||
) : ListAdapter<Song, DetailSongAdapter.ViewHolder>(DiffCallback()) {
|
) : ListAdapter<Song, DetailSongAdapter.ViewHolder>(DiffCallback()) {
|
||||||
|
private var currentSong: Song? = null
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
return ViewHolder(
|
return ViewHolder(
|
||||||
ItemAlbumSongBinding.inflate(LayoutInflater.from(parent.context))
|
ItemAlbumSongBinding.inflate(LayoutInflater.from(parent.context)),
|
||||||
|
accent.first.toColor(parent.context)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,11 +29,17 @@ class DetailSongAdapter(
|
||||||
|
|
||||||
// Generic ViewHolder for a song
|
// Generic ViewHolder for a song
|
||||||
inner class ViewHolder(
|
inner class ViewHolder(
|
||||||
private val binding: ItemAlbumSongBinding
|
private val binding: ItemAlbumSongBinding,
|
||||||
|
@ColorInt private val resolvedAccent: Int
|
||||||
) : BaseViewHolder<Song>(binding, doOnClick) {
|
) : BaseViewHolder<Song>(binding, doOnClick) {
|
||||||
|
|
||||||
override fun onBind(model: Song) {
|
override fun onBind(model: Song) {
|
||||||
binding.song = model
|
binding.song = model
|
||||||
|
|
||||||
|
if (model == currentSong) {
|
||||||
|
binding.songName.setTextColor(resolvedAccent)
|
||||||
|
}
|
||||||
|
|
||||||
binding.songName.requestLayout()
|
binding.songName.requestLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,6 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
// TODO: Add exit functionality
|
|
||||||
binding.libraryToolbar.apply {
|
binding.libraryToolbar.apply {
|
||||||
overflowIcon = ContextCompat.getDrawable(
|
overflowIcon = ContextCompat.getDrawable(
|
||||||
requireContext(), R.drawable.ic_sort_none
|
requireContext(), R.drawable.ic_sort_none
|
||||||
|
@ -78,7 +77,7 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add icons to overflow menu items
|
// TODO: Add icons to overflow menu items?
|
||||||
menu.apply {
|
menu.apply {
|
||||||
val item = findItem(R.id.action_search)
|
val item = findItem(R.id.action_search)
|
||||||
val searchView = item.actionView as SearchView
|
val searchView = item.actionView as SearchView
|
||||||
|
@ -118,7 +117,7 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Change LibraryAdapter to a ListAdapter
|
// FIXME: Change LibraryAdapter to a ListAdapter
|
||||||
// [If there's a way to preserve scroll position properly]
|
// [If there's a way to preserve scroll position properly]
|
||||||
binding.libraryRecycler.apply {
|
binding.libraryRecycler.apply {
|
||||||
adapter = libraryAdapter
|
adapter = libraryAdapter
|
||||||
|
|
|
@ -4,10 +4,9 @@ import android.net.Uri
|
||||||
|
|
||||||
// --- MUSIC MODELS ---
|
// --- MUSIC MODELS ---
|
||||||
// TODO: Remove parent/child references so that they can be parcelable [Would require genre rework]
|
// TODO: Remove parent/child references so that they can be parcelable [Would require genre rework]
|
||||||
// TODO: Don't determine artist/album/song counts on the fly [If possible]
|
|
||||||
|
|
||||||
// The base model for all music
|
// The base model for all music
|
||||||
// This is used in a lot of general functions in order to cut down on code
|
// This is used in a lot of general functions in order to have generic utilities
|
||||||
sealed class BaseModel {
|
sealed class BaseModel {
|
||||||
abstract val id: Long
|
abstract val id: Long
|
||||||
abstract val name: String
|
abstract val name: String
|
||||||
|
@ -39,14 +38,13 @@ data class Album(
|
||||||
|
|
||||||
val songs = mutableListOf<Song>()
|
val songs = mutableListOf<Song>()
|
||||||
val numSongs: Int get() = songs.size
|
val numSongs: Int get() = songs.size
|
||||||
val totalDuration: String
|
val totalDuration: String by lazy {
|
||||||
get() {
|
var seconds: Long = 0
|
||||||
var seconds: Long = 0
|
songs.forEach {
|
||||||
songs.forEach {
|
seconds += it.seconds
|
||||||
seconds += it.seconds
|
|
||||||
}
|
|
||||||
return seconds.toDuration()
|
|
||||||
}
|
}
|
||||||
|
seconds.toDuration()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Artist
|
// Artist
|
||||||
|
@ -58,22 +56,20 @@ data class Artist(
|
||||||
val genres = mutableListOf<Genre>()
|
val genres = mutableListOf<Genre>()
|
||||||
|
|
||||||
val numAlbums: Int get() = albums.size
|
val numAlbums: Int get() = albums.size
|
||||||
val numSongs: Int
|
val numSongs: Int by lazy {
|
||||||
get() {
|
var num = 0
|
||||||
var num = 0
|
albums.forEach {
|
||||||
albums.forEach {
|
num += it.numSongs
|
||||||
num += it.numSongs
|
|
||||||
}
|
|
||||||
return num
|
|
||||||
}
|
}
|
||||||
val songs: MutableList<Song>
|
num
|
||||||
get() {
|
}
|
||||||
val songs = mutableListOf<Song>()
|
val songs: MutableList<Song> by lazy {
|
||||||
albums.forEach {
|
val songs = mutableListOf<Song>()
|
||||||
songs.addAll(it.songs)
|
albums.forEach {
|
||||||
}
|
songs.addAll(it.songs)
|
||||||
return songs
|
|
||||||
}
|
}
|
||||||
|
songs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Genre
|
// Genre
|
||||||
|
@ -84,22 +80,20 @@ data class Genre(
|
||||||
val artists = mutableListOf<Artist>()
|
val artists = mutableListOf<Artist>()
|
||||||
|
|
||||||
val numArtists: Int get() = artists.size
|
val numArtists: Int get() = artists.size
|
||||||
val numAlbums: Int
|
val numAlbums: Int by lazy {
|
||||||
get() {
|
var num = 0
|
||||||
var num = 0
|
artists.forEach {
|
||||||
artists.forEach {
|
num += it.numAlbums
|
||||||
num += it.numAlbums
|
|
||||||
}
|
|
||||||
return num
|
|
||||||
}
|
}
|
||||||
val numSongs: Int
|
num
|
||||||
get() {
|
}
|
||||||
var num = 0
|
val numSongs: Int by lazy {
|
||||||
artists.forEach {
|
var num = 0
|
||||||
num += it.numSongs
|
artists.forEach {
|
||||||
}
|
num += it.numSongs
|
||||||
return num
|
|
||||||
}
|
}
|
||||||
|
num
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Header [Used for search, nothing else]
|
// Header [Used for search, nothing else]
|
||||||
|
|
|
@ -24,7 +24,6 @@ private val ID3_GENRES = arrayOf(
|
||||||
"Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal",
|
"Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal",
|
||||||
"Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock",
|
"Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock",
|
||||||
|
|
||||||
// Winamp extensions
|
|
||||||
"Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival",
|
"Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival",
|
||||||
"Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock",
|
"Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock",
|
||||||
"Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour",
|
"Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour",
|
||||||
|
@ -154,8 +153,9 @@ fun TextView.bindAlbumInfo(album: Album) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bind the album year
|
||||||
@BindingAdapter("albumYear")
|
@BindingAdapter("albumYear")
|
||||||
fun TextView.bindAlbumDate(album: Album) {
|
fun TextView.bindAlbumYear(album: Album) {
|
||||||
text = album.year.toYear(context)
|
text = album.year.toYear(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,12 @@ import coil.size.Size
|
||||||
import okio.buffer
|
import okio.buffer
|
||||||
import okio.source
|
import okio.source
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import org.oxycblt.auxio.R
|
||||||
|
|
||||||
const val MOSAIC_BITMAP_SIZE = 512
|
const val MOSAIC_BITMAP_SIZE = 512
|
||||||
const val MOSAIC_BITMAP_INCREMENT = 256
|
const val MOSAIC_BITMAP_INCREMENT = 256
|
||||||
|
|
||||||
// A Fetcher that takes multiple cover uris and turns them into a 2x2 mosaic image.
|
// A Fetcher that takes multiple cover uris and turns them into a 2x2 mosaic image.
|
||||||
// TODO: Add 4x4 mosaics?
|
|
||||||
class MosaicFetcher(private val context: Context) : Fetcher<List<Uri>> {
|
class MosaicFetcher(private val context: Context) : Fetcher<List<Uri>> {
|
||||||
override suspend fun fetch(
|
override suspend fun fetch(
|
||||||
pool: BitmapPool,
|
pool: BitmapPool,
|
||||||
|
@ -46,13 +46,20 @@ class MosaicFetcher(private val context: Context) : Fetcher<List<Uri>> {
|
||||||
if (streams.size < 4) {
|
if (streams.size < 4) {
|
||||||
streams.forEach { it.close() }
|
streams.forEach { it.close() }
|
||||||
|
|
||||||
// FIXME: What if all the streams fail?
|
return if (streams.isNotEmpty()) {
|
||||||
|
SourceResult(
|
||||||
return SourceResult(
|
source = streams[0].source().buffer(),
|
||||||
source = streams[0].source().buffer(),
|
mimeType = context.contentResolver.getType(data[0]),
|
||||||
mimeType = context.contentResolver.getType(data[0]),
|
dataSource = DataSource.DISK
|
||||||
dataSource = DataSource.DISK
|
)
|
||||||
)
|
} else {
|
||||||
|
// If ALL the streams failed, then don't even bother with that.
|
||||||
|
DrawableResult(
|
||||||
|
drawable = R.drawable.ic_song.toDrawable(),
|
||||||
|
isSampled = false,
|
||||||
|
dataSource = DataSource.DISK
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the mosaic, code adapted from Phonograph.
|
// Create the mosaic, code adapted from Phonograph.
|
||||||
|
|
|
@ -35,7 +35,7 @@ class CompactPlaybackFragment : Fragment() {
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
binding.lifecycleOwner = this
|
binding.lifecycleOwner = viewLifecycleOwner
|
||||||
|
|
||||||
// Put a placeholder song in the binding & hide the playback fragment initially,
|
// Put a placeholder song in the binding & hide the playback fragment initially,
|
||||||
// as for some reason the attach event doesn't register anymore w/LiveData
|
// as for some reason the attach event doesn't register anymore w/LiveData
|
||||||
|
@ -59,6 +59,7 @@ class CompactPlaybackFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Fix the thing where the icons will animate on startup
|
||||||
playbackModel.isPlaying.observe(viewLifecycleOwner) {
|
playbackModel.isPlaying.observe(viewLifecycleOwner) {
|
||||||
if (it) {
|
if (it) {
|
||||||
// Animate the icon transition when the playing status switches
|
// Animate the icon transition when the playing status switches
|
||||||
|
@ -78,4 +79,10 @@ class CompactPlaybackFragment : Fragment() {
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
|
||||||
|
playbackModel.updateStaticIconStatus(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,10 @@ import org.oxycblt.auxio.theme.disable
|
||||||
import org.oxycblt.auxio.theme.enable
|
import org.oxycblt.auxio.theme.enable
|
||||||
import org.oxycblt.auxio.theme.toColor
|
import org.oxycblt.auxio.theme.toColor
|
||||||
|
|
||||||
|
// TODO: Possibly add some swipe-to-next-track function, could require a ViewPager.
|
||||||
class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
|
|
||||||
// TODO: Implement media controls
|
|
||||||
// TODO: Implement nav to artists/albums
|
// TODO: Implement nav to artists/albums
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.oxycblt.auxio.playback
|
||||||
|
|
||||||
// Enum for instruction how the queue should function.
|
// Enum for instruction how the queue should function.
|
||||||
// ALL SONGS -> Play from all songs
|
// ALL SONGS -> Play from all songs
|
||||||
// IN_GENRE -> Play from the genre
|
|
||||||
// IN_ARTIST -> Play from the songs of the artist
|
// IN_ARTIST -> Play from the songs of the artist
|
||||||
// IN_ALBUM -> Play from the songs of the album
|
// IN_ALBUM -> Play from the songs of the album
|
||||||
enum class PlaybackMode {
|
enum class PlaybackMode {
|
||||||
|
|
|
@ -14,10 +14,10 @@ import org.oxycblt.auxio.music.toDuration
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
import kotlin.random.Random.Default.nextLong
|
import kotlin.random.Random.Default.nextLong
|
||||||
|
|
||||||
// TODO: Implement media controls
|
// TODO: Queue
|
||||||
// TODO: Implement persistence
|
|
||||||
// TODO: Add the playback service itself
|
// TODO: Add the playback service itself
|
||||||
// TODO: Possibly add some swipe-to-next-track function, could require a ViewPager.
|
// TODO: Add loop control [From playback]
|
||||||
|
// TODO: Implement persistence through Bundles and sanity checks [I want to keep my shuffles, okay?]
|
||||||
// A ViewModel that acts as an intermediary between PlaybackService and the Playback Fragments.
|
// A ViewModel that acts as an intermediary between PlaybackService and the Playback Fragments.
|
||||||
class PlaybackViewModel : ViewModel() {
|
class PlaybackViewModel : ViewModel() {
|
||||||
private val mCurrentSong = MutableLiveData<Song>()
|
private val mCurrentSong = MutableLiveData<Song>()
|
||||||
|
|
|
@ -27,7 +27,7 @@ class SongsFragment : Fragment() {
|
||||||
val musicStore = MusicStore.getInstance()
|
val musicStore = MusicStore.getInstance()
|
||||||
|
|
||||||
// TODO: Add option to search songs if LibraryFragment isn't enabled
|
// TODO: Add option to search songs if LibraryFragment isn't enabled
|
||||||
// TODO: Maybe add fast scrolling or sorting
|
// TODO: Fast scrolling?
|
||||||
|
|
||||||
// --- UI SETUP ---
|
// --- UI SETUP ---
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="32dp"
|
android:width="24dp"
|
||||||
android:height="32dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24"
|
android:viewportHeight="24"
|
||||||
android:tint="@color/control_color">
|
android:tint="@color/control_color">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="32dp"
|
||||||
android:height="24dp"
|
android:height="32dp"
|
||||||
android:viewportWidth="24"
|
android:viewportWidth="24"
|
||||||
android:viewportHeight="24"
|
android:viewportHeight="24"
|
||||||
android:tint="@color/control_color">
|
android:tint="@color/control_color">
|
|
@ -131,7 +131,7 @@
|
||||||
android:backgroundTint="?android:attr/colorPrimary"
|
android:backgroundTint="?android:attr/colorPrimary"
|
||||||
android:contentDescription="@string/description_play"
|
android:contentDescription="@string/description_play"
|
||||||
android:onClick="@{() -> playbackModel.play(album, true)}"
|
android:onClick="@{() -> playbackModel.play(album, true)}"
|
||||||
android:src="@drawable/ic_shuffle_small"
|
android:src="@drawable/ic_shuffle"
|
||||||
android:tint="@color/background"
|
android:tint="@color/background"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/album_details"
|
app:layout_constraintBottom_toBottomOf="@+id/album_details"
|
||||||
app:layout_constraintDimensionRatio="1:1"
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
|
|
@ -98,6 +98,7 @@
|
||||||
app:layout_constraintTop_toBottomOf="@+id/artist_genre"
|
app:layout_constraintTop_toBottomOf="@+id/artist_genre"
|
||||||
tools:text="2 Albums, 20 Songs" />
|
tools:text="2 Albums, 20 Songs" />
|
||||||
|
|
||||||
|
<!-- TODO: Improve these two buttons so that they don't look as cluttered -->
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/artist_play"
|
android:id="@+id/artist_play"
|
||||||
style="@style/Widget.AppCompat.Button.Borderless"
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
|
@ -112,11 +113,11 @@
|
||||||
android:onClick="@{() -> playbackModel.play(artist, false)}"
|
android:onClick="@{() -> playbackModel.play(artist, false)}"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/artist_counts"
|
app:layout_constraintBottom_toBottomOf="@+id/artist_counts"
|
||||||
app:layout_constraintDimensionRatio="1:1"
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/album_shuffle"
|
app:layout_constraintEnd_toStartOf="@+id/artist_shuffle"
|
||||||
app:layout_constraintTop_toTopOf="@+id/artist_genre" />
|
app:layout_constraintTop_toTopOf="@+id/artist_genre" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/album_shuffle"
|
android:id="@+id/artist_shuffle"
|
||||||
style="@style/Widget.AppCompat.Button.Borderless"
|
style="@style/Widget.AppCompat.Button.Borderless"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
@ -126,7 +127,7 @@
|
||||||
android:backgroundTint="?android:attr/colorPrimary"
|
android:backgroundTint="?android:attr/colorPrimary"
|
||||||
android:contentDescription="@string/description_play"
|
android:contentDescription="@string/description_play"
|
||||||
android:onClick="@{() -> playbackModel.play(artist, true)}"
|
android:onClick="@{() -> playbackModel.play(artist, true)}"
|
||||||
android:src="@drawable/ic_shuffle_small"
|
android:src="@drawable/ic_shuffle"
|
||||||
android:tint="@color/background"
|
android:tint="@color/background"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/artist_counts"
|
app:layout_constraintBottom_toBottomOf="@+id/artist_counts"
|
||||||
app:layout_constraintDimensionRatio="1:1"
|
app:layout_constraintDimensionRatio="1:1"
|
||||||
|
|
|
@ -191,7 +191,7 @@
|
||||||
android:layout_width="@dimen/size_play_pause_compact"
|
android:layout_width="@dimen/size_play_pause_compact"
|
||||||
android:layout_height="@dimen/size_play_pause_compact"
|
android:layout_height="@dimen/size_play_pause_compact"
|
||||||
android:layout_marginEnd="@dimen/margin_mid_large"
|
android:layout_marginEnd="@dimen/margin_mid_large"
|
||||||
android:src="@drawable/ic_shuffle"
|
android:src="@drawable/ic_shuffle_large"
|
||||||
android:background="@drawable/ui_unbounded_ripple"
|
android:background="@drawable/ui_unbounded_ripple"
|
||||||
android:onClick="@{() -> playbackModel.invertShuffleStatus()}"
|
android:onClick="@{() -> playbackModel.invertShuffleStatus()}"
|
||||||
android:contentDescription="@{playbackModel.isShuffling() ? @string/description_shuffle_off : @string/description_shuffle_on"
|
android:contentDescription="@{playbackModel.isShuffling() ? @string/description_shuffle_off : @string/description_shuffle_on"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_shuffle"
|
android:id="@+id/action_shuffle"
|
||||||
android:icon="@drawable/ic_shuffle_small"
|
android:icon="@drawable/ic_shuffle"
|
||||||
android:title="@string/label_shuffle"
|
android:title="@string/label_shuffle"
|
||||||
app:showAsAction="always" />
|
app:showAsAction="always" />
|
||||||
</menu>
|
</menu>
|
Loading…
Reference in a new issue