Fix search slow, last added slow
This commit is contained in:
parent
27190d5b74
commit
e75246ff46
36 changed files with 732 additions and 501 deletions
61
.github/stale.yml
vendored
Normal file
61
.github/stale.yml
vendored
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
# Configuration for probot-stale - https://github.com/probot/stale
|
||||||
|
|
||||||
|
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
||||||
|
daysUntilStale: 60
|
||||||
|
|
||||||
|
# Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
|
||||||
|
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
||||||
|
daysUntilClose: 7
|
||||||
|
|
||||||
|
# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
|
||||||
|
onlyLabels: []
|
||||||
|
|
||||||
|
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
||||||
|
exemptLabels:
|
||||||
|
- pinned
|
||||||
|
- security
|
||||||
|
- "[Status] Maybe Later"
|
||||||
|
|
||||||
|
# Set to true to ignore issues in a project (defaults to false)
|
||||||
|
exemptProjects: false
|
||||||
|
|
||||||
|
# Set to true to ignore issues in a milestone (defaults to false)
|
||||||
|
exemptMilestones: false
|
||||||
|
|
||||||
|
# Set to true to ignore issues with an assignee (defaults to false)
|
||||||
|
exemptAssignees: false
|
||||||
|
|
||||||
|
# Label to use when marking as stale
|
||||||
|
staleLabel: wontfix
|
||||||
|
|
||||||
|
# Comment to post when marking as stale. Set to `false` to disable
|
||||||
|
markComment: >
|
||||||
|
This issue has been automatically marked as stale because it has not had
|
||||||
|
recent activity. It will be closed if no further activity occurs. Thank you
|
||||||
|
for your contributions.
|
||||||
|
|
||||||
|
# Comment to post when removing the stale label.
|
||||||
|
# unmarkComment: >
|
||||||
|
# Your comment here.
|
||||||
|
|
||||||
|
# Comment to post when closing a stale Issue or Pull Request.
|
||||||
|
# closeComment: >
|
||||||
|
# Your comment here.
|
||||||
|
|
||||||
|
# Limit the number of actions per hour, from 1-30. Default is 30
|
||||||
|
limitPerRun: 30
|
||||||
|
|
||||||
|
# Limit to only `issues` or `pulls`
|
||||||
|
# only: issues
|
||||||
|
|
||||||
|
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
|
||||||
|
# pulls:
|
||||||
|
# daysUntilStale: 30
|
||||||
|
# markComment: >
|
||||||
|
# This pull request has been automatically marked as stale because it has not had
|
||||||
|
# recent activity. It will be closed if no further activity occurs. Thank you
|
||||||
|
# for your contributions.
|
||||||
|
|
||||||
|
# issues:
|
||||||
|
# exemptLabels:
|
||||||
|
# - confirmed
|
|
@ -83,6 +83,7 @@ android {
|
||||||
kapt {
|
kapt {
|
||||||
generateStubs = true
|
generateStubs = true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def getProperties(String fileName) {
|
def getProperties(String fileName) {
|
||||||
|
@ -107,9 +108,9 @@ dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation project(':appthemehelper')
|
implementation project(':appthemehelper')
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
implementation 'androidx.fragment:fragment:1.2.0-alpha04'
|
implementation 'androidx.fragment:fragment:1.2.0-beta02'
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta04'
|
implementation 'androidx.recyclerview:recyclerview:1.1.0-beta05'
|
||||||
implementation "androidx.gridlayout:gridlayout:1.0.0"
|
implementation "androidx.gridlayout:gridlayout:1.0.0"
|
||||||
implementation "androidx.cardview:cardview:1.0.0"
|
implementation "androidx.cardview:cardview:1.0.0"
|
||||||
implementation "androidx.palette:palette:1.0.0"
|
implementation "androidx.palette:palette:1.0.0"
|
||||||
|
@ -118,12 +119,12 @@ dependencies {
|
||||||
implementation 'androidx.palette:palette-ktx:1.0.0'
|
implementation 'androidx.palette:palette-ktx:1.0.0'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
|
|
||||||
implementation 'com.google.android.material:material:1.1.0-beta01'
|
implementation 'com.google.android.material:material:1.2.0-alpha01'
|
||||||
implementation 'com.google.android.play:core:1.6.3'
|
implementation 'com.google.android.play:core:1.6.3'
|
||||||
|
|
||||||
implementation 'com.squareup.retrofit2:retrofit:2.6.1'
|
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
|
||||||
implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
|
implementation 'com.squareup.retrofit2:converter-gson:2.6.2'
|
||||||
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.1'
|
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.2'
|
||||||
|
|
||||||
implementation 'com.afollestad.material-dialogs:core:3.1.1'
|
implementation 'com.afollestad.material-dialogs:core:3.1.1'
|
||||||
implementation 'com.afollestad.material-dialogs:input:3.1.1'
|
implementation 'com.afollestad.material-dialogs:input:3.1.1'
|
||||||
|
@ -147,6 +148,10 @@ dependencies {
|
||||||
|
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"
|
||||||
|
|
||||||
|
|
||||||
implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:3.4.0.201406110918-r'
|
implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:3.4.0.201406110918-r'
|
||||||
|
|
||||||
implementation 'com.github.ksoichiro:android-observablescrollview:1.6.0'
|
implementation 'com.github.ksoichiro:android-observablescrollview:1.6.0'
|
||||||
|
@ -163,4 +168,3 @@ dependencies {
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Hemanth Savarala.
|
||||||
|
*
|
||||||
|
* Licensed under the GNU General Public License v3
|
||||||
|
*
|
||||||
|
* This is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package code.name.monkey.retromusic
|
||||||
|
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by hemanths on 2019-10-23.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class AppExecutors constructor(
|
||||||
|
val ioContext: CoroutineContext = Dispatchers.IO,
|
||||||
|
val uiContext: CoroutineContext = Dispatchers.Main
|
||||||
|
)
|
24
app/src/main/java/code/name/monkey/retromusic/Result.kt
Normal file
24
app/src/main/java/code/name/monkey/retromusic/Result.kt
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Hemanth Savarala.
|
||||||
|
*
|
||||||
|
* Licensed under the GNU General Public License v3
|
||||||
|
*
|
||||||
|
* This is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package code.name.monkey.retromusic
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by hemanths on 2019-10-23.
|
||||||
|
*/
|
||||||
|
|
||||||
|
sealed class Result<out T : Any> {
|
||||||
|
class Success<out T : Any>(val data: T) : Result<T>()
|
||||||
|
class Error(val exception: Throwable) : Result<Nothing>()
|
||||||
|
}
|
|
@ -129,7 +129,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
|
||||||
val uri = intent.data
|
val uri = intent.data
|
||||||
val mimeType = intent.type
|
val mimeType = intent.type
|
||||||
var handled = false
|
var handled = false
|
||||||
println("uri -> $uri")
|
|
||||||
if (intent.action != null && intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) {
|
if (intent.action != null && intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) {
|
||||||
val songs = SearchQueryHelper.getSongs(this, intent.extras!!)
|
val songs = SearchQueryHelper.getSongs(this, intent.extras!!)
|
||||||
if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
|
if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
|
||||||
|
|
|
@ -25,6 +25,7 @@ import code.name.monkey.retromusic.model.Playlist
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter
|
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter
|
||||||
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsView
|
import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsView
|
||||||
|
import code.name.monkey.retromusic.util.DensityUtil
|
||||||
import code.name.monkey.retromusic.util.PlaylistsUtil
|
import code.name.monkey.retromusic.util.PlaylistsUtil
|
||||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||||
import code.name.monkey.retromusic.util.ViewUtil
|
import code.name.monkey.retromusic.util.ViewUtil
|
||||||
|
@ -50,6 +51,9 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
setDrawUnderStatusBar()
|
setDrawUnderStatusBar()
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
App.musicComponent.inject(this)
|
||||||
|
|
||||||
|
playlistSongsPresenter.attachView(this)
|
||||||
|
|
||||||
setStatusbarColor(Color.TRANSPARENT)
|
setStatusbarColor(Color.TRANSPARENT)
|
||||||
setNavigationbarColorAuto()
|
setNavigationbarColorAuto()
|
||||||
|
@ -65,10 +69,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
App.musicComponent.inject(this)
|
|
||||||
|
|
||||||
playlistSongsPresenter.attachView(this)
|
|
||||||
|
|
||||||
setUpToolBar()
|
setUpToolBar()
|
||||||
setUpRecyclerView()
|
setUpRecyclerView()
|
||||||
}
|
}
|
||||||
|
@ -160,14 +160,12 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
override fun onMediaStoreChanged() {
|
||||||
super.onMediaStoreChanged()
|
super.onMediaStoreChanged()
|
||||||
|
|
||||||
if (playlist !is AbsCustomPlaylist) {
|
if (playlist !is AbsCustomPlaylist) {
|
||||||
// Playlist deleted
|
// Playlist deleted
|
||||||
if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) {
|
if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) {
|
||||||
finish()
|
finish()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Playlist renamed
|
// Playlist renamed
|
||||||
val playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id.toLong())
|
val playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id.toLong())
|
||||||
if (playlistName != playlist.name) {
|
if (playlistName != playlist.name) {
|
||||||
|
@ -182,8 +180,13 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli
|
||||||
supportActionBar!!.title = title
|
supportActionBar!!.title = title
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIsEmpty() {
|
private fun checkForPadding() {
|
||||||
|
val height = DensityUtil.dip2px(this, 52f)
|
||||||
|
recyclerView.setPadding(0, 0, 0, (height ))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkIsEmpty() {
|
||||||
|
checkForPadding()
|
||||||
empty.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
empty.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||||
emptyText.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
emptyText.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
package code.name.monkey.retromusic.activities
|
package code.name.monkey.retromusic.activities
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.app.SearchManager
|
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.ActivityNotFoundException
|
import android.content.ActivityNotFoundException
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
@ -77,6 +75,10 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch
|
||||||
keyboardPopup.setTextColor(this)
|
keyboardPopup.setTextColor(this)
|
||||||
keyboardPopup.iconTint = this
|
keyboardPopup.iconTint = this
|
||||||
}
|
}
|
||||||
|
if (savedInstanceState != null) {
|
||||||
|
query = savedInstanceState.getString(QUERY);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupRecyclerView() {
|
private fun setupRecyclerView() {
|
||||||
|
@ -104,15 +106,9 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupSearchView() {
|
private fun setupSearchView() {
|
||||||
getSystemService(Context.SEARCH_SERVICE) as SearchManager
|
|
||||||
searchView.addTextChangedListener(this)
|
searchView.addTextChangedListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
searchPresenter.search(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
searchPresenter.detachView()
|
searchPresenter.detachView()
|
||||||
|
@ -123,11 +119,6 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch
|
||||||
outState.putString(QUERY, query)
|
outState.putString(QUERY, query)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
|
|
||||||
super.onRestoreInstanceState(savedInstanceState)
|
|
||||||
searchPresenter.search(savedInstanceState.getString(QUERY, ""))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setUpToolBar() {
|
private fun setUpToolBar() {
|
||||||
title = null
|
title = null
|
||||||
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
appBarLayout.setBackgroundColor(ATHUtil.resolveColor(this, R.attr.colorPrimary))
|
||||||
|
@ -135,14 +126,14 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch
|
||||||
|
|
||||||
|
|
||||||
private fun search(query: String) {
|
private fun search(query: String) {
|
||||||
this.query = query.trim { it <= ' ' }
|
this.query = query
|
||||||
voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE
|
voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE
|
||||||
searchPresenter.search(query)
|
searchPresenter.search(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMediaStoreChanged() {
|
override fun onMediaStoreChanged() {
|
||||||
super.onMediaStoreChanged()
|
super.onMediaStoreChanged()
|
||||||
searchPresenter.search(query!!)
|
query?.let { search(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onQueryTextSubmit(query: String): Boolean {
|
override fun onQueryTextSubmit(query: String): Boolean {
|
||||||
|
|
|
@ -16,27 +16,21 @@ import code.name.monkey.retromusic.extensions.show
|
||||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.Album
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.Artist
|
||||||
|
import code.name.monkey.retromusic.model.Home
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
import code.name.monkey.retromusic.model.Playlist
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
import com.google.android.material.textview.MaterialTextView
|
import com.google.android.material.textview.MaterialTextView
|
||||||
|
|
||||||
|
|
||||||
class HomeAdapter(
|
class HomeAdapter(
|
||||||
private val activity: AppCompatActivity,
|
private val activity: AppCompatActivity,
|
||||||
private val displayMetrics: DisplayMetrics,
|
private val displayMetrics: DisplayMetrics
|
||||||
private val repository: Repository
|
|
||||||
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
|
private var list = ArrayList<Home>()
|
||||||
|
|
||||||
override fun getItemViewType(position: Int): Int {
|
override fun getItemViewType(position: Int): Int {
|
||||||
return when (position) {
|
return list[position].homeSection
|
||||||
0 -> TOP_ARTISTS
|
|
||||||
1 -> TOP_ALBUMS
|
|
||||||
2 -> RECENT_ARTISTS
|
|
||||||
3 -> RECENT_ALBUMS
|
|
||||||
4 -> PLAYLISTS
|
|
||||||
else -> -1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
@ -51,35 +45,39 @@ class HomeAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
println(getItemViewType(position))
|
println("ViewType ${getItemViewType(position)}")
|
||||||
when (getItemViewType(position)) {
|
when (getItemViewType(position)) {
|
||||||
RECENT_ALBUMS -> {
|
RECENT_ALBUMS -> {
|
||||||
val viewHolder = holder as AlbumViewHolder
|
val viewHolder = holder as AlbumViewHolder
|
||||||
viewHolder.bindView(repository.recentAlbums(), R.string.recent_albums, R.string.recent_added_albums)
|
viewHolder.bindView(list[position].arrayList.toAlbums(), R.string.recent_albums, R.string.recent_added_albums)
|
||||||
}
|
}
|
||||||
TOP_ALBUMS -> {
|
TOP_ALBUMS -> {
|
||||||
val viewHolder = holder as AlbumViewHolder
|
val viewHolder = holder as AlbumViewHolder
|
||||||
|
viewHolder.bindView(list[position].arrayList.toAlbums(), R.string.top_albums, R.string.most_played_albums)
|
||||||
viewHolder.bindView(repository.topAlbums(), R.string.top_albums, R.string.most_played_albums)
|
|
||||||
}
|
}
|
||||||
RECENT_ARTISTS -> {
|
RECENT_ARTISTS -> {
|
||||||
val viewHolder = holder as ArtistViewHolder
|
val viewHolder = holder as ArtistViewHolder
|
||||||
viewHolder.bindView(repository.recentArtists(), R.string.recent_artists, R.string.recent_added_artists)
|
viewHolder.bindView(list[position].arrayList.toArtists(), R.string.recent_artists, R.string.recent_added_artists)
|
||||||
}
|
}
|
||||||
TOP_ARTISTS -> {
|
TOP_ARTISTS -> {
|
||||||
val viewHolder = holder as ArtistViewHolder
|
val viewHolder = holder as ArtistViewHolder
|
||||||
|
|
||||||
viewHolder.bindView(repository.recentArtists(), R.string.top_artists, R.string.most_played_artists)
|
viewHolder.bindView(list[position].arrayList.toArtists(), R.string.top_artists, R.string.most_played_artists)
|
||||||
}
|
}
|
||||||
PLAYLISTS -> {
|
PLAYLISTS -> {
|
||||||
val viewHolder = holder as PlaylistViewHolder
|
val viewHolder = holder as PlaylistViewHolder
|
||||||
viewHolder.bindView(repository.favoritePlaylist, R.string.favorites, R.string.favorites_songs)
|
viewHolder.bindView(list[position].arrayList as ArrayList<Playlist>, R.string.favorites, R.string.favorites_songs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
return 5
|
return list.size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun swapData(sections: ArrayList<Home>) {
|
||||||
|
list = sections
|
||||||
|
notifyDataSetChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -108,6 +106,8 @@ class HomeAdapter(
|
||||||
text.text = activity.getString(subtitleRes)
|
text.text = activity.getString(subtitleRes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
|
inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
|
||||||
|
@ -154,3 +154,20 @@ class HomeAdapter(
|
||||||
val text: MaterialTextView = itemView.findViewById(R.id.text)
|
val text: MaterialTextView = itemView.findViewById(R.id.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <E> ArrayList<E>.toAlbums(): ArrayList<Album> {
|
||||||
|
val arrayList = ArrayList<Album>()
|
||||||
|
for (x in this) {
|
||||||
|
arrayList.add(x as Album)
|
||||||
|
}
|
||||||
|
return arrayList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <E> ArrayList<E>.toArtists(): ArrayList<Artist> {
|
||||||
|
val arrayList = ArrayList<Artist>()
|
||||||
|
for (x in this) {
|
||||||
|
arrayList.add(x as Artist)
|
||||||
|
}
|
||||||
|
return arrayList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.util.MusicUtil
|
import code.name.monkey.retromusic.util.MusicUtil
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.NavigationUtil
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import java.util.*
|
|
||||||
import android.util.Pair as UtilPair
|
import android.util.Pair as UtilPair
|
||||||
|
|
||||||
class SearchAdapter(
|
class SearchAdapter(
|
||||||
|
@ -57,7 +56,7 @@ class SearchAdapter(
|
||||||
holder.title?.text = artist.name
|
holder.title?.text = artist.name
|
||||||
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
|
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
|
||||||
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
|
ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
|
||||||
.build().into(holder.image);
|
.build().into(holder.image)
|
||||||
}
|
}
|
||||||
SONG -> {
|
SONG -> {
|
||||||
val song = dataSet?.get(position) as Song
|
val song = dataSet?.get(position) as Song
|
||||||
|
@ -79,16 +78,14 @@ class SearchAdapter(
|
||||||
init {
|
init {
|
||||||
itemView.setOnLongClickListener(null)
|
itemView.setOnLongClickListener(null)
|
||||||
|
|
||||||
if (menu != null) {
|
|
||||||
if (itemViewType == SONG) {
|
if (itemViewType == SONG) {
|
||||||
menu!!.visibility = View.VISIBLE
|
menu?.visibility = View.VISIBLE
|
||||||
menu!!.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
menu?.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
|
||||||
override val song: Song
|
override val song: Song
|
||||||
get() = dataSet!![adapterPosition] as Song
|
get() = dataSet!![adapterPosition] as Song
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
menu!!.visibility = View.GONE
|
menu?.visibility = View.GONE
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
when (itemViewType) {
|
when (itemViewType) {
|
||||||
|
@ -126,7 +123,6 @@ class SearchAdapter(
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private const val HEADER = 0
|
private const val HEADER = 0
|
||||||
private const val ALBUM = 1
|
private const val ALBUM = 1
|
||||||
private const val ARTIST = 2
|
private const val ARTIST = 2
|
||||||
|
|
|
@ -215,9 +215,7 @@ class PlaylistAdapter(protected val activity: AppCompatActivity, dataSet: ArrayL
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val TAG: String = PlaylistAdapter::class.java.simpleName
|
val TAG: String = PlaylistAdapter::class.java.simpleName
|
||||||
|
|
||||||
private const val SMART_PLAYLIST = 0
|
private const val SMART_PLAYLIST = 0
|
||||||
private const val DEFAULT_PLAYLIST = 1
|
private const val DEFAULT_PLAYLIST = 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ abstract class AbsLibraryPagerRecyclerViewFragment<A : RecyclerView.Adapter<*>,
|
||||||
|
|
||||||
private fun initAdapter() {
|
private fun initAdapter() {
|
||||||
adapter = createAdapter()
|
adapter = createAdapter()
|
||||||
adapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
adapter?.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
|
||||||
override fun onChanged() {
|
override fun onChanged() {
|
||||||
super.onChanged()
|
super.onChanged()
|
||||||
checkIsEmpty()
|
checkIsEmpty()
|
||||||
|
|
|
@ -2,7 +2,6 @@ package code.name.monkey.retromusic.fragments.mainactivity.home
|
||||||
|
|
||||||
import android.app.ActivityOptions
|
import android.app.ActivityOptions
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Color
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.DisplayMetrics
|
import android.util.DisplayMetrics
|
||||||
import android.view.*
|
import android.view.*
|
||||||
|
@ -18,7 +17,6 @@ import code.name.monkey.retromusic.Constants.USER_BANNER
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import code.name.monkey.retromusic.adapter.HomeAdapter
|
import code.name.monkey.retromusic.adapter.HomeAdapter
|
||||||
import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment
|
import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment
|
||||||
import code.name.monkey.retromusic.extensions.hide
|
|
||||||
import code.name.monkey.retromusic.extensions.show
|
import code.name.monkey.retromusic.extensions.show
|
||||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||||
|
@ -28,8 +26,8 @@ import code.name.monkey.retromusic.model.Home
|
||||||
import code.name.monkey.retromusic.model.smartplaylist.HistoryPlaylist
|
import code.name.monkey.retromusic.model.smartplaylist.HistoryPlaylist
|
||||||
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
|
import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
|
||||||
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist
|
import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist
|
||||||
|
import code.name.monkey.retromusic.mvp.presenter.HomePresenter
|
||||||
import code.name.monkey.retromusic.mvp.presenter.HomeView
|
import code.name.monkey.retromusic.mvp.presenter.HomeView
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
|
||||||
import code.name.monkey.retromusic.util.Compressor
|
import code.name.monkey.retromusic.util.Compressor
|
||||||
import code.name.monkey.retromusic.util.NavigationUtil
|
import code.name.monkey.retromusic.util.NavigationUtil
|
||||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||||
|
@ -49,19 +47,14 @@ import javax.inject.Inject
|
||||||
class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallbacks, HomeView {
|
class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallbacks, HomeView {
|
||||||
private lateinit var homeAdapter: HomeAdapter
|
private lateinit var homeAdapter: HomeAdapter
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var repository: Repository
|
lateinit var homePresenter: HomePresenter
|
||||||
|
|
||||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
private lateinit var toolbar: Toolbar
|
private lateinit var toolbar: Toolbar
|
||||||
|
|
||||||
override fun sections(sections: ArrayList<Home>) {
|
override fun sections(sections: ArrayList<Home>) {
|
||||||
val finalList = sections.sortedWith(compareBy { it.priority })
|
println(sections.size)
|
||||||
|
homeAdapter.swapData(sections)
|
||||||
if (sections.isEmpty()) {
|
|
||||||
showEmptyView()
|
|
||||||
} else {
|
|
||||||
emptyContainer.hide()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, viewGroup: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, viewGroup: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
|
@ -133,17 +126,18 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
|
||||||
titleWelcome.text = String.format("%s", PreferenceUtil.getInstance(requireContext()).userName)
|
titleWelcome.text = String.format("%s", PreferenceUtil.getInstance(requireContext()).userName)
|
||||||
|
|
||||||
App.musicComponent.inject(this)
|
App.musicComponent.inject(this)
|
||||||
homeAdapter = HomeAdapter(mainActivity, displayMetrics, repository)
|
homeAdapter = HomeAdapter(mainActivity, displayMetrics)
|
||||||
|
|
||||||
recyclerView.apply {
|
recyclerView.apply {
|
||||||
layoutManager = LinearLayoutManager(mainActivity)
|
layoutManager = LinearLayoutManager(mainActivity)
|
||||||
adapter = homeAdapter
|
adapter = homeAdapter
|
||||||
}
|
}
|
||||||
|
homePresenter.attachView(this)
|
||||||
|
homePresenter.loadSections()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun toolbarColor(): Int {
|
private fun toolbarColor(): Int {
|
||||||
return if (PreferenceUtil.getInstance(requireContext()).isHomeBanner) {
|
return if (PreferenceUtil.getInstance(requireContext()).isHomeBanner) {
|
||||||
toolbarContainer.setBackgroundColor(Color.TRANSPARENT)
|
|
||||||
ColorUtil.withAlpha(RetroColorUtil.toolbarColor(mainActivity), 0.85f)
|
ColorUtil.withAlpha(RetroColorUtil.toolbarColor(mainActivity), 0.85f)
|
||||||
} else {
|
} else {
|
||||||
RetroColorUtil.toolbarColor(mainActivity)
|
RetroColorUtil.toolbarColor(mainActivity)
|
||||||
|
@ -176,6 +170,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
disposable.dispose()
|
disposable.dispose()
|
||||||
|
homePresenter.detachView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showEmptyView() {
|
override fun showEmptyView() {
|
||||||
|
|
|
@ -16,7 +16,6 @@ package code.name.monkey.retromusic.loaders
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.R
|
||||||
import io.reactivex.Observable
|
|
||||||
|
|
||||||
|
|
||||||
object SearchLoader {
|
object SearchLoader {
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Hemanth Savarala.
|
||||||
|
*
|
||||||
|
* Licensed under the GNU General Public License v3
|
||||||
|
*
|
||||||
|
* This is free software: you can redistribute it and/or modify it under
|
||||||
|
* the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package code.name.monkey.retromusic.misc
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.text.TextUtils
|
||||||
|
import code.name.monkey.retromusic.R
|
||||||
|
import code.name.monkey.retromusic.loaders.AlbumLoader
|
||||||
|
import code.name.monkey.retromusic.loaders.ArtistLoader
|
||||||
|
import code.name.monkey.retromusic.loaders.SongLoader
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
internal class AsyncSearchResultLoader(context: Context, private val query: String) : WrappedAsyncTaskLoader<List<Any>>(context) {
|
||||||
|
|
||||||
|
override fun loadInBackground(): List<Any>? {
|
||||||
|
val results = ArrayList<Any>()
|
||||||
|
if (!TextUtils.isEmpty(query)) {
|
||||||
|
val songs = SongLoader.getSongs(context, query.trim { it <= ' ' })
|
||||||
|
if (!songs.isEmpty()) {
|
||||||
|
results.add(context.resources.getString(R.string.songs))
|
||||||
|
results.addAll(songs)
|
||||||
|
}
|
||||||
|
|
||||||
|
val artists = ArtistLoader.getArtists(context, query.trim { it <= ' ' })
|
||||||
|
if (!artists.isEmpty()) {
|
||||||
|
results.add(context.resources.getString(R.string.artists))
|
||||||
|
results.addAll(artists)
|
||||||
|
}
|
||||||
|
|
||||||
|
val albums = AlbumLoader.getAlbums(context, query.trim { it <= ' ' })
|
||||||
|
if (!albums.isEmpty()) {
|
||||||
|
results.add(context.resources.getString(R.string.albums))
|
||||||
|
results.addAll(albums)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,13 +14,17 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp
|
package code.name.monkey.retromusic.mvp
|
||||||
|
|
||||||
|
import androidx.annotation.CallSuper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hemanths on 16/08/17.
|
* Created by hemanths on 16/08/17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
interface Presenter<T> {
|
interface Presenter<T> {
|
||||||
|
@CallSuper
|
||||||
fun attachView(view: T)
|
fun attachView(view: T)
|
||||||
|
|
||||||
|
@CallSuper
|
||||||
fun detachView()
|
fun detachView()
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,16 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.Album
|
import code.name.monkey.retromusic.model.Album
|
||||||
import code.name.monkey.retromusic.mvp.BaseView
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import io.reactivex.disposables.Disposable
|
import kotlinx.coroutines.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,22 +39,30 @@ interface AlbumsPresenter : Presenter<AlbumsView> {
|
||||||
|
|
||||||
class AlbumsPresenterImpl @Inject constructor(
|
class AlbumsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<AlbumsView>(), AlbumsPresenter {
|
) : PresenterImpl<AlbumsView>(), AlbumsPresenter, CoroutineScope {
|
||||||
|
private val job = Job()
|
||||||
|
|
||||||
private var disposable: Disposable? = null
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.IO + job
|
||||||
private fun showList(albums: ArrayList<Album>) {
|
|
||||||
view?.albums(albums)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun detachView() {
|
override fun detachView() {
|
||||||
super.detachView()
|
super.detachView()
|
||||||
disposable?.dispose()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadAlbums() {
|
override fun loadAlbums() {
|
||||||
disposable = repository.allAlbumsFlowable
|
launch {
|
||||||
.subscribe({ view?.albums(it) }, { t -> println(t) })
|
when (val result = repository.allAlbums()) {
|
||||||
|
is Result.Success -> {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
view?.albums(result.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Result.Error -> {
|
||||||
|
view?.showEmptyView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,13 +14,15 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.Artist
|
import code.name.monkey.retromusic.model.Artist
|
||||||
import code.name.monkey.retromusic.mvp.BaseView
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import io.reactivex.disposables.Disposable
|
import kotlinx.coroutines.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
interface ArtistsView : BaseView {
|
interface ArtistsView : BaseView {
|
||||||
fun artists(artists: ArrayList<Artist>)
|
fun artists(artists: ArrayList<Artist>)
|
||||||
|
@ -32,18 +34,26 @@ interface ArtistsPresenter : Presenter<ArtistsView> {
|
||||||
|
|
||||||
class ArtistsPresenterImpl @Inject constructor(
|
class ArtistsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<ArtistsView>(), ArtistsPresenter {
|
) : PresenterImpl<ArtistsView>(), ArtistsPresenter, CoroutineScope {
|
||||||
|
private val job = Job()
|
||||||
|
|
||||||
private var disposable: Disposable? = null
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
override fun detachView() {
|
override fun detachView() {
|
||||||
super.detachView()
|
super.detachView()
|
||||||
disposable?.dispose()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun loadArtists() {
|
override fun loadArtists() {
|
||||||
disposable = repository.allArtistsFlowable
|
launch {
|
||||||
.subscribe({ view?.artists(it) }, { t -> println(t) })
|
when (val result = repository.allArtists()) {
|
||||||
|
is Result.Success -> withContext(Dispatchers.Main) {
|
||||||
|
view?.artists(result.data)
|
||||||
|
}
|
||||||
|
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,16 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.mvp.BaseView
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import io.reactivex.disposables.Disposable
|
import kotlinx.coroutines.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,18 +39,29 @@ interface GenreDetailsPresenter : Presenter<GenreDetailsView> {
|
||||||
|
|
||||||
class GenreDetailsPresenterImpl @Inject constructor(
|
class GenreDetailsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<GenreDetailsView>(), GenreDetailsPresenter {
|
) : PresenterImpl<GenreDetailsView>(), GenreDetailsPresenter, CoroutineScope {
|
||||||
|
private val job = Job()
|
||||||
|
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
override fun detachView() {
|
override fun detachView() {
|
||||||
super.detachView()
|
super.detachView()
|
||||||
disposable?.dispose()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var disposable: Disposable? = null
|
|
||||||
|
|
||||||
override fun loadGenreSongs(genreId: Int) {
|
override fun loadGenreSongs(genreId: Int) {
|
||||||
disposable = repository.getGenreFlowable(genreId)
|
launch {
|
||||||
.subscribe({ view?.songs(it) }, { t -> println(t) })
|
when (val result = repository.getGenre(genreId)) {
|
||||||
|
is Result.Success -> withContext(Dispatchers.Main) {
|
||||||
|
view?.songs(result.data)
|
||||||
|
}
|
||||||
|
is Result.Error -> withContext(Dispatchers.Main) {
|
||||||
|
view?.showEmptyView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,16 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.Genre
|
import code.name.monkey.retromusic.model.Genre
|
||||||
import code.name.monkey.retromusic.mvp.BaseView
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import io.reactivex.disposables.Disposable
|
import kotlinx.coroutines.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Hemanth S (h4h13).
|
* @author Hemanth S (h4h13).
|
||||||
|
@ -35,13 +37,26 @@ interface GenresPresenter : Presenter<GenresView> {
|
||||||
|
|
||||||
class GenresPresenterImpl @Inject constructor(
|
class GenresPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<GenresView>(), GenresPresenter {
|
) : PresenterImpl<GenresView>(), GenresPresenter, CoroutineScope {
|
||||||
|
private val job = Job()
|
||||||
|
|
||||||
private var disposable: Disposable? = null
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
|
override fun detachView() {
|
||||||
|
super.detachView()
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
override fun loadGenres() {
|
override fun loadGenres() {
|
||||||
disposable = repository.allGenresFlowable
|
launch {
|
||||||
.subscribe({ view.genres(it) }, { t -> println(t) })
|
when (val result = repository.allGenres()) {
|
||||||
|
is Result.Success -> withContext(Dispatchers.Main) {
|
||||||
|
view?.genres(result.data)
|
||||||
|
}
|
||||||
|
is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,7 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
import code.name.monkey.retromusic.R
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.PLAYLISTS
|
|
||||||
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.RECENT_ALBUMS
|
|
||||||
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.RECENT_ARTISTS
|
|
||||||
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.TOP_ALBUMS
|
|
||||||
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.TOP_ARTISTS
|
|
||||||
import code.name.monkey.retromusic.model.Home
|
import code.name.monkey.retromusic.model.Home
|
||||||
import code.name.monkey.retromusic.mvp.BaseView
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
|
@ -27,7 +22,9 @@ import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
|
operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
|
||||||
add(disposable)
|
add(disposable)
|
||||||
|
@ -40,238 +37,38 @@ interface HomeView : BaseView {
|
||||||
interface HomePresenter : Presenter<HomeView> {
|
interface HomePresenter : Presenter<HomeView> {
|
||||||
fun loadSections()
|
fun loadSections()
|
||||||
|
|
||||||
|
|
||||||
class HomePresenterImpl @Inject constructor(
|
class HomePresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<HomeView>(), HomePresenter {
|
) : PresenterImpl<HomeView>(), HomePresenter, CoroutineScope {
|
||||||
|
private val job = Job()
|
||||||
|
|
||||||
private val hashSet: HashSet<Home> = HashSet()
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
|
override fun detachView() {
|
||||||
|
super.detachView()
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
override fun loadSections() {
|
override fun loadSections() {
|
||||||
loadRecentArtists()
|
launch {
|
||||||
loadRecentAlbums()
|
val list = ArrayList<Home>()
|
||||||
loadTopArtists()
|
val recentArtistResult = listOf(
|
||||||
loadATopAlbums()
|
repository.topArtists(),
|
||||||
loadFavorite()
|
repository.topAlbums(),
|
||||||
//loadHomeSection()
|
repository.recentArtists(),
|
||||||
}
|
repository.recentAlbums(),
|
||||||
|
repository.favoritePlaylist()
|
||||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
)
|
||||||
|
for (r in recentArtistResult) {
|
||||||
private fun showData(sections: ArrayList<Home>) {
|
when (r) {
|
||||||
if (sections.isEmpty()) {
|
is Result.Success -> list.add(r.data)
|
||||||
view.showEmptyView()
|
|
||||||
} else {
|
|
||||||
view.sections(sections)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
private fun loadRecentArtists() {
|
if (list.isNotEmpty()) view?.sections(list) else view?.showEmptyView()
|
||||||
disposable += repository.recentArtistsFlowable
|
|
||||||
.subscribe {
|
|
||||||
if (it.isNotEmpty()) hashSet.add(
|
|
||||||
Home(0,
|
|
||||||
R.string.recent_artists,
|
|
||||||
R.string.recent_added_artists,
|
|
||||||
it,
|
|
||||||
RECENT_ARTISTS,
|
|
||||||
R.drawable.ic_artist_white_24dp
|
|
||||||
))
|
|
||||||
showData(ArrayList(hashSet))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadRecentAlbums() {
|
|
||||||
disposable += repository.recentAlbumsFlowable
|
|
||||||
.subscribe {
|
|
||||||
if (it.isNotEmpty()) hashSet.add(
|
|
||||||
Home(1,
|
|
||||||
R.string.recent_albums,
|
|
||||||
R.string.recent_added_albums,
|
|
||||||
it,
|
|
||||||
RECENT_ALBUMS,
|
|
||||||
R.drawable.ic_album_white_24dp
|
|
||||||
))
|
|
||||||
showData(ArrayList(hashSet))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadTopArtists() {
|
|
||||||
disposable += repository.topArtistsFlowable
|
|
||||||
.subscribe {
|
|
||||||
if (it.isNotEmpty()) hashSet.add(
|
|
||||||
Home(2,
|
|
||||||
R.string.top_artists,
|
|
||||||
R.string.most_played_artists,
|
|
||||||
it,
|
|
||||||
TOP_ARTISTS,
|
|
||||||
R.drawable.ic_artist_white_24dp
|
|
||||||
))
|
|
||||||
showData(ArrayList(hashSet))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadATopAlbums() {
|
|
||||||
disposable += repository.topAlbumsFlowable
|
|
||||||
.subscribe {
|
|
||||||
if (it.isNotEmpty()) hashSet.add(
|
|
||||||
Home(3,
|
|
||||||
R.string.top_albums,
|
|
||||||
R.string.most_played_albums,
|
|
||||||
it,
|
|
||||||
TOP_ALBUMS,
|
|
||||||
R.drawable.ic_album_white_24dp
|
|
||||||
))
|
|
||||||
showData(ArrayList(hashSet))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadFavorite() {
|
|
||||||
disposable += repository.favoritePlaylistFlowable
|
|
||||||
.subscribe {
|
|
||||||
if (it.isNotEmpty()) hashSet.add(
|
|
||||||
Home(4,
|
|
||||||
R.string.favorites,
|
|
||||||
R.string.favorites_songs,
|
|
||||||
it,
|
|
||||||
PLAYLISTS,
|
|
||||||
R.drawable.ic_favorite_white_24dp
|
|
||||||
))
|
|
||||||
showData(ArrayList(hashSet))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*private fun loadHomeSection() {
|
|
||||||
val ob = listOf(repository.recentArtistsFlowable,
|
|
||||||
repository.recentAlbumsFlowable,
|
|
||||||
repository.topArtistsFlowable,
|
|
||||||
repository.topAlbumsFlowable,
|
|
||||||
repository.favoritePlaylistFlowable)
|
|
||||||
|
|
||||||
disposable += Observable.combineLatest(ob) {
|
|
||||||
val hashSet: HashSet<Home> = HashSet()
|
|
||||||
val recentArtist = it[0] as ArrayList<Artist>
|
|
||||||
if (recentArtist.isNotEmpty()) hashSet.add(
|
|
||||||
Home(0,
|
|
||||||
R.string.recent_artists,
|
|
||||||
0,
|
|
||||||
recentArtist,
|
|
||||||
RECENT_ARTISTS,
|
|
||||||
R.drawable.ic_artist_white_24dp
|
|
||||||
))
|
|
||||||
val recentAlbums = it[1] as ArrayList<Album>
|
|
||||||
if (recentAlbums.isNotEmpty()) hashSet.add(
|
|
||||||
Home(1,
|
|
||||||
R.string.recent_albums,
|
|
||||||
0,
|
|
||||||
recentAlbums,
|
|
||||||
RECENT_ALBUMS,
|
|
||||||
R.drawable.ic_album_white_24dp
|
|
||||||
))
|
|
||||||
val topArtists = it[2] as ArrayList<Artist>
|
|
||||||
if (topArtists.isNotEmpty()) hashSet.add(
|
|
||||||
Home(2,
|
|
||||||
R.string.top_artists,
|
|
||||||
0,
|
|
||||||
topArtists,
|
|
||||||
TOP_ARTISTS,
|
|
||||||
R.drawable.ic_artist_white_24dp
|
|
||||||
))
|
|
||||||
val topAlbums = it[3] as ArrayList<Album>
|
|
||||||
if (topAlbums.isNotEmpty()) hashSet.add(
|
|
||||||
Home(3,
|
|
||||||
R.string.top_albums,
|
|
||||||
0,
|
|
||||||
topAlbums,
|
|
||||||
TOP_ALBUMS,
|
|
||||||
R.drawable.ic_album_white_24dp
|
|
||||||
))
|
|
||||||
val playlists = it[4] as ArrayList<Playlist>
|
|
||||||
if (playlists.isNotEmpty()) hashSet.add(
|
|
||||||
Home(4,
|
|
||||||
R.string.favorites,
|
|
||||||
0,
|
|
||||||
playlists,
|
|
||||||
PLAYLISTS,
|
|
||||||
R.drawable.ic_favorite_white_24dp
|
|
||||||
))
|
|
||||||
return@combineLatest hashSet
|
|
||||||
}.subscribe {
|
|
||||||
view.sections(ArrayList(it))
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*class HomePresenter(
|
|
||||||
private val view: HomeContract.HomeView,
|
|
||||||
private val repositoryImpl: RepositoryImpl
|
|
||||||
) : Presenter(), HomeContract.HomePresenter {
|
|
||||||
private val hashSet: HashSet<Home> = HashSet()
|
|
||||||
|
|
||||||
override fun homeSections() {
|
|
||||||
loadRecentArtists()
|
|
||||||
loadRecentAlbums()
|
|
||||||
loadTopArtists()
|
|
||||||
loadATopAlbums()
|
|
||||||
loadFavorite()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun subscribe() {
|
|
||||||
homeSections()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun unsubscribe() {
|
|
||||||
disposable.dispose()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadRecentArtists() {
|
|
||||||
disposable += repositoryImpl.recentArtistsFlowable
|
|
||||||
.subscribe({
|
|
||||||
if (it.isNotEmpty()) hashSet.add(Home(0, R.string.recent_artists, 0, it, RECENT_ARTISTS, R.drawable.ic_artist_white_24dp))
|
|
||||||
view.showData(ArrayList(hashSet))
|
|
||||||
}, {
|
|
||||||
view.showEmptyView()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadRecentAlbums() {
|
|
||||||
disposable += repositoryImpl.recentAlbumsFlowable
|
|
||||||
.subscribe({
|
|
||||||
if (it.isNotEmpty()) hashSet.add(Home(1, R.string.recent_albums, 0, it, RECENT_ALBUMS, R.drawable.ic_album_white_24dp))
|
|
||||||
view.showData(ArrayList(hashSet))
|
|
||||||
}, {
|
|
||||||
view.showEmptyView()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadATopAlbums() {
|
|
||||||
disposable += repositoryImpl.topAlbumsFlowable
|
|
||||||
.subscribe({
|
|
||||||
if (it.isNotEmpty()) hashSet.add(Home(3, R.string.top_albums, 0, it, TOP_ALBUMS, R.drawable.ic_album_white_24dp))
|
|
||||||
view.showData(ArrayList(hashSet))
|
|
||||||
}, {
|
|
||||||
view.showEmptyView()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadTopArtists() {
|
|
||||||
disposable += repositoryImpl.topArtistsFlowable
|
|
||||||
.subscribe({
|
|
||||||
if (it.isNotEmpty()) hashSet.add(Home(2, R.string.top_artists, 0, it, TOP_ARTISTS, R.drawable.ic_artist_white_24dp))
|
|
||||||
view.showData(ArrayList(hashSet))
|
|
||||||
}, {
|
|
||||||
view.showEmptyView()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun loadFavorite() {
|
|
||||||
disposable += repositoryImpl.favoritePlaylistFlowable
|
|
||||||
.subscribe({
|
|
||||||
if (it.isNotEmpty()) hashSet.add(Home(4, R.string.favorites, 0, it, PLAYLISTS, R.drawable.ic_favorite_white_24dp))
|
|
||||||
view.showData(ArrayList(hashSet))
|
|
||||||
}, {
|
|
||||||
view.showEmptyView()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
|
@ -14,13 +14,15 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
import code.name.monkey.retromusic.model.Playlist
|
||||||
import code.name.monkey.retromusic.mvp.BaseView
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import io.reactivex.disposables.Disposable
|
import kotlinx.coroutines.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,13 +39,29 @@ interface PlaylistsPresenter : Presenter<PlaylistView> {
|
||||||
|
|
||||||
class PlaylistsPresenterImpl @Inject constructor(
|
class PlaylistsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<PlaylistView>(), PlaylistsPresenter {
|
) : PresenterImpl<PlaylistView>(), PlaylistsPresenter, CoroutineScope {
|
||||||
|
|
||||||
private var disposable: Disposable? = null
|
private val job = Job()
|
||||||
|
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
|
override fun detachView() {
|
||||||
|
super.detachView()
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
override fun playlists() {
|
override fun playlists() {
|
||||||
disposable = repository.allPlaylistsFlowable
|
launch {
|
||||||
.subscribe({ view?.playlists(it) }, { t -> println(t) })
|
when (val result = repository.allPlaylists()) {
|
||||||
|
is Result.Success -> withContext(Dispatchers.Main) {
|
||||||
|
view?.playlists(result.data)
|
||||||
|
}
|
||||||
|
is Result.Error -> withContext(Dispatchers.Main) {
|
||||||
|
view?.showEmptyView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,16 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.Playlist
|
import code.name.monkey.retromusic.model.Playlist
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.mvp.BaseView
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import io.reactivex.disposables.Disposable
|
import kotlinx.coroutines.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hemanths on 20/08/17.
|
* Created by hemanths on 20/08/17.
|
||||||
|
@ -35,18 +37,29 @@ interface PlaylistSongsPresenter : Presenter<PlaylistSongsView> {
|
||||||
|
|
||||||
class PlaylistSongsPresenterImpl @Inject constructor(
|
class PlaylistSongsPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<PlaylistSongsView>(), PlaylistSongsPresenter {
|
) : PresenterImpl<PlaylistSongsView>(), PlaylistSongsPresenter, CoroutineScope {
|
||||||
|
|
||||||
private var disposable: Disposable? = null
|
private var job: Job = Job()
|
||||||
|
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
override fun loadPlaylistSongs(playlist: Playlist) {
|
override fun loadPlaylistSongs(playlist: Playlist) {
|
||||||
disposable = repository.getPlaylistSongsFlowable(playlist)
|
launch {
|
||||||
.subscribe({ view?.songs(it) }, { t -> println(t) })
|
when (val songs = repository.getPlaylistSongs(playlist)) {
|
||||||
|
is Result.Success -> withContext(Dispatchers.Main) {
|
||||||
|
view?.songs(songs.data)
|
||||||
|
}
|
||||||
|
is Result.Error -> withContext(Dispatchers.Main) {
|
||||||
|
view?.showEmptyView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun detachView() {
|
override fun detachView() {
|
||||||
super.detachView()
|
super.detachView()
|
||||||
disposable?.dispose()
|
job.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,19 +14,22 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result.Error
|
||||||
|
import code.name.monkey.retromusic.Result.Success
|
||||||
|
import code.name.monkey.retromusic.mvp.BaseView
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hemanths on 20/08/17.
|
* Created by hemanths on 20/08/17.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
interface SearchView {
|
interface SearchView : BaseView {
|
||||||
fun showData(data: MutableList<Any>)
|
fun showData(data: MutableList<Any>)
|
||||||
|
|
||||||
fun showEmptyView()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SearchPresenter : Presenter<SearchView> {
|
interface SearchPresenter : Presenter<SearchView> {
|
||||||
|
@ -35,18 +38,27 @@ interface SearchPresenter : Presenter<SearchView> {
|
||||||
|
|
||||||
class SearchPresenterImpl @Inject constructor(
|
class SearchPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<SearchView>(), SearchPresenter {
|
) : PresenterImpl<SearchView>(), SearchPresenter, CoroutineScope {
|
||||||
|
|
||||||
override fun attachView(view: SearchView) {
|
override val coroutineContext: CoroutineContext
|
||||||
super.attachView(view)
|
get() = Dispatchers.IO + job
|
||||||
}
|
|
||||||
|
private var job: Job = Job()
|
||||||
|
|
||||||
override fun detachView() {
|
override fun detachView() {
|
||||||
super.detachView()
|
super.detachView()
|
||||||
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun search(query: String?) {
|
override fun search(query: String?) {
|
||||||
view?.showData(repository.search(query))
|
launch {
|
||||||
|
when (val result = repository.search(query)) {
|
||||||
|
is Success -> withContext(Dispatchers.Main) {
|
||||||
|
view?.showData(result.data)
|
||||||
|
}
|
||||||
|
is Error -> withContext(Dispatchers.Main) { view?.showEmptyView() }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,13 +14,15 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.mvp.presenter
|
package code.name.monkey.retromusic.mvp.presenter
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.Song
|
import code.name.monkey.retromusic.model.Song
|
||||||
import code.name.monkey.retromusic.mvp.Presenter
|
import code.name.monkey.retromusic.mvp.Presenter
|
||||||
import code.name.monkey.retromusic.mvp.PresenterImpl
|
import code.name.monkey.retromusic.mvp.PresenterImpl
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
import io.reactivex.disposables.Disposable
|
import kotlinx.coroutines.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by hemanths on 10/08/17.
|
* Created by hemanths on 10/08/17.
|
||||||
|
@ -33,21 +35,27 @@ interface SongView {
|
||||||
|
|
||||||
interface SongPresenter : Presenter<SongView> {
|
interface SongPresenter : Presenter<SongView> {
|
||||||
fun loadSongs()
|
fun loadSongs()
|
||||||
|
|
||||||
class SongPresenterImpl @Inject constructor(
|
class SongPresenterImpl @Inject constructor(
|
||||||
private val repository: Repository
|
private val repository: Repository
|
||||||
) : PresenterImpl<SongView>(), SongPresenter {
|
) : PresenterImpl<SongView>(), SongPresenter, CoroutineScope {
|
||||||
|
|
||||||
private var disposable: Disposable? = null
|
private var job: Job = Job()
|
||||||
|
|
||||||
|
override val coroutineContext: CoroutineContext
|
||||||
|
get() = Dispatchers.IO + job
|
||||||
|
|
||||||
override fun loadSongs() {
|
override fun loadSongs() {
|
||||||
disposable = repository.allSongsFlowable
|
launch {
|
||||||
.subscribe({ view?.songs(it) }, { t -> print(t) })
|
when (val songs = repository.allSongs()) {
|
||||||
|
is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) }
|
||||||
|
is Result.Error -> view?.showEmptyView()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun detachView() {
|
override fun detachView() {
|
||||||
super.detachView()
|
super.detachView()
|
||||||
disposable?.dispose()
|
job.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,11 @@
|
||||||
package code.name.monkey.retromusic.providers
|
package code.name.monkey.retromusic.providers
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import code.name.monkey.retromusic.App
|
import code.name.monkey.retromusic.R
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
|
import code.name.monkey.retromusic.Result.Error
|
||||||
|
import code.name.monkey.retromusic.Result.Success
|
||||||
|
import code.name.monkey.retromusic.adapter.HomeAdapter
|
||||||
import code.name.monkey.retromusic.loaders.*
|
import code.name.monkey.retromusic.loaders.*
|
||||||
import code.name.monkey.retromusic.model.*
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||||
|
@ -27,6 +31,205 @@ import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
class RepositoryImpl(private val context: Context) : Repository {
|
class RepositoryImpl(private val context: Context) : Repository {
|
||||||
|
|
||||||
|
override suspend fun allAlbums(): Result<ArrayList<Album>> {
|
||||||
|
return try {
|
||||||
|
val albums = AlbumLoader.getAllAlbums(context)
|
||||||
|
if (albums.isNotEmpty()) {
|
||||||
|
Success(albums)
|
||||||
|
} else {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun allArtists(): Result<ArrayList<Artist>> {
|
||||||
|
return try {
|
||||||
|
val artists = ArtistLoader.getAllArtists(context)
|
||||||
|
if (artists.isNotEmpty()) {
|
||||||
|
Success(artists)
|
||||||
|
} else {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun allPlaylists(): Result<ArrayList<Playlist>> {
|
||||||
|
return try {
|
||||||
|
val playlists = PlaylistLoader.getAllPlaylists(context)
|
||||||
|
if (playlists.isNotEmpty()) {
|
||||||
|
Success(playlists)
|
||||||
|
} else {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun allGenres(): Result<ArrayList<Genre>> {
|
||||||
|
return try {
|
||||||
|
val genres = GenreLoader.getAllGenres(context)
|
||||||
|
if (genres.isNotEmpty()) {
|
||||||
|
Success(genres)
|
||||||
|
} else {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun search(query: String?): Result<MutableList<Any>> {
|
||||||
|
return try {
|
||||||
|
val result = SearchLoader.searchAll(context, query)
|
||||||
|
if (result.isNotEmpty()) {
|
||||||
|
Success(result)
|
||||||
|
} else {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun allSongs(): Result<ArrayList<Song>> {
|
||||||
|
return try {
|
||||||
|
val songs = SongLoader.getAllSongs(context);
|
||||||
|
if (songs.isEmpty()) {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
} else {
|
||||||
|
Success(songs);
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getPlaylistSongs(playlist: Playlist): Result<ArrayList<Song>> {
|
||||||
|
return try {
|
||||||
|
val songs: ArrayList<Song> = if (playlist is AbsCustomPlaylist) {
|
||||||
|
playlist.getSongs(context)
|
||||||
|
} else {
|
||||||
|
PlaylistSongsLoader.getPlaylistSongList(context, playlist.id)
|
||||||
|
}
|
||||||
|
Success(songs);
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun getGenre(genreId: Int): Result<ArrayList<Song>> {
|
||||||
|
return try {
|
||||||
|
val songs = GenreLoader.getSongs(context, genreId)
|
||||||
|
if (songs.isEmpty()) {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
} else {
|
||||||
|
Success(songs);
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun recentArtists(): Result<Home> {
|
||||||
|
return try {
|
||||||
|
val artists = LastAddedSongsLoader.getLastAddedArtists(context)
|
||||||
|
if (artists.isEmpty()) {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
} else {
|
||||||
|
Success(Home(0,
|
||||||
|
R.string.recent_artists,
|
||||||
|
R.string.recent_added_artists,
|
||||||
|
artists,
|
||||||
|
HomeAdapter.RECENT_ARTISTS,
|
||||||
|
R.drawable.ic_artist_white_24dp))
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun recentAlbums(): Result<Home> {
|
||||||
|
return try {
|
||||||
|
val albums = LastAddedSongsLoader.getLastAddedAlbums(context)
|
||||||
|
if (albums.isEmpty()) {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
} else {
|
||||||
|
Success(Home(1,
|
||||||
|
R.string.recent_albums,
|
||||||
|
R.string.recent_added_albums,
|
||||||
|
albums,
|
||||||
|
HomeAdapter.RECENT_ALBUMS,
|
||||||
|
R.drawable.ic_album_white_24dp
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun topAlbums(): Result<Home> {
|
||||||
|
return try {
|
||||||
|
val albums = TopAndRecentlyPlayedTracksLoader.getTopAlbums(context)
|
||||||
|
if (albums.isEmpty()) {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
} else {
|
||||||
|
Success(Home(3,
|
||||||
|
R.string.top_albums,
|
||||||
|
R.string.most_played_albums,
|
||||||
|
albums,
|
||||||
|
HomeAdapter.TOP_ALBUMS,
|
||||||
|
R.drawable.ic_album_white_24dp
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override suspend fun topArtists(): Result<Home> {
|
||||||
|
return try {
|
||||||
|
val artists = TopAndRecentlyPlayedTracksLoader.getTopArtists(context)
|
||||||
|
if (artists.isEmpty()) {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
} else {
|
||||||
|
Success(Home(2,
|
||||||
|
R.string.top_artists,
|
||||||
|
R.string.most_played_artists,
|
||||||
|
artists,
|
||||||
|
HomeAdapter.TOP_ARTISTS,
|
||||||
|
R.drawable.ic_artist_white_24dp
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun favoritePlaylist(): Result<Home> {
|
||||||
|
return try {
|
||||||
|
val playlists = PlaylistLoader.getFavoritePlaylist(context)
|
||||||
|
if (playlists.isEmpty()) {
|
||||||
|
Error(Throwable("No items found"))
|
||||||
|
} else {
|
||||||
|
Success(Home(4,
|
||||||
|
R.string.favorites,
|
||||||
|
R.string.favorites_songs,
|
||||||
|
playlists,
|
||||||
|
HomeAdapter.PLAYLISTS,
|
||||||
|
R.drawable.ic_favorite_white_24dp
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun artistInfoFloable(
|
override fun artistInfoFloable(
|
||||||
name: String,
|
name: String,
|
||||||
lang: String?,
|
lang: String?,
|
||||||
|
@ -37,41 +240,6 @@ class RepositoryImpl(private val context: Context) : Repository {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun search(query: String?): MutableList<Any> {
|
|
||||||
return SearchLoader.searchAll(context, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun allAlbums(): ArrayList<Album> {
|
|
||||||
return AlbumLoader.getAllAlbums(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun recentAlbums(): ArrayList<Album> {
|
|
||||||
return LastAddedSongsLoader.getLastAddedAlbums(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun topAlbums(): ArrayList<Album> {
|
|
||||||
return TopAndRecentlyPlayedTracksLoader.getTopAlbums(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun allArtists(): ArrayList<Artist> {
|
|
||||||
return ArtistLoader.getAllArtists(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun recentArtists(): ArrayList<Artist> {
|
|
||||||
return LastAddedSongsLoader.getLastAddedArtists(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun topArtists(): ArrayList<Artist> {
|
|
||||||
return TopAndRecentlyPlayedTracksLoader.getTopArtists(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun allPlaylists(): ArrayList<Playlist> {
|
|
||||||
return PlaylistLoader.getAllPlaylists(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun allGenres(): ArrayList<Genre> {
|
|
||||||
return GenreLoader.getAllGenres(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getSongFlowable(id: Int): Observable<Song> {
|
override fun getSongFlowable(id: Int): Observable<Song> {
|
||||||
return SongLoader.getSongFlowable(context, id)
|
return SongLoader.getSongFlowable(context, id)
|
||||||
|
@ -91,10 +259,9 @@ class RepositoryImpl(private val context: Context) : Repository {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>> {
|
override fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>> {
|
||||||
return PlaylistSongsLoader.getPlaylistSongListFlowable(context, playlist)
|
return PlaylistSongsLoader.getPlaylistSongListFlowable(context, playlist)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.computation())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,12 +271,6 @@ class RepositoryImpl(private val context: Context) : Repository {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
}
|
}
|
||||||
|
|
||||||
override val favoritePlaylist: ArrayList<Playlist>
|
|
||||||
get() = PlaylistLoader.getFavoritePlaylist(context)
|
|
||||||
|
|
||||||
override fun allSongs(): ArrayList<Song> {
|
|
||||||
return SongLoader.getAllSongs(context)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val favoritePlaylistFlowable: Observable<ArrayList<Playlist>>
|
override val favoritePlaylistFlowable: Observable<ArrayList<Playlist>>
|
||||||
get() = PlaylistLoader.getFavoritePlaylistFlowable(context)
|
get() = PlaylistLoader.getFavoritePlaylistFlowable(context)
|
||||||
|
@ -180,13 +341,5 @@ class RepositoryImpl(private val context: Context) : Repository {
|
||||||
return ArtistLoader.getArtist(context, artistId.toInt())
|
return ArtistLoader.getArtist(context, artistId.toInt())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPlaylistSongs(playlist: Playlist): ArrayList<Song> {
|
|
||||||
return PlaylistSongsLoader.getPlaylistSongList(context, playlist)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getGenre(genreId: Int): ArrayList<Song> {
|
|
||||||
return GenreLoader.getSongs(context, genreId)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
package code.name.monkey.retromusic.providers.interfaces
|
package code.name.monkey.retromusic.providers.interfaces
|
||||||
|
|
||||||
|
import code.name.monkey.retromusic.Result
|
||||||
import code.name.monkey.retromusic.model.*
|
import code.name.monkey.retromusic.model.*
|
||||||
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
@ -24,44 +25,57 @@ import io.reactivex.Observable
|
||||||
|
|
||||||
interface Repository {
|
interface Repository {
|
||||||
|
|
||||||
val allSongsFlowable: Observable<ArrayList<Song>>
|
suspend fun allAlbums(): Result<ArrayList<Album>>
|
||||||
|
|
||||||
fun allSongs(): ArrayList<Song>
|
suspend fun allSongs(): Result<ArrayList<Song>>
|
||||||
|
|
||||||
|
suspend fun allArtists(): Result<ArrayList<Artist>>
|
||||||
|
|
||||||
|
suspend fun allPlaylists(): Result<ArrayList<Playlist>>
|
||||||
|
|
||||||
|
suspend fun allGenres(): Result<ArrayList<Genre>>
|
||||||
|
|
||||||
|
suspend fun search(query: String?): Result<MutableList<Any>>
|
||||||
|
|
||||||
|
suspend fun getPlaylistSongs(playlist: Playlist): Result<ArrayList<Song>>
|
||||||
|
|
||||||
|
suspend fun getGenre(genreId: Int): Result<ArrayList<Song>>
|
||||||
|
|
||||||
|
suspend fun recentArtists(): Result<Home>
|
||||||
|
|
||||||
|
suspend fun topArtists(): Result<Home>
|
||||||
|
|
||||||
|
suspend fun topAlbums(): Result<Home>
|
||||||
|
|
||||||
|
suspend fun recentAlbums(): Result<Home>
|
||||||
|
|
||||||
|
suspend fun favoritePlaylist(): Result<Home>
|
||||||
|
|
||||||
|
val allSongsFlowable: Observable<ArrayList<Song>>
|
||||||
|
|
||||||
val suggestionSongsFlowable: Observable<ArrayList<Song>>
|
val suggestionSongsFlowable: Observable<ArrayList<Song>>
|
||||||
|
|
||||||
val allAlbumsFlowable: Observable<ArrayList<Album>>
|
val allAlbumsFlowable: Observable<ArrayList<Album>>
|
||||||
|
|
||||||
fun allAlbums(): ArrayList<Album>
|
|
||||||
|
|
||||||
val recentAlbumsFlowable: Observable<ArrayList<Album>>
|
val recentAlbumsFlowable: Observable<ArrayList<Album>>
|
||||||
|
|
||||||
fun recentAlbums(): ArrayList<Album>
|
|
||||||
|
|
||||||
val topAlbumsFlowable: Observable<ArrayList<Album>>
|
val topAlbumsFlowable: Observable<ArrayList<Album>>
|
||||||
|
|
||||||
fun topAlbums(): ArrayList<Album>
|
|
||||||
|
|
||||||
val allArtistsFlowable: Observable<ArrayList<Artist>>
|
val allArtistsFlowable: Observable<ArrayList<Artist>>
|
||||||
|
|
||||||
fun allArtists(): ArrayList<Artist>
|
|
||||||
|
|
||||||
val recentArtistsFlowable: Observable<ArrayList<Artist>>
|
val recentArtistsFlowable: Observable<ArrayList<Artist>>
|
||||||
|
|
||||||
fun recentArtists(): ArrayList<Artist>
|
|
||||||
|
|
||||||
val topArtistsFlowable: Observable<ArrayList<Artist>>
|
val topArtistsFlowable: Observable<ArrayList<Artist>>
|
||||||
|
|
||||||
fun topArtists(): ArrayList<Artist>
|
|
||||||
|
|
||||||
val allPlaylistsFlowable: Observable<ArrayList<Playlist>>
|
val allPlaylistsFlowable: Observable<ArrayList<Playlist>>
|
||||||
|
|
||||||
fun allPlaylists(): ArrayList<Playlist>
|
|
||||||
|
|
||||||
val allGenresFlowable: Observable<ArrayList<Genre>>
|
val allGenresFlowable: Observable<ArrayList<Genre>>
|
||||||
|
|
||||||
fun allGenres(): ArrayList<Genre>
|
|
||||||
|
|
||||||
fun getSongFlowable(id: Int): Observable<Song>
|
fun getSongFlowable(id: Int): Observable<Song>
|
||||||
|
|
||||||
fun getSong(id: Int): Song
|
fun getSong(id: Int): Song
|
||||||
|
@ -74,19 +88,13 @@ interface Repository {
|
||||||
|
|
||||||
fun getArtistById(artistId: Long): Artist
|
fun getArtistById(artistId: Long): Artist
|
||||||
|
|
||||||
fun search(query: String?): MutableList<Any>
|
|
||||||
|
|
||||||
fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>>
|
fun getPlaylistSongsFlowable(playlist: Playlist): Observable<ArrayList<Song>>
|
||||||
|
|
||||||
fun getPlaylistSongs(playlist: Playlist): ArrayList<Song>
|
|
||||||
|
|
||||||
fun getGenreFlowable(genreId: Int): Observable<ArrayList<Song>>
|
fun getGenreFlowable(genreId: Int): Observable<ArrayList<Song>>
|
||||||
|
|
||||||
fun getGenre(genreId: Int): ArrayList<Song>
|
|
||||||
|
|
||||||
val favoritePlaylistFlowable: Observable<ArrayList<Playlist>>
|
val favoritePlaylistFlowable: Observable<ArrayList<Playlist>>
|
||||||
|
|
||||||
val favoritePlaylist: ArrayList<Playlist>
|
|
||||||
|
|
||||||
fun artistInfoFloable(name: String,
|
fun artistInfoFloable(name: String,
|
||||||
lang: String?,
|
lang: String?,
|
||||||
|
|
|
@ -54,8 +54,16 @@
|
||||||
tools:background="@color/md_red_400"
|
tools:background="@color/md_red_400"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
tools:srcCompat="@tools:sample/backgrounds/scenic[9]" />
|
tools:srcCompat="@tools:sample/backgrounds/scenic[9]" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@drawable/shadow_up_full_theme"
|
||||||
|
android:backgroundTint="?colorPrimary" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -78,6 +86,7 @@
|
||||||
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
||||||
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
||||||
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
||||||
|
app:cardBackgroundColor="@android:color/transparent"
|
||||||
app:cardCornerRadius="8dp"
|
app:cardCornerRadius="8dp"
|
||||||
app:cardElevation="6dp"
|
app:cardElevation="6dp"
|
||||||
app:cardUseCompatPadding="true"
|
app:cardUseCompatPadding="true"
|
||||||
|
@ -114,8 +123,8 @@
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:cardElevation="8dp"
|
|
||||||
app:cardBackgroundColor="?colorPrimary"
|
app:cardBackgroundColor="?colorPrimary"
|
||||||
|
app:cardElevation="8dp"
|
||||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||||
|
|
||||||
<include layout="@layout/home_content" />
|
<include layout="@layout/home_content" />
|
||||||
|
|
|
@ -53,8 +53,16 @@
|
||||||
tools:background="@color/md_red_400"
|
tools:background="@color/md_red_400"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
tools:srcCompat="@tools:sample/backgrounds/scenic[9]" />
|
tools:srcCompat="@tools:sample/backgrounds/scenic[9]" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@drawable/shadow_up_full_theme"
|
||||||
|
android:backgroundTint="?colorPrimary" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -77,6 +85,7 @@
|
||||||
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
||||||
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
||||||
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
||||||
|
app:cardBackgroundColor="@android:color/transparent"
|
||||||
app:cardCornerRadius="8dp"
|
app:cardCornerRadius="8dp"
|
||||||
app:cardElevation="6dp"
|
app:cardElevation="6dp"
|
||||||
app:cardUseCompatPadding="true"
|
app:cardUseCompatPadding="true"
|
||||||
|
|
|
@ -53,6 +53,13 @@
|
||||||
tools:background="@color/md_red_400"
|
tools:background="@color/md_red_400"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
tools:srcCompat="@tools:sample/backgrounds/scenic[9]" />
|
tools:srcCompat="@tools:sample/backgrounds/scenic[9]" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="bottom"
|
||||||
|
android:background="@drawable/shadow_up_full_theme"
|
||||||
|
android:backgroundTint="?colorPrimary" />
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
@ -77,6 +84,7 @@
|
||||||
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
||||||
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
||||||
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
||||||
|
app:cardBackgroundColor="@android:color/transparent"
|
||||||
app:cardCornerRadius="8dp"
|
app:cardCornerRadius="8dp"
|
||||||
app:cardElevation="6dp"
|
app:cardElevation="6dp"
|
||||||
app:cardUseCompatPadding="true"
|
app:cardUseCompatPadding="true"
|
||||||
|
@ -111,8 +119,8 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/toolbar_margin_horizontal"
|
android:layout_marginStart="@dimen/toolbar_margin_horizontal"
|
||||||
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
||||||
app:cardElevation="8dp"
|
|
||||||
app:cardBackgroundColor="?colorPrimary"
|
app:cardBackgroundColor="?colorPrimary"
|
||||||
|
app:cardElevation="8dp"
|
||||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||||
|
|
||||||
<include layout="@layout/home_content" />
|
<include layout="@layout/home_content" />
|
||||||
|
|
|
@ -29,43 +29,27 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_scrollFlags="scroll|enterAlways">
|
app:layout_scrollFlags="scroll|enterAlways">
|
||||||
|
|
||||||
<ViewStub
|
|
||||||
android:id="@+id/cab_stub"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="48dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.appbar.MaterialToolbar
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
style="@style/Toolbar"
|
style="@style/Toolbar"
|
||||||
app:navigationIcon="@drawable/ic_keyboard_backspace_black_24dp"
|
app:navigationIcon="@drawable/ic_keyboard_backspace_black_24dp"
|
||||||
app:titleTextAppearance="@style/ToolbarTextAppearanceNormal" />
|
app:titleTextAppearance="@style/ToolbarTextAppearanceNormal" />
|
||||||
|
|
||||||
|
<ViewStub
|
||||||
|
android:id="@+id/cab_stub"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
<com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
|
||||||
android:id="@+id/recyclerView"
|
android:id="@+id/recyclerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:scrollbars="none" />
|
android:scrollbars="none"
|
||||||
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||||
<Space
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="52dp" />
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@android:id/empty"
|
android:id="@android:id/empty"
|
||||||
|
@ -73,7 +57,9 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:layout_width="96dp"
|
android:layout_width="96dp"
|
||||||
|
|
|
@ -69,22 +69,12 @@
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<androidx.core.widget.NestedScrollView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
|
|
||||||
|
|
||||||
<FrameLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@android:id/empty"
|
android:id="@android:id/empty"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:paddingTop="48dp"
|
|
||||||
android:paddingBottom="48dp"
|
|
||||||
android:text="@string/no_results"
|
android:text="@string/no_results"
|
||||||
android:textAppearance="@style/TextViewHeadline6"
|
android:textAppearance="@style/TextViewHeadline6"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
@ -96,9 +86,8 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:scrollbarStyle="outsideOverlay"
|
android:scrollbarStyle="outsideOverlay"
|
||||||
android:scrollbars="vertical" />
|
android:scrollbars="vertical"
|
||||||
</FrameLayout>
|
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
android:id="@+id/keyboardPopup"
|
android:id="@+id/keyboardPopup"
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
||||||
|
|
||||||
<FrameLayout
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:id="@+id/toolbarContainer"
|
android:id="@+id/toolbarContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -74,6 +74,9 @@
|
||||||
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
android:layout_marginTop="@dimen/toolbar_margin_vertical"
|
||||||
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
android:layout_marginEnd="@dimen/toolbar_margin_horizontal"
|
||||||
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
android:layout_marginBottom="@dimen/toolbar_margin_vertical"
|
||||||
|
app:cardBackgroundColor="@android:color/transparent"
|
||||||
|
app:cardCornerRadius="8dp"
|
||||||
|
app:cardUseCompatPadding="true"
|
||||||
app:layout_scrollFlags="scroll|enterAlways"
|
app:layout_scrollFlags="scroll|enterAlways"
|
||||||
app:shapeAppearance="@style/ToolbarCornerCardView">
|
app:shapeAppearance="@style/ToolbarCornerCardView">
|
||||||
|
|
||||||
|
@ -89,7 +92,7 @@
|
||||||
app:titleMarginStart="0dp"
|
app:titleMarginStart="0dp"
|
||||||
app:titleTextAppearance="@style/ToolbarTextAppearanceSearch"
|
app:titleTextAppearance="@style/ToolbarTextAppearanceSearch"
|
||||||
tools:ignore="UnusedAttribute" />
|
tools:ignore="UnusedAttribute" />
|
||||||
</FrameLayout>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||||
</com.google.android.material.appbar.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
@ -103,8 +106,8 @@
|
||||||
<com.google.android.material.card.MaterialCardView
|
<com.google.android.material.card.MaterialCardView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:cardElevation="8dp"
|
|
||||||
app:cardBackgroundColor="?colorPrimary"
|
app:cardBackgroundColor="?colorPrimary"
|
||||||
|
app:cardElevation="8dp"
|
||||||
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
app:shapeAppearanceOverlay="@style/TopCornerCardView">
|
||||||
|
|
||||||
<include layout="@layout/home_content" />
|
<include layout="@layout/home_content" />
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/TextViewCaption"
|
android:textAppearance="@style/TextViewCaption"
|
||||||
|
android:visibility="gone"
|
||||||
tools:text="@tools:sample/full_names" />
|
tools:text="@tools:sample/full_names" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
<com.google.android.material.textview.MaterialTextView
|
<com.google.android.material.textview.MaterialTextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
|
android:visibility="gone"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textAppearance="@style/TextViewCaption"
|
android:textAppearance="@style/TextViewCaption"
|
||||||
|
|
|
@ -620,7 +620,7 @@
|
||||||
<string name="grid_style_label"><![CDATA[Grids & Style]]></string>
|
<string name="grid_style_label"><![CDATA[Grids & Style]]></string>
|
||||||
<string name="welcome">Welcome,</string>
|
<string name="welcome">Welcome,</string>
|
||||||
<string name="premium">Get Premium</string>
|
<string name="premium">Get Premium</string>
|
||||||
<string name="pro_summary">Now playing themes, Carousel effect, Color theme and more..</string>
|
<string name="pro_summary">Now playing themes, Carousel effect and more..</string>
|
||||||
<string name="action_play_all">Play all</string>
|
<string name="action_play_all">Play all</string>
|
||||||
<string name="start_play_music">Start playing music.</string>
|
<string name="start_play_music">Start playing music.</string>
|
||||||
<string name="keyboard">Keyboard</string>
|
<string name="keyboard">Keyboard</string>
|
||||||
|
|
|
@ -27,7 +27,7 @@ android {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
implementation 'com.google.android.material:material:1.1.0-alpha10'
|
implementation 'com.google.android.material:material:1.1.0-beta01'
|
||||||
implementation 'androidx.preference:preference:1.1.0'
|
implementation 'androidx.preference:preference:1.1.0'
|
||||||
implementation 'androidx.cardview:cardview:1.0.0'
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
// Used for the list preference classes
|
// Used for the list preference classes
|
||||||
|
|
Loading…
Reference in a new issue