Improve semantics

Remove some useless TODOs, update naming in places.
This commit is contained in:
OxygenCobalt 2020-10-18 09:06:16 -06:00
parent 00667151dc
commit 2811c83543
20 changed files with 89 additions and 76 deletions

View file

@ -89,7 +89,6 @@ class MainFragment : Fragment() {
// --- VIEWMODEL SETUP ---
// TODO: Add a slide animation to this
// Change CompactPlaybackFragment's visibility here so that an animation occurs.
playbackModel.currentSong.observe(viewLifecycleOwner) {
if (it == null) {

View file

@ -86,7 +86,6 @@ class AlbumDetailFragment : Fragment() {
// Observe playback model to update the play button
// TODO: Make these icons animated
// TODO: Shuffle button/option, unsure of which one
playbackModel.currentMode.observe(viewLifecycleOwner) {
updatePlayButton(it, binding)
}

View file

@ -18,9 +18,6 @@ import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.theme.applyDivider
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() {
private val args: ArtistDetailFragmentArgs by navArgs()

View file

@ -8,7 +8,6 @@ import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
// TODO: Add ability to highlight currently playing songs
class DetailAlbumAdapter(
private val doOnClick: (Album) -> Unit
) : ListAdapter<Album, DetailAlbumAdapter.ViewHolder>(DiffCallback()) {
@ -25,7 +24,7 @@ class DetailAlbumAdapter(
// Generic ViewHolder for a detail album
inner class ViewHolder(
private val binding: ItemArtistAlbumBinding
private val binding: ItemArtistAlbumBinding,
) : BaseViewHolder<Album>(binding, doOnClick) {
override fun onBind(model: Album) {

View file

@ -2,18 +2,24 @@ package org.oxycblt.auxio.detail.adapters
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.annotation.ColorInt
import androidx.recyclerview.widget.ListAdapter
import org.oxycblt.auxio.databinding.ItemAlbumSongBinding
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.recycler.DiffCallback
import org.oxycblt.auxio.recycler.viewholders.BaseViewHolder
import org.oxycblt.auxio.theme.accent
import org.oxycblt.auxio.theme.toColor
class DetailSongAdapter(
private val doOnClick: (Song) -> Unit
) : ListAdapter<Song, DetailSongAdapter.ViewHolder>(DiffCallback()) {
private var currentSong: Song? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): 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
inner class ViewHolder(
private val binding: ItemAlbumSongBinding
private val binding: ItemAlbumSongBinding,
@ColorInt private val resolvedAccent: Int
) : BaseViewHolder<Song>(binding, doOnClick) {
override fun onBind(model: Song) {
binding.song = model
if (model == currentSong) {
binding.songName.setTextColor(resolvedAccent)
}
binding.songName.requestLayout()
}
}

View file

@ -56,7 +56,6 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
// --- UI SETUP ---
// TODO: Add exit functionality
binding.libraryToolbar.apply {
overflowIcon = ContextCompat.getDrawable(
requireContext(), R.drawable.ic_sort_none
@ -78,7 +77,7 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
true
}
// TODO: Add icons to overflow menu items
// TODO: Add icons to overflow menu items?
menu.apply {
val item = findItem(R.id.action_search)
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]
binding.libraryRecycler.apply {
adapter = libraryAdapter

View file

@ -4,10 +4,9 @@ import android.net.Uri
// --- MUSIC MODELS ---
// 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
// 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 {
abstract val id: Long
abstract val name: String
@ -39,13 +38,12 @@ data class Album(
val songs = mutableListOf<Song>()
val numSongs: Int get() = songs.size
val totalDuration: String
get() {
val totalDuration: String by lazy {
var seconds: Long = 0
songs.forEach {
seconds += it.seconds
}
return seconds.toDuration()
seconds.toDuration()
}
}
@ -58,21 +56,19 @@ data class Artist(
val genres = mutableListOf<Genre>()
val numAlbums: Int get() = albums.size
val numSongs: Int
get() {
val numSongs: Int by lazy {
var num = 0
albums.forEach {
num += it.numSongs
}
return num
num
}
val songs: MutableList<Song>
get() {
val songs: MutableList<Song> by lazy {
val songs = mutableListOf<Song>()
albums.forEach {
songs.addAll(it.songs)
}
return songs
songs
}
}
@ -84,21 +80,19 @@ data class Genre(
val artists = mutableListOf<Artist>()
val numArtists: Int get() = artists.size
val numAlbums: Int
get() {
val numAlbums: Int by lazy {
var num = 0
artists.forEach {
num += it.numAlbums
}
return num
num
}
val numSongs: Int
get() {
val numSongs: Int by lazy {
var num = 0
artists.forEach {
num += it.numSongs
}
return num
num
}
}

View file

@ -24,7 +24,6 @@ private val ID3_GENRES = arrayOf(
"Cabaret", "New Wave", "Psychadelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal",
"Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock",
// Winamp extensions
"Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival",
"Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock",
"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")
fun TextView.bindAlbumDate(album: Album) {
fun TextView.bindAlbumYear(album: Album) {
text = album.year.toYear(context)
}

View file

@ -17,12 +17,12 @@ import coil.size.Size
import okio.buffer
import okio.source
import java.io.InputStream
import org.oxycblt.auxio.R
const val MOSAIC_BITMAP_SIZE = 512
const val MOSAIC_BITMAP_INCREMENT = 256
// 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>> {
override suspend fun fetch(
pool: BitmapPool,
@ -46,13 +46,20 @@ class MosaicFetcher(private val context: Context) : Fetcher<List<Uri>> {
if (streams.size < 4) {
streams.forEach { it.close() }
// FIXME: What if all the streams fail?
return SourceResult(
return if (streams.isNotEmpty()) {
SourceResult(
source = streams[0].source().buffer(),
mimeType = context.contentResolver.getType(data[0]),
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.

View file

@ -35,7 +35,7 @@ class CompactPlaybackFragment : Fragment() {
// --- UI SETUP ---
binding.lifecycleOwner = this
binding.lifecycleOwner = viewLifecycleOwner
// 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
@ -59,6 +59,7 @@ class CompactPlaybackFragment : Fragment() {
}
}
// TODO: Fix the thing where the icons will animate on startup
playbackModel.isPlaying.observe(viewLifecycleOwner) {
if (it) {
// Animate the icon transition when the playing status switches
@ -78,4 +79,10 @@ class CompactPlaybackFragment : Fragment() {
return binding.root
}
override fun onDestroy() {
super.onDestroy()
playbackModel.updateStaticIconStatus(true)
}
}

View file

@ -19,10 +19,10 @@ import org.oxycblt.auxio.theme.disable
import org.oxycblt.auxio.theme.enable
import org.oxycblt.auxio.theme.toColor
// TODO: Possibly add some swipe-to-next-track function, could require a ViewPager.
class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
private val playbackModel: PlaybackViewModel by activityViewModels()
// TODO: Implement media controls
// TODO: Implement nav to artists/albums
override fun onCreateView(
inflater: LayoutInflater,

View file

@ -2,7 +2,6 @@ package org.oxycblt.auxio.playback
// Enum for instruction how the queue should function.
// ALL SONGS -> Play from all songs
// IN_GENRE -> Play from the genre
// IN_ARTIST -> Play from the songs of the artist
// IN_ALBUM -> Play from the songs of the album
enum class PlaybackMode {

View file

@ -14,10 +14,10 @@ import org.oxycblt.auxio.music.toDuration
import kotlin.random.Random
import kotlin.random.Random.Default.nextLong
// TODO: Implement media controls
// TODO: Implement persistence
// TODO: Queue
// 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.
class PlaybackViewModel : ViewModel() {
private val mCurrentSong = MutableLiveData<Song>()

View file

@ -27,7 +27,7 @@ class SongsFragment : Fragment() {
val musicStore = MusicStore.getInstance()
// TODO: Add option to search songs if LibraryFragment isn't enabled
// TODO: Maybe add fast scrolling or sorting
// TODO: Fast scrolling?
// --- UI SETUP ---

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="32dp"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="@color/control_color">

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:width="32dp"
android:height="32dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="@color/control_color">

View file

@ -131,7 +131,7 @@
android:backgroundTint="?android:attr/colorPrimary"
android:contentDescription="@string/description_play"
android:onClick="@{() -> playbackModel.play(album, true)}"
android:src="@drawable/ic_shuffle_small"
android:src="@drawable/ic_shuffle"
android:tint="@color/background"
app:layout_constraintBottom_toBottomOf="@+id/album_details"
app:layout_constraintDimensionRatio="1:1"

View file

@ -98,6 +98,7 @@
app:layout_constraintTop_toBottomOf="@+id/artist_genre"
tools:text="2 Albums, 20 Songs" />
<!-- TODO: Improve these two buttons so that they don't look as cluttered -->
<ImageButton
android:id="@+id/artist_play"
style="@style/Widget.AppCompat.Button.Borderless"
@ -112,11 +113,11 @@
android:onClick="@{() -> playbackModel.play(artist, false)}"
app:layout_constraintBottom_toBottomOf="@+id/artist_counts"
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" />
<ImageButton
android:id="@+id/album_shuffle"
android:id="@+id/artist_shuffle"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
android:layout_height="0dp"
@ -126,7 +127,7 @@
android:backgroundTint="?android:attr/colorPrimary"
android:contentDescription="@string/description_play"
android:onClick="@{() -> playbackModel.play(artist, true)}"
android:src="@drawable/ic_shuffle_small"
android:src="@drawable/ic_shuffle"
android:tint="@color/background"
app:layout_constraintBottom_toBottomOf="@+id/artist_counts"
app:layout_constraintDimensionRatio="1:1"

View file

@ -191,7 +191,7 @@
android:layout_width="@dimen/size_play_pause_compact"
android:layout_height="@dimen/size_play_pause_compact"
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:onClick="@{() -> playbackModel.invertShuffleStatus()}"
android:contentDescription="@{playbackModel.isShuffling() ? @string/description_shuffle_off : @string/description_shuffle_on"

View file

@ -3,7 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_shuffle"
android:icon="@drawable/ic_shuffle_small"
android:icon="@drawable/ic_shuffle"
android:title="@string/label_shuffle"
app:showAsAction="always" />
</menu>