From 17a66450d4cc4ced4ee7479d63d3af983daa0ceb Mon Sep 17 00:00:00 2001 From: Hemanth S Date: Tue, 21 Jul 2020 00:35:48 +0530 Subject: [PATCH] MVP is Gone --- app/build.gradle | 5 ++ app/src/main/AndroidManifest.xml | 6 +- .../java/code/name/monkey/retromusic/App.kt | 7 ++ .../code/name/monkey/retromusic/MainModule.kt | 40 +++++++++++ .../code/name/monkey/retromusic/Result.kt | 26 ------- .../retromusic/activities/MainActivity.kt | 6 +- .../activities/albums/AlbumDetailsActivity.kt | 41 +++++------ .../albums/AlbumDetailsViewModel.kt | 15 ++-- .../albums/AlbumDetailsViewModelFactory.kt | 19 ------ .../artists/ArtistDetailActivity.kt | 38 ++++------- .../artists/ArtistDetailsViewModel.kt | 13 ++-- .../artists/ArtistDetailsViewModelFactory.kt | 19 ------ .../{ => genre}/GenreDetailsActivity.kt | 53 +++++---------- .../activities/genre/GenreDetailsViewModel.kt | 49 +++++++++++++ .../{ => playlist}/PlaylistDetailActivity.kt | 68 +++++++------------ .../playlist/PlaylistDetailsViewModel.kt | 67 ++++++++++++++++++ .../activities/{ => search}/SearchActivity.kt | 45 ++++++------ .../activities/search/SearchViewModel.kt | 22 ++++++ .../AppShortcutLauncherActivity.kt | 2 +- .../retromusic/fragments/LibraryViewModel.kt | 32 ++++----- .../name/monkey/retromusic/mvp/BaseView.kt | 24 ------- .../name/monkey/retromusic/mvp/Presenter.kt | 30 -------- .../monkey/retromusic/mvp/PresenterImpl.java | 30 -------- .../mvp/presenter/AlbumDetailsPresenter.kt | 35 ---------- .../mvp/presenter/ArtistDetailsPresenter.kt | 31 --------- .../mvp/presenter/GenreDetailsPresenter.kt | 59 ---------------- .../mvp/presenter/PlaylistSongsPresenter.kt | 63 ----------------- .../mvp/presenter/SearchPresenter.kt | 61 ----------------- .../retromusic/providers/ProviderModule.kt | 11 +++ .../retromusic/util/NavigationUtil.java | 6 +- 30 files changed, 341 insertions(+), 582 deletions(-) create mode 100644 app/src/main/java/code/name/monkey/retromusic/MainModule.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/Result.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsViewModelFactory.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailsViewModelFactory.kt rename app/src/main/java/code/name/monkey/retromusic/activities/{ => genre}/GenreDetailsActivity.kt (78%) create mode 100644 app/src/main/java/code/name/monkey/retromusic/activities/genre/GenreDetailsViewModel.kt rename app/src/main/java/code/name/monkey/retromusic/activities/{ => playlist}/PlaylistDetailActivity.kt (81%) create mode 100644 app/src/main/java/code/name/monkey/retromusic/activities/playlist/PlaylistDetailsViewModel.kt rename app/src/main/java/code/name/monkey/retromusic/activities/{ => search}/SearchActivity.kt (88%) create mode 100644 app/src/main/java/code/name/monkey/retromusic/activities/search/SearchViewModel.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/mvp/BaseView.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/mvp/Presenter.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/mvp/PresenterImpl.java delete mode 100644 app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumDetailsPresenter.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/mvp/presenter/GenreDetailsPresenter.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/mvp/presenter/PlaylistSongsPresenter.kt delete mode 100644 app/src/main/java/code/name/monkey/retromusic/mvp/presenter/SearchPresenter.kt create mode 100644 app/src/main/java/code/name/monkey/retromusic/providers/ProviderModule.kt diff --git a/app/build.gradle b/app/build.gradle index a4ed083d..fbd8bd3a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -163,4 +163,9 @@ dependencies { implementation 'me.jorgecastillo:androidcolorx:0.2.0' debugImplementation 'com.amitshekhar.android:debug-db:1.0.4' implementation 'com.github.dhaval2404:imagepicker:1.7.1' + + def koin_version = "2.1.5" + implementation "org.koin:koin-core:$koin_version" + implementation "org.koin:koin-android:$koin_version" + implementation "org.koin:koin-android-viewmodel:$koin_version" } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5453babf..07c6c27d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -107,7 +107,7 @@ - + @@ -116,7 +116,7 @@ - + @@ -124,7 +124,7 @@ + AlbumDetailsViewModel(get(), albumId) + } + + viewModel { (artistId: Int) -> + ArtistDetailsViewModel(get(), artistId) + } + + viewModel { (playlist: Playlist) -> + PlaylistDetailsViewModel(get(), playlist) + } + + viewModel { (genre: Genre) -> + GenreDetailsViewModel(get(), genre) + } + + viewModel { + SearchViewModel(get()) + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/Result.kt b/app/src/main/java/code/name/monkey/retromusic/Result.kt deleted file mode 100644 index 64b638a6..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/Result.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 { - - class Success(val data: T) : Result() - - class Error(val exception: Throwable) : Result() -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt index c58330ab..e5c91ae7 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt @@ -13,7 +13,6 @@ import android.view.View import androidx.core.app.ActivityCompat import androidx.fragment.app.Fragment import androidx.fragment.app.commit -import androidx.lifecycle.ViewModelProvider import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil.resolveColor @@ -64,6 +63,7 @@ import com.google.android.play.core.install.model.InstallStatus.INSTALLED import com.google.android.play.core.install.model.UpdateAvailability import com.google.android.play.core.tasks.Task import kotlinx.android.synthetic.main.activity_main_content.* +import org.koin.android.ext.android.inject import java.util.* class MainActivity : AbsSlidingMusicPanelActivity(), @@ -74,7 +74,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), const val APP_UPDATE_REQUEST_CODE = 9002 } - lateinit var libraryViewModel: LibraryViewModel + val libraryViewModel: LibraryViewModel by inject() private var cab: MaterialCab? = null private val intentFilter = IntentFilter(Intent.ACTION_SCREEN_OFF) private lateinit var currentFragment: MainActivityFragmentCallbacks @@ -123,9 +123,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), hideStatusBar() setBottomBarVisibility(View.VISIBLE) - libraryViewModel = ViewModelProvider(this).get(LibraryViewModel::class.java) addMusicServiceEventListener(libraryViewModel) - if (savedInstanceState == null) { selectedFragment(PreferenceUtil.lastPage) } else { diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsActivity.kt index 2f3c819e..5ce2a2ba 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsActivity.kt @@ -10,7 +10,6 @@ import android.view.SubMenu import android.view.View import android.widget.ImageView import androidx.core.app.ActivityCompat -import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager @@ -37,7 +36,6 @@ import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Artist -import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView import code.name.monkey.retromusic.rest.model.LastFmAlbum import code.name.monkey.retromusic.util.* import code.name.monkey.retromusic.util.color.MediaNotificationProcessor @@ -45,10 +43,12 @@ import com.afollestad.materialcab.MaterialCab import com.bumptech.glide.Glide import kotlinx.android.synthetic.main.activity_album.* import kotlinx.android.synthetic.main.activity_album_content.* +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import java.util.* import android.util.Pair as UtilPair -class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, CabHolder { +class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder { override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab { cab?.let { if (it.isActive) it.finish() @@ -68,7 +68,9 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C return cab as MaterialCab } - private lateinit var viewModel: AlbumDetailsViewModel + private val detailsViewModel: AlbumDetailsViewModel by viewModel { + parametersOf(extraNotNull(EXTRA_ALBUM_ID).value) + } private lateinit var simpleSongAdapter: SimpleSongAdapter private lateinit var album: Album private lateinit var artistImage: ImageView @@ -100,19 +102,19 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C window.sharedElementsUseOverlay = true windowEnterTransition() - val albumId = extraNotNull(EXTRA_ALBUM_ID).value + addMusicServiceEventListener(detailsViewModel) ActivityCompat.postponeEnterTransition(this) - val viewModelFactory = AlbumDetailsViewModelFactory(application, albumId) - viewModel = ViewModelProvider(this, viewModelFactory).get(AlbumDetailsViewModel::class.java) - addMusicServiceEventListener(viewModel) - viewModel.getAlbum().observe(this, androidx.lifecycle.Observer { + //val viewModelFactory = AlbumDetailsViewModelFactory(application, albumId) + //viewModel = ViewModelProvider(this, viewModelFactory).get(AlbumDetailsViewModel::class.java) + + detailsViewModel.getAlbum().observe(this, androidx.lifecycle.Observer { ActivityCompat.startPostponedEnterTransition(this@AlbumDetailsActivity) album(it) }) - viewModel.getArtist().observe(this, androidx.lifecycle.Observer { + detailsViewModel.getArtist().observe(this, androidx.lifecycle.Observer { loadArtistImage(it) }) - viewModel.getAlbumInfo().observe(this, androidx.lifecycle.Observer { + detailsViewModel.getAlbumInfo().observe(this, androidx.lifecycle.Observer { aboutAlbum(it) }) setupRecyclerView() @@ -153,11 +155,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C } } - override fun complete() { + fun complete() { ActivityCompat.startPostponedEnterTransition(this) } - override fun album(album: Album) { + fun album(album: Album) { complete() if (album.songs!!.isEmpty()) { finish() @@ -190,11 +192,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C } loadAlbumCover() simpleSongAdapter.swapDataSet(album.songs) - viewModel.loadArtist(album.artistId) - viewModel.loadAlbumInfo(album) + detailsViewModel.loadArtist(album.artistId) + detailsViewModel.loadAlbumInfo(album) } - override fun moreAlbums(albums: List) { + fun moreAlbums(albums: List) { moreTitle.show() moreRecyclerView.show() moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName) @@ -209,7 +211,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C moreRecyclerView.adapter = albumAdapter } - override fun aboutAlbum(lastFmAlbum: LastFmAlbum) { + fun aboutAlbum(lastFmAlbum: LastFmAlbum) { if (lastFmAlbum.album != null) { if (lastFmAlbum.album.wiki != null) { aboutAlbumText.show() @@ -230,7 +232,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C } } - override fun loadArtistImage(artist: Artist) { + fun loadArtistImage(artist: Artist) { ArtistGlideRequest.Builder.from(Glide.with(this), artist) .generatePalette(this) .build() @@ -391,8 +393,9 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C override fun onDestroy() { super.onDestroy() - removeMusicServiceEventListener(viewModel) + removeMusicServiceEventListener(detailsViewModel) } + companion object { const val EXTRA_ALBUM_ID = "extra_album_id" diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsViewModel.kt index 112d7e04..113fa907 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsViewModel.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsViewModel.kt @@ -1,9 +1,8 @@ package code.name.monkey.retromusic.activities.albums -import android.app.Application -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import code.name.monkey.retromusic.interfaces.MusicServiceEventListener import code.name.monkey.retromusic.model.Album @@ -16,10 +15,10 @@ import kotlinx.coroutines.async import kotlinx.coroutines.launch class AlbumDetailsViewModel( - application: Application, + private val repository: RepositoryImpl, private val albumId: Int -) : AndroidViewModel(application), MusicServiceEventListener { - private val _repository = RepositoryImpl(application.applicationContext) +) : ViewModel(), MusicServiceEventListener { + private val _album = MutableLiveData() private val _artist = MutableLiveData() private val _lastFmAlbum = MutableLiveData() @@ -38,18 +37,18 @@ class AlbumDetailsViewModel( } fun loadAlbumInfo(album: Album) = viewModelScope.launch(Dispatchers.IO) { - val lastFmAlbum = _repository.albumInfo(album.artistName ?: "-", album.title ?: "-") + val lastFmAlbum = repository.albumInfo(album.artistName ?: "-", album.title ?: "-") _lastFmAlbum.postValue(lastFmAlbum) } fun loadArtist(artistId: Int) = viewModelScope.launch(Dispatchers.IO) { - val artist = _repository.artistById(artistId) + val artist = repository.artistById(artistId) _artist.postValue(artist) } private val loadAlbumAsync: Deferred get() = viewModelScope.async(Dispatchers.IO) { - _repository.albumById(albumId) + repository.albumById(albumId) } override fun onMediaStoreChanged() { diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsViewModelFactory.kt b/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsViewModelFactory.kt deleted file mode 100644 index 7f5aa847..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/activities/albums/AlbumDetailsViewModelFactory.kt +++ /dev/null @@ -1,19 +0,0 @@ -package code.name.monkey.retromusic.activities.albums - -import android.app.Application -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider - -class AlbumDetailsViewModelFactory( - private val application: Application, - private val albumId: Int -) : - ViewModelProvider.AndroidViewModelFactory(application) { - override fun create(modelClass: Class): T { - return if (modelClass.isAssignableFrom(AlbumDetailsViewModel::class.java)) { - AlbumDetailsViewModel(application, albumId) as T - } else { - throw IllegalArgumentException("ViewModel Not Found") - } - } -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailActivity.kt index a4422ffa..e254f4e3 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailActivity.kt @@ -11,7 +11,6 @@ import android.view.View import android.widget.Toast import androidx.core.app.ActivityCompat import androidx.core.text.HtmlCompat -import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager @@ -31,7 +30,6 @@ import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Artist -import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView import code.name.monkey.retromusic.rest.model.LastFmArtist import code.name.monkey.retromusic.util.* import code.name.monkey.retromusic.util.color.MediaNotificationProcessor @@ -39,10 +37,12 @@ import com.afollestad.materialcab.MaterialCab import com.bumptech.glide.Glide import kotlinx.android.synthetic.main.activity_artist_content.* import kotlinx.android.synthetic.main.activity_artist_details.* +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import java.util.* import kotlin.collections.ArrayList -class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, CabHolder { +class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder { override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab { cab?.let { if (it.isActive) it.finish() @@ -68,7 +68,9 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, private lateinit var songAdapter: SimpleSongAdapter private lateinit var albumAdapter: HorizontalAlbumAdapter private var forceDownload: Boolean = false - private lateinit var viewModel: ArtistDetailsViewModel + private val detailsViewModel: ArtistDetailsViewModel by viewModel { + parametersOf(extraNotNull(EXTRA_ARTIST_ID).value) + } override fun createContentView(): View { return wrapSlidingMusicPanel(R.layout.activity_artist_details) @@ -93,23 +95,16 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, setBottomBarVisibility(View.GONE) window.sharedElementsUseOverlay = true windowEnterTransition() - - val artistId = extraNotNull(EXTRA_ARTIST_ID).value - val viewModelFactory = ArtistDetailsViewModelFactory(application, artistId) - viewModel = - ViewModelProvider(this, viewModelFactory).get(ArtistDetailsViewModel::class.java) - addMusicServiceEventListener(viewModel) - viewModel.getArtist().observe(this, androidx.lifecycle.Observer { + ActivityCompat.postponeEnterTransition(this) + addMusicServiceEventListener(detailsViewModel) + detailsViewModel.getArtist().observe(this, androidx.lifecycle.Observer { ActivityCompat.startPostponedEnterTransition(this@ArtistDetailActivity) artist(it) }) - viewModel.getArtistInfo().observe(this, androidx.lifecycle.Observer { + detailsViewModel.getArtistInfo().observe(this, androidx.lifecycle.Observer { artistInfo(it) }) - ActivityCompat.postponeEnterTransition(this) - setupRecyclerView() - playAction.apply { setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) } } @@ -155,14 +150,11 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, } } - override fun showEmptyView() { - } - - override fun complete() { + fun complete() { ActivityCompat.startPostponedEnterTransition(this) } - override fun artist(artist: Artist) { + fun artist(artist: Artist) { complete() if (artist.songCount <= 0) { finish() @@ -203,10 +195,10 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, ) { biography = null this.lang = lang - viewModel.loadBiography(name, lang, null) + detailsViewModel.loadBiography(name, lang, null) } - override fun artistInfo(lastFmArtist: LastFmArtist?) { + fun artistInfo(lastFmArtist: LastFmArtist?) { if (lastFmArtist != null && lastFmArtist.artist != null) { val bioContent = lastFmArtist.artist.bio.content if (bioContent != null && bioContent.trim { it <= ' ' }.isNotEmpty()) { @@ -323,7 +315,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, override fun onDestroy() { super.onDestroy() - removeMusicServiceEventListener(viewModel) + removeMusicServiceEventListener(detailsViewModel) } companion object { diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailsViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailsViewModel.kt index 502bafe8..e236bdf8 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailsViewModel.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailsViewModel.kt @@ -1,9 +1,8 @@ package code.name.monkey.retromusic.activities.artists -import android.app.Application -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import code.name.monkey.retromusic.interfaces.MusicServiceEventListener import code.name.monkey.retromusic.model.Artist @@ -15,15 +14,15 @@ import kotlinx.coroutines.async import kotlinx.coroutines.launch class ArtistDetailsViewModel( - application: Application, + private val repository: RepositoryImpl, private val artistId: Int -) : AndroidViewModel(application), MusicServiceEventListener { +) : ViewModel(), MusicServiceEventListener { private val loadArtistDetailsAsync: Deferred get() = viewModelScope.async(Dispatchers.IO) { - _repository.artistById(artistId) + repository.artistById(artistId) } - private val _repository = RepositoryImpl(application.applicationContext) + private val _artist = MutableLiveData() private val _lastFmArtist = MutableLiveData() @@ -41,7 +40,7 @@ class ArtistDetailsViewModel( } fun loadBiography(name: String, lang: String?, cache: String?) = viewModelScope.launch { - val info = _repository.artistInfo(name, lang, cache) + val info = repository.artistInfo(name, lang, cache) _lastFmArtist.postValue(info) } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailsViewModelFactory.kt b/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailsViewModelFactory.kt deleted file mode 100644 index e3ab552b..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/activities/artists/ArtistDetailsViewModelFactory.kt +++ /dev/null @@ -1,19 +0,0 @@ -package code.name.monkey.retromusic.activities.artists - -import android.app.Application -import androidx.lifecycle.ViewModel -import androidx.lifecycle.ViewModelProvider - -class ArtistDetailsViewModelFactory( - private val application: Application, - private val artistId: Int -) : - ViewModelProvider.AndroidViewModelFactory(application) { - override fun create(modelClass: Class): T { - return if (modelClass.isAssignableFrom(ArtistDetailsViewModel::class.java)) { - ArtistDetailsViewModel(application, artistId) as T - } else { - throw IllegalArgumentException("ViewModel Not Found") - } - } -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/GenreDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/genre/GenreDetailsActivity.kt similarity index 78% rename from app/src/main/java/code/name/monkey/retromusic/activities/GenreDetailsActivity.kt rename to app/src/main/java/code/name/monkey/retromusic/activities/genre/GenreDetailsActivity.kt index d410f45d..8a4524b4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/GenreDetailsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/genre/GenreDetailsActivity.kt @@ -1,4 +1,4 @@ -package code.name.monkey.retromusic.activities +package code.name.monkey.retromusic.activities.genre import android.os.Bundle import android.view.Menu @@ -17,24 +17,25 @@ import code.name.monkey.retromusic.helper.menu.GenreMenuHelper import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Song -import code.name.monkey.retromusic.mvp.presenter.GenreDetailsPresenter -import code.name.monkey.retromusic.mvp.presenter.GenreDetailsPresenter.GenreDetailsPresenterImpl -import code.name.monkey.retromusic.mvp.presenter.GenreDetailsView -import code.name.monkey.retromusic.providers.RepositoryImpl import code.name.monkey.retromusic.util.DensityUtil import code.name.monkey.retromusic.util.RetroColorUtil import com.afollestad.materialcab.MaterialCab import kotlinx.android.synthetic.main.activity_playlist_detail.* +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf import java.util.* /** * @author Hemanth S (h4h13). */ -class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDetailsView { +class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder { - private lateinit var genreDetailsPresenter: GenreDetailsPresenter + private val detailsViewModel: GenreDetailsViewModel by viewModel { + parametersOf(extraNotNull(EXTRA_GENRE_ID).value) + } + private lateinit var genre: Genre private lateinit var songAdapter: ShuffleButtonSongAdapter private var cab: MaterialCab? = null @@ -62,38 +63,25 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDet setTaskDescriptionColorAuto() setLightNavigationBar(true) setBottomBarVisibility(View.GONE) - - genre = extraNotNull(EXTRA_GENRE_ID).value - - setUpToolBar() + applyToolbar(toolbar) setupRecyclerView() - genreDetailsPresenter = - GenreDetailsPresenterImpl(RepositoryImpl(this)) - genreDetailsPresenter.attachView(this) - } + detailsViewModel.getSongs().observe(this, androidx.lifecycle.Observer { + songs(it) + }) - private fun setUpToolBar() { - applyToolbar(toolbar) - title = genre.name - } + detailsViewModel.getGenre().observe(this, androidx.lifecycle.Observer { + genre = it + supportActionBar?.title = it.name + }) - override fun onResume() { - super.onResume() - genreDetailsPresenter.loadGenreSongs(genre.id) - } - - override fun onDestroy() { - super.onDestroy() - genreDetailsPresenter.detachView() + addMusicServiceEventListener(detailsViewModel) } override fun createContentView(): View { return wrapSlidingMusicPanel(R.layout.activity_playlist_detail) } - override fun showEmptyView() { - } override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_genre_detail, menu) @@ -122,7 +110,7 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDet }) } - override fun songs(songs: List) { + fun songs(songs: List) { songAdapter.swapDataSet(songs) } @@ -149,11 +137,6 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDet } } - override fun onMediaStoreChanged() { - super.onMediaStoreChanged() - genreDetailsPresenter.loadGenreSongs(genre.id) - } - companion object { const val EXTRA_GENRE_ID = "extra_genre_id" } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/genre/GenreDetailsViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/activities/genre/GenreDetailsViewModel.kt new file mode 100644 index 00000000..03aba809 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/activities/genre/GenreDetailsViewModel.kt @@ -0,0 +1,49 @@ +package code.name.monkey.retromusic.activities.genre + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import code.name.monkey.retromusic.interfaces.MusicServiceEventListener +import code.name.monkey.retromusic.model.Genre +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.providers.RepositoryImpl +import kotlinx.coroutines.Dispatchers.Main +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class GenreDetailsViewModel( + private val repository: RepositoryImpl, + private val genre: Genre +) : ViewModel(), MusicServiceEventListener { + + private val _playListSongs = MutableLiveData>() + private val _genre = MutableLiveData().apply { + postValue(genre) + } + + fun getSongs(): LiveData> = _playListSongs + + fun getGenre(): LiveData = _genre + + init { + loadGenreSongs(genre) + } + + private fun loadGenreSongs(genre: Genre) = viewModelScope.launch { + val songs = repository.getGenre(genre.id) + withContext(Main) { _playListSongs.postValue(songs) } + } + + override fun onMediaStoreChanged() { + loadGenreSongs(genre) + } + + override fun onServiceConnected() {} + override fun onServiceDisconnected() {} + override fun onQueueChanged() {} + override fun onPlayingMetaChanged() {} + override fun onPlayStateChanged() {} + override fun onRepeatModeChanged() {} + override fun onShuffleModeChanged() {} +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PlaylistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/playlist/PlaylistDetailActivity.kt similarity index 81% rename from app/src/main/java/code/name/monkey/retromusic/activities/PlaylistDetailActivity.kt rename to app/src/main/java/code/name/monkey/retromusic/activities/playlist/PlaylistDetailActivity.kt index ee92f74d..f740275d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/PlaylistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/playlist/PlaylistDetailActivity.kt @@ -1,9 +1,10 @@ -package code.name.monkey.retromusic.activities +package code.name.monkey.retromusic.activities.playlist import android.os.Bundle import android.view.Menu import android.view.MenuItem import android.view.View +import androidx.lifecycle.Observer import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import code.name.monkey.appthemehelper.util.ATHUtil @@ -16,14 +17,9 @@ import code.name.monkey.retromusic.extensions.applyToolbar import code.name.monkey.retromusic.extensions.extraNotNull import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper import code.name.monkey.retromusic.interfaces.CabHolder -import code.name.monkey.retromusic.loaders.PlaylistLoader import code.name.monkey.retromusic.model.AbsCustomPlaylist import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Song -import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter -import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter.PlaylistSongsPresenterImpl -import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsView -import code.name.monkey.retromusic.providers.RepositoryImpl import code.name.monkey.retromusic.util.DensityUtil import code.name.monkey.retromusic.util.PlaylistsUtil import code.name.monkey.retromusic.util.RetroColorUtil @@ -32,11 +28,15 @@ import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemA import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils import kotlinx.android.synthetic.main.activity_playlist_detail.* +import org.koin.android.viewmodel.ext.android.viewModel +import org.koin.core.parameter.parametersOf -class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, PlaylistSongsView { +class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder { - private lateinit var presenter: PlaylistSongsPresenter + private val viewModel: PlaylistDetailsViewModel by viewModel { + parametersOf(extraNotNull(EXTRA_PLAYLIST).value) + } private lateinit var playlist: Playlist private var cab: MaterialCab? = null private lateinit var adapter: SongAdapter @@ -52,13 +52,20 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli setLightNavigationBar(true) setBottomBarVisibility(View.GONE) - presenter = PlaylistSongsPresenterImpl(RepositoryImpl(this)) - presenter.attachView(this) - playlist = extraNotNull(EXTRA_PLAYLIST).value setUpToolBar() setUpRecyclerView() + + viewModel.getSongs().observe(this, Observer { + songs(it) + }) + + viewModel.getPlaylist().observe(this, Observer { + playlist = it + supportActionBar?.title = it.name + }) + addMusicServiceEventListener(viewModel) } override fun createContentView(): View { @@ -66,7 +73,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli } private fun setUpRecyclerView() { - recyclerView.layoutManager = LinearLayoutManager(this) if (playlist is AbsCustomPlaylist) { adapter = PlaylistSongAdapter(this, ArrayList(), R.layout.item_list, this) @@ -108,11 +114,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli }) } - override fun onResume() { - super.onResume() - presenter.loadPlaylistSongs(playlist) - } - private fun setUpToolBar() { applyToolbar(toolbar) title = playlist.name @@ -162,28 +163,6 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli } } - override fun onMediaStoreChanged() { - super.onMediaStoreChanged() - if (playlist !is AbsCustomPlaylist) { - // Playlist deleted - if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) { - finish() - return - } - // Playlist renamed - val playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id.toLong()) - if (playlistName != playlist.name) { - playlist = PlaylistLoader.getPlaylist(this, playlist.id) - setToolbarTitle(playlist.name) - } - } - presenter.loadPlaylistSongs(playlist) - } - - private fun setToolbarTitle(title: String) { - supportActionBar?.title = title - } - private fun checkForPadding() { val height = DensityUtil.dip2px(this, 52f) recyclerView.setPadding(0, 0, 0, (height)) @@ -223,16 +202,19 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli wrappedAdapter = null } super.onDestroy() - presenter.detachView() } - override fun showEmptyView() { + fun showEmptyView() { empty.visibility = View.VISIBLE emptyText.visibility = View.VISIBLE } - override fun songs(songs: List) { - adapter.swapDataSet(songs) + fun songs(songs: List) { + if (songs.isNotEmpty()) { + adapter.swapDataSet(songs) + } else { + showEmptyView() + } } companion object { diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/playlist/PlaylistDetailsViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/activities/playlist/PlaylistDetailsViewModel.kt new file mode 100644 index 00000000..0ea4bc03 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/activities/playlist/PlaylistDetailsViewModel.kt @@ -0,0 +1,67 @@ +package code.name.monkey.retromusic.activities.playlist + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import code.name.monkey.retromusic.App +import code.name.monkey.retromusic.interfaces.MusicServiceEventListener +import code.name.monkey.retromusic.loaders.PlaylistLoader +import code.name.monkey.retromusic.model.AbsCustomPlaylist +import code.name.monkey.retromusic.model.Playlist +import code.name.monkey.retromusic.model.Song +import code.name.monkey.retromusic.providers.RepositoryImpl +import code.name.monkey.retromusic.util.PlaylistsUtil +import kotlinx.coroutines.Dispatchers.Main +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class PlaylistDetailsViewModel( + private val repository: RepositoryImpl, + private var playlist: Playlist +) : ViewModel(), MusicServiceEventListener { + private val _playListSongs = MutableLiveData>() + + private val _playlist = MutableLiveData().apply { + postValue(playlist) + } + + fun getPlaylist(): LiveData = _playlist + + fun getSongs(): LiveData> = _playListSongs + + init { + loadPlaylistSongs(playlist) + } + + private fun loadPlaylistSongs(playlist: Playlist) = viewModelScope.launch { + val songs = repository.getPlaylistSongs(playlist) + withContext(Main) { _playListSongs.postValue(songs) } + } + + override fun onMediaStoreChanged() { + if (playlist !is AbsCustomPlaylist) { + // Playlist deleted + if (!PlaylistsUtil.doesPlaylistExist(App.getContext(), playlist.id)) { + //TODO Finish the page + return + } + // Playlist renamed + val playlistName = + PlaylistsUtil.getNameForPlaylist(App.getContext(), playlist.id.toLong()) + if (playlistName != playlist.name) { + playlist = PlaylistLoader.getPlaylist(App.getContext(), playlist.id) + _playlist.postValue(playlist) + } + } + loadPlaylistSongs(playlist) + } + + override fun onServiceConnected() {} + override fun onServiceDisconnected() {} + override fun onQueueChanged() {} + override fun onPlayingMetaChanged() {} + override fun onPlayStateChanged() {} + override fun onRepeatModeChanged() {} + override fun onShuffleModeChanged() {} +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/SearchActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/search/SearchActivity.kt similarity index 88% rename from app/src/main/java/code/name/monkey/retromusic/activities/SearchActivity.kt rename to app/src/main/java/code/name/monkey/retromusic/activities/search/SearchActivity.kt index b62bc5e2..fbc65789 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/SearchActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/search/SearchActivity.kt @@ -1,4 +1,4 @@ -package code.name.monkey.retromusic.activities +package code.name.monkey.retromusic.activities.search import android.app.Activity import android.app.Service @@ -24,19 +24,17 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity import code.name.monkey.retromusic.adapter.SearchAdapter -import code.name.monkey.retromusic.mvp.presenter.SearchPresenter -import code.name.monkey.retromusic.mvp.presenter.SearchPresenter.SearchPresenterImpl -import code.name.monkey.retromusic.mvp.presenter.SearchView -import code.name.monkey.retromusic.providers.RepositoryImpl +import code.name.monkey.retromusic.extensions.extra import code.name.monkey.retromusic.util.RetroUtil import com.google.android.material.textfield.TextInputEditText import kotlinx.android.synthetic.main.activity_search.* +import org.koin.android.ext.android.inject import java.util.* import kotlin.collections.ArrayList -class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatcher, SearchView { +class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatcher { - private lateinit var presenter: SearchPresenter + private val viewModel: SearchViewModel by inject() private var searchAdapter: SearchAdapter? = null private var query: String? = null @@ -49,14 +47,11 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch setTaskDescriptionColorAuto() setLightNavigationBar(true) - presenter = SearchPresenterImpl(RepositoryImpl(this)) - presenter.attachView(this) - setupRecyclerView() setUpToolBar() setupSearchView() - if (intent.getBooleanExtra(EXTRA_SHOW_MIC, false)) { + if (extra(EXTRA_SHOW_MIC).value == true) { startMicSearch() } @@ -84,6 +79,10 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch if (savedInstanceState != null) { query = savedInstanceState.getString(QUERY) } + + viewModel.getSearchResult().observe(this, androidx.lifecycle.Observer { + showData(it) + }) } private fun setupRecyclerView() { @@ -114,11 +113,6 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch searchView.addTextChangedListener(this) } - override fun onDestroy() { - super.onDestroy() - presenter.detachView() - } - override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString(QUERY, query) @@ -133,7 +127,7 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch TransitionManager.beginDelayedTransition(appBarLayout) voiceSearch.visibility = if (query.isNotEmpty()) View.GONE else View.VISIBLE clearText.visibility = if (query.isNotEmpty()) View.VISIBLE else View.GONE - presenter.search(query) + viewModel.search(query) } override fun onMediaStoreChanged() { @@ -158,12 +152,16 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch } } - override fun showEmptyView() { + private fun showEmptyView() { searchAdapter?.swapDataSet(ArrayList()) } - override fun showData(data: MutableList) { - searchAdapter?.swapDataSet(data) + private fun showData(data: MutableList) { + if (data.isNotEmpty()) { + searchAdapter?.swapDataSet(data) + } else { + showEmptyView() + } } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -175,7 +173,7 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS) query = result?.get(0) searchView.setText(query, BufferType.EDITABLE) - presenter.search(query!!) + viewModel.search(query!!) } } } @@ -190,7 +188,10 @@ class SearchActivity : AbsMusicServiceActivity(), OnQueryTextListener, TextWatch intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault()) intent.putExtra(RecognizerIntent.EXTRA_PROMPT, getString(R.string.speech_prompt)) try { - startActivityForResult(intent, REQ_CODE_SPEECH_INPUT) + startActivityForResult( + intent, + REQ_CODE_SPEECH_INPUT + ) } catch (e: ActivityNotFoundException) { e.printStackTrace() Toast.makeText(this, getString(R.string.speech_not_supported), Toast.LENGTH_SHORT) diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/search/SearchViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/activities/search/SearchViewModel.kt new file mode 100644 index 00000000..550a8d23 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/activities/search/SearchViewModel.kt @@ -0,0 +1,22 @@ +package code.name.monkey.retromusic.activities.search + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import code.name.monkey.retromusic.providers.RepositoryImpl +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.Dispatchers.Main +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class SearchViewModel(private val repository: RepositoryImpl) : ViewModel() { + private val results = MutableLiveData>() + + fun getSearchResult(): LiveData> = results + + fun search(query: String?) = viewModelScope.launch(IO) { + val result = repository.search(query) + withContext(Main) { results.postValue(result) } + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.kt b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.kt index 1bf1e90c..96a9123b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/appshortcuts/AppShortcutLauncherActivity.kt @@ -17,7 +17,7 @@ package code.name.monkey.retromusic.appshortcuts import android.app.Activity import android.content.Intent import android.os.Bundle -import code.name.monkey.retromusic.activities.SearchActivity +import code.name.monkey.retromusic.activities.search.SearchActivity import code.name.monkey.retromusic.appshortcuts.shortcuttype.LastAddedShortcutType import code.name.monkey.retromusic.appshortcuts.shortcuttype.SearchShortCutType import code.name.monkey.retromusic.appshortcuts.shortcuttype.ShuffleAllShortcutType diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt index 256c91ae..9ffa6af5 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt @@ -1,25 +1,23 @@ package code.name.monkey.retromusic.fragments -import android.app.Application -import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import code.name.monkey.retromusic.adapter.HomeAdapter import code.name.monkey.retromusic.fragments.ReloadType.* import code.name.monkey.retromusic.interfaces.MusicServiceEventListener import code.name.monkey.retromusic.model.* import code.name.monkey.retromusic.providers.RepositoryImpl -import code.name.monkey.retromusic.providers.interfaces.Repository import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.async import kotlinx.coroutines.launch -class LibraryViewModel(application: Application) : - AndroidViewModel(application), MusicServiceEventListener { +class LibraryViewModel( + private val repository: RepositoryImpl +) : ViewModel(), MusicServiceEventListener { - private val _repository: Repository = RepositoryImpl(application.applicationContext) private val _albums = MutableLiveData>() private val _songs = MutableLiveData>() private val _artists = MutableLiveData>() @@ -52,12 +50,12 @@ class LibraryViewModel(application: Application) : private fun loadHomeSections() = viewModelScope.launch { val list = mutableListOf() val result = listOf( - _repository.topArtists(), - _repository.topAlbums(), - _repository.recentArtists(), - _repository.recentAlbums(), - _repository.suggestions(), - _repository.favoritePlaylist() + repository.topArtists(), + repository.topAlbums(), + repository.recentArtists(), + repository.recentAlbums(), + repository.suggestions(), + repository.favoritePlaylist() ) result.forEach { if (it != null && it.arrayList.isNotEmpty()) { @@ -75,27 +73,27 @@ class LibraryViewModel(application: Application) : private val loadSongs: Deferred> get() = viewModelScope.async(IO) { - _repository.allSongs() + repository.allSongs() } private val loadAlbums: Deferred> get() = viewModelScope.async(IO) { - _repository.allAlbums() + repository.allAlbums() } private val loadArtists: Deferred> get() = viewModelScope.async(IO) { - _repository.allArtists() + repository.allArtists() } private val loadPlaylists: Deferred> get() = viewModelScope.async(IO) { - _repository.allPlaylists() + repository.allPlaylists() } private val loadGenres: Deferred> get() = viewModelScope.async(IO) { - _repository.allGenres() + repository.allGenres() } fun forceReload(reloadType: ReloadType) = viewModelScope.launch { diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/BaseView.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/BaseView.kt deleted file mode 100644 index 72507aa1..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/BaseView.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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.mvp - -/** - * Created by hemanths on 09/08/17. - */ - -interface BaseView { - - fun showEmptyView() -} diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/Presenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/Presenter.kt deleted file mode 100644 index 3e6889ad..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/Presenter.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.mvp - -import androidx.annotation.CallSuper - -/** - * Created by hemanths on 16/08/17. - */ - - -interface Presenter { - @CallSuper - fun attachView(view: T) - - @CallSuper - fun detachView() -} diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/PresenterImpl.java b/app/src/main/java/code/name/monkey/retromusic/mvp/PresenterImpl.java deleted file mode 100644 index 82d9950b..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/PresenterImpl.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.mvp; - -/** - * Created by hemanths on 2019-09-04. - */ -public abstract class PresenterImpl { - protected T view; - - public void attachView(T view) { - this.view = view; - } - - public void detachView() { - view = null; - } -} diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumDetailsPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumDetailsPresenter.kt deleted file mode 100644 index b032530f..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumDetailsPresenter.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.mvp.presenter - -import code.name.monkey.retromusic.model.Album -import code.name.monkey.retromusic.model.Artist -import code.name.monkey.retromusic.rest.model.LastFmAlbum - -/** - * Created by hemanths on 20/08/17. - */ -interface AlbumDetailsView { - - fun album(album: Album) - - fun complete() - - fun loadArtistImage(artist: Artist) - - fun moreAlbums(albums: List) - - fun aboutAlbum(lastFmAlbum: LastFmAlbum) -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.kt deleted file mode 100644 index cd58717f..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * 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.mvp.presenter - -import code.name.monkey.retromusic.model.Artist -import code.name.monkey.retromusic.mvp.BaseView -import code.name.monkey.retromusic.rest.model.LastFmArtist - -/** - * Created by hemanths on 20/08/17. - */ -interface ArtistDetailsView : BaseView { - - fun artist(artist: Artist) - - fun artistInfo(lastFmArtist: LastFmArtist?) - - fun complete() -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/GenreDetailsPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/GenreDetailsPresenter.kt deleted file mode 100644 index a3782fd1..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/GenreDetailsPresenter.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.mvp.presenter - -import code.name.monkey.retromusic.model.Song -import code.name.monkey.retromusic.mvp.BaseView -import code.name.monkey.retromusic.mvp.Presenter -import code.name.monkey.retromusic.mvp.PresenterImpl -import code.name.monkey.retromusic.providers.interfaces.Repository -import kotlinx.coroutines.* -import kotlinx.coroutines.Dispatchers.Main -import kotlin.coroutines.CoroutineContext - -/** - * Created by hemanths on 20/08/17. - */ - -interface GenreDetailsView : BaseView { - - fun songs(songs: List) -} - -interface GenreDetailsPresenter : Presenter { - fun loadGenreSongs(genreId: Int) - - class GenreDetailsPresenterImpl constructor( - private val repository: Repository - ) : PresenterImpl(), GenreDetailsPresenter, CoroutineScope { - - private val job = Job() - - override val coroutineContext: CoroutineContext - get() = Dispatchers.IO + job - - override fun detachView() { - super.detachView() - job.cancel() - } - - override fun loadGenreSongs(genreId: Int) { - launch { - val result = repository.getGenre(genreId) - withContext(Main) { view?.songs(result) } - } - } - } -} diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/PlaylistSongsPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/PlaylistSongsPresenter.kt deleted file mode 100644 index df7d2e52..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/PlaylistSongsPresenter.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.mvp.presenter - -import code.name.monkey.retromusic.model.Playlist -import code.name.monkey.retromusic.model.Song -import code.name.monkey.retromusic.mvp.BaseView -import code.name.monkey.retromusic.mvp.Presenter -import code.name.monkey.retromusic.mvp.PresenterImpl -import code.name.monkey.retromusic.providers.interfaces.Repository -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers.IO -import kotlinx.coroutines.Dispatchers.Main -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import kotlin.coroutines.CoroutineContext - -/** - * Created by hemanths on 20/08/17. - */ -interface PlaylistSongsView : BaseView { - - fun songs(songs: List) -} - -interface PlaylistSongsPresenter : Presenter { - fun loadPlaylistSongs(playlist: Playlist) - - class PlaylistSongsPresenterImpl constructor( - private val repository: Repository - ) : PresenterImpl(), PlaylistSongsPresenter, CoroutineScope { - - private var job: Job = Job() - - override val coroutineContext: CoroutineContext - get() = IO + job - - override fun loadPlaylistSongs(playlist: Playlist) { - launch { - val songs = repository.getPlaylistSongs(playlist) - withContext(Main) { view?.songs(songs) } - } - } - - override fun detachView() { - super.detachView() - job.cancel() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/SearchPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/SearchPresenter.kt deleted file mode 100644 index 709cc550..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/SearchPresenter.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.mvp.presenter - -import code.name.monkey.retromusic.mvp.BaseView -import code.name.monkey.retromusic.mvp.Presenter -import code.name.monkey.retromusic.mvp.PresenterImpl -import code.name.monkey.retromusic.providers.interfaces.Repository -import kotlinx.coroutines.* - -import kotlin.coroutines.CoroutineContext - -/** - * Created by hemanths on 20/08/17. - */ - -interface SearchView : BaseView { - - fun showData(data: MutableList) -} - -interface SearchPresenter : Presenter { - - fun search(query: String?) - - class SearchPresenterImpl constructor( - private val repository: Repository - ) : PresenterImpl(), SearchPresenter, CoroutineScope { - - override val coroutineContext: CoroutineContext - get() = Dispatchers.IO + job - - private var job: Job = Job() - - override fun detachView() { - super.detachView() - job.cancel() - } - - override fun search(query: String?) { - launch { - val result = repository.search(query) - withContext(Dispatchers.Main) { view?.showData(result) } - } - } - } -} - - diff --git a/app/src/main/java/code/name/monkey/retromusic/providers/ProviderModule.kt b/app/src/main/java/code/name/monkey/retromusic/providers/ProviderModule.kt new file mode 100644 index 00000000..00588a7c --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/providers/ProviderModule.kt @@ -0,0 +1,11 @@ +package code.name.monkey.retromusic.providers + +import org.eclipse.egit.github.core.Repository +import org.koin.dsl.bind +import org.koin.dsl.module + +val provideModules = module { + single { + RepositoryImpl(get()) + } bind Repository::class +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java index c67d0c92..a95fa881 100755 --- a/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java @@ -30,13 +30,13 @@ import org.jetbrains.annotations.NotNull; import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.activities.AboutActivity; import code.name.monkey.retromusic.activities.DriveModeActivity; -import code.name.monkey.retromusic.activities.GenreDetailsActivity; +import code.name.monkey.retromusic.activities.genre.GenreDetailsActivity; import code.name.monkey.retromusic.activities.LicenseActivity; import code.name.monkey.retromusic.activities.LyricsActivity; import code.name.monkey.retromusic.activities.PlayingQueueActivity; -import code.name.monkey.retromusic.activities.PlaylistDetailActivity; +import code.name.monkey.retromusic.activities.playlist.PlaylistDetailActivity; import code.name.monkey.retromusic.activities.PurchaseActivity; -import code.name.monkey.retromusic.activities.SearchActivity; +import code.name.monkey.retromusic.activities.search.SearchActivity; import code.name.monkey.retromusic.activities.SettingsActivity; import code.name.monkey.retromusic.activities.SupportDevelopmentActivity; import code.name.monkey.retromusic.activities.UserInfoActivity;