Code refactor and Genre category added to home

This commit is contained in:
Hemanth S 2020-07-26 01:52:37 +05:30
parent d4ab36fd69
commit c23e959356
21 changed files with 149 additions and 58 deletions

View file

@ -167,8 +167,11 @@ dependencies {
def koin_version = "2.1.5"
implementation "org.koin:koin-core:$koin_version"
implementation "org.koin:koin-android:$koin_version"
implementation "org.koin:koin-android-viewmodel:$koin_version"
implementation "org.koin:koin-core-ext:$koin_version"
implementation "org.koin:koin-androidx-scope:$koin_version"
implementation "org.koin:koin-androidx-viewmodel:$koin_version"
implementation "org.koin:koin-androidx-fragment:$koin_version"
implementation "org.koin:koin-androidx-ext:$koin_version"
def nav_version = "2.3.0"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"

View file

@ -59,11 +59,6 @@
#-keep class org.jaudiotagger.** { *; }
#For cast
-keep class code.name.monkey.retromusic.cast.CastOptionsProvider { *; }
-keep class android.support.** { *; }
-keep class com.google.** { *; }
-keep class java.nio.file.** { *; }
-obfuscationdictionary build/obfuscation-dictionary.txt
-classobfuscationdictionary build/class-dictionary.txt

View file

@ -20,7 +20,6 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import code.name.monkey.retromusic.network.networkModule
import code.name.monkey.retromusic.providers.provideModules
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.TransactionDetails
@ -37,7 +36,7 @@ class App : MultiDexApplication() {
startKoin {
androidContext(this@App)
modules(listOf(mainModule, provideModules, networkModule))
modules(appModules)
}
// default theme
if (!ThemeStore.isConfigured(this, 3)) {

View file

@ -8,11 +8,20 @@ import code.name.monkey.retromusic.activities.search.SearchViewModel
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Playlist
import org.koin.android.viewmodel.dsl.viewModel
import code.name.monkey.retromusic.network.networkModule
import code.name.monkey.retromusic.providers.RepositoryImpl
import org.eclipse.egit.github.core.Repository
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.bind
import org.koin.dsl.module
private val dataModule = module {
single {
RepositoryImpl(get(), get())
} bind Repository::class
}
val mainModule = module {
private val viewModules = module {
viewModel {
LibraryViewModel(get())
@ -38,3 +47,5 @@ val mainModule = module {
SearchViewModel(get())
}
}
val appModules = listOf(dataModule, viewModules, networkModule)

View file

@ -74,7 +74,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
const val APP_UPDATE_REQUEST_CODE = 9002
}
val libraryViewModel: LibraryViewModel by inject()
private val libraryViewModel: LibraryViewModel by inject()
private var cab: MaterialCab? = null
private val intentFilter = IntentFilter(Intent.ACTION_SCREEN_OFF)
private lateinit var currentFragment: MainActivityFragmentCallbacks
@ -621,8 +621,13 @@ class MainActivity : AbsSlidingMusicPanelActivity(),
fragment: Fragment,
tag: String
) {
supportFragmentManager.commit {
setCustomAnimations(
R.anim.retro_fragment_open_enter,
R.anim.retro_fragment_open_exit,
R.anim.retro_fragment_fade_enter,
R.anim.retro_fragment_fade_exit
)
replace(R.id.fragment_container, fragment, tag)
}
currentFragment = fragment as MainActivityFragmentCallbacks

View file

@ -50,6 +50,7 @@ class HomeAdapter(
.inflate(R.layout.metal_section_recycler_view, parent, false)
)
}
GENRES -> GenreViewHolder(layout)
FAVOURITES -> PlaylistViewHolder(layout)
else -> {
SuggestionsViewHolder(
@ -103,6 +104,10 @@ class HomeAdapter(
R.string.favorites
)
}
GENRES -> {
val viewHolder = holder as GenreViewHolder
viewHolder.bind(list[position].arrayList as List<Genre>, R.string.genres)
}
}
}
@ -117,7 +122,15 @@ class HomeAdapter(
companion object {
@IntDef(RECENT_ALBUMS, TOP_ALBUMS, RECENT_ARTISTS, TOP_ARTISTS, SUGGESTIONS, FAVOURITES)
@IntDef(
RECENT_ALBUMS,
TOP_ALBUMS,
RECENT_ARTISTS,
TOP_ARTISTS,
SUGGESTIONS,
FAVOURITES,
GENRES
)
@Retention(AnnotationRetention.SOURCE)
annotation class HomeSection
@ -127,6 +140,7 @@ class HomeAdapter(
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) {
@ -214,6 +228,18 @@ class HomeAdapter(
}
}
private inner class GenreViewHolder(itemView: View) : AbsHomeViewItem(itemView) {
fun bind(genres: List<Genre>, titleRes: Int) {
title.text = activity.getString(titleRes)
recyclerView.apply {
show()
layoutManager = GridLayoutManager(activity, 2, GridLayoutManager.HORIZONTAL, false)
val genreAdapter = GenreAdapter(activity, genres, R.layout.item_grid_genre)
adapter = genreAdapter
}
}
}
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)

View file

@ -57,7 +57,8 @@ class LibraryViewModel(
repository.recentArtists(),
repository.recentAlbums(),
repository.suggestions(),
repository.favoritePlaylist()
repository.favoritePlaylist(),
repository.homeGenres()
)
result.forEach {
if (it != null && it.arrayList.isNotEmpty()) {

View file

@ -6,18 +6,22 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.album.AlbumAdapter
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
import code.name.monkey.retromusic.util.PreferenceUtil
import org.koin.android.viewmodel.ext.android.sharedViewModel
class AlbumsFragment :
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager>(),
MainActivityFragmentCallbacks {
private val libraryViewModel: LibraryViewModel by sharedViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainActivity.libraryViewModel.allAlbums
libraryViewModel.allAlbums
.observe(viewLifecycleOwner, Observer { albums ->
if (albums.isNotEmpty())
adapter?.swapDataSet(albums)
@ -73,7 +77,7 @@ class AlbumsFragment :
}
override fun setSortOrder(sortOrder: String) {
mainActivity.libraryViewModel.forceReload(ReloadType.Albums)
libraryViewModel.forceReload(ReloadType.Albums)
}
override fun loadLayoutRes(): Int {

View file

@ -6,17 +6,22 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
import code.name.monkey.retromusic.util.PreferenceUtil
import org.koin.android.viewmodel.ext.android.sharedViewModel
class ArtistsFragment :
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<ArtistAdapter, GridLayoutManager>(),
MainActivityFragmentCallbacks {
private val libraryViewModel: LibraryViewModel by sharedViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainActivity.libraryViewModel.allArtists
libraryViewModel.allArtists
.observe(viewLifecycleOwner, Observer { artists ->
if (artists.isNotEmpty()) {
adapter?.swapDataSet(artists)
@ -34,7 +39,7 @@ class ArtistsFragment :
get() = R.string.no_artists
override fun setSortOrder(sortOrder: String) {
mainActivity.libraryViewModel.forceReload(ReloadType.Artists)
libraryViewModel.forceReload(ReloadType.Artists)
}
override fun createLayoutManager(): GridLayoutManager {

View file

@ -20,15 +20,19 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.GenreAdapter
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewFragment
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
import org.koin.android.viewmodel.ext.android.sharedViewModel
class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
MainActivityFragmentCallbacks {
private val libraryViewModel: LibraryViewModel by sharedViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainActivity.libraryViewModel.allGenres
libraryViewModel.allGenres
.observe(viewLifecycleOwner, Observer { genres ->
if (genres.isNotEmpty()) {
adapter?.swapDataSet(genres)

View file

@ -24,6 +24,7 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
import code.name.monkey.retromusic.glide.UserProfileGlideRequest
@ -39,9 +40,12 @@ import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.abs_playlists.*
import kotlinx.android.synthetic.main.fragment_banner_home.*
import kotlinx.android.synthetic.main.home_content.*
import org.koin.android.viewmodel.ext.android.sharedViewModel
class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallbacks {
private lateinit var homeAdapter: HomeAdapter
private val libraryViewModel: LibraryViewModel by sharedViewModel()
override fun onCreateView(
inflater: LayoutInflater,
@ -112,7 +116,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
adapter = homeAdapter
}
mainActivity.libraryViewModel.homeSections
libraryViewModel.homeSections
.observe(viewLifecycleOwner, Observer { sections ->
homeAdapter.swapData(sections)
})

View file

@ -8,18 +8,20 @@ import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewFragment
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
import org.koin.android.viewmodel.ext.android.sharedViewModel
class PlaylistsFragment :
AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, GridLayoutManager>(),
MainActivityFragmentCallbacks {
private val libraryViewModel: LibraryViewModel by sharedViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainActivity.libraryViewModel.allPlaylisits
.observe(viewLifecycleOwner, Observer { playlists ->
libraryViewModel.allPlaylisits.observe(viewLifecycleOwner, Observer { playlists ->
if (playlists.isNotEmpty()) {
adapter?.swapDataSet(playlists)
} else {

View file

@ -8,18 +8,22 @@ import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.ShuffleButtonSongAdapter
import code.name.monkey.retromusic.adapter.song.SongAdapter
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsLibraryPagerRecyclerViewCustomGridSizeFragment
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
import code.name.monkey.retromusic.util.PreferenceUtil
import org.koin.android.viewmodel.ext.android.sharedViewModel
class SongsFragment :
AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdapter, GridLayoutManager>(),
MainActivityFragmentCallbacks {
private val libraryViewModel: LibraryViewModel by sharedViewModel()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mainActivity.libraryViewModel.allSongs
.observe(viewLifecycleOwner, Observer {
libraryViewModel.allSongs.observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty()) {
adapter?.swapDataSet(it)
} else {
@ -93,7 +97,7 @@ class SongsFragment :
}
override fun setSortOrder(sortOrder: String) {
mainActivity.libraryViewModel.forceReload(ReloadType.Songs)
libraryViewModel.forceReload(ReloadType.Songs)
}
companion object {

View file

@ -1,11 +0,0 @@
package code.name.monkey.retromusic.providers
import org.eclipse.egit.github.core.Repository
import org.koin.dsl.bind
import org.koin.dsl.module
val provideModules = module {
single {
RepositoryImpl(get(), get())
} bind Repository::class
}

View file

@ -32,19 +32,19 @@ class RepositoryImpl(
override suspend fun allAlbums(): List<Album> = AlbumLoader.getAllAlbums(context)
override suspend fun albumById(albumId: Int): Album = AlbumLoader.getAlbum(context, albumId)
override suspend fun allArtists(): List<Artist> = ArtistLoader.getAllArtists(context)
override suspend fun artistById(artistId: Int): Artist =
ArtistLoader.getArtist(context, artistId)
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 albumById(albumId: Int): Album = AlbumLoader.getAlbum(context, albumId)
override suspend fun artistById(artistId: Int): Artist =
ArtistLoader.getArtist(context, artistId)
override suspend fun suggestions(): Home? {
val songs = NotRecentlyPlayedPlaylist(context).getSongs(context).shuffled().apply {
if (size > 9) subList(0, 9)
@ -59,6 +59,23 @@ class RepositoryImpl(
return null
}
override suspend fun homeGenres(): Home? {
val genres =
GenreLoader.getAllGenres(context)
.shuffled()
.take(10)
.filter { it.name.length > 4 }
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)

View file

@ -58,4 +58,6 @@ interface Repository {
suspend fun favoritePlaylist(): Home?
suspend fun suggestions(): Home?
suspend fun homeGenres(): Home?
}

View file

@ -11,7 +11,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:layoutAnimation="@anim/layout_animation_fall_down"
android:overScrollMode="never"
android:scrollbars="none"
app:layout_dodgeInsetEdges="bottom"

View file

@ -37,7 +37,6 @@
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutAnimation="@anim/layout_animation_fall_down"
android:nestedScrollingEnabled="false"
android:overScrollMode="never"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView 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="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="8dp"
app:cardUseCompatPadding="true">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:textAppearance="@style/TextViewHeadline6"
tools:text="@tools:sample/full_names" />
</com.google.android.material.card.MaterialCardView>

View file

@ -47,6 +47,10 @@
app:popExitAnim="@anim/retro_fragment_close_exit" />
<action
android:id="@+id/action_mainSettingsFragment_to_personalizeSettingsFragment"
app:enterAnim="@anim/retro_fragment_open_enter"
app:exitAnim="@anim/retro_fragment_open_exit"
app:popEnterAnim="@anim/retro_fragment_close_enter"
app:popExitAnim="@anim/retro_fragment_close_exit"
app:destination="@id/personalizeSettingsFragment" />
<action
android:id="@+id/action_mainSettingsFragment_to_notificationSettingsFragment"

View file

@ -10,7 +10,7 @@ buildscript {
}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.android.tools.build:gradle:4.0.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:bundletool:0.9.0'
classpath "gradle.plugin.ru.cleverpumpkin.proguard-dictionaries-generator:plugin:1.0.8"