Android Navigation code refactor

This commit is contained in:
Hemanth S 2020-08-13 13:54:36 +05:30
parent 9552e617b5
commit 23f4fee872
81 changed files with 1235 additions and 919 deletions

View file

@ -12,7 +12,7 @@
"filters": [],
"properties": [],
"versionCode": 10438,
"versionName": "3.5.650_0810",
"versionName": "3.5.650_0812",
"enabled": true,
"outputFile": "app-release.apk"
}

View file

@ -106,6 +106,7 @@
</intent-filter>
</activity>
<activity android:name=".activities.PlayingQueueActivity" />
<activity android:name=".activities.SettingsActivity" />
<activity android:name=".activities.tageditor.AlbumTagEditorActivity" />
<activity android:name=".activities.tageditor.SongTagEditorActivity" />
<activity android:name=".activities.LyricsActivity" />
@ -257,5 +258,8 @@
<meta-data
android:name="com.android.vending.splits.required"
android:value="true" />
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
</manifest>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,25 @@
package code.name.monkey.retromusic
import androidx.annotation.IntDef
@IntDef(
RECENT_ALBUMS,
TOP_ALBUMS,
RECENT_ARTISTS,
TOP_ARTISTS,
SUGGESTIONS,
FAVOURITES,
GENRES,
PLAYLISTS
)
@Retention(AnnotationRetention.SOURCE)
annotation class HomeSection
const val RECENT_ALBUMS = 3
const val TOP_ALBUMS = 1
const val RECENT_ARTISTS = 2
const val TOP_ARTISTS = 0
const val SUGGESTIONS = 5
const val FAVOURITES = 4
const val GENRES = 6
const val PLAYLISTS = 7

View file

@ -0,0 +1,25 @@
/*
* Copyright (C) 2020 Fatih Giris. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package code.name.monkey.retromusic
/**
* Generic class that holds the network state
*/
sealed class Result<out R> {
data class Success<out T>(val data: T) : Result<T>()
object Loading : Result<Nothing>()
object Error : Result<Nothing>()
}

View file

@ -2,16 +2,13 @@ package code.name.monkey.retromusic.activities
import android.content.Intent
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.view.View
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import code.name.monkey.retromusic.extensions.findNavController
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.helper.MusicPlayerRemote.openAndShuffleQueue
@ -19,7 +16,6 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote.openQueue
import code.name.monkey.retromusic.helper.MusicPlayerRemote.playFromUri
import code.name.monkey.retromusic.helper.MusicPlayerRemote.shuffleMode
import code.name.monkey.retromusic.helper.SearchQueryHelper.getSongs
import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.loaders.AlbumLoader.getAlbum
import code.name.monkey.retromusic.loaders.ArtistLoader.getArtist
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader.getPlaylistSongList
@ -27,15 +23,10 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.AppRater.appLaunched
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import com.afollestad.materialcab.MaterialCab
import com.afollestad.materialdialogs.color.ColorChooserDialog
import org.koin.android.ext.android.inject
import java.util.*
class MainActivity : AbsSlidingMusicPanelActivity(),
SharedPreferences.OnSharedPreferenceChangeListener, CabHolder,
ColorChooserDialog.ColorCallback {
class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener {
companion object {
const val TAG = "MainActivity"
const val EXPAND_PANEL = "expand_panel"
@ -44,7 +35,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
private val libraryViewModel: LibraryViewModel by inject()
private var cab: MaterialCab? = null
private var blockRequestPermissions = false
override fun createContentView(): View {
@ -59,7 +50,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
setLightNavigationBar(true)
setTaskDescriptionColorAuto()
hideStatusBar()
setBottomBarVisibility(View.VISIBLE)
appLaunched(this)
addMusicServiceEventListener(libraryViewModel)
updateTabs()
@ -177,46 +167,4 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
}
return id
}
override fun handleBackPress(): Boolean {
if (cab != null && cab!!.isActive) {
cab?.finish()
return true
}
return super.handleBackPress()
}
override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
cab?.let {
if (it.isActive) it.finish()
}
cab = MaterialCab(this, R.id.cab_stub)
.setMenu(menuRes)
.setCloseDrawableRes(R.drawable.ic_close)
.setBackgroundColor(
RetroColorUtil.shiftBackgroundColorForLightText(
ATHUtil.resolveColor(
this,
R.attr.colorSurface
)
)
)
.start(callback)
return cab as MaterialCab
}
override fun onColorSelection(dialog: ColorChooserDialog, selectedColor: Int) {
when (dialog.title) {
R.string.accent_color -> {
ThemeStore.editTheme(this).accentColor(selectedColor).commit()
if (VersionUtils.hasNougatMR())
DynamicShortcutManager(this).updateDynamicShortcuts()
}
}
recreate()
}
override fun onColorChooserDismissed(dialog: ColorChooserDialog) {
}
}

View file

@ -14,6 +14,7 @@ import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.ThemedFastScroller
import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
@ -103,7 +104,7 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
}
}
})
//ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView)
val fastScroller = ThemedFastScroller.create(recyclerView)
}
private fun checkForPadding() {

View file

@ -0,0 +1,61 @@
package code.name.monkey.retromusic.activities
import android.os.Bundle
import android.view.MenuItem
import androidx.navigation.NavController
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import code.name.monkey.retromusic.extensions.applyToolbar
import code.name.monkey.retromusic.extensions.findNavController
import com.afollestad.materialdialogs.color.ColorChooserDialog
import kotlinx.android.synthetic.main.activity_settings.*
class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback {
override fun onCreate(savedInstanceState: Bundle?) {
setDrawUnderStatusBar()
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_settings)
setStatusbarColorAuto()
setNavigationbarColorAuto()
setLightNavigationBar(true)
setupToolbar()
}
private fun setupToolbar() {
setTitle(R.string.action_settings)
applyToolbar(toolbar)
val navController: NavController = findNavController(R.id.contentFrame)
navController.addOnDestinationChangedListener { _, _, _ ->
toolbar.title = navController.currentDestination?.label
}
}
override fun onSupportNavigateUp(): Boolean {
return findNavController(R.id.contentFrame).navigateUp() || super.onSupportNavigateUp()
}
override fun onColorSelection(dialog: ColorChooserDialog, selectedColor: Int) {
when (dialog.title) {
R.string.accent_color -> {
ThemeStore.editTheme(this).accentColor(selectedColor).commit()
if (VersionUtils.hasNougatMR())
DynamicShortcutManager(this).updateDynamicShortcuts()
}
}
recreate()
}
override fun onColorChooserDismissed(dialog: ColorChooserDialog) {
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
}
return super.onOptionsItemSelected(item)
}
}

View file

@ -10,7 +10,6 @@ import android.text.TextUtils
import android.view.MenuItem
import android.widget.Toast
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants.USER_BANNER
import code.name.monkey.retromusic.Constants.USER_PROFILE
@ -49,7 +48,7 @@ class UserInfoActivity : AbsBaseActivity() {
setLightNavigationBar(true)
applyToolbar(toolbar)
MaterialUtil.setTint(nameContainer, false)
nameContainer.accentColor()
name.setText(PreferenceUtil.userName)
userImage.setOnClickListener {

View file

@ -7,12 +7,17 @@ import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.widget.FrameLayout
import androidx.annotation.LayoutRes
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.lifecycle.Observer
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RetroBottomSheetBehavior
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.dimToPixel
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.MiniPlayerFragment
import code.name.monkey.retromusic.fragments.NowPlayingScreen
@ -132,9 +137,7 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
if (miniPlayerFragment?.view == null) return
val alpha = 1 - progress
miniPlayerFragment?.view?.alpha = alpha
// necessary to make the views below clickable
miniPlayerFragment?.view?.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
bottomNavigationView.translationY = progress * 500
bottomNavigationView.alpha = alpha
}
@ -171,32 +174,25 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
return bottomNavigationView
}
fun setBottomBarVisibility(visible: Int) {
bottomNavigationView.visibility = visible
fun hideBottomBarVisibility(visible: Boolean) {
bottomNavigationView.isVisible = visible
hideBottomBar(MusicPlayerRemote.playingQueue.isEmpty())
}
private fun hideBottomBar(hide: Boolean) {
val heightOfBar = dimToPixel(R.dimen.mini_player_height)
val heightOfBarWithTabs = dimToPixel(R.dimen.mini_player_height_expanded)
val isBottomBarVisible = bottomNavigationView.isVisible
if (hide) {
behavior.isHideable = true
behavior.peekHeight = 0
bottomNavigationView.elevation = dipToPix(10f)
collapsePanel()
ViewCompat.setElevation(bottomNavigationView, 10f)
} else {
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
slidingPanel.elevation = dipToPix(10f)
bottomNavigationView.elevation = dipToPix(10f)
ViewCompat.setElevation(bottomNavigationView, 10f)
ViewCompat.setElevation(slidingPanel, 10f)
behavior.isHideable = false
behavior.peekHeight =
if (bottomNavigationView.visibility == View.VISIBLE) {
heightOfBarWithTabs
} else {
heightOfBar
}
}
behavior.peekHeight = if (isBottomBarVisible) heightOfBar * 2 else heightOfBar
}
}
@ -304,7 +300,7 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
fun hideBottomNavigation() {
behavior.isHideable = true
behavior.peekHeight = 0
setBottomBarVisibility(View.GONE)
hideBottomBarVisibility(false)
}
fun updateTabs() {

View file

@ -3,8 +3,8 @@ package code.name.monkey.retromusic.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.annotation.IntDef
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.os.bundleOf
@ -13,22 +13,17 @@ import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.HORIZONTAL
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
import code.name.monkey.retromusic.PeekingLinearLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.adapter.album.AlbumAdapter
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
import code.name.monkey.retromusic.adapter.song.SongAdapter
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.fragments.albums.AlbumClickListener
import code.name.monkey.retromusic.fragments.artists.ArtistClickListener
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
@ -36,7 +31,7 @@ import com.google.android.material.card.MaterialCardView
class HomeAdapter(
private val activity: AppCompatActivity
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
) : RecyclerView.Adapter<RecyclerView.ViewHolder>(), ArtistClickListener, AlbumClickListener {
private var list = listOf<Home>()
@ -49,14 +44,9 @@ class HomeAdapter(
.inflate(R.layout.section_recycler_view, parent, false)
return when (viewType) {
RECENT_ARTISTS, TOP_ARTISTS -> ArtistViewHolder(layout)
TOP_ALBUMS, RECENT_ALBUMS -> {
AlbumViewHolder(
LayoutInflater.from(activity)
.inflate(R.layout.metal_section_recycler_view, parent, false)
)
}
GENRES -> GenreViewHolder(layout)
FAVOURITES -> PlaylistViewHolder(layout)
TOP_ALBUMS, RECENT_ALBUMS -> AlbumViewHolder(layout)
else -> {
SuggestionsViewHolder(
LayoutInflater.from(activity).inflate(
@ -70,55 +60,62 @@ class HomeAdapter(
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val home = list[position]
when (getItemViewType(position)) {
RECENT_ALBUMS -> {
val viewHolder = holder as AlbumViewHolder
viewHolder.bindView(
list[position].arrayList as List<Album>,
R.string.recent_albums,
"Most recently added albums"
viewHolder.bindView(home.arrayList as List<Album>, R.string.recent_albums)
viewHolder.clickableArea.setOnClickListener {
activity.findNavController(R.id.fragment_container).navigate(
R.id.detailListFragment,
bundleOf("type" to RECENT_ALBUMS)
)
}
}
TOP_ALBUMS -> {
val viewHolder = holder as AlbumViewHolder
viewHolder.bindView(
list[position].arrayList as List<Album>,
R.string.top_albums,
"Most played albums"
viewHolder.bindView(home.arrayList as List<Album>, R.string.top_albums)
viewHolder.clickableArea.setOnClickListener {
activity.findNavController(R.id.fragment_container).navigate(
R.id.detailListFragment,
bundleOf("type" to TOP_ALBUMS)
)
}
}
RECENT_ARTISTS -> {
val viewHolder = holder as ArtistViewHolder
viewHolder.bindView(
list[position].arrayList as List<Artist>,
R.string.recent_artists,
"Most recently added artists"
viewHolder.bindView(home.arrayList, R.string.recent_artists)
viewHolder.clickableArea.setOnClickListener {
activity.findNavController(R.id.fragment_container).navigate(
R.id.detailListFragment,
bundleOf("type" to RECENT_ARTISTS)
)
}
}
TOP_ARTISTS -> {
val viewHolder = holder as ArtistViewHolder
viewHolder.bindView(
list[position].arrayList as List<Artist>,
R.string.top_artists,
"Most played artists"
viewHolder.bindView(home.arrayList, R.string.top_artists)
viewHolder.clickableArea.setOnClickListener {
activity.findNavController(R.id.fragment_container).navigate(
R.id.detailListFragment,
bundleOf("type" to TOP_ARTISTS)
)
}
}
SUGGESTIONS -> {
val viewHolder = holder as SuggestionsViewHolder
viewHolder.bindView(
list[position].arrayList as List<Song>
)
viewHolder.bindView(home.arrayList)
}
FAVOURITES -> {
val viewHolder = holder as PlaylistViewHolder
viewHolder.bindView(
list[position].arrayList as List<Playlist>,
R.string.favorites
)
viewHolder.bindView(home.arrayList, R.string.favorites)
}
GENRES -> {
val viewHolder = holder as GenreViewHolder
viewHolder.bind(list[position].arrayList as List<Genre>, R.string.genres)
viewHolder.bind(home.arrayList, R.string.genres)
}
PLAYLISTS -> {
}
}
}
@ -132,82 +129,26 @@ class HomeAdapter(
notifyDataSetChanged()
}
companion object {
@IntDef(
RECENT_ALBUMS,
TOP_ALBUMS,
RECENT_ARTISTS,
TOP_ARTISTS,
SUGGESTIONS,
FAVOURITES,
GENRES
)
@Retention(AnnotationRetention.SOURCE)
annotation class HomeSection
const val RECENT_ALBUMS = 3
const val TOP_ALBUMS = 1
const val RECENT_ARTISTS = 2
const val TOP_ARTISTS = 0
const val SUGGESTIONS = 5
const val FAVOURITES = 4
const val GENRES = 6
private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) {
fun bindView(albums: List<Album>, titleRes: Int) {
title.text = activity.getString(titleRes)
recyclerView.apply {
adapter = albumAdapter(albums)
layoutManager = gridLayoutManager()
}
}
}
private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view), AlbumClickListener {
fun bindView(list: List<Album>, titleRes: Int, message: String) {
if (list.isNotEmpty()) {
val albumAdapter = AlbumAdapter(activity, list, R.layout.pager_item, null, this)
private inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
fun bindView(artists: List<Any>, titleRes: Int) {
recyclerView.apply {
show()
adapter = albumAdapter
layoutManager = PeekingLinearLayoutManager(activity, HORIZONTAL, false)
layoutManager = linearLayoutManager()
adapter = artistsAdapter(artists as List<Artist>)
}
title.text = activity.getString(titleRes)
}
}
override fun onAlbumClick(albumId: Int, view: View) {
activity.findNavController(R.id.fragment_container).navigate(
R.id.albumDetailsFragment,
bundleOf(EXTRA_ALBUM_ID to albumId),
null,
FragmentNavigatorExtras(
view to activity.getString(R.string.transition_album_art)
)
)
}
}
private inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view), ArtistClickListener {
fun bindView(list: List<Artist>, titleRes: Int, message: String) {
if (list.isNotEmpty()) {
val manager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
val artistAdapter = ArtistAdapter(
activity,
list,
PreferenceUtil.homeGridStyle,
null,
this
)
recyclerView.apply {
show()
layoutManager = manager
adapter = artistAdapter
}
title.text = activity.getString(titleRes)
}
}
override fun onArtist(artistId: Int) {
activity.findNavController(R.id.fragment_container).navigate(
R.id.artistDetailsFragment,
bundleOf(EXTRA_ARTIST_ID to artistId)
)
}
}
private inner class SuggestionsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val images = listOf(
R.id.image1,
@ -220,18 +161,19 @@ class HomeAdapter(
R.id.image8
)
fun bindView(arrayList: List<Song>) {
fun bindView(songs: List<Any>) {
songs as List<Song>
val color = ThemeStore.accentColor(activity)
itemView.findViewById<TextView>(R.id.message).setTextColor(color)
itemView.findViewById<MaterialCardView>(R.id.card6).apply {
setCardBackgroundColor(ColorUtil.withAlpha(color, 0.2f))
}
if (arrayList.size > 9)
if (songs.size > 9)
images.forEachIndexed { index, i ->
itemView.findViewById<View>(i).setOnClickListener {
MusicPlayerRemote.playNext(arrayList[index])
MusicPlayerRemote.playNext(songs[index])
}
SongGlideRequest.Builder.from(Glide.with(activity), arrayList[index])
SongGlideRequest.Builder.from(Glide.with(activity), songs[index])
.asBitmap()
.build()
.into(itemView.findViewById(i))
@ -241,33 +183,29 @@ class HomeAdapter(
}
private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) {
fun bindView(arrayList: List<Playlist>, titleRes: Int) {
text.text = "You're all time favorites"
if (arrayList.isNotEmpty()) {
val songs = PlaylistSongsLoader.getPlaylistSongList(activity, arrayList[0])
if (songs.isNotEmpty()) {
fun bindView(songs: List<Any>, titleRes: Int) {
arrow.hide()
recyclerView.apply {
show()
val songAdapter =
SongAdapter(activity, songs, R.layout.item_album_card, null)
layoutManager =
GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
val songAdapter = SongAdapter(
activity,
songs as MutableList<Song>,
R.layout.item_album_card, null
)
layoutManager = linearLayoutManager()
adapter = songAdapter
}
title.text = activity.getString(titleRes)
}
}
}
}
private inner class GenreViewHolder(itemView: View) : AbsHomeViewItem(itemView) {
fun bind(genres: List<Genre>, titleRes: Int) {
fun bind(genres: List<Any>, titleRes: Int) {
arrow.hide()
title.text = activity.getString(titleRes)
text.text = "Genres for you"
recyclerView.apply {
show()
layoutManager = GridLayoutManager(activity, 2, GridLayoutManager.HORIZONTAL, false)
val genreAdapter = GenreAdapter(activity, genres, R.layout.item_grid_genre)
layoutManager = GridLayoutManager(activity, 3, GridLayoutManager.HORIZONTAL, false)
val genreAdapter =
GenreAdapter(activity, genres as List<Genre>, R.layout.item_grid_genre)
adapter = genreAdapter
}
}
@ -276,6 +214,38 @@ class HomeAdapter(
open inner class AbsHomeViewItem(itemView: View) : RecyclerView.ViewHolder(itemView) {
val recyclerView: RecyclerView = itemView.findViewById(R.id.recyclerView)
val title: AppCompatTextView = itemView.findViewById(R.id.title)
val text: AppCompatTextView = itemView.findViewById(R.id.text)
val arrow: ImageView = itemView.findViewById(R.id.arrow)
val clickableArea: ViewGroup = itemView.findViewById(R.id.clickable_area)
}
fun artistsAdapter(artists: List<Artist>) =
ArtistAdapter(activity, artists, PreferenceUtil.homeGridStyle, null, this)
fun albumAdapter(albums: List<Album>) =
AlbumAdapter(activity, albums, R.layout.item_image, null, this)
fun gridLayoutManager() = GridLayoutManager(activity, 1, GridLayoutManager.HORIZONTAL, false)
fun linearLayoutManager() = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
override fun onArtist(artistId: Int, imageView: ImageView) {
activity.findNavController(R.id.fragment_container).navigate(
R.id.artistDetailsFragment,
bundleOf(EXTRA_ARTIST_ID to artistId),
null,
FragmentNavigatorExtras(
imageView to activity.getString(R.string.transition_album_art)
)
)
}
override fun onAlbumClick(albumId: Int, view: View) {
activity.findNavController(R.id.fragment_container).navigate(
R.id.albumDetailsFragment,
bundleOf(EXTRA_ALBUM_ID to albumId),
null,
FragmentNavigatorExtras(
view to activity.getString(R.string.transition_album_art)
)
)
}
}

View file

@ -1,12 +1,12 @@
package code.name.monkey.retromusic.adapter.artist
import android.app.ActivityOptions
import android.content.res.ColorStateList
import android.content.res.Resources
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
@ -131,7 +131,6 @@ class ArtistAdapter(
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init {
setImageTransitionName(activity.getString(R.string.transition_artist_image))
menu?.visibility = View.GONE
}
@ -140,15 +139,13 @@ class ArtistAdapter(
if (isInQuickSelectMode) {
toggleChecked(layoutPosition)
} else {
val activityOptions = ActivityOptions.makeSceneTransitionAnimation(
activity,
imageContainerCard ?: image,
image?.let {
ViewCompat.setTransitionName(
it,
activity.getString(R.string.transition_artist_image)
)
artistClickListener.onArtist(dataSet[layoutPosition].id)
/*NavigationUtil.goToArtistOptions(
activity, dataSet[layoutPosition].id, activityOptions
)*/
artistClickListener.onArtist(dataSet[layoutPosition].id, it)
}
}
}

View file

@ -148,7 +148,6 @@ open class SongAdapter(
return ""
}
}
return MusicUtil.getSectionName(sectionName)
}

View file

@ -33,6 +33,8 @@ import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
import com.google.android.material.button.MaterialButton
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
fun Int.ripAlpha(): Int {
return ColorUtil.stripAlpha(this)
@ -117,3 +119,14 @@ fun MaterialButton.applyColor(color: Int) {
setTextColor(textColorColorStateList)
iconTint = textColorColorStateList
}
fun TextInputLayout.accentColor() {
val accentColor = ThemeStore.accentColor(context)
val colorState = ColorStateList.valueOf(accentColor)
boxStrokeColor = accentColor
defaultHintTextColor = colorState
isHintAnimationEnabled = true
}
fun TextInputEditText.accentColor(){
}

View file

@ -0,0 +1,130 @@
package code.name.monkey.retromusic.fragments
import android.os.Bundle
import android.view.View
import android.widget.ImageView
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.adapter.album.AlbumAdapter
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
import code.name.monkey.retromusic.adapter.song.SongAdapter
import code.name.monkey.retromusic.fragments.albums.AlbumClickListener
import code.name.monkey.retromusic.fragments.artists.ArtistClickListener
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.providers.RepositoryImpl
import kotlinx.android.synthetic.main.fragment_playlist_detail.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.inject
class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail),
ArtistClickListener, AlbumClickListener {
private val args by navArgs<DetailListFragmentArgs>()
private val repository by inject<RepositoryImpl>()
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
mainActivity.setSupportActionBar(toolbar)
mainActivity.hideBottomBarVisibility(false)
when (args.type) {
TOP_ARTISTS -> {
loadArtists(R.string.top_artists, TOP_ARTISTS)
}
RECENT_ARTISTS -> {
loadArtists(R.string.recent_artists, RECENT_ARTISTS)
}
TOP_ALBUMS -> {
loadAlbums(R.string.top_albums, TOP_ALBUMS)
}
RECENT_ALBUMS -> {
loadAlbums(R.string.recent_albums, RECENT_ALBUMS)
}
FAVOURITES -> {
loadFavorite()
}
}
}
private fun loadFavorite() {
toolbar.setTitle(R.string.favorites)
CoroutineScope(IO).launch {
val songs = repository.favoritePlaylistHome()
withContext(Main) {
recyclerView.apply {
adapter = SongAdapter(
requireActivity(),
songs.arrayList as MutableList<Song>,
R.layout.item_list, null
)
layoutManager = linearLayoutManager()
}
}
}
}
private fun loadArtists(title: Int, type: Int) {
toolbar.setTitle(title)
CoroutineScope(IO).launch {
val artists =
if (type == TOP_ARTISTS) repository.topArtists() else repository.recentArtists()
withContext(Main) {
recyclerView.apply {
adapter = artistAdapter(artists)
layoutManager = gridLayoutManager()
}
}
}
}
private fun loadAlbums(title: Int, type: Int) {
toolbar.setTitle(title)
CoroutineScope(IO).launch {
val albums =
if (type == TOP_ALBUMS) repository.topAlbums() else repository.recentAlbums()
withContext(Main) {
recyclerView.apply {
adapter = albumAdapter(albums)
layoutManager = gridLayoutManager()
}
}
}
}
private fun artistAdapter(artists: List<Artist>): ArtistAdapter = ArtistAdapter(
requireActivity(),
artists,
R.layout.item_grid_circle,
null, this@DetailListFragment
)
private fun albumAdapter(albums: List<Album>): AlbumAdapter = AlbumAdapter(
requireActivity(),
albums,
R.layout.item_grid,
null, this@DetailListFragment
)
private fun linearLayoutManager(): LinearLayoutManager =
LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
private fun gridLayoutManager(): GridLayoutManager =
GridLayoutManager(requireContext(), 2, GridLayoutManager.VERTICAL, false)
override fun onArtist(artistId: Int, imageView: ImageView) {
}
override fun onAlbumClick(albumId: Int, view: View) {
}
}

View file

@ -4,7 +4,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.fragments.ReloadType.*
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
import code.name.monkey.retromusic.model.*
@ -18,13 +17,13 @@ class LibraryViewModel(
private val repository: RepositoryImpl
) : ViewModel(), MusicServiceEventListener {
private val paletteColor = MutableLiveData<Int>()
private val albums = MutableLiveData<List<Album>>()
private val songs = MutableLiveData<List<Song>>()
private val artists = MutableLiveData<List<Artist>>()
private val playlists = MutableLiveData<List<Playlist>>()
private val genres = MutableLiveData<List<Genre>>()
private val home = MutableLiveData<List<Home>>()
private val paletteColor = MutableLiveData<Int>()
val paletteColorLiveData: LiveData<Int> = paletteColor
val homeLiveData: LiveData<List<Home>> = home
@ -46,38 +45,14 @@ class LibraryViewModel(
artists.value = loadArtists.await()
playlists.value = loadPlaylists.await()
genres.value = loadGenres.await()
loadHomeSections()
home.value = loadHome.await()
}
private fun loadHomeSections() = viewModelScope.launch {
val list = mutableListOf<Home>()
val result = listOf(
repository.topArtists(),
repository.topAlbums(),
repository.recentArtists(),
repository.recentAlbums()/*,
repository.suggestions(),
repository.favoritePlaylist(),
repository.homeGenres()*/
)
result.forEach {
if (it != null && it.arrayList.isNotEmpty()) {
if (it.homeSection == HomeAdapter.SUGGESTIONS) {
if (it.arrayList.size > 9) {
list.add(it)
}
} else {
list.add(it)
}
}
}
home.value = list
}
private val loadHome: Deferred<List<Home>>
get() = viewModelScope.async { repository.homeSections() }
private val loadSongs: Deferred<List<Song>>
get() = viewModelScope.async(IO) {
repository.allSongs()
}
get() = viewModelScope.async(IO) { repository.allSongs() }
private val loadAlbums: Deferred<List<Album>>
get() = viewModelScope.async(IO) {
@ -99,6 +74,7 @@ class LibraryViewModel(
repository.allGenres()
}
fun forceReload(reloadType: ReloadType) = viewModelScope.launch {
when (reloadType) {
Songs -> songs.value = loadSongs.await()
@ -114,15 +90,37 @@ class LibraryViewModel(
override fun onMediaStoreChanged() {
loadLibraryContent()
println("onMediaStoreChanged")
}
override fun onServiceConnected() {}
override fun onServiceDisconnected() {}
override fun onQueueChanged() {}
override fun onPlayingMetaChanged() {}
override fun onPlayStateChanged() {}
override fun onRepeatModeChanged() {}
override fun onShuffleModeChanged() {}
override fun onServiceConnected() {
println("onServiceConnected")
}
override fun onServiceDisconnected() {
println("onServiceDisconnected")
}
override fun onQueueChanged() {
println("onQueueChanged")
}
override fun onPlayingMetaChanged() {
println("onPlayingMetaChanged")
}
override fun onPlayStateChanged() {
println("onPlayStateChanged")
}
override fun onRepeatModeChanged() {
println("onRepeatModeChanged")
}
override fun onShuffleModeChanged() {
println("onShuffleModeChanged")
}
}

View file

@ -6,13 +6,13 @@ import android.net.Uri
import android.os.Bundle
import android.view.View
import androidx.core.app.ShareCompat
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.ContributorAdapter
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.model.Contributor
import code.name.monkey.retromusic.util.NavigationUtil
import com.google.gson.Gson
@ -24,7 +24,7 @@ import kotlinx.android.synthetic.main.card_social.*
import java.io.IOException
import java.nio.charset.StandardCharsets
class AboutFragment : AbsMainActivityFragment(R.layout.fragment_about), View.OnClickListener {
class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
version.setSummary(getAppVersion())

View file

@ -62,17 +62,15 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)
mainActivity.hideBottomBarVisibility(false)
mainActivity.addMusicServiceEventListener(detailsViewModel)
mainActivity.setSupportActionBar(toolbar)
mainActivity.setBottomBarVisibility(View.GONE)
toolbar.title = null
image.transitionName = getString(R.string.transition_album_art)
postponeEnterTransition()
playerActivity?.addMusicServiceEventListener(detailsViewModel)
detailsViewModel.getAlbum().observe(viewLifecycleOwner, Observer {
startPostponedEnterTransition()
showAlbum(it)
startPostponedEnterTransition()
})
detailsViewModel.getArtist().observe(viewLifecycleOwner, Observer {
loadArtistImage(it)

View file

@ -5,6 +5,7 @@ import android.view.View
import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
import androidx.navigation.findNavController
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import code.name.monkey.retromusic.R
@ -19,10 +20,9 @@ class AlbumsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
libraryViewModel.albumsLiveData
.observe(viewLifecycleOwner, Observer { albums ->
if (albums.isNotEmpty())
adapter?.swapDataSet(albums)
libraryViewModel.albumsLiveData.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
adapter?.swapDataSet(listOf())
})
@ -98,7 +98,11 @@ class AlbumsFragment :
val controller = requireActivity().findNavController(R.id.fragment_container)
controller.navigate(
R.id.albumDetailsFragment,
bundleOf(EXTRA_ALBUM_ID to albumId)
bundleOf(EXTRA_ALBUM_ID to albumId),
null,
FragmentNavigatorExtras(
view to getString(R.string.transition_album_art)
)
)
}
}

View file

@ -56,17 +56,19 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
private var lang: String? = null
private var biography: Spanned? = null
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)
mainActivity.setSupportActionBar(toolbar)
mainActivity.setBottomBarVisibility(View.GONE)
mainActivity.hideBottomBarVisibility(false)
toolbar.title = null
setupRecyclerView()
postponeEnterTransition()
detailsViewModel.getArtist().observe(viewLifecycleOwner, Observer {
startPostponedEnterTransition()
showArtist(it)
startPostponedEnterTransition()
})
detailsViewModel.getArtistInfo().observe(viewLifecycleOwner, Observer {
artistInfo(it)
@ -129,7 +131,7 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
)
songTitle.text = songText
albumTitle.text = albumText
songAdapter.swapDataSet(artist.songs)
songAdapter.swapDataSet(artist.songs.sortedBy { it.trackNumber })
artist.albums?.let { albumAdapter.swapDataSet(it) }
}
@ -175,6 +177,7 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
.generatePalette(requireContext()).build()
.dontAnimate().into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(colors: MediaNotificationProcessor) {
startPostponedEnterTransition()
setColors(colors)
}
})

View file

@ -2,6 +2,7 @@ package code.name.monkey.retromusic.fragments.artists
import android.os.Bundle
import android.view.View
import android.widget.ImageView
import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
@ -25,13 +26,11 @@ class ArtistsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
libraryViewModel.artistsLiveData
.observe(viewLifecycleOwner, Observer { artists ->
if (artists.isNotEmpty()) {
adapter?.swapDataSet(artists)
} else {
libraryViewModel.artistsLiveData.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
adapter?.swapDataSet(listOf())
}
})
}
@ -101,12 +100,12 @@ class ArtistsFragment :
}
}
override fun onArtist(artistId: Int) {
override fun onArtist(artistId: Int, imageView: ImageView) {
val controller = findActivityNavController(R.id.fragment_container)
controller.navigate(R.id.artistDetailsFragment, bundleOf(EXTRA_ARTIST_ID to artistId))
}
}
interface ArtistClickListener {
fun onArtist(artistId: Int)
fun onArtist(artistId: Int, imageView: ImageView)
}

View file

@ -18,6 +18,7 @@ import me.zhanghai.android.fastscroll.FastScroller
import me.zhanghai.android.fastscroll.FastScrollerBuilder
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : RecyclerView.LayoutManager> :
AbsMusicServiceFragment(R.layout.fragment_main_activity_recycler_view),
AppBarLayout.OnOffsetChangedListener {
@ -41,15 +42,17 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
}
private fun setUpRecyclerView() {
recyclerView.layoutManager = layoutManager
recyclerView.adapter = adapter
val fastScroller = create(recyclerView)
recyclerView.setOnApplyWindowInsetsListener(
recyclerView.apply {
layoutManager = this@AbsRecyclerViewFragment.layoutManager
adapter = this@AbsRecyclerViewFragment.adapter
val fastScroller = create(this)
setOnApplyWindowInsetsListener(
ScrollingViewOnApplyWindowInsetsListener(
recyclerView,
fastScroller
)
)
}
checkForPadding()
}

View file

@ -35,7 +35,7 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
setHasOptionsMenu(true)
mainActivity.addMusicServiceEventListener(detailsViewModel)
mainActivity.setSupportActionBar(toolbar)
mainActivity.setBottomBarVisibility(View.GONE)
mainActivity.hideBottomBarVisibility(false)
setupRecyclerView()
detailsViewModel.getSongs().observe(viewLifecycleOwner, androidx.lifecycle.Observer {

View file

@ -32,13 +32,11 @@ class GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
libraryViewModel.genresLiveData
.observe(viewLifecycleOwner, Observer { genres ->
if (genres.isNotEmpty()) {
adapter?.swapDataSet(genres)
} else {
libraryViewModel.genresLiveData.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
adapter?.swapDataSet(listOf())
}
})
}

View file

@ -25,6 +25,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.extensions.findActivityNavController
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
@ -57,9 +58,7 @@ class HomeFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setStatusBarColorAuto(view)
bannerImage?.setOnClickListener {
val options = ActivityOptions.makeSceneTransitionAnimation(
mainActivity,
@ -70,14 +69,14 @@ class HomeFragment :
}
lastAdded.setOnClickListener {
requireActivity().findNavController(R.id.fragment_container).navigate(
findActivityNavController(R.id.fragment_container).navigate(
R.id.playlistDetailsFragment,
bundleOf(EXTRA_PLAYLIST to LastAddedPlaylist(requireActivity()))
)
}
topPlayed.setOnClickListener {
requireActivity().findNavController(R.id.fragment_container).navigate(
findActivityNavController(R.id.fragment_container).navigate(
R.id.playlistDetailsFragment,
bundleOf(EXTRA_PLAYLIST to MyTopTracksPlaylist(requireActivity()))
)
@ -110,9 +109,8 @@ class HomeFragment :
adapter = homeAdapter
}
libraryViewModel.homeLiveData
.observe(viewLifecycleOwner, Observer { sections ->
homeAdapter.swapData(sections)
libraryViewModel.homeLiveData.observe(viewLifecycleOwner, Observer {
homeAdapter.swapData(it)
})
loadProfile()

View file

@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.navigation.fragment.findNavController
import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
@ -17,11 +16,21 @@ import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.fragment_library.*
class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)
mainActivity.setBottomBarVisibility(View.VISIBLE)
mainActivity.hideBottomBarVisibility(true)
mainActivity.setSupportActionBar(toolbar)
mainActivity.supportActionBar?.title = null
toolbar.setNavigationOnClickListener {
findNavController().navigate(
R.id.searchFragment,
null,
navOptions
)
}
setupNavigationController()
}
@ -67,13 +76,8 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_search -> findNavController().navigate(
R.id.searchFragment,
null,
navOptions
)
R.id.action_settings -> findNavController().navigate(
R.id.settingsFragment,
R.id.settingsActivity,
null,
navOptions
)

View file

@ -43,7 +43,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
setHasOptionsMenu(true)
mainActivity.addMusicServiceEventListener(viewModel)
mainActivity.setSupportActionBar(toolbar)
mainActivity.setBottomBarVisibility(View.GONE)
mainActivity.hideBottomBarVisibility(false)
playlist = arguments.extraPlaylist

View file

@ -19,12 +19,11 @@ class PlaylistsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
libraryViewModel.playlisitsLiveData.observe(viewLifecycleOwner, Observer { playlists ->
if (playlists.isNotEmpty()) {
adapter?.swapDataSet(playlists)
} else {
libraryViewModel.playlisitsLiveData.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
adapter?.swapDataSet(listOf())
}
})
}

View file

@ -39,7 +39,7 @@ class SearchFragment : AbsMainActivityFragment(R.layout.fragment_search), TextWa
super.onViewCreated(view, savedInstanceState)
mainActivity.setSupportActionBar(toolbar)
mainActivity.hideBottomNavigation()
mainActivity.setBottomBarVisibility(View.GONE)
mainActivity.hideBottomBarVisibility(false)
setupRecyclerView()
setupSearchView()

View file

@ -1,23 +0,0 @@
package code.name.monkey.retromusic.fragments.settings
import android.os.Bundle
import android.view.View
import androidx.navigation.NavController
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.findNavController
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import kotlinx.android.synthetic.main.fragment_settings.*
class SettingsFragment : AbsMainActivityFragment(R.layout.fragment_settings) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainActivity.setSupportActionBar(toolbar)
mainActivity.hideBottomNavigation()
mainActivity.setBottomBarVisibility(View.GONE)
val navController: NavController = findNavController(R.id.contentFrame)
navController.addOnDestinationChangedListener { _, _, _ ->
toolbar.title = navController.currentDestination?.label
}
}
}

View file

@ -23,11 +23,10 @@ class SongsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
libraryViewModel.songsLiveData.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty()) {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
} else {
else
adapter?.swapDataSet(listOf())
}
})
}

View file

@ -14,13 +14,10 @@
package code.name.monkey.retromusic.model
import androidx.annotation.DrawableRes
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.HomeSection
import code.name.monkey.retromusic.HomeSection
class Home(
val arrayList: List<*>,
val arrayList: List<Any>,
@HomeSection
val homeSection: Int,
@DrawableRes
val icon: Int
val homeSection: Int
)

View file

@ -15,8 +15,7 @@
package code.name.monkey.retromusic.providers
import android.content.Context
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.loaders.*
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.model.smartplaylist.NotRecentlyPlayedPlaylist
@ -24,6 +23,10 @@ import code.name.monkey.retromusic.network.LastFMService
import code.name.monkey.retromusic.network.model.LastFmAlbum
import code.name.monkey.retromusic.network.model.LastFmArtist
import code.name.monkey.retromusic.providers.interfaces.Repository
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flow
class RepositoryImpl(
private val context: Context,
@ -39,41 +42,24 @@ class RepositoryImpl(
override suspend fun artistById(artistId: Int): Artist =
ArtistLoader.getArtist(context, artistId)
override suspend fun recentArtists(): List<Artist> =
LastAddedSongsLoader.getLastAddedArtists(context)
override suspend fun topArtists(): List<Artist> =
TopAndRecentlyPlayedTracksLoader.getTopArtists(context)
override suspend fun topAlbums(): List<Album> =
TopAndRecentlyPlayedTracksLoader.getTopAlbums(context)
override suspend fun recentAlbums(): List<Album> =
LastAddedSongsLoader.getLastAddedAlbums(context)
override suspend fun allPlaylists(): List<Playlist> = PlaylistLoader.getAllPlaylists(context)
override suspend fun allGenres(): List<Genre> = GenreLoader.getAllGenres(context)
override suspend fun allSongs(): List<Song> = SongLoader.getAllSongs(context)
override suspend fun suggestions(): Home? {
val songs = NotRecentlyPlayedPlaylist(context).getSongs(context).shuffled().apply {
if (size > 9) subList(0, 9)
}
if (songs.isNotEmpty()) {
return Home(
songs,
HomeAdapter.SUGGESTIONS,
R.drawable.ic_audiotrack
)
}
return null
}
override suspend fun homeGenres(): Home? {
val genres =
GenreLoader.getAllGenres(context)
.shuffled()
.filter { it.name.length in 5..10 }
if (genres.isNotEmpty()) {
return Home(
genres,
HomeAdapter.GENRES,
R.drawable.ic_guitar
)
}
return null
}
override suspend fun search(query: String?): MutableList<Any> =
SearchLoader.searchAll(context, query)
@ -89,52 +75,6 @@ class RepositoryImpl(
override suspend fun getGenre(genreId: Int): ArrayList<Song> =
GenreLoader.getSongs(context, genreId)
override suspend fun recentArtists(): Home? {
val artists = LastAddedSongsLoader.getLastAddedArtists(context)
return if (artists.isNotEmpty()) Home(
artists,
HomeAdapter.RECENT_ARTISTS,
R.drawable.ic_artist
) else null
}
override suspend fun recentAlbums(): Home? {
val albums = LastAddedSongsLoader.getLastAddedAlbums(context)
return if (albums.isNotEmpty()) Home(
albums,
HomeAdapter.RECENT_ALBUMS,
R.drawable.ic_album
) else null
}
override suspend fun topAlbums(): Home? {
val albums = TopAndRecentlyPlayedTracksLoader.getTopAlbums(context)
return if (albums.isNotEmpty()) Home(
albums,
HomeAdapter.TOP_ALBUMS,
R.drawable.ic_album
) else null
}
override suspend fun topArtists(): Home? {
val artists = TopAndRecentlyPlayedTracksLoader.getTopArtists(context)
return if (artists.isNotEmpty()) Home(
artists,
HomeAdapter.TOP_ARTISTS,
R.drawable.ic_artist
) else null
}
override suspend fun favoritePlaylist(): Home? {
val playlists = PlaylistLoader.getFavoritePlaylist(context)
return if (playlists.isNotEmpty()) Home(
playlists,
HomeAdapter.FAVOURITES,
R.drawable.ic_favorite
) else null
}
override suspend fun artistInfo(
name: String,
@ -148,4 +88,149 @@ class RepositoryImpl(
album: String
): LastFmAlbum = lastFMService.albumInfo(artist, album)
@ExperimentalCoroutinesApi
override suspend fun homeSectionsFlow(): Flow<Result<List<Home>>> {
val homes = MutableStateFlow<Result<List<Home>>>(value = Result.Loading)
println("homeSections:Loading")
val homeSections = mutableListOf<Home>()
val sections = listOf(
topArtistsHome(),
topAlbumsHome(),
recentArtistsHome(),
recentAlbumsHome(),
suggestionsHome(),
favoritePlaylistHome(),
genresHome()
)
for (section in sections) {
if (section.arrayList.isNotEmpty()) {
println("${section.homeSection} -> ${section.arrayList.size}")
homeSections.add(section)
}
}
if (homeSections.isEmpty()) {
homes.value = Result.Error
} else {
homes.value = Result.Success(homeSections)
}
return homes
}
override suspend fun homeSections(): List<Home> {
val homeSections = mutableListOf<Home>()
val sections = listOf(
topArtistsHome(),
topAlbumsHome(),
recentArtistsHome(),
recentAlbumsHome(),
suggestionsHome(),
favoritePlaylistHome(),
genresHome()
)
for (section in sections) {
if (section.arrayList.isNotEmpty()) {
println("${section.homeSection} -> ${section.arrayList.size}")
homeSections.add(section)
}
}
return homeSections
}
suspend fun playlists(): Home {
val playlist = PlaylistLoader.getAllPlaylists(context)
return Home(playlist, TOP_ALBUMS)
}
override suspend fun suggestionsHome(): Home {
val songs =
NotRecentlyPlayedPlaylist(context).getSongs(context).shuffled().takeUnless {
it.size > 9
}?.take(9) ?: emptyList<Song>()
return Home(songs, SUGGESTIONS)
}
override suspend fun genresHome(): Home {
val genres = GenreLoader.getAllGenres(context).shuffled()
return Home(genres, GENRES)
}
override suspend fun recentArtistsHome(): Home {
val artists = LastAddedSongsLoader.getLastAddedArtists(context).take(5)
return Home(artists, RECENT_ARTISTS)
}
override suspend fun recentAlbumsHome(): Home {
val albums = LastAddedSongsLoader.getLastAddedAlbums(context).take(5)
return Home(albums, RECENT_ALBUMS)
}
override suspend fun topAlbumsHome(): Home {
val albums = TopAndRecentlyPlayedTracksLoader.getTopAlbums(context).take(5)
return Home(albums, TOP_ALBUMS)
}
override suspend fun topArtistsHome(): Home {
val artists = TopAndRecentlyPlayedTracksLoader.getTopArtists(context).take(5)
return Home(artists, TOP_ARTISTS)
}
override suspend fun favoritePlaylistHome(): Home {
val playlists = PlaylistLoader.getFavoritePlaylist(context).take(5)
val songs = if (playlists.isNotEmpty())
PlaylistSongsLoader.getPlaylistSongList(context, playlists[0])
else emptyList<Song>()
return Home(songs, FAVOURITES)
}
override fun songsFlow(): Flow<Result<List<Song>>> = flow {
emit(Result.Loading)
val data = SongLoader.getAllSongs(context)
if (data.isEmpty()) {
emit(Result.Error)
} else {
emit(Result.Success(data))
}
}
override fun albumsFlow(): Flow<Result<List<Album>>> = flow {
emit(Result.Loading)
val data = AlbumLoader.getAllAlbums(context)
if (data.isEmpty()) {
emit(Result.Error)
} else {
emit(Result.Success(data))
}
}
override fun artistsFlow(): Flow<Result<List<Artist>>> = flow {
emit(Result.Loading)
val data = ArtistLoader.getAllArtists(context)
if (data.isEmpty()) {
emit(Result.Error)
} else {
emit(Result.Success(data))
}
}
override fun playlistsFlow(): Flow<Result<List<Playlist>>> = flow {
emit(Result.Loading)
val data = PlaylistLoader.getAllPlaylists(context)
if (data.isEmpty()) {
emit(Result.Error)
} else {
emit(Result.Success(data))
}
}
override fun genresFlow(): Flow<Result<List<Genre>>> = flow {
emit(Result.Loading)
val data = GenreLoader.getAllGenres(context)
if (data.isEmpty()) {
emit(Result.Error)
} else {
emit(Result.Success(data))
}
}
}

View file

@ -14,9 +14,11 @@
package code.name.monkey.retromusic.providers.interfaces
import code.name.monkey.retromusic.Result
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.network.model.LastFmAlbum
import code.name.monkey.retromusic.network.model.LastFmArtist
import kotlinx.coroutines.flow.Flow
/**
* Created by hemanths on 11/08/17.
@ -47,17 +49,41 @@ interface Repository {
suspend fun albumInfo(artist: String, album: String): LastFmAlbum
suspend fun artistById(artistId: Int): Artist
suspend fun recentArtists(): Home?
suspend fun topArtists(): Home?
suspend fun recentArtists(): List<Artist>
suspend fun topAlbums(): Home?
suspend fun topArtists(): List<Artist>
suspend fun recentAlbums(): Home?
suspend fun topAlbums(): List<Album>
suspend fun favoritePlaylist(): Home?
suspend fun recentAlbums(): List<Album>
suspend fun suggestions(): Home?
suspend fun recentArtistsHome(): Home
suspend fun topArtistsHome(): Home
suspend fun topAlbumsHome(): Home
suspend fun recentAlbumsHome(): Home
suspend fun favoritePlaylistHome(): Home
suspend fun suggestionsHome(): Home
suspend fun genresHome(): Home
suspend fun homeSections(): List<Home>
suspend fun homeSectionsFlow(): Flow<Result<List<Home>>>
fun songsFlow(): Flow<Result<List<Song>>>
fun albumsFlow(): Flow<Result<List<Album>>>
fun artistsFlow(): Flow<Result<List<Artist>>>
fun playlistsFlow(): Flow<Result<List<Playlist>>>
fun genresFlow(): Flow<Result<List<Genre>>>
suspend fun homeGenres(): Home?
}

View file

@ -66,5 +66,5 @@ class BottomNavigationBarTinted @JvmOverloads constructor(
}
fun Int.addAlpha(): Int {
return ColorUtil.withAlpha(this, 0.12f)
return ColorUtil.withAlpha(this, 0.38f)
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:app="http://schemas.android.com/apk/res-auto"
app:fontProviderAuthority="com.google.android.gms.fonts"
app:fontProviderPackage="com.google.android.gms"
app:fontProviderQuery="Pacifico"
app:fontProviderCerts="@array/com_google_android_gms_fonts_certs">
</font-family>

View file

@ -1,6 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="0dp"
tools:ignore="UnusedAttribute">
<include layout="@layout/status_bar" />
</FrameLayout>
<androidx.fragment.app.FragmentContainerView
android:id="@+id/fragment_container"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
@ -8,4 +25,4 @@
app:defaultNavHost="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:navGraph="@navigation/main_graph" />
</LinearLayout>

View file

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<code.name.monkey.retromusic.views.StatusBarView
android:id="@+id/status_bar"
android:layout_width="match_parent"
android:layout_height="0dp"
tools:ignore="UnusedAttribute" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
<androidx.core.widget.NestedScrollView
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/contentFrame"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:defaultNavHost="true"
app:navGraph="@navigation/settings_graph" />
</androidx.core.widget.NestedScrollView>
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Toolbar"
app:layout_collapseMode="pin"
app:navigationIcon="@drawable/ic_keyboard_backspace_black"
app:titleTextAppearance="@style/ToolbarTextAppearanceNormal"
tools:title="@string/action_settings" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View file

@ -1,21 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:orientation="vertical"
tools:ignore="UnusedAttribute">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/status_bar" />
</FrameLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -137,4 +123,3 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View file

@ -1,21 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:orientation="vertical"
tools:ignore="UnusedAttribute">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/status_bar" />
</FrameLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -61,7 +47,6 @@
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:transitionName="@string/transition_artist_image"
app:cardCornerRadius="24dp"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
@ -73,6 +58,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:transitionName="@string/transition_artist_image"
tools:srcCompat="@tools:sample/backgrounds/scenic" />
</com.google.android.material.card.MaterialCardView>
@ -122,4 +108,3 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View file

@ -1,23 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?colorSurface"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="0dp"
tools:ignore="UnusedAttribute">
<include layout="@layout/status_bar" />
</FrameLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -38,11 +22,19 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"
app:navigationIcon="@drawable/ic_search"
app:popupTheme="?attr/toolbarPopupTheme"
app:title="@string/app_name"
app:titleTextAppearance="@style/ToolbarTextAppearanceNormal.Library"
app:titleTextColor="?attr/colorControlNormal"
tools:ignore="UnusedAttribute" />
app:title="@null"
tools:ignore="UnusedAttribute">
<com.google.android.material.textview.MaterialTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/app_name"
android:textStyle="bold"
android:textAppearance="@style/TextViewHeadline6" />
</androidx.appcompat.widget.Toolbar>
<ViewStub
android:id="@+id/cab_stub"
@ -60,4 +52,3 @@
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
app:navGraph="@navigation/library_graph" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -36,7 +37,8 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_diamond_stone"
app:tint="?colorOnSecondary" />
app:tint="?colorOnSecondary"
tools:tint="?attr/colorAccent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
@ -47,6 +49,8 @@
android:text="@string/retro_music_pro"
android:textAppearance="@style/TextViewSubtitle1"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/diamondIcon" />
<com.google.android.material.textview.MaterialTextView
@ -58,6 +62,9 @@
android:paddingEnd="16dp"
android:paddingBottom="12dp"
android:text="@string/pro_summary"
android:textAppearance="@style/TextViewBody2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
<View
@ -77,6 +84,7 @@
android:gravity="start|center_vertical"
android:text="@string/buy_now"
android:textAllCaps="false"
android:textAppearance="@style/TextViewButton"
android:textColor="?colorAccent"
android:textStyle="bold"
app:backgroundTint="?attr/colorSurface"

View file

@ -1,21 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:orientation="vertical"
tools:ignore="UnusedAttribute">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/status_bar" />
</FrameLayout>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
@ -85,4 +71,3 @@
tools:visibility="visible" />
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>

View file

@ -9,10 +9,11 @@
<com.google.android.material.card.MaterialCardView
android:id="@+id/imageContainer"
android:layout_width="112dp"
android:layout_height="156dp"
android:layout_margin="8dp"
android:layout_width="148dp"
android:layout_height="0dp"
android:layout_margin="4dp"
app:cardCornerRadius="12dp"
app:layout_constraintDimensionRatio="3:4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
@ -24,21 +25,23 @@
android:scaleType="centerCrop"
app:srcCompat="@drawable/default_album_art"
tools:src="@tools:sample/avatars" />
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="@drawable/shadow_up"
android:ellipsize="end"
android:maxLines="1"
android:maxLines="2"
android:padding="8dp"
android:textAppearance="@style/TextViewNormal"
android:textColor="?android:attr/textColorPrimary"
android:textAppearance="@style/TextViewBody1"
android:textColor="@color/md_white_1000"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageContainer"
tools:ignore="MissingPrefix"
tools:text="@tools:sample/full_names" />
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -12,7 +12,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textAppearance="@style/TextViewHeadline6"
android:textAppearance="@style/TextViewSubtitle1"
tools:text="@tools:sample/full_names" />
</com.google.android.material.card.MaterialCardView>

View file

@ -35,7 +35,9 @@
android:ellipsize="end"
android:maxLines="1"
android:padding="8dp"
android:textAppearance="@style/TextViewNormal"
android:textAppearance="@style/TextViewBody1"
android:textColor="?android:attr/textColorPrimary"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/imageContainer"

View file

@ -10,8 +10,7 @@
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:padding="16dp"
android:text="@string/suggestion_songs"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold"
@ -20,18 +19,6 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingTop="4dp"
android:text="Randomly selected songs for you"
android:textAppearance="@style/TextViewCaption"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/card1"
@ -137,7 +124,6 @@
android:id="@+id/card6"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="12dp"
android:clickable="true"
android:focusable="true"
app:cardBackgroundColor="?attr/colorSurface"
@ -148,7 +134,7 @@
app:layout_constraintEnd_toStartOf="@id/card7"
app:layout_constraintHorizontal_weight="4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/text">
app:layout_constraintTop_toBottomOf="@id/title">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/message"
@ -164,14 +150,13 @@
android:id="@+id/card7"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="12dp"
app:cardCornerRadius="8dp"
app:cardUseCompatPadding="true"
app:layout_constraintDimensionRatio="1,1"
app:layout_constraintEnd_toStartOf="@id/card8"
app:layout_constraintHorizontal_weight="2"
app:layout_constraintStart_toEndOf="@id/card6"
app:layout_constraintTop_toBottomOf="@id/text">
app:layout_constraintTop_toTopOf="@id/card6">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image1"
@ -185,14 +170,13 @@
android:id="@+id/card8"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="12dp"
app:cardCornerRadius="8dp"
app:cardUseCompatPadding="true"
app:layout_constraintDimensionRatio="1,1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="4"
app:layout_constraintStart_toEndOf="@id/card7"
app:layout_constraintTop_toBottomOf="@id/text">
app:layout_constraintTop_toTopOf="@id/card7">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image2"

View file

@ -11,9 +11,7 @@
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:padding="16dp"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold"
app:layout_constrainedWidth="true"
@ -22,19 +20,6 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingTop="4dp"
android:textAppearance="@style/TextViewCaption"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="@tools:sample/full_names" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
@ -42,9 +27,8 @@
android:nestedScrollingEnabled="false"
android:overScrollMode="never"
android:visibility="gone"
android:layout_marginTop="12dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text"
app:layout_constraintTop_toBottomOf="@+id/title"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -5,47 +5,49 @@
android:id="@+id/recentArtistContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
android:orientation="vertical"
android:paddingBottom="12dp">
<LinearLayout
android:id="@+id/clickable_area"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/rectSelector"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingTop="16dp"
android:layout_weight="1"
android:padding="16dp"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/full_names" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/text"
android:layout_width="0dp"
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/arrow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingHorizontal="16dp"
android:paddingTop="4dp"
android:textAppearance="@style/TextViewCaption"
app:layout_constrainedWidth="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
tools:text="@tools:sample/full_names" />
android:padding="16dp"
app:srcCompat="@drawable/ic_arrow_forward"
app:tint="?attr/colorControlNormal" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:nestedScrollingEnabled="false"
android:overScrollMode="never"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text"
app:layout_constraintTop_toBottomOf="@+id/clickable_area"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -49,7 +49,6 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:elevation="0dp"
android:visibility="gone"
app:itemHorizontalTranslationEnabled="false"
app:itemIconTint="@drawable/bottom_navigation_item_colors"
app:itemTextAppearanceActive="@style/BottomSheetItemTextAppearance"

View file

@ -16,11 +16,6 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".DrawerActivity">
<item
android:id="@+id/action_search"
android:icon="@drawable/ic_search"
android:title="@string/action_search"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_settings"

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -43,6 +43,7 @@
<fragment
android:id="@+id/action_home"
android:name="code.name.monkey.retromusic.fragments.home.HomeFragment"
android:label=""
tools:layout="@layout/fragment_banner_home"/>
</navigation>

View file

@ -52,7 +52,7 @@
<fragment
android:id="@+id/libraryFragment"
android:name="code.name.monkey.retromusic.fragments.library.LibraryFragment"
android:label="LibraryFragment"
android:label=""
tools:layout="@layout/fragment_library">
<action
android:id="@+id/action_main_to_library"
@ -62,16 +62,25 @@
app:destination="@id/settings_graph" />
</fragment>
<fragment
android:id="@+id/detailListFragment"
android:name="code.name.monkey.retromusic.fragments.DetailListFragment"
android:label="DetailListFragment">
<argument
android:name="type"
app:argType="integer" />
</fragment>
<fragment
android:id="@+id/searchFragment"
android:name="code.name.monkey.retromusic.fragments.search.SearchFragment"
android:label="SearchFragment"
tools:layout="@layout/fragment_search" />
<fragment
android:id="@+id/settingsFragment"
android:name="code.name.monkey.retromusic.fragments.settings.SettingsFragment"
android:label="SettingsFragment"
tools:layout="@layout/fragment_settings" />
<activity
android:id="@+id/settingsActivity"
android:name="code.name.monkey.retromusic.activities.SettingsActivity"
android:label="SettingsActivity" />
</navigation>

View file

@ -69,7 +69,12 @@
<action
android:id="@+id/action_mainSettingsFragment_to_aboutActivity"
app:destination="@id/aboutActivity" />
app:destination="@id/aboutActivity"
app:enterAnim="@anim/retro_fragment_open_enter"
app:exitAnim="@anim/retro_fragment_open_exit"
app:launchSingleTop="true"
app:popEnterAnim="@anim/retro_fragment_close_enter"
app:popExitAnim="@anim/retro_fragment_close_exit" />
</fragment>
<fragment

View file

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<transitionSet>
<changeBounds/>
<changeTransform/>
<transitionSet
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="375"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:transitionOrdering="together">
<changeClipBounds/>
<changeImageTransform/>
<changeTransform/>
<changeBounds/>
</transitionSet>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Copyright 2018 Google LLC
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="375"
android:interpolator="@android:interpolator/fast_out_slow_in"
android:startDelay="25">
<fade>
<targets android:targetId="@id/imageContainerCard" />
</fade>
<fade>
<targets android:targetId="@id/paletteColorContainer" />
</fade>
</transitionSet>

View file

@ -15,11 +15,9 @@
<resources>
<style name="Theme.RetroMusic.Base.Adaptive" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="md_background_color">?attr/colorSurface</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActivityTransitions">true</item>
<item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Dark</item>
<item name="mcab_popup_theme">@style/ThemeOverlay.AppCompat.Dark</item>
<item name="windowActionBarOverlay">true</item>
@ -30,8 +28,6 @@
<item name="rectSelector">@drawable/rect_selector</item>
<item name="android:actionOverflowButtonStyle">@style/Widget.ActionButton.Overflow</item>
<item name="android:windowLightNavigationBar">false</item>
<!--Manual setting colors-->
<item name="colorSurface">@color/darkColorSurface</item>
</style>
</resources>

View file

@ -15,11 +15,9 @@
<resources>
<style name="Theme.RetroMusic.Base.Adaptive" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="md_background_color">?attr/colorSurface</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActivityTransitions">true</item>
<item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Dark</item>
<item name="mcab_popup_theme">@style/ThemeOverlay.AppCompat.Dark</item>
<item name="windowActionBarOverlay">true</item>
@ -29,7 +27,6 @@
<item name="roundSelector">@drawable/round_selector</item>
<item name="rectSelector">@drawable/rect_selector</item>
<item name="android:actionOverflowButtonStyle">@style/Widget.ActionButton.Overflow</item>
<!--Manual setting colors-->
<item name="colorPrimary">@color/darkColorPrimary</item>
<item name="colorSurface">@color/darkColorSurface</item>
</style>

View file

@ -21,7 +21,6 @@
<style name="BottomSheetItemTextAppearance" parent="Widget.MaterialComponents.BottomNavigationView.Colored">
<item name="android:breakStrategy">simple</item>
<item name="android:hyphenationFrequency">none</item>
<item name="android:textSize">13sp</item>
</style>
</resources>

View file

@ -15,20 +15,18 @@
<resources>
<style name="Theme.RetroMusic.Base.Adaptive" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowActivityTransitions">true</item>
<item name="windowActionBarOverlay">true</item>
<item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="mcab_popup_theme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item>
<item name="materialButtonStyle">@style/MaterialButtonTheme</item>
<item name="roundSelector">@drawable/round_selector</item>
<item name="rectSelector">@drawable/rect_selector</item>
<item name="android:actionOverflowButtonStyle">@style/Widget.ActionButton.Overflow</item>
<item name="android:windowLightNavigationBar">true</item>
<item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item>
<item name="materialButtonStyle">@style/MaterialButtonTheme</item>
</style>
<style name="Theme.RetroMusic.Base" parent="Theme.MaterialComponents.NoActionBar">

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="com_google_android_gms_fonts_certs">
<item>@array/com_google_android_gms_fonts_certs_dev</item>
<item>@array/com_google_android_gms_fonts_certs_prod</item>
</array>
<string-array name="com_google_android_gms_fonts_certs_dev">
<item>
MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
</item>
</string-array>
<string-array name="com_google_android_gms_fonts_certs_prod">
<item>
MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
</item>
</string-array>
</resources>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="preloaded_fonts" translatable="false">
<item>@font/pacifico</item>
</array>
</resources>

View file

@ -65,6 +65,8 @@
<style name="ToolbarTextAppearanceNormal.Library" parent="ToolbarTextAppearanceNormal">
<item name="android:textAppearance">@style/TextViewHeadline6</item>
<item name="fontFamily">@font/pacifico</item>
<item name="android:fontFamily">@font/pacifico</item>
</style>
<style name="BigTitleTextAppearanceToolbar">
@ -131,6 +133,8 @@
<style name="TextViewBody1" parent="TextAppearance.MaterialComponents.Body1" />
<style name="TextViewButton" parent="TextAppearance.MaterialComponents.Button" />
<style name="TextViewBody2" parent="TextAppearance.MaterialComponents.Body2" />
<style name="TextViewOverline" parent="TextAppearance.MaterialComponents.Overline" />

View file

@ -8,11 +8,11 @@
<item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="mcab_popup_theme">@style/ThemeOverlay.AppCompat.Light</item>
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
<item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item>
<item name="materialButtonStyle">@style/MaterialButtonTheme</item>
<item name="roundSelector">@drawable/round_selector</item>
<item name="rectSelector">@drawable/rect_selector</item>
<item name="android:actionOverflowButtonStyle">@style/Widget.ActionButton.Overflow</item>
<item name="materialAlertDialogTheme">@style/MaterialAlertDialogTheme</item>
<item name="materialButtonStyle">@style/MaterialButtonTheme</item>
</style>
<style name="Theme.RetroMusic.Base" parent="Theme.MaterialComponents.NoActionBar">