diff --git a/app/build.gradle b/app/build.gradle index b1584cf7c..137e6fbff 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -22,8 +22,8 @@ android { vectorDrawables.useSupportLibrary = true applicationId "code.name.monkey.retromusic" - versionCode 405 - versionName '3.4.900' + versionCode 408 + versionName '3.5.000' multiDexEnabled true @@ -129,8 +129,8 @@ dependencies { implementation 'androidx.preference:preference:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'androidx.core:core-ktx:1.1.0' - implementation 'androidx.fragment:fragment:1.2.0' + implementation 'androidx.core:core-ktx:1.2.0' + implementation 'androidx.fragment:fragment:1.2.1' implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'com.google.android.material:material:1.2.0-alpha04' diff --git a/app/src/main/assets/retro-changelog.html b/app/src/main/assets/retro-changelog.html index 4e4bceafc..b5cdef453 100644 --- a/app/src/main/assets/retro-changelog.html +++ b/app/src/main/assets/retro-changelog.html @@ -1 +1 @@ -

v3.4.900

v3.4.850

v3.4.800

v3.4.700

v3.4.600

v3.4.500

If you see entire app white or dark or black select same theme in settings to fix

FAQ's

*If you face any UI related issues you clear app data and cache, if its not working try to uninstall and install again.

\ No newline at end of file +

v.3.5.000

v3.4.900

v3.4.850

v3.4.800

v3.4.700

v3.4.600

v3.4.500

If you see entire app white or dark or black select same theme in settings to fix

FAQ's

*If you face any UI related issues you clear app data and cache, if its not working try to uninstall and install again.

\ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/Constants.kt b/app/src/main/java/code/name/monkey/retromusic/Constants.kt index 3da9b5471..d7cf6fc36 100644 --- a/app/src/main/java/code/name/monkey/retromusic/Constants.kt +++ b/app/src/main/java/code/name/monkey/retromusic/Constants.kt @@ -31,7 +31,7 @@ object Constants { const val FAQ_LINK = "https://github.com/h4h13/RetroMusicPlayer/blob/master/FAQ.md" const val PINTEREST = "https://in.pinterest.com/retromusicapp/" - const val BASE_SELECTION = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''" + const val baseSelection = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''" val baseProjection = arrayOf(BaseColumns._ID, // 0 MediaStore.Audio.AudioColumns.TITLE, // 1 diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/AlbumDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/AlbumDetailsActivity.kt index a1318a866..8c80992e5 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/AlbumDetailsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/AlbumDetailsActivity.kt @@ -8,7 +8,6 @@ import android.view.Menu import android.view.MenuItem import android.view.SubMenu import android.view.View -import android.widget.ImageView import androidx.core.app.ActivityCompat import androidx.recyclerview.widget.DefaultItemAnimator import androidx.recyclerview.widget.GridLayoutManager @@ -27,14 +26,15 @@ import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog import code.name.monkey.retromusic.dialogs.DeleteSongsDialog import code.name.monkey.retromusic.extensions.ripAlpha import code.name.monkey.retromusic.extensions.show +import code.name.monkey.retromusic.glide.AlbumGlideRequest import code.name.monkey.retromusic.glide.ArtistGlideRequest import code.name.monkey.retromusic.glide.RetroMusicColoredTarget -import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.helper.MusicPlayerRemote 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.model.Song import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsPresenter import code.name.monkey.retromusic.mvp.presenter.AlbumDetailsView import code.name.monkey.retromusic.rest.model.LastFmAlbum @@ -48,6 +48,7 @@ import com.bumptech.glide.Glide import kotlinx.android.synthetic.main.activity_album.albumCoverContainer import kotlinx.android.synthetic.main.activity_album.albumText import kotlinx.android.synthetic.main.activity_album.albumTitle +import kotlinx.android.synthetic.main.activity_album.artistImage import kotlinx.android.synthetic.main.activity_album.image import kotlinx.android.synthetic.main.activity_album.toolbar import kotlinx.android.synthetic.main.activity_album_content.aboutAlbumText @@ -62,7 +63,6 @@ import kotlinx.android.synthetic.main.activity_album_content.scrobbles import kotlinx.android.synthetic.main.activity_album_content.scrobblesLabel import kotlinx.android.synthetic.main.activity_album_content.shuffleAction import kotlinx.android.synthetic.main.activity_album_content.songTitle -import java.util.ArrayList import javax.inject.Inject import android.util.Pair as UtilPair @@ -88,8 +88,9 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C private lateinit var simpleSongAdapter: SimpleSongAdapter private lateinit var album: Album - private lateinit var artistImage: ImageView + private lateinit var songs: List private var cab: MaterialCab? = null + private val savedSortOrder: String get() = PreferenceUtil.getInstance(this).albumDetailSongSortOrder @@ -106,7 +107,6 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C slide.excludeTarget(R.id.status_bar, true) slide.excludeTarget(android.R.id.statusBarBackground, true) slide.excludeTarget(android.R.id.navigationBarBackground, true) - window.enterTransition = slide } @@ -124,7 +124,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C albumDetailsPresenter.attachView(this) if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) { - intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { + intent.extras?.getLong(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) albumCoverContainer?.transitionName = "${getString(R.string.transition_album_art)}_$it" } @@ -135,12 +135,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C windowEnterTransition() ActivityCompat.postponeEnterTransition(this) - - artistImage = findViewById(R.id.artistImage) - setupRecyclerView() artistImage.setOnClickListener { + println("Click Artist $album") val artistPairs = ActivityOptions.makeSceneTransitionAnimation( this, UtilPair.create( @@ -151,10 +149,10 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C NavigationUtil.goToArtistOptions(this, album.artistId, artistPairs) } playAction.apply { - setOnClickListener { MusicPlayerRemote.openQueue(album.songs!!, 0, true) } + setOnClickListener { MusicPlayerRemote.openQueue(songs, 0, true) } } shuffleAction.apply { - setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album.songs!!, true) } + setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songs, true) } } aboutAlbumText.setOnClickListener { @@ -187,39 +185,30 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C override fun album(album: Album) { complete() - if (album.songs!!.isEmpty()) { - finish() - return - } this.album = album - albumTitle.text = album.title if (MusicUtil.getYearString(album.year) == "-") { - albumText.text = String.format( - "%s • %s", - album.artistName, - MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs)) - ) + albumText.text = String.format("%s", album.artist) } else { - albumText.text = String.format( - "%s • %s • %s", - album.artistName, - MusicUtil.getYearString(album.year), - MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs)) - ) + albumText.text = String.format("%s • %s", album.artist, MusicUtil.getYearString(album.year)) } loadAlbumCover() - simpleSongAdapter.swapDataSet(album.songs) + albumDetailsPresenter.albumSongs(album.id) albumDetailsPresenter.loadMore(album.artistId) - albumDetailsPresenter.aboutAlbum(album.artistName!!, album.title!!) + albumDetailsPresenter.aboutAlbum(album.artist, album.title) } - override fun moreAlbums(albums: ArrayList) { + override fun songs(songs: List) { + this.songs = songs + simpleSongAdapter.swapDataSet(songs) + } + + override fun moreAlbums(albums: List) { moreTitle.show() moreRecyclerView.show() - moreTitle.text = String.format(getString(R.string.label_more_from), album.artistName) + moreTitle.text = String.format(getString(R.string.label_more_from), album.artist) - val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null) + val albumAdapter = HorizontalAlbumAdapter(this, albums, null) moreRecyclerView.layoutManager = GridLayoutManager( this, 1, @@ -250,19 +239,23 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C } override fun loadArtistImage(artist: Artist) { - ArtistGlideRequest.Builder.from(Glide.with(this), artist).generatePalette(this).build() - .dontAnimate().dontTransform().into(object : RetroMusicColoredTarget(artistImage) { + ArtistGlideRequest.Builder.from(Glide.with(this), artist) + .generatePalette(this) + .build() + .dontAnimate() + .dontTransform() + .into(object : RetroMusicColoredTarget(artistImage) { override fun onColorReady(color: Int) { } }) } private fun loadAlbumCover() { - SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong()) - .checkIgnoreMediaStore(this) - .ignoreMediaStore(PreferenceUtil.getInstance(this).ignoreMediaStoreArtwork()) + AlbumGlideRequest.Builder(Glide.with(this), album.id) .generatePalette(this) - .build().dontAnimate().dontTransform() + .build() + .dontAnimate() + .dontTransform() .into(object : RetroMusicColoredTarget(image) { override fun onColorReady(color: Int) { setColors(color) @@ -362,16 +355,18 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C private fun setUpSortOrderMenu(sortOrder: SubMenu) { when (savedSortOrder) { - AlbumSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title).isChecked = true - AlbumSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true - AlbumSongSortOrder.SONG_TRACK_LIST -> sortOrder.findItem(R.id.action_sort_order_track_list).isChecked = - true - AlbumSongSortOrder.SONG_DURATION -> sortOrder.findItem(R.id.action_sort_order_artist_song_duration) - .isChecked = true + AlbumSongSortOrder.SONG_A_Z -> + sortOrder.findItem(R.id.action_sort_order_title).isChecked = true + AlbumSongSortOrder.SONG_Z_A -> + sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true + AlbumSongSortOrder.SONG_TRACK_LIST -> + sortOrder.findItem(R.id.action_sort_order_track_list).isChecked = true + AlbumSongSortOrder.SONG_DURATION -> + sortOrder.findItem(R.id.action_sort_order_artist_song_duration).isChecked = true } } - private fun setSaveSortOrder(sortOrder: String?) { + private fun setSaveSortOrder(sortOrder: String) { PreferenceUtil.getInstance(this).albumDetailSongSortOrder = sortOrder reload() } @@ -383,7 +378,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView, C private fun reload() { if (intent.extras!!.containsKey(EXTRA_ALBUM_ID)) { - intent.extras?.getInt(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) } + intent.extras?.getLong(EXTRA_ALBUM_ID)?.let { albumDetailsPresenter.loadAlbum(it) } } else { finish() } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt index 359bfde6f..e34e468a4 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/ArtistDetailActivity.kt @@ -29,7 +29,9 @@ import code.name.monkey.retromusic.glide.ArtistGlideRequest 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.Album import code.name.monkey.retromusic.model.Artist +import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView import code.name.monkey.retromusic.rest.model.LastFmArtist @@ -57,7 +59,6 @@ import kotlinx.android.synthetic.main.activity_artist_details.artistTitle import kotlinx.android.synthetic.main.activity_artist_details.image import kotlinx.android.synthetic.main.activity_artist_details.text import kotlinx.android.synthetic.main.activity_artist_details.toolbar -import java.text.DecimalFormat import java.util.Locale import javax.inject.Inject @@ -84,6 +85,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, private var cab: MaterialCab? = null private var biography: Spanned? = null private lateinit var artist: Artist + private lateinit var songs: List private lateinit var songAdapter: SimpleSongAdapter private lateinit var albumAdapter: HorizontalAlbumAdapter private var forceDownload: Boolean = false @@ -118,7 +120,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, artistDetailsPresenter.attachView(this) if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) { - intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { + intent.extras?.getLong(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) val name = "${getString(R.string.transition_artist_image)}_$it" artistCoverContainer?.transitionName = name @@ -133,10 +135,10 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, setupRecyclerView() playAction.apply { - setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) } + setOnClickListener { MusicPlayerRemote.openQueue(songs, 0, true) } } shuffleAction.apply { - setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(artist.songs, true) } + setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songs, true) } } biographyText.setOnClickListener { @@ -154,7 +156,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, } private fun setupRecyclerView() { - albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null) + albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), null) albumRecyclerView.apply { itemAnimator = DefaultItemAnimator() layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false) @@ -189,6 +191,15 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, ActivityCompat.startPostponedEnterTransition(this) } + override fun songs(songs: List) { + this.songs = songs + songAdapter.swapDataSet(songs) + } + + override fun albums(albums: List) { + albumAdapter.swapDataSet(ArrayList(albums)) + } + override fun artist(artist: Artist) { complete() if (artist.songCount <= 0) { @@ -202,13 +213,11 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, } artistTitle.text = artist.name text.text = String.format( - "%s • %s", - MusicUtil.getArtistInfoString(this, artist), - MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(artist.songs)) + "%s", + MusicUtil.getArtistInfoString(this, artist) ) - - songAdapter.swapDataSet(artist.songs) - albumAdapter.swapDataSet(artist.albums!!) + artistDetailsPresenter.loadArtistAlbums(artist.id) + artistDetailsPresenter.loadArtistSongs(artist.id) } private fun loadBiography( @@ -281,30 +290,17 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, MaterialUtil.setTint(button = playAction, color = buttonColor) val toolbarColor = ATHUtil.resolveColor(this, R.attr.colorSurface) - //status_bar.setBackgroundColor(toolbarColor) + toolbar.setBackgroundColor(toolbarColor) setSupportActionBar(toolbar) supportActionBar?.title = null } - private fun numberFormat(count: Float): String { - val prefixes = arrayOf("", "K", "M", "B", "T", "P", "E") - var index = 0 - var finalCount = count - while (finalCount / 1000 >= 1) { - finalCount /= 1000 - index++ - } - val decimal = DecimalFormat("#.##") - return String.format("%s %s", decimal.format(finalCount), prefixes[index]) - } - override fun onOptionsItemSelected(item: MenuItem): Boolean { return handleSortOrderMenuItem(item) } private fun handleSortOrderMenuItem(item: MenuItem): Boolean { - val songs = artist.songs when (item.itemId) { android.R.id.home -> { super.onBackPressed() @@ -354,7 +350,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView, private fun reload() { if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) { - intent.extras?.getInt(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) } + intent.extras?.getLong(EXTRA_ARTIST_ID)?.let { artistDetailsPresenter.loadArtist(it) } } else { finish() } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/GenreDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/GenreDetailsActivity.kt index 23d0b8510..b9238f83e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/GenreDetailsActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/GenreDetailsActivity.kt @@ -129,7 +129,7 @@ class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), CabHolder, GenreDet }) } - override fun songs(songs: ArrayList) { + override fun songs(songs: List) { songAdapter.swapDataSet(songs) } 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 7a9513d78..ab1d7dc7a 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 @@ -19,8 +19,6 @@ import code.name.monkey.retromusic.fragments.mainactivity.home.BannerHomeFragmen import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.SearchQueryHelper import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks -import code.name.monkey.retromusic.loaders.AlbumLoader -import code.name.monkey.retromusic.loaders.ArtistLoader import code.name.monkey.retromusic.loaders.PlaylistSongsLoader import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.util.AppRater @@ -155,14 +153,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP val id = parseIdFromIntent(intent, "albumId", "album").toInt() if (id >= 0) { val position = intent.getIntExtra("position", 0) - MusicPlayerRemote.openQueue(AlbumLoader.getAlbum(this, id).songs!!, position, true) + //MusicPlayerRemote.openQueue(AlbumLoader.getAlbum(this, id).songs!!, position, true) handled = true } } else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) { val id = parseIdFromIntent(intent, "artistId", "artist").toInt() if (id >= 0) { val position = intent.getIntExtra("position", 0) - MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).songs, position, true) + //MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).songs, position, true) handled = true } } @@ -220,7 +218,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { - if (key == PreferenceUtil.GENERAL_THEME || key == PreferenceUtil.BLACK_THEME || key == PreferenceUtil.ADAPTIVE_COLOR_APP || key == PreferenceUtil.DOMINANT_COLOR || key == PreferenceUtil.USER_NAME || key == PreferenceUtil.TOGGLE_FULL_SCREEN || key == PreferenceUtil.TOGGLE_VOLUME || key == PreferenceUtil.ROUND_CORNERS || key == PreferenceUtil.CAROUSEL_EFFECT || key == PreferenceUtil.NOW_PLAYING_SCREEN_ID || key == PreferenceUtil.TOGGLE_GENRE || key == PreferenceUtil.BANNER_IMAGE_PATH || key == PreferenceUtil.PROFILE_IMAGE_PATH || key == PreferenceUtil.CIRCULAR_ALBUM_ART || key == PreferenceUtil.KEEP_SCREEN_ON || key == PreferenceUtil.TOGGLE_SEPARATE_LINE || key == PreferenceUtil.ALBUM_GRID_STYLE || key == PreferenceUtil.ARTIST_GRID_STYLE || key == PreferenceUtil.TOGGLE_HOME_BANNER || key == PreferenceUtil.TOGGLE_ADD_CONTROLS || key == PreferenceUtil.ALBUM_COVER_STYLE || key == PreferenceUtil.HOME_ARTIST_GRID_STYLE || key == PreferenceUtil.ALBUM_COVER_TRANSFORM || key == PreferenceUtil.DESATURATED_COLOR || key == PreferenceUtil.TAB_TEXT_MODE || key == PreferenceUtil.LIBRARY_CATEGORIES + if (key == PreferenceUtil.GENERAL_THEME || key == PreferenceUtil.BLACK_THEME || key == PreferenceUtil.ADAPTIVE_COLOR_APP || key == PreferenceUtil.DOMINANT_COLOR || key == PreferenceUtil.USER_NAME || key == PreferenceUtil.TOGGLE_FULL_SCREEN || key == PreferenceUtil.TOGGLE_VOLUME || key == PreferenceUtil.ROUND_CORNERS || key == PreferenceUtil.CAROUSEL_EFFECT || key == PreferenceUtil.NOW_PLAYING_SCREEN_ID || key == PreferenceUtil.TOGGLE_GENRE || key == PreferenceUtil.BANNER_IMAGE_PATH || key == PreferenceUtil.PROFILE_IMAGE_PATH || key == PreferenceUtil.CIRCULAR_ALBUM_ART || key == PreferenceUtil.KEEP_SCREEN_ON || key == PreferenceUtil.TOGGLE_SEPARATE_LINE || key == PreferenceUtil.TOGGLE_HOME_BANNER || key == PreferenceUtil.TOGGLE_ADD_CONTROLS || key == PreferenceUtil.ALBUM_COVER_STYLE || key == PreferenceUtil.HOME_ARTIST_GRID_STYLE || key == PreferenceUtil.ALBUM_COVER_TRANSFORM || key == PreferenceUtil.DESATURATED_COLOR || key == PreferenceUtil.TAB_TEXT_MODE || key == PreferenceUtil.LIBRARY_CATEGORIES ) postRecreate() } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PlaylistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/PlaylistDetailActivity.kt index f09afd9ab..ab22a62e1 100644 --- a/app/src/main/java/code/name/monkey/retromusic/activities/PlaylistDetailActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/PlaylistDetailActivity.kt @@ -238,7 +238,7 @@ class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, Playli emptyText.visibility = View.VISIBLE } - override fun songs(songs: ArrayList) { + override fun songs(songs: List) { adapter.swapDataSet(songs) } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt index a51a8976f..865a078ba 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt @@ -40,7 +40,7 @@ import java.util.Collections abstract class AbsTagEditorActivity : AbsBaseActivity() { - protected var id: Int = 0 + protected var id: Long = 0 private set private var paletteColorPrimary: Int = 0 private var isInNoImageMode: Boolean = false @@ -187,22 +187,16 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() { } setUpViews() - setStatusbarColorAuto() setNavigationbarColorAuto() setTaskDescriptionColorAuto() } private fun setUpViews() { - setUpScrollView() setUpFab() setUpImageView() } - private fun setUpScrollView() { - //observableScrollView.setScrollViewCallbacks(observableScrollViewCallbacks); - } - private lateinit var items: List private fun setUpImageView() { @@ -261,7 +255,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() { private fun getIntentExtras() { val intentExtras = intent.extras if (intentExtras != null) { - id = intentExtras.getInt(EXTRA_ID) + id = intentExtras.getLong(EXTRA_ID) } } @@ -406,7 +400,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() { } } - class ArtworkInfo constructor(val albumId: Int, val artwork: Bitmap?) + class ArtworkInfo constructor(val albumId: Long, val artwork: Bitmap?) companion object { @@ -415,5 +409,4 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() { private val TAG = AbsTagEditorActivity::class.java.simpleName private const val REQUEST_CODE_SELECT_IMAGE = 1000 } - } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt index 244141e6e..28437c3f0 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt @@ -15,7 +15,6 @@ import android.widget.Toast import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.extensions.appHandleColor import code.name.monkey.retromusic.extensions.applyToolbar import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper @@ -32,6 +31,8 @@ import kotlinx.android.synthetic.main.activity_album_tag_editor.albumArtistConta import kotlinx.android.synthetic.main.activity_album_tag_editor.albumArtistText import kotlinx.android.synthetic.main.activity_album_tag_editor.albumText import kotlinx.android.synthetic.main.activity_album_tag_editor.albumTitleContainer +import kotlinx.android.synthetic.main.activity_album_tag_editor.artistContainer +import kotlinx.android.synthetic.main.activity_album_tag_editor.artistText import kotlinx.android.synthetic.main.activity_album_tag_editor.genreContainer import kotlinx.android.synthetic.main.activity_album_tag_editor.genreTitle import kotlinx.android.synthetic.main.activity_album_tag_editor.imageContainer @@ -39,7 +40,6 @@ import kotlinx.android.synthetic.main.activity_album_tag_editor.toolbar import kotlinx.android.synthetic.main.activity_album_tag_editor.yearContainer import kotlinx.android.synthetic.main.activity_album_tag_editor.yearTitle import org.jaudiotagger.tag.FieldKey -import java.util.ArrayList import java.util.EnumMap class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher { @@ -58,7 +58,9 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher { override fun loadImageFromFile(selectedFileUri: Uri?) { - Glide.with(this@AlbumTagEditorActivity).load(selectedFileUri).asBitmap() + Glide.with(this@AlbumTagEditorActivity) + .load(selectedFileUri) + .asBitmap() .transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java) .diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true) .into(object : SimpleTarget() { @@ -115,15 +117,18 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher { MaterialUtil.setTint(genreContainer, false) MaterialUtil.setTint(albumTitleContainer, false) MaterialUtil.setTint(albumArtistContainer, false) + MaterialUtil.setTint(artistContainer, false) - albumText.appHandleColor().addTextChangedListener(this) - albumArtistText.appHandleColor().addTextChangedListener(this) - genreTitle.appHandleColor().addTextChangedListener(this) - yearTitle.appHandleColor().addTextChangedListener(this) + albumText.addTextChangedListener(this) + artistText.addTextChangedListener(this) + albumArtistText.addTextChangedListener(this) + genreTitle.addTextChangedListener(this) + yearTitle.addTextChangedListener(this) } private fun fillViewsWithFileTags() { albumText.setText(albumTitle) + artistText.setText(artistName) albumArtistText.setText(albumArtistName) genreTitle.setText(genreName) yearTitle.setText(songYear) @@ -141,10 +146,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher { deleteAlbumArt = false } - override fun onPause() { - super.onPause() - } - private fun toastLoadingFailed() { Toast.makeText( this@AlbumTagEditorActivity, @@ -170,21 +171,24 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher { val fieldKeyValueMap = EnumMap(FieldKey::class.java) fieldKeyValueMap[FieldKey.ALBUM] = albumText.text.toString() //android seems not to recognize album_artist field so we additionally write the normal artist field - fieldKeyValueMap[FieldKey.ARTIST] = albumArtistText.text.toString() + fieldKeyValueMap[FieldKey.ARTIST] = artistText.text.toString() fieldKeyValueMap[FieldKey.ALBUM_ARTIST] = albumArtistText.text.toString() fieldKeyValueMap[FieldKey.GENRE] = genreTitle.text.toString() fieldKeyValueMap[FieldKey.YEAR] = yearTitle.text.toString() writeValuesToFiles( fieldKeyValueMap, - if (deleteAlbumArt) ArtworkInfo(id, null) - else if (albumArtBitmap == null) null else ArtworkInfo(id, albumArtBitmap!!) + when { + deleteAlbumArt -> ArtworkInfo(id, null) + albumArtBitmap == null -> null + else -> ArtworkInfo(id, albumArtBitmap!!) + } ) } override fun getSongPaths(): List { - val songs = AlbumLoader.getAlbum(this, id).songs - val paths = ArrayList(songs!!.size) + val songs = AlbumLoader.getSongsForAlbum(this, id) + val paths = ArrayList(songs.size) for (song in songs) { paths.add(song.data) } @@ -207,7 +211,6 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher { } companion object { - val TAG: String = AlbumTagEditorActivity::class.java.simpleName } } diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt index a76f74e9b..c5e8fde98 100755 --- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt +++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt @@ -6,7 +6,6 @@ import android.text.Editable import android.text.TextWatcher import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.retromusic.R -import code.name.monkey.retromusic.extensions.appHandleColor import code.name.monkey.retromusic.extensions.applyToolbar import code.name.monkey.retromusic.loaders.SongLoader import kotlinx.android.synthetic.main.activity_song_tag_editor.albumArtistContainer @@ -43,7 +42,6 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher { setNoImageMode() setUpViews() applyToolbar(toolbar) - } private fun setUpViews() { @@ -58,15 +56,15 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher { MaterialUtil.setTint(trackNumberContainer, false) MaterialUtil.setTint(lyricsContainer, false) - songText.appHandleColor().addTextChangedListener(this) - albumText.appHandleColor().addTextChangedListener(this) - albumArtistText.appHandleColor().addTextChangedListener(this) - artistText.appHandleColor().addTextChangedListener(this) - genreText.appHandleColor().addTextChangedListener(this) - yearText.appHandleColor().addTextChangedListener(this) - trackNumberText.appHandleColor().addTextChangedListener(this) - lyricsText.appHandleColor().addTextChangedListener(this) - songComposerText.appHandleColor().addTextChangedListener(this) + songText.addTextChangedListener(this) + albumText.addTextChangedListener(this) + albumArtistText.addTextChangedListener(this) + artistText.addTextChangedListener(this) + genreText.addTextChangedListener(this) + yearText.addTextChangedListener(this) + trackNumberText.addTextChangedListener(this) + lyricsText.addTextChangedListener(this) + songComposerText.addTextChangedListener(this) } private fun fillViewsWithFileTags() { diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt index ae5ed811c..2b888ed94 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt @@ -9,7 +9,6 @@ import code.name.monkey.retromusic.R import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.util.NavigationUtil -import java.util.ArrayList import java.util.Locale /** @@ -18,11 +17,11 @@ import java.util.Locale class GenreAdapter( private val activity: Activity, - dataSet: ArrayList, + dataSet: List, private val mItemLayoutRes: Int ) : RecyclerView.Adapter() { - var dataSet = ArrayList() + var dataSet = listOf() private set init { @@ -48,7 +47,7 @@ class GenreAdapter( return dataSet.size } - fun swapDataSet(list: ArrayList) { + fun swapDataSet(list: List) { dataSet = list notifyDataSetChanged() } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt index 10ce8b0ab..25c901536 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt @@ -52,7 +52,6 @@ class HomeAdapter( } override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { - println("ViewType ${getItemViewType(position)}") when (getItemViewType(position)) { RECENT_ALBUMS -> { val viewHolder = holder as AlbumViewHolder @@ -121,7 +120,6 @@ class HomeAdapter( activity, list, PreferenceUtil.getInstance(activity).getHomeGridStyle(activity), - false, null ) adapter = artistAdapter diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt index e2f7efdbb..75319f7c9 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt @@ -9,8 +9,9 @@ import androidx.recyclerview.widget.RecyclerView import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.retromusic.R import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder +import code.name.monkey.retromusic.glide.AlbumGlideRequest import code.name.monkey.retromusic.glide.ArtistGlideRequest -import code.name.monkey.retromusic.glide.SongGlideRequest +import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.menu.SongMenuHelper import code.name.monkey.retromusic.loaders.PlaylistSongsLoader @@ -60,9 +61,18 @@ class SearchAdapter( ALBUM -> { val album = dataSet?.get(position) as Album holder.title?.text = album.title - holder.text?.text = album.artistName - SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) - .checkIgnoreMediaStore(activity).build().into(holder.image) + holder.text?.text = album.artist + holder.image?.let { + AlbumGlideRequest.Builder(Glide.with(activity), album.id) + .generatePalette(activity) + .build() + .dontAnimate() + .dontTransform() + .into(object : RetroMusicColoredTarget(it) { + override fun onColorReady(color: Int) { + } + }) + } } ARTIST -> { val artist = dataSet?.get(position) as Artist @@ -134,21 +144,24 @@ class SearchAdapter( val item = dataSet!![adapterPosition] when (itemViewType) { ALBUM -> { + item as Album val options = ActivityOptions.makeSceneTransitionAnimation( activity, UtilPair.create(image, activity.getString(R.string.transition_album_art)) ) - NavigationUtil.goToAlbumOptions(activity, (item as Album).id, options) + NavigationUtil.goToAlbumOptions(activity, item.id, options) } ARTIST -> { + item as Artist val options = ActivityOptions.makeSceneTransitionAnimation( activity, UtilPair.create(image, activity.getString(R.string.transition_artist_image)) ) - NavigationUtil.goToArtistOptions(activity, (item as Artist).id, options) + NavigationUtil.goToArtistOptions(activity, item.id, options) } GENRE -> { - NavigationUtil.goToGenre(activity, item as Genre) + item as Genre + NavigationUtil.goToGenre(activity, item) } PLAYLIST -> { NavigationUtil.goToPlaylistNew(activity, item as Playlist) diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt index 13f2fc89d..4c100e055 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt @@ -2,7 +2,6 @@ package code.name.monkey.retromusic.adapter.album import android.app.ActivityOptions import android.content.res.ColorStateList -import android.graphics.drawable.Drawable import android.view.LayoutInflater import android.view.MenuItem import android.view.View @@ -13,9 +12,8 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.retromusic.R import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder +import code.name.monkey.retromusic.glide.AlbumGlideRequest import code.name.monkey.retromusic.glide.RetroMusicColoredTarget -import code.name.monkey.retromusic.glide.SongGlideRequest -import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.interfaces.CabHolder @@ -29,9 +27,8 @@ import me.zhanghai.android.fastscroll.PopupTextProvider open class AlbumAdapter( protected val activity: AppCompatActivity, - dataSet: ArrayList, - protected var itemLayoutRes: Int, - usePalette: Boolean, + dataSet: List, + var itemLayoutRes: Int, cabHolder: CabHolder? ) : AbsMultiSelectAdapter( activity, @@ -39,28 +36,15 @@ open class AlbumAdapter( R.menu.menu_media_selection ), PopupTextProvider { - var dataSet: ArrayList + var dataSet: List protected set - protected var usePalette = false - init { this.dataSet = dataSet - this.usePalette = usePalette this.setHasStableIds(true) } - fun useItemLayout(itemLayoutRes: Int) { - this.itemLayoutRes = itemLayoutRes - notifyDataSetChanged() - } - - fun usePalette(usePalette: Boolean) { - this.usePalette = usePalette - notifyDataSetChanged() - } - - fun swapDataSet(dataSet: ArrayList) { + fun swapDataSet(dataSet: List) { this.dataSet = dataSet notifyDataSetChanged() } @@ -79,7 +63,7 @@ open class AlbumAdapter( } protected open fun getAlbumText(album: Album): String? { - return album.artistName + return album.artist } override fun onBindViewHolder(holder: ViewHolder, position: Int) { @@ -88,15 +72,6 @@ open class AlbumAdapter( holder.itemView.isActivated = isChecked holder.title?.text = getAlbumTitle(album) holder.text?.text = getAlbumText(album) - holder.playSongs?.setOnClickListener { - album.songs?.let { songs -> - MusicPlayerRemote.openQueue( - songs, - 0, - true - ) - } - } loadAlbumCover(album, holder) } @@ -123,15 +98,12 @@ open class AlbumAdapter( if (holder.image == null) { return } - - SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) - .checkIgnoreMediaStore(activity).generatePalette(activity).build() + AlbumGlideRequest.Builder(Glide.with(activity), album.id) + .generatePalette(activity) + .build() + .dontAnimate() + .dontTransform() .into(object : RetroMusicColoredTarget(holder.image!!) { - override fun onLoadCleared(placeholder: Drawable?) { - super.onLoadCleared(placeholder) - setColors(defaultFooterColor, holder) - } - override fun onColorReady(color: Int) { setColors(color, holder) } @@ -143,7 +115,7 @@ open class AlbumAdapter( } override fun getItemId(position: Int): Long { - return dataSet[position].id.toLong() + return dataSet[position].id } override fun getIdentifier(position: Int): Album? { @@ -163,7 +135,7 @@ open class AlbumAdapter( private fun getSongList(albums: List): ArrayList { val songs = ArrayList() for (album in albums) { - songs.addAll(album.songs!!) + //songs.addAll(album.songs!!) } return songs } @@ -177,7 +149,7 @@ open class AlbumAdapter( when (PreferenceUtil.getInstance(activity).albumSortOrder) { SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName = dataSet[position].title - SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].artistName + SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].artist SortOrder.AlbumSortOrder.ALBUM_YEAR -> return MusicUtil.getYearString( dataSet[position].year ) diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumFullWidthAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumFullWidthAdapter.kt index 24c088c8b..e167e7bd2 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumFullWidthAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumFullWidthAdapter.kt @@ -22,9 +22,8 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.glide.AlbumGlideRequest import code.name.monkey.retromusic.glide.RetroMusicColoredTarget -import code.name.monkey.retromusic.glide.SongGlideRequest -import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.views.MetalRecyclerViewPager @@ -46,15 +45,6 @@ class AlbumFullWidthAdapter( val album = dataSet[position] holder.title?.text = getAlbumTitle(album) holder.text?.text = getAlbumText(album) - holder.playSongs?.setOnClickListener { - album.songs?.let { songs -> - MusicPlayerRemote.openQueue( - songs, - 0, - true - ) - } - } loadAlbumCover(album, holder) } @@ -63,21 +53,32 @@ class AlbumFullWidthAdapter( } private fun getAlbumText(album: Album): String? { - return album.artistName + return album.artist } private fun loadAlbumCover(album: Album, holder: FullMetalViewHolder) { if (holder.image == null) { return } - SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) + + AlbumGlideRequest.Builder(Glide.with(activity), album.id) + .generatePalette(activity) + .build() + .dontAnimate() + .dontTransform() + .into(object : RetroMusicColoredTarget(holder.image!!) { + override fun onColorReady(color: Int) { + + } + }) + /*SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) .checkIgnoreMediaStore(activity) .generatePalette(activity) .build() .into(object : RetroMusicColoredTarget(holder.image!!) { override fun onColorReady(color: Int) { } - }) + })*/ } override fun getItemCount(): Int { diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt index 5fb268b15..80e56669c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt @@ -1,26 +1,23 @@ package code.name.monkey.retromusic.adapter.album -import android.graphics.drawable.Drawable import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import code.name.monkey.appthemehelper.util.ATHUtil +import code.name.monkey.retromusic.glide.AlbumGlideRequest import code.name.monkey.retromusic.glide.RetroMusicColoredTarget -import code.name.monkey.retromusic.glide.SongGlideRequest import code.name.monkey.retromusic.helper.HorizontalAdapterHelper import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.util.MusicUtil import com.bumptech.glide.Glide -import java.util.ArrayList class HorizontalAlbumAdapter( activity: AppCompatActivity, - dataSet: ArrayList, - usePalette: Boolean, + dataSet: List, cabHolder: CabHolder? ) : AlbumAdapter( - activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, usePalette, cabHolder + activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, cabHolder ) { override fun createViewHolder(view: View, viewType: Int): ViewHolder { @@ -36,17 +33,14 @@ class HorizontalAlbumAdapter( override fun loadAlbumCover(album: Album, holder: ViewHolder) { if (holder.image == null) return - SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong()) - .checkIgnoreMediaStore(activity).generatePalette(activity).build() + AlbumGlideRequest.Builder(Glide.with(activity), album.id) + .generatePalette(activity) + .build() + .dontAnimate() + .dontTransform() .into(object : RetroMusicColoredTarget(holder.image!!) { - override fun onLoadCleared(placeholder: Drawable?) { - super.onLoadCleared(placeholder) - setColors(albumArtistFooterColor, holder) - } - override fun onColorReady(color: Int) { - if (usePalette) setColors(color, holder) - else setColors(albumArtistFooterColor, holder) + //setColors(color, holder) } }) } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/artist/ArtistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/artist/ArtistAdapter.kt index 362299e32..2b1ae68b4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/artist/ArtistAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/artist/ArtistAdapter.kt @@ -28,26 +28,20 @@ import java.util.ArrayList class ArtistAdapter( val activity: AppCompatActivity, - var dataSet: ArrayList, + var dataSet: List, var itemLayoutRes: Int, - var usePalette: Boolean, cabHolder: CabHolder? ) : AbsMultiSelectAdapter( activity, cabHolder, R.menu.menu_media_selection ), PopupTextProvider { - fun swapDataSet(dataSet: ArrayList) { + fun swapDataSet(dataSet: List) { this.dataSet = dataSet notifyDataSetChanged() } - fun usePalette(usePalette: Boolean) { - this.usePalette = usePalette - notifyDataSetChanged() - } - override fun getItemId(position: Int): Long { - return dataSet[position].id.toLong() + return dataSet[position].id } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { @@ -121,7 +115,7 @@ class ArtistAdapter( private fun getSongList(artists: List): ArrayList { val songs = ArrayList() for (artist in artists) { - songs.addAll(artist.songs) // maybe async in future? + //songs.addAll(artist.songs) // maybe async in future? } return songs } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/base/MediaEntryViewHolder.java b/app/src/main/java/code/name/monkey/retromusic/adapter/base/MediaEntryViewHolder.java index 014d7ea15..d39194120 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/base/MediaEntryViewHolder.java +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/base/MediaEntryViewHolder.java @@ -17,7 +17,6 @@ package code.name.monkey.retromusic.adapter.base; import android.graphics.Color; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; import androidx.annotation.NonNull; @@ -60,8 +59,6 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold @Nullable public View paletteColorContainer; - @Nullable - public ImageButton playSongs; @Nullable public RecyclerView recyclerView; @@ -93,7 +90,6 @@ public class MediaEntryViewHolder extends AbstractDraggableSwipeableItemViewHold paletteColorContainer = itemView.findViewById(R.id.paletteColorContainer); recyclerView = itemView.findViewById(R.id.recycler_view); mask = itemView.findViewById(R.id.mask); - playSongs = itemView.findViewById(R.id.playSongs); dummyContainer = itemView.findViewById(R.id.dummy_view); if (imageContainerCard != null) { diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt index 28f11ab3d..3d76940de 100755 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt @@ -34,7 +34,7 @@ import java.util.ArrayList class PlaylistAdapter( private val activity: AppCompatActivity, - var dataSet: ArrayList, + var dataSet: List, private var itemLayoutRes: Int, cabHolder: CabHolder? ) : AbsMultiSelectAdapter( @@ -49,7 +49,7 @@ class PlaylistAdapter( setHasStableIds(true) } - fun swapDataSet(dataSet: ArrayList) { + fun swapDataSet(dataSet: List) { this.dataSet = dataSet notifyDataSetChanged() } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/AbsOffsetSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/AbsOffsetSongAdapter.kt index b3427584c..89d3e5116 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/AbsOffsetSongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/AbsOffsetSongAdapter.kt @@ -9,11 +9,10 @@ import code.name.monkey.retromusic.R import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Song -import java.util.ArrayList abstract class AbsOffsetSongAdapter( activity: AppCompatActivity, - dataSet: ArrayList, + dataSet: MutableList, @LayoutRes itemLayoutRes: Int, cabHolder: CabHolder? ) : SongAdapter(activity, dataSet, itemLayoutRes, cabHolder) { diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlaylistSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlaylistSongAdapter.kt index 44a29b285..7cf315ae4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlaylistSongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlaylistSongAdapter.kt @@ -63,7 +63,7 @@ open class PlaylistSongAdapter( imageContainerCard ?: image, "${activity.getString(R.string.transition_album_art)}_${song.albumId}" ) - NavigationUtil.goToAlbumOptions(activity, song.albumId, activityOptions) + NavigationUtil.goToAlbumOptions(activity, song.albumId.toLong(), activityOptions) return true } return super.onSongMenuItemClick(item) diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/ShuffleButtonSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/ShuffleButtonSongAdapter.kt index 785a6925e..4f3935ad4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/ShuffleButtonSongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/ShuffleButtonSongAdapter.kt @@ -7,11 +7,10 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Song import com.google.android.material.button.MaterialButton -import java.util.ArrayList class ShuffleButtonSongAdapter( activity: AppCompatActivity, - dataSet: ArrayList, + dataSet: MutableList, itemLayoutRes: Int, cabHolder: CabHolder? ) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes, cabHolder) { diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt index 7bc79e954..aabef3608 100755 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SimpleSongAdapter.kt @@ -6,18 +6,16 @@ import androidx.appcompat.app.AppCompatActivity import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.MusicUtil -import java.util.ArrayList class SimpleSongAdapter( context: AppCompatActivity, - songs: ArrayList, + songs: MutableList, layoutRes: Int, cabHolder: CabHolder? ) : SongAdapter(context, songs, layoutRes, cabHolder) { - override fun swapDataSet(dataSet: ArrayList) { - this.dataSet.clear() - this.dataSet = dataSet + override fun swapDataSet(dataSet: List) { + this.dataSet = dataSet.toMutableList() notifyDataSetChanged() } diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt index adda7308d..6ff8d47df 100644 --- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/SongAdapter.kt @@ -34,7 +34,7 @@ import java.util.ArrayList open class SongAdapter( protected val activity: AppCompatActivity, - dataSet: ArrayList, + dataSet: MutableList, protected var itemLayoutRes: Int, cabHolder: CabHolder?, showSectionName: Boolean = true @@ -42,7 +42,7 @@ open class SongAdapter( activity, cabHolder, R.menu.menu_media_selection ), MaterialCab.Callback, PopupTextProvider { - var dataSet: ArrayList + var dataSet: MutableList private var showSectionName = true init { @@ -51,8 +51,8 @@ open class SongAdapter( this.setHasStableIds(true) } - open fun swapDataSet(dataSet: ArrayList) { - this.dataSet = dataSet + open fun swapDataSet(dataSet: List) { + this.dataSet = dataSet.toMutableList() notifyDataSetChanged() } @@ -177,7 +177,7 @@ open class SongAdapter( imageContainerCard ?: image, "${activity.getString(R.string.transition_album_art)}_${song.albumId}" ) - NavigationUtil.goToAlbumOptions(activity, song.albumId, activityOptions) + NavigationUtil.goToAlbumOptions(activity, song.albumId.toLong(), activityOptions) return true } } diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt index 0cf5f072f..9ae8af570 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt @@ -27,11 +27,10 @@ import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.list.listItems - class AddToPlaylistDialog : DialogFragment() { override fun onCreateDialog( - savedInstanceState: Bundle? + savedInstanceState: Bundle? ): Dialog { val playlists = PlaylistLoader.getAllPlaylists(requireContext()) val playlistNames: MutableList = mutableListOf() @@ -47,7 +46,9 @@ class AddToPlaylistDialog : DialogFragment() { val songs = arguments!!.getParcelableArrayList("songs") ?: return@listItems if (index == 0) { dialog.dismiss() - activity?.supportFragmentManager?.let { CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") } + activity?.supportFragmentManager?.let { + CreatePlaylistDialog.create(songs).show(it, "ADD_TO_PLAYLIST") + } } else { dialog.dismiss() PlaylistsUtil.addToPlaylist(requireContext(), songs, playlists[index - 1].id, true) @@ -64,10 +65,10 @@ class AddToPlaylistDialog : DialogFragment() { return create(list) } - fun create(songs: ArrayList): AddToPlaylistDialog { + fun create(songs: List): AddToPlaylistDialog { val dialog = AddToPlaylistDialog() val args = Bundle() - args.putParcelableArrayList("songs", songs) + args.putParcelableArrayList("songs", ArrayList(songs)) dialog.arguments = args return dialog } diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.kt index be3b01d30..5870d135c 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/BlacklistFolderChooserDialog.kt @@ -29,8 +29,8 @@ import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.list.listItems import java.io.File -import java.util.* -import kotlin.collections.ArrayList +import java.util.Collections +import java.util.Comparator class BlacklistFolderChooserDialog : DialogFragment() { @@ -40,7 +40,6 @@ class BlacklistFolderChooserDialog : DialogFragment() { private var canGoUp = false private var callback: FolderCallback? = null - private fun contentsArray(): List { if (parentContents == null) { return if (canGoUp) { @@ -81,7 +80,11 @@ class BlacklistFolderChooserDialog : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { var savedInstanceStateFinal = savedInstanceState if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && - ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.checkSelfPermission( + requireActivity(), + Manifest.permission.READ_EXTERNAL_STORAGE + ) != PackageManager.PERMISSION_GRANTED + ) { return MaterialDialog(requireActivity(), BottomSheet(LayoutMode.WRAP_CONTENT)).show { title(R.string.md_error_label) cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt index 0ccb5a695..c90afc8f4 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt @@ -23,7 +23,6 @@ import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R.layout import code.name.monkey.retromusic.R.string -import code.name.monkey.retromusic.extensions.appHandleColor import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.PlaylistsUtil import code.name.monkey.retromusic.util.PreferenceUtil @@ -35,36 +34,35 @@ import com.afollestad.materialdialogs.customview.getCustomView import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout - class CreatePlaylistDialog : DialogFragment() { private lateinit var playlistView: TextInputEditText private lateinit var actionNewPlaylistContainer: TextInputLayout override fun onCreateDialog( - savedInstanceState: Bundle? + savedInstanceState: Bundle? ): Dialog { val materialDialog = MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)) - .show { - cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) - title(string.new_playlist_title) - customView(layout.dialog_playlist) - negativeButton(android.R.string.cancel) - positiveButton(string.create_action) { - if (activity == null) { - return@positiveButton - } - val songs = arguments?.getParcelableArrayList("songs") - ?: return@positiveButton + .show { + cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) + title(string.new_playlist_title) + customView(layout.dialog_playlist) + negativeButton(android.R.string.cancel) + positiveButton(string.create_action) { + if (activity == null) { + return@positiveButton + } + val songs = arguments?.getParcelableArrayList("songs") + ?: return@positiveButton - if (playlistView.text.toString().trim { it <= ' ' }.isNotEmpty()) { - val playlistId = PlaylistsUtil.createPlaylist(requireContext(), playlistView.text.toString()) - if (playlistId != -1 && activity != null) { - PlaylistsUtil.addToPlaylist(requireContext(), songs, playlistId, true) - } + if (playlistView.text.toString().trim { it <= ' ' }.isNotEmpty()) { + val playlistId = PlaylistsUtil.createPlaylist(requireContext(), playlistView.text.toString()) + if (playlistId != -1 && activity != null) { + PlaylistsUtil.addToPlaylist(requireContext(), songs, playlistId, true) } } } + } val dialogView = materialDialog.getCustomView() playlistView = dialogView.findViewById(R.id.actionNewPlaylist) @@ -73,7 +71,10 @@ class CreatePlaylistDialog : DialogFragment() { MaterialUtil.setTint(actionNewPlaylistContainer, false) val playlistId = arguments!!.getLong(MediaStore.Audio.Playlists.Members.PLAYLIST_ID) - playlistView.appHandleColor().setText(PlaylistsUtil.getNameForPlaylist(requireContext(), playlistId), TextView.BufferType.EDITABLE) + playlistView.setText( + PlaylistsUtil.getNameForPlaylist(requireContext(), playlistId), + TextView.BufferType.EDITABLE + ) return materialDialog } diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.kt index 267993db4..902c245e5 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.kt @@ -104,10 +104,10 @@ class DeleteSongsDialog : DialogFragment() { return create(list) } - fun create(songs: ArrayList): DeleteSongsDialog { + fun create(songs: List): DeleteSongsDialog { val dialog = DeleteSongsDialog() val args = Bundle() - args.putParcelableArrayList("songs", songs) + args.putParcelableArrayList("songs", ArrayList(songs)) dialog.arguments = args return dialog } diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt index c0df89875..4ad284c33 100644 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt @@ -23,7 +23,6 @@ import code.name.monkey.appthemehelper.util.MaterialUtil import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R.layout import code.name.monkey.retromusic.R.string -import code.name.monkey.retromusic.extensions.appHandleColor import code.name.monkey.retromusic.util.PlaylistsUtil import code.name.monkey.retromusic.util.PreferenceUtil import com.afollestad.materialdialogs.LayoutMode @@ -60,7 +59,7 @@ class RenamePlaylistDialog : DialogFragment() { MaterialUtil.setTint(actionNewPlaylistContainer, false) val playlistId = arguments!!.getLong(PLAYLIST_ID) - playlistView.appHandleColor() + playlistView .setText(PlaylistsUtil.getNameForPlaylist(context!!, playlistId), TextView.BufferType.EDITABLE) return materialDialog } diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/CursorExt.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/CursorExt.kt new file mode 100644 index 000000000..b1aa14859 --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/extensions/CursorExt.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2020 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.extensions + +import android.database.Cursor + +/** + * Created by hemanths on 2020-02-05. + */ + +fun Cursor?.forEach( + closeAfter: Boolean = false, + each: Cursor.() -> Unit +) { + if (this == null) return + if (moveToFirst()) { + do { + each(this) + } while (moveToNext()) + } + if (closeAfter) { + close() + } +} + +fun Cursor?.mapList( + closeAfter: Boolean = false, + mapper: Cursor.() -> T +): MutableList { + val result = mutableListOf() + forEach(closeAfter = closeAfter) { + result.add(mapper(this)) + } + return result +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt index 64e400dca..6912f1211 100644 --- a/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt +++ b/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt @@ -17,11 +17,7 @@ package code.name.monkey.retromusic.extensions import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.EditText import androidx.annotation.LayoutRes -import code.name.monkey.appthemehelper.ThemeStore -import code.name.monkey.appthemehelper.util.TintHelper - @Suppress("UNCHECKED_CAST") fun ViewGroup.inflate(@LayoutRes layout: Int): T { @@ -40,9 +36,4 @@ fun View.hidden() { visibility = View.INVISIBLE } -fun View.showOrHide(show: Boolean) = if (show) show() else hide() - -fun EditText.appHandleColor(): EditText { - TintHelper.colorHandles(this, ThemeStore.accentColor(context)) - return this -} \ No newline at end of file +fun View.showOrHide(show: Boolean) = if (show) show() else hide() \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt index acb67d598..070942532 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt @@ -10,21 +10,19 @@ enum class NowPlayingScreen constructor( @param:DrawableRes @field:DrawableRes val drawableResId: Int, val id: Int ) { - - NORMAL(R.string.normal, R.drawable.np_normal, 0), - FLAT(R.string.flat, R.drawable.np_flat, 1), - FIT(R.string.fit, R.drawable.np_fit, 12), - TINY(R.string.tiny, R.drawable.np_tiny, 7), - PEAK(R.string.peak, R.drawable.np_peak, 14), - ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10), BLUR(R.string.blur, R.drawable.np_blur, 4), BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9), CARD(R.string.card, R.drawable.np_card, 6), COLOR(R.string.color, R.drawable.np_color, 5), CIRCLE(R.string.circle, R.drawable.np_minimalistic_circle, 15), + FIT(R.string.fit, R.drawable.np_fit, 12), + FLAT(R.string.flat, R.drawable.np_flat, 1), FULL(R.string.full, R.drawable.np_full, 2), MATERIAL(R.string.material, R.drawable.np_material, 11), + NORMAL(R.string.normal, R.drawable.np_normal, 0), + PEAK(R.string.peak, R.drawable.np_peak, 14), PLAIN(R.string.plain, R.drawable.np_plain, 3), SIMPLE(R.string.simple, R.drawable.np_simple, 8), + TINY(R.string.tiny, R.drawable.np_tiny, 7), } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsLibraryPagerRecyclerViewCustomGridSizeFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsLibraryPagerRecyclerViewCustomGridSizeFragment.kt index 60ba8e84d..8b078163f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsLibraryPagerRecyclerViewCustomGridSizeFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsLibraryPagerRecyclerViewCustomGridSizeFragment.kt @@ -34,6 +34,7 @@ abstract class AbsLibraryPagerRecyclerViewCustomGridSizeFragment { - NavigationUtil.goToArtist(requireActivity(), song.artistId) + NavigationUtil.goToArtist(requireActivity(), song.artistId.toInt()) return true } R.id.now_playing -> { diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/AlbumsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/AlbumsFragment.kt index d915a4c29..80feff28e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/AlbumsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/AlbumsFragment.kt @@ -41,7 +41,7 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment) { + override fun albums(albums: List) { adapter?.swapDataSet(albums) } @@ -53,21 +53,13 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment(), ArtistsView { - override fun artists(artists: ArrayList) { + override fun artists(artists: List) { adapter?.swapDataSet(artists) } @@ -66,7 +66,6 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment(), GenresView { - override fun genres(genres: ArrayList) { + override fun genres(genres: List) { adapter?.swapDataSet(genres) } override fun showEmptyView() { - } override fun createLayoutManager(): LinearLayoutManager { @@ -48,11 +46,9 @@ class GenresFragment : AbsLibraryPagerRecyclerViewFragment) { + override fun playlists(playlists: List) { adapter?.swapDataSet(playlists) } diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/SongsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/SongsFragment.kt index d58e0365b..08db8976f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/SongsFragment.kt +++ b/app/src/main/java/code/name/monkey/retromusic/fragments/mainactivity/SongsFragment.kt @@ -40,7 +40,7 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment) { + override fun songs(songs: List) { adapter?.swapDataSet(songs) } @@ -73,17 +73,6 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment if (isAdded) { - val drawable = DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM, - intArrayOf(animation.animatedValue as Int, - ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)), 0) + val drawable = DrawableGradient( + GradientDrawable.Orientation.TOP_BOTTOM, + intArrayOf( + animation.animatedValue as Int, + ATHUtil.resolveColor(requireContext(), R.attr.colorSurface) + ), 0 + ) colorGradientBackground?.background = drawable } } @@ -70,7 +73,11 @@ class PlayerFragment : AbsPlayerFragment() { lastColor = color callbacks?.onPaletteColorChanged() - ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.colorControlNormal), requireActivity()) + ToolbarContentTintHelper.colorizeToolbar( + playerToolbar, + ATHUtil.resolveColor(context, R.attr.colorControlNormal), + requireActivity() + ) if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) { colorize(color) @@ -88,9 +95,10 @@ class PlayerFragment : AbsPlayerFragment() { toggleFavorite(MusicPlayerRemote.currentSong) } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle?): View? { + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { return inflater.inflate(R.layout.fragment_player, container, false) } @@ -101,19 +109,24 @@ class PlayerFragment : AbsPlayerFragment() { setUpPlayerToolbar() } - private fun setUpSubFragments() { - playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment - val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment + playbackControlsFragment = + childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment + val playerAlbumCoverFragment = + childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment playerAlbumCoverFragment.setCallbacks(this) } private fun setUpPlayerToolbar() { playerToolbar.inflateMenu(R.menu.menu_player) - playerToolbar.setNavigationOnClickListener {requireActivity().onBackPressed() } + playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() } playerToolbar.setOnMenuItemClickListener(this) - ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.colorControlNormal), requireActivity()) + ToolbarContentTintHelper.colorizeToolbar( + playerToolbar, + ATHUtil.resolveColor(context, R.attr.colorControlNormal), + requireActivity() + ) } override fun onServiceConnected() { diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/AlbumGlideRequest.kt b/app/src/main/java/code/name/monkey/retromusic/glide/AlbumGlideRequest.kt new file mode 100644 index 000000000..765d1647d --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/glide/AlbumGlideRequest.kt @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020 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.glide + +import android.R.anim +import android.content.Context +import code.name.monkey.retromusic.R.drawable +import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder +import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper +import code.name.monkey.retromusic.util.MusicUtil +import com.bumptech.glide.BitmapRequestBuilder +import com.bumptech.glide.DrawableTypeRequest +import com.bumptech.glide.RequestManager +import com.bumptech.glide.load.Key +import com.bumptech.glide.load.engine.DiskCacheStrategy.NONE +import com.bumptech.glide.signature.MediaStoreSignature + +/** + * Created by hemanths on 2020-02-05. + */ + +class AlbumGlideRequest { + + companion object { + private val DEFAULT_DISK_CACHE_STRATEGY = NONE + private const val DEFAULT_ERROR_IMAGE = drawable.default_album_art + private const val DEFAULT_ANIMATION = anim.fade_in + + private fun createBaseRequest( + requestManager: RequestManager, + albumId: Long + ): DrawableTypeRequest<*> = + requestManager.loadFromMediaStore(MusicUtil.getMediaStoreAlbumCoverUri(albumId)) + + private fun createSignature(albumId: Long): Key? { + return MediaStoreSignature("", albumId, 0) + } + } + + class Builder(val requestManager: RequestManager, val albumId: Long) { + companion object { + fun from(requestManager: RequestManager, albumId: Long): Builder { + return Builder(requestManager, albumId) + } + } + + fun generatePalette(context: Context): PaletteBuilder { + return PaletteBuilder(this, context) + } + } + + class PaletteBuilder(private val builder: Builder, private val context: Context) { + + fun build(): BitmapRequestBuilder = + createBaseRequest(builder.requestManager, builder.albumId) + .asBitmap() + .transcode(BitmapPaletteTranscoder(context), BitmapPaletteWrapper::class.java) + .diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY) + .error(DEFAULT_ERROR_IMAGE) + .animate(DEFAULT_ANIMATION) + .signature(createSignature(builder.albumId)) + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt b/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt index 63a20dfb1..f4425533b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt +++ b/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt @@ -20,11 +20,9 @@ import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.retromusic.R import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper -import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.RetroColorUtil import com.bumptech.glide.request.animation.GlideAnimation - abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) { protected val defaultFooterColor: Int @@ -40,15 +38,17 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi onColorReady(defaultFooterColor) } - override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation?) { + override fun onResourceReady( + resource: BitmapPaletteWrapper?, + glideAnimation: GlideAnimation? + ) { super.onResourceReady(resource, glideAnimation) val defaultColor = defaultFooterColor resource?.let { - onColorReady(if (PreferenceUtil.getInstance(getView().context).isDominantColor) - RetroColorUtil.getDominantColor(it.bitmap, defaultColor) - else - RetroColorUtil.getColor(it.palette, defaultColor)) + onColorReady( + RetroColorUtil.getColor(it.palette, defaultColor) + ) } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/palette/BitmapPaletteWrapper.java b/app/src/main/java/code/name/monkey/retromusic/glide/palette/BitmapPaletteWrapper.java index 4aa89e086..7eed93ae8 100644 --- a/app/src/main/java/code/name/monkey/retromusic/glide/palette/BitmapPaletteWrapper.java +++ b/app/src/main/java/code/name/monkey/retromusic/glide/palette/BitmapPaletteWrapper.java @@ -18,7 +18,9 @@ import android.graphics.Bitmap; import androidx.palette.graphics.Palette; public class BitmapPaletteWrapper { + private final Bitmap mBitmap; + private final Palette mPalette; public BitmapPaletteWrapper(Bitmap bitmap, Palette palette) { diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt b/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt index d5ee33294..caaca1203 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt @@ -29,7 +29,6 @@ import android.os.Environment import android.os.IBinder import android.provider.DocumentsContract import android.provider.MediaStore -import android.util.Log import android.widget.Toast import androidx.core.content.ContextCompat import code.name.monkey.retromusic.loaders.SongLoader @@ -158,7 +157,7 @@ object MusicPlayerRemote { return cursor.getString(columnIndex) } } catch (e: Exception) { - Log.e(TAG, e.message) + println(e.message) } finally { cursor?.close() } @@ -222,7 +221,7 @@ object MusicPlayerRemote { /** * Async */ - fun openQueue(queue: ArrayList, startPosition: Int, startPlaying: Boolean) { + fun openQueue(queue: List, startPosition: Int, startPlaying: Boolean) { if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) { musicService!!.openQueue(queue, startPosition, startPlaying) if (PreferenceUtil.getInstance(musicService).isShuffleModeOn) @@ -233,7 +232,7 @@ object MusicPlayerRemote { /** * Async */ - fun openAndShuffleQueue(queue: ArrayList, startPlaying: Boolean) { + fun openAndShuffleQueue(queue: List, startPlaying: Boolean) { var startPosition = 0 if (queue.isNotEmpty()) { startPosition = Random().nextInt(queue.size) @@ -246,7 +245,7 @@ object MusicPlayerRemote { } private fun tryToHandleOpenPlayingQueue( - queue: ArrayList, + queue: List, startPosition: Int, startPlaying: Boolean ): Boolean { @@ -316,7 +315,7 @@ object MusicPlayerRemote { return false } - fun playNext(songs: ArrayList): Boolean { + fun playNext(songs: List): Boolean { if (musicService != null) { if (playingQueue.size > 0) { musicService!!.addSongs(position + 1, songs) @@ -353,7 +352,7 @@ object MusicPlayerRemote { return false } - fun enqueue(songs: ArrayList): Boolean { + fun enqueue(songs: List): Boolean { if (musicService != null) { if (playingQueue.size > 0) { musicService!!.addSongs(songs) diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt b/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt index 56f4a5192..0798af20e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/SortOrder.kt @@ -21,6 +21,7 @@ class SortOrder { * Artist sort order entries. */ interface ArtistSortOrder { + companion object { /* Artist sort order A-Z */ @@ -41,6 +42,7 @@ class SortOrder { * Album sort order entries. */ interface AlbumSortOrder { + companion object { /* Album sort order A-Z */ @@ -57,7 +59,7 @@ class SortOrder { + ", " + MediaStore.Audio.Albums.DEFAULT_SORT_ORDER) /* Album sort order year */ - const val ALBUM_YEAR = MediaStore.Audio.Media.YEAR + " DESC" + const val ALBUM_YEAR = MediaStore.Audio.Albums.FIRST_YEAR + " DESC" } } @@ -65,6 +67,7 @@ class SortOrder { * Song sort order entries. */ interface SongSortOrder { + companion object { /* Song sort order A-Z */ @@ -97,6 +100,7 @@ class SortOrder { * Album song sort order entries. */ interface AlbumSongSortOrder { + companion object { /* Album song sort order A-Z */ @@ -118,6 +122,7 @@ class SortOrder { * Artist song sort order entries. */ interface ArtistSongSortOrder { + companion object { /* Artist song sort order A-Z */ @@ -144,6 +149,7 @@ class SortOrder { * Artist album sort order entries. */ interface ArtistAlbumSortOrder { + companion object { /* Artist album sort order A-Z */ @@ -164,6 +170,7 @@ class SortOrder { * Genre sort order entries. */ interface GenreSortOrder { + companion object { /* Genre sort order A-Z */ @@ -173,5 +180,4 @@ class SortOrder { const val ALBUM_Z_A = "$GENRE_A_Z DESC" } } - } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt index bc125739f..de0a4e8af 100644 --- a/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt +++ b/app/src/main/java/code/name/monkey/retromusic/helper/menu/SongMenuHelper.kt @@ -91,7 +91,7 @@ object SongMenuHelper { return true } R.id.action_go_to_artist -> { - NavigationUtil.goToArtist(activity, song.artistId) + NavigationUtil.goToArtist(activity, song.artistId.toInt()) return true } } diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/AlbumLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/AlbumLoader.kt index 2865b620f..fd334a5b5 100644 --- a/app/src/main/java/code/name/monkey/retromusic/loaders/AlbumLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/loaders/AlbumLoader.kt @@ -15,89 +15,136 @@ package code.name.monkey.retromusic.loaders import android.content.Context -import android.provider.MediaStore.Audio.AudioColumns +import android.database.Cursor +import android.provider.BaseColumns +import android.provider.MediaStore +import android.provider.MediaStore.Audio.Albums.* +import code.name.monkey.appthemehelper.util.VersionUtils +import code.name.monkey.retromusic.Constants.baseProjection +import code.name.monkey.retromusic.extensions.mapList import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.PreferenceUtil -import java.util.* -import kotlin.collections.ArrayList - +import android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI as SONGS_URI /** * Created by hemanths on 11/08/17. */ -object AlbumLoader { +object AlbumLoader { - fun getAlbums( - context: Context, - query: String - ): ArrayList { - val songs = SongLoader.getSongs(SongLoader.makeSongCursor( - context, - AudioColumns.ALBUM + " LIKE ?", - arrayOf("%$query%"), - getSongLoaderSortOrder(context)) + fun getAllAlbums(context: Context): List { + return makeAlbumCursor(context, null, null) + .mapList(true) { + Album.fromCursor(this) + } + } + + fun getAlbum(context: Context, id: Long): Album { + return getAlbum(makeAlbumCursor(context, "_id=?", arrayOf(id.toString()))) + } + + fun getSongsForAlbum(context: Context, albumId: Long): ArrayList { + return SongLoader.getSongs(makeAlbumSongCursor(context, albumId)) + } + + fun getAlbumsForArtist(context: Context, artistId: Long): List { + return makeAlbumForArtistCursor(context, artistId).mapList(true) { + Album.fromCursor(this, artistId) + } + } + + private fun makeAlbumForArtistCursor(context: Context, artistId: Long): Cursor? { + if (artistId == -1L) { + return null + } + return context.contentResolver.query( + MediaStore.Audio.Artists.Albums.getContentUri("external", artistId), + arrayOf( + getAlbumId(), + "album", + "artist", + "numsongs", + "minyear" + ), + null, + null, + DEFAULT_SORT_ORDER ) - return splitIntoAlbums(songs) } - fun getAlbum( - context: Context, - albumId: Int - ): Album { - val songs = SongLoader.getSongs( - SongLoader.makeSongCursor( - context, - AudioColumns.ALBUM_ID + "=?", - arrayOf(albumId.toString()), - getSongLoaderSortOrder(context))) - val album = Album(songs) - sortSongsByTrackNumber(album) - return album + private fun getAlbum(cursor: Cursor?): Album { + return cursor?.use { + if (cursor.moveToFirst()) { + Album.fromCursor(cursor) + } else { + null + } + } ?: Album() } - fun getAllAlbums( - context: Context - ): ArrayList { - val songs = SongLoader.getSongs(SongLoader.makeSongCursor(context, null, null, getSongLoaderSortOrder(context))) - return splitIntoAlbums(songs) + private fun makeAlbumCursor(context: Context, selection: String?, paramArrayOfString: Array?): Cursor? { + return context.contentResolver.query( + EXTERNAL_CONTENT_URI, + arrayOf( + getAlbumId(), + "album", "artist", + "artist_id", + "numsongs", + "minyear" + ), + selection, + paramArrayOfString, + PreferenceUtil.getInstance(context).albumSortOrder + ) + } + + private fun makeAlbumSongCursor(context: Context, albumID: Long): Cursor? { + val selection = "is_music=1 AND title != '' AND album_id=$albumID" + return context.contentResolver.query( + SONGS_URI, + baseProjection, + selection, + null, + PreferenceUtil.getInstance(context).albumDetailSongSortOrder + ) } fun splitIntoAlbums( - songs: ArrayList? + songs: ArrayList? ): ArrayList { val albums = ArrayList() if (songs != null) { for (song in songs) { - getOrCreateAlbum(albums, song.albumId).songs?.add(song) + getOrCreateAlbum(albums, song) } } - for (album in albums) { - sortSongsByTrackNumber(album) - } return albums } private fun getOrCreateAlbum( - albums: ArrayList, - albumId: Int + albums: ArrayList, + song: Song ): Album { for (album in albums) { - if (album.songs!!.isNotEmpty() && album.songs[0].albumId == albumId) { + if (album.id == song.albumId) { return album } } - val album = Album() + val album = Album.fromSong(song) albums.add(album) return album } - private fun sortSongsByTrackNumber(album: Album) { - album.songs?.sortWith(Comparator { o1, o2 -> o1.trackNumber.compareTo(o2.trackNumber) }) - } - - private fun getSongLoaderSortOrder(context: Context): String { - return PreferenceUtil.getInstance(context).albumSortOrder + ", " + PreferenceUtil.getInstance(context).albumSongSortOrder + fun getAlbums(context: Context, paramString: String): List { + return makeAlbumCursor(context, "album LIKE ?", arrayOf("$paramString%")) + .mapList(true) { Album.fromCursor(this) } } } + +/* +* Android Q and more don't have `_id` for Albums and Artist albums so we have to use album_id +* */ +fun getAlbumId(): String { + return if (VersionUtils.hasQ()) ALBUM_ID else BaseColumns._ID +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/ArtistLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/ArtistLoader.kt index e4ce09c85..0844e407a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/loaders/ArtistLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/loaders/ArtistLoader.kt @@ -15,64 +15,107 @@ package code.name.monkey.retromusic.loaders import android.content.Context -import android.provider.MediaStore.Audio.AudioColumns +import android.database.Cursor +import android.provider.MediaStore +import code.name.monkey.retromusic.Constants.baseProjection +import code.name.monkey.retromusic.extensions.mapList import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Artist +import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.util.PreferenceUtil - object ArtistLoader { - private fun getSongLoaderSortOrder(context: Context): String { - return PreferenceUtil.getInstance(context).artistSortOrder + ", " + PreferenceUtil.getInstance(context).artistAlbumSortOrder + ", " + PreferenceUtil.getInstance(context).albumSongSortOrder - } fun getAllArtists(context: Context): ArrayList { - val songs = SongLoader.getSongs(SongLoader.makeSongCursor( - context, - null, null, - getSongLoaderSortOrder(context)) - ) - return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs)) + return getArtists(makeArtistCursor(context, null, null)) } - fun getArtists(context: Context, query: String): ArrayList { - val songs = SongLoader.getSongs(SongLoader.makeSongCursor( - context, - AudioColumns.ARTIST + " LIKE ?", - arrayOf("%$query%"), - getSongLoaderSortOrder(context)) - ) - return splitIntoArtists(AlbumLoader.splitIntoAlbums(songs)) + fun getArtist(context: Context, artistId: Long): Artist { + return getArtist(makeArtistCursor(context, "_id=?", arrayOf(artistId.toString()))) } - fun splitIntoArtists(albums: ArrayList?): ArrayList { + private fun getArtist(cursor: Cursor?): Artist { + return cursor?.use { + if (cursor.moveToFirst()) { + Artist.fromCursor(cursor) + } else { + null + } + } ?: Artist() + } + + fun getArtists(context: Context, paramString: String): List { + return makeArtistCursor(context, "artist LIKE ?", arrayOf("$paramString%")) + .mapList(true) { + Artist.fromCursor(this) + } + } + + private fun getArtists(cursor: Cursor?): ArrayList { val artists = ArrayList() - if (albums != null) { + if (cursor != null && cursor.moveToFirst()) { + do { + artists.add(getArtistFromCursor(cursor)) + } while (cursor.moveToNext()) + } + return artists + } + + private fun getArtistFromCursor(cursor: Cursor): Artist { + return Artist.fromCursor(cursor) + } + + private fun makeArtistCursor(context: Context, selection: String?, paramArrayOfString: Array?): Cursor? { + return context.contentResolver.query( + MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI, + arrayOf( + "_id", + "artist", + "number_of_albums", + "number_of_tracks" + ), + selection, + paramArrayOfString, + PreferenceUtil.getInstance(context).artistSortOrder + ) + } + + fun getSongsForArtist(context: Context, artistId: Long): List { + return makeArtistSongCursor(context, artistId) + .mapList(true) { Song.fromCursor(this, artistId = artistId) } + } + + private fun makeArtistSongCursor(context: Context, artistId: Long): Cursor? { + val artistSongSortOrder = MediaStore.Audio.Media.DEFAULT_SORT_ORDER + val uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI + val selection = "is_music=1 AND title != '' AND artist_id=$artistId" + return context.contentResolver.query( + uri, + baseProjection, + selection, + null, + artistSongSortOrder + ) + } + + fun splitIntoArtists(albums: ArrayList): ArrayList { + val artists = ArrayList() + if (albums.isNotEmpty()) { for (album in albums) { - getOrCreateArtist(artists, album.artistId).albums!!.add(album) + getOrCreateArtist(artists, album) } } return artists } - private fun getOrCreateArtist(artists: ArrayList, artistId: Int): Artist { + private fun getOrCreateArtist(artists: ArrayList, album: Album): Artist { for (artist in artists) { - if (artist.albums!!.isNotEmpty() && artist.albums[0].songs!!.isNotEmpty() && artist.albums[0].songs!![0].artistId == artistId) { + if (artist.id == album.artistId) { return artist } } - val album = Artist() - artists.add(album) - return album + val a = Artist.fromAlbum(album) + artists.add(a) + return a } - - fun getArtist(context: Context, artistId: Int): Artist { - val songs = SongLoader.getSongs(SongLoader.makeSongCursor( - context, - AudioColumns.ARTIST_ID + "=?", - arrayOf(artistId.toString()), - getSongLoaderSortOrder(context)) - ) - return Artist(AlbumLoader.splitIntoAlbums(songs)) - } -} +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/GenreLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/GenreLoader.kt index 09afd12ac..e539abc0e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/loaders/GenreLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/loaders/GenreLoader.kt @@ -19,7 +19,7 @@ import android.database.Cursor import android.net.Uri import android.provider.BaseColumns import android.provider.MediaStore.Audio.Genres -import code.name.monkey.retromusic.Constants.BASE_SELECTION +import code.name.monkey.retromusic.Constants.baseSelection import code.name.monkey.retromusic.Constants.baseProjection import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Song @@ -94,7 +94,7 @@ object GenreLoader { try { return context.contentResolver.query( Genres.Members.getContentUri("external", genreId.toLong()), - baseProjection, BASE_SELECTION, null, PreferenceUtil.getInstance(context).songSortOrder) + baseProjection, baseSelection, null, PreferenceUtil.getInstance(context).songSortOrder) } catch (e: SecurityException) { return null } diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/LastAddedSongsLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/LastAddedSongsLoader.kt index 358bd595e..3a9e2d50d 100644 --- a/app/src/main/java/code/name/monkey/retromusic/loaders/LastAddedSongsLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/loaders/LastAddedSongsLoader.kt @@ -36,10 +36,11 @@ object LastAddedSongsLoader { val cutoff = PreferenceUtil.getInstance(context).lastAddedCutoff return SongLoader.makeSongCursor( - context, - MediaStore.Audio.Media.DATE_ADDED + ">?", - arrayOf(cutoff.toString()), - MediaStore.Audio.Media.DATE_ADDED + " DESC") + context, + MediaStore.Audio.Media.DATE_ADDED + ">?", + arrayOf(cutoff.toString()), + MediaStore.Audio.Media.DATE_ADDED + " DESC" + ) } fun getLastAddedAlbums(context: Context): ArrayList { diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/PlaylistSongsLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/PlaylistSongsLoader.kt index 3073db67d..a1e041e0e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/loaders/PlaylistSongsLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/loaders/PlaylistSongsLoader.kt @@ -18,7 +18,7 @@ import android.content.Context import android.database.Cursor import android.provider.MediaStore import android.provider.MediaStore.Audio.AudioColumns -import code.name.monkey.retromusic.Constants.BASE_SELECTION +import code.name.monkey.retromusic.Constants.baseSelection import code.name.monkey.retromusic.model.AbsCustomPlaylist import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.PlaylistSong @@ -104,7 +104,7 @@ object PlaylistSongsLoader { MediaStore.Audio.Playlists.Members._ID,//11 AudioColumns.COMPOSER )// 12 - , BASE_SELECTION, null, + , baseSelection, null, MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER ) } catch (e: SecurityException) { diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/SongLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/SongLoader.kt index e03b6ef7b..bf24f0f98 100644 --- a/app/src/main/java/code/name/monkey/retromusic/loaders/SongLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/loaders/SongLoader.kt @@ -18,10 +18,9 @@ import android.content.Context import android.database.Cursor import android.provider.MediaStore import android.provider.MediaStore.Audio.AudioColumns -import code.name.monkey.retromusic.Constants.BASE_SELECTION import code.name.monkey.retromusic.Constants.baseProjection +import code.name.monkey.retromusic.Constants.baseSelection import code.name.monkey.retromusic.model.Song -import code.name.monkey.retromusic.providers.BlacklistStore import code.name.monkey.retromusic.util.PreferenceUtil import java.util.ArrayList @@ -61,7 +60,7 @@ object SongLoader { return getSongs(cursor) } - fun getSong( + private fun getSong( cursor: Cursor? ): Song { val song: Song @@ -75,98 +74,79 @@ object SongLoader { } @JvmStatic - fun getSong(context: Context, queryId: Int): Song { + fun getSong(context: Context, queryId: Long): Song { val cursor = makeSongCursor(context, AudioColumns._ID + "=?", arrayOf(queryId.toString())) return getSong(cursor) } private fun getSongFromCursorImpl( cursor: Cursor - ): Song { - val id = cursor.getInt(0) - val title = cursor.getString(1) - val trackNumber = cursor.getInt(2) - val year = cursor.getInt(3) - val duration = cursor.getLong(4) - val data = cursor.getString(5) - val dateModified = cursor.getLong(6) - val albumId = cursor.getInt(7) - val albumName = cursor.getString(8) - val artistId = cursor.getInt(9) - val artistName = cursor.getString(10) - val composer = cursor.getString(11) - - return Song( - id, title, trackNumber, year, duration, data, dateModified, albumId, - albumName ?: "", artistId, artistName, composer ?: "" - ) - } + ): Song = Song.fromCursor(cursor) + @JvmStatic @JvmOverloads fun makeSongCursor( context: Context, - selection: String?, - selectionValues: Array?, + selectionString: String?, + selectionValuesArray: Array?, sortOrder: String = PreferenceUtil.getInstance(context).songSortOrder - ): Cursor? { - var selectionFinal = selection - var selectionValuesFinal = selectionValues - selectionFinal = if (selection != null && selection.trim { it <= ' ' } != "") { - "$BASE_SELECTION AND $selectionFinal" + ): Cursor { + var selectionValues: Array? = arrayOf() + var selection = if (selectionString != null && selectionString.trim() != "") { + "$baseSelection AND $selectionString" } else { - BASE_SELECTION + baseSelection } // Blacklist - val paths = BlacklistStore.getInstance(context).paths + /*val paths = BlacklistStore.getInstance(context).paths if (paths.isNotEmpty()) { - selectionFinal = generateBlacklistSelection(selectionFinal, paths.size) - selectionValuesFinal = addBlacklistSelectionValues(selectionValuesFinal, paths) + selection = generateBlacklistSelection(selection, paths.size) + selectionValues = addBlacklistSelectionValues(selectionValuesArray, paths) + }*/ + if (PreferenceUtil.getInstance(context).filterLength != 0) { + selection = + "$selection AND ${MediaStore.Audio.Media.DURATION} >= ${PreferenceUtil.getInstance(context).filterLength * 1000}" } - try { - return context.contentResolver.query( - MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, - baseProjection, - selectionFinal + " AND " + MediaStore.Audio.Media.DURATION + ">= " + (PreferenceUtil.getInstance( - context - ).filterLength * 1000), - selectionValuesFinal, - sortOrder - ) - } catch (e: SecurityException) { - return null - } - } - - private fun generateBlacklistSelection( - selection: String?, - pathCount: Int - ): String { - val newSelection = StringBuilder( - if (selection != null && selection.trim { it <= ' ' } != "") "$selection AND " else "") - newSelection.append(AudioColumns.DATA + " NOT LIKE ?") - for (i in 0 until pathCount - 1) { - newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?") - } - return newSelection.toString() - } - - private fun addBlacklistSelectionValues( - selectionValues: Array?, - paths: ArrayList - ): Array? { - var selectionValuesFinal = selectionValues - if (selectionValuesFinal == null) { - selectionValuesFinal = emptyArray() - } - val newSelectionValues = Array(selectionValuesFinal.size + paths.size) { - "n = $it" - } - System.arraycopy(selectionValuesFinal, 0, newSelectionValues, 0, selectionValuesFinal.size) - for (i in selectionValuesFinal.size until newSelectionValues.size) { - newSelectionValues[i] = paths[i - selectionValuesFinal.size] + "%" - } - return newSelectionValues + return context.contentResolver.query( + MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, + baseProjection, + selection, + selectionValuesArray, + sortOrder + ) + ?: throw IllegalStateException("Unable to query ${MediaStore.Audio.Media.EXTERNAL_CONTENT_URI}, system returned null.") } } + +fun generateBlacklistSelection( + selection: String?, + pathCount: Int +): String { + val newSelection = StringBuilder( + if (selection != null && selection.trim { it <= ' ' } != "") "$selection AND " else "") + newSelection.append(AudioColumns.DATA + " NOT LIKE ?") + for (i in 0 until pathCount - 1) { + newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?") + } + return newSelection.toString() +} + +fun addBlacklistSelectionValues( + selectionValues: Array?, + paths: ArrayList +): Array? { + var selectionValuesFinal = selectionValues + if (selectionValuesFinal == null) { + selectionValuesFinal = emptyArray() + } + val newSelectionValues = Array(selectionValuesFinal.size + paths.size) { + "n = $it" + } + System.arraycopy(selectionValuesFinal, 0, newSelectionValues, 0, selectionValuesFinal.size) + for (i in selectionValuesFinal.size until newSelectionValues.size) { + newSelectionValues[i] = paths[i - selectionValuesFinal.size] + "%" + } + return newSelectionValues +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/TopAndRecentlyPlayedTracksLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/TopAndRecentlyPlayedTracksLoader.kt index d7f6bee36..02bad780f 100644 --- a/app/src/main/java/code/name/monkey/retromusic/loaders/TopAndRecentlyPlayedTracksLoader.kt +++ b/app/src/main/java/code/name/monkey/retromusic/loaders/TopAndRecentlyPlayedTracksLoader.kt @@ -143,6 +143,6 @@ object TopAndRecentlyPlayedTracksLoader { } fun getTopArtists(context: Context): ArrayList { - return ArtistLoader.splitIntoArtists(getTopAlbums(context)) + return ArtistLoader.splitIntoArtists(getTopAlbums(context)) } } diff --git a/app/src/main/java/code/name/monkey/retromusic/misc/AsyncSearchResultLoader.kt b/app/src/main/java/code/name/monkey/retromusic/misc/AsyncSearchResultLoader.kt deleted file mode 100644 index a9c9486a4..000000000 --- a/app/src/main/java/code/name/monkey/retromusic/misc/AsyncSearchResultLoader.kt +++ /dev/null @@ -1,50 +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.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>(context) { - - override fun loadInBackground(): List? { - val results = ArrayList() - 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 - } -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Album.kt b/app/src/main/java/code/name/monkey/retromusic/model/Album.kt index f718d0f88..432a94105 100644 --- a/app/src/main/java/code/name/monkey/retromusic/model/Album.kt +++ b/app/src/main/java/code/name/monkey/retromusic/model/Album.kt @@ -14,41 +14,72 @@ package code.name.monkey.retromusic.model -import java.util.ArrayList +import android.database.Cursor +import android.provider.MediaStore +import android.provider.MediaStore.Audio.Albums.ALBUM +import android.provider.MediaStore.Audio.Albums.ARTIST +import android.provider.MediaStore.Audio.Albums.FIRST_YEAR +import android.provider.MediaStore.Audio.Albums.NUMBER_OF_SONGS +import code.name.monkey.retromusic.loaders.getAlbumId -class Album { - val songs: ArrayList? +data class Album( + var id: Long = 0, + var title: String = "", + var artist: String = "", + var artistId: Long = 0, + var songCount: Int = 0, + var year: Int = 0 +) { - val id: Int - get() = safeGetFirstSong().albumId + companion object { + fun fromCursor(cursor: Cursor, artistId: Long = -1): Album { + return Album( + id = cursor.value(getAlbumId()), + title = cursor.valueOrEmpty(ALBUM), + artist = cursor.valueOrEmpty(ARTIST), + artistId = if (artistId == -1L) cursor.value(MediaStore.Audio.AudioColumns.ARTIST_ID) else artistId, + songCount = cursor.value(NUMBER_OF_SONGS), + year = cursor.value(FIRST_YEAR) + ) + } - val title: String? - get() = safeGetFirstSong().albumName - - val artistId: Int - get() = safeGetFirstSong().artistId - - val artistName: String? - get() = safeGetFirstSong().artistName - - val year: Int - get() = safeGetFirstSong().year - - val dateModified: Long - get() = safeGetFirstSong().dateModified - - val songCount: Int - get() = songs!!.size - - constructor(songs: ArrayList) { - this.songs = songs - } - - constructor() { - this.songs = ArrayList() - } - - fun safeGetFirstSong(): Song { - return if (songs!!.isEmpty()) Song.emptySong else songs[0] + fun fromSong(song: Song): Album { + return Album(song.albumId, song.albumName, song.artistName, song.artistId, -1, song.year) + } } } + +fun Cursor.valueOrEmpty(name: String): String = valueOrDefault(name, "") + +inline fun Cursor.value(name: String): T { + val index = getColumnIndexOrThrow(name) + return when (T::class) { + Short::class -> getShort(index) as T + Int::class -> getInt(index) as T + Long::class -> getLong(index) as T + Boolean::class -> (getInt(index) == 1) as T + String::class -> getString(index) as T + Float::class -> getFloat(index) as T + Double::class -> getDouble(index) as T + ByteArray::class -> getBlob(index) as T + else -> throw IllegalStateException("What do I do with ${T::class.java.simpleName}?") + } +} + +inline fun Cursor.valueOrDefault(name: String, defaultValue: T): T { + val index = getColumnIndex(name) + if (index == -1) { + return defaultValue + } + return when (T::class) { + Short::class -> getShort(index) as? T ?: defaultValue + Int::class -> getInt(index) as? T ?: defaultValue + Long::class -> getLong(index) as? T ?: defaultValue + Boolean::class -> (getInt(index) == 1) as T + String::class -> getString(index) as? T ?: defaultValue + Float::class -> getFloat(index) as? T ?: defaultValue + Double::class -> getDouble(index) as? T ?: defaultValue + ByteArray::class -> getBlob(index) as? T ?: defaultValue + else -> throw IllegalStateException("What do I do with ${T::class.java.simpleName}?") + } +} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Artist.kt b/app/src/main/java/code/name/monkey/retromusic/model/Artist.kt index 8d8462eff..45374ce69 100644 --- a/app/src/main/java/code/name/monkey/retromusic/model/Artist.kt +++ b/app/src/main/java/code/name/monkey/retromusic/model/Artist.kt @@ -14,57 +14,34 @@ package code.name.monkey.retromusic.model -import code.name.monkey.retromusic.util.MusicUtil -import java.util.ArrayList +import android.database.Cursor +import android.provider.MediaStore.Audio.Artists.ARTIST +import android.provider.MediaStore.Audio.Artists.NUMBER_OF_ALBUMS +import android.provider.MediaStore.Audio.Artists.NUMBER_OF_TRACKS +import android.provider.MediaStore.Audio.Artists._ID -class Artist { - val albums: ArrayList? - - val id: Int - get() = safeGetFirstAlbum().artistId - - val name: String - get() { - val name = safeGetFirstAlbum().artistName - return if (MusicUtil.isArtistNameUnknown(name)) { - UNKNOWN_ARTIST_DISPLAY_NAME - } else name!! - } - - val songCount: Int - get() { - var songCount = 0 - for (album in albums!!) { - songCount += album.songCount - } - return songCount - } - - val albumCount: Int - get() = albums!!.size - - val songs: ArrayList - get() { - val songs = ArrayList() - for (album in albums!!) { - songs.addAll(album.songs!!) - } - return songs - } - - constructor(albums: ArrayList) { - this.albums = albums - } - - constructor() { - this.albums = ArrayList() - } - - fun safeGetFirstAlbum(): Album { - return if (albums!!.isEmpty()) Album() else albums[0] - } +class Artist( + var id: Long = 0, + var name: String = "", + var songCount: Int = 0, + var albumCount: Int = 0 +) { companion object { + + fun fromCursor(cursor: Cursor): Artist { + return Artist( + id = cursor.value(_ID), + name = cursor.value(ARTIST), + songCount = cursor.value(NUMBER_OF_TRACKS), + albumCount = cursor.value(NUMBER_OF_ALBUMS) + ) + } + + fun fromAlbum(album: Album): Artist { + return Artist(album.artistId, album.artist, -1, -1) + } + const val UNKNOWN_ARTIST_DISPLAY_NAME = "Unknown Artist" } } diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Song.kt b/app/src/main/java/code/name/monkey/retromusic/model/Song.kt index 9f8b33c81..17b554626 100644 --- a/app/src/main/java/code/name/monkey/retromusic/model/Song.kt +++ b/app/src/main/java/code/name/monkey/retromusic/model/Song.kt @@ -13,21 +13,23 @@ */ package code.name.monkey.retromusic.model +import android.database.Cursor import android.os.Parcelable +import android.provider.MediaStore.Audio.Media import kotlinx.android.parcel.Parcelize @Parcelize open class Song( - val id: Int, + val id: Long, val title: String, val trackNumber: Int, val year: Int, val duration: Long, val data: String, val dateModified: Long, - val albumId: Int, + val albumId: Long, val albumName: String, - val artistId: Int, + val artistId: Long, val artistName: String, val composer: String? ) : Parcelable { @@ -49,5 +51,22 @@ open class Song( "", "" ) + + fun fromCursor(cursor: Cursor, albumId: Long = -1, artistId: Long = -1): Song { + return Song( + id = cursor.value(Media._ID), + albumId = cursor.valueOrDefault(Media.ALBUM_ID, albumId), + artistId = cursor.valueOrDefault(Media.ARTIST_ID, artistId), + albumName = cursor.valueOrEmpty(Media.ALBUM), + artistName = cursor.valueOrEmpty(Media.ARTIST), + composer = cursor.valueOrEmpty(Media.COMPOSER), + data = cursor.valueOrEmpty(Media.DATA), + dateModified = cursor.value(Media.DATE_MODIFIED), + duration = cursor.value(Media.DURATION), + title = cursor.valueOrEmpty(Media.TITLE), + trackNumber = cursor.value(Media.TRACK), + year = cursor.value(Media.YEAR) + ) + } } } \ No newline at end of file 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 index 3fcfefd6e..08b2fd70c 100644 --- 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 @@ -17,6 +17,7 @@ package code.name.monkey.retromusic.mvp.presenter import code.name.monkey.retromusic.Result.Success import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Artist +import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.providers.interfaces.Repository @@ -36,21 +37,24 @@ interface AlbumDetailsView { fun album(album: Album) + fun songs(songs: List) + fun complete() fun loadArtistImage(artist: Artist) - fun moreAlbums( - albums: ArrayList - ) + fun moreAlbums(albums: List) fun aboutAlbum(lastFmAlbum: LastFmAlbum) } interface AlbumDetailsPresenter : Presenter { - fun loadAlbum(albumId: Int) + fun loadAlbum(albumId: Long) + + fun albumSongs(albumId: Long) + + fun loadMore(artistId: Long) - fun loadMore(artistId: Int) fun aboutAlbum(artist: String, album: String) class AlbumDetailsPresenterImpl @Inject constructor( @@ -60,7 +64,7 @@ interface AlbumDetailsPresenter : Presenter { private val job = Job() private lateinit var album: Album - override fun loadMore(artistId: Int) { + override fun loadMore(artistId: Long) { launch { when (val result = repository.artistById(artistId)) { is Success -> withContext(Dispatchers.Main) { showArtistImage(result.data) } @@ -80,13 +84,9 @@ interface AlbumDetailsPresenter : Presenter { private fun showArtistImage(artist: Artist) { view?.loadArtistImage(artist) - - artist.albums?.filter { it.id != album.id }?.let { - if (it.isNotEmpty()) view?.moreAlbums(ArrayList(it)) - } } - override fun loadAlbum(albumId: Int) { + override fun loadAlbum(albumId: Long) { launch { when (val result = repository.albumById(albumId)) { is Success -> withContext(Dispatchers.Main) { @@ -98,6 +98,15 @@ interface AlbumDetailsPresenter : Presenter { } } + override fun albumSongs(albumId: Long) { + launch { + when (val result = repository.albumSongsById(albumId)) { + is Success -> withContext(Dispatchers.Main) { view.songs(result.data) } + is Error -> withContext(Dispatchers.Main) {} + } + } + } + override fun detachView() { super.detachView() job.cancel() diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumPresenter.kt index 093087ddb..dd7d57143 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumPresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/AlbumPresenter.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch import kotlinx.coroutines.withContext -import java.util.ArrayList import javax.inject.Inject import kotlin.coroutines.CoroutineContext @@ -33,35 +32,37 @@ import kotlin.coroutines.CoroutineContext * Created by hemanths on 12/08/17. */ interface AlbumsView : BaseView { - fun albums(albums: ArrayList) + + fun albums(albums: List) } interface AlbumsPresenter : Presenter { - fun loadAlbums() + fun loadAlbums() - class AlbumsPresenterImpl @Inject constructor( + class AlbumsPresenterImpl @Inject constructor( private val repository: Repository - ) : PresenterImpl(), AlbumsPresenter, CoroutineScope { - private val job = Job() + ) : PresenterImpl(), AlbumsPresenter, CoroutineScope { - override val coroutineContext: CoroutineContext - get() = Dispatchers.IO + job + private val job = Job() - override fun detachView() { - super.detachView() - job.cancel() - } + override val coroutineContext: CoroutineContext + get() = Dispatchers.IO + job - override fun loadAlbums() { - launch { - when (val result = repository.allAlbums()) { - is Result.Success -> withContext(Dispatchers.Main) { - view?.albums(result.data) - } - is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() } - } - } - } - } + override fun detachView() { + super.detachView() + job.cancel() + } + + override fun loadAlbums() { + launch { + when (val result = repository.allAlbums()) { + is Result.Success -> withContext(Dispatchers.Main) { + view?.albums(result.data) + } + is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() } + } + } + } + } } \ 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 index 80f1eafca..40f823417 100644 --- 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 @@ -14,8 +14,10 @@ package code.name.monkey.retromusic.mvp.presenter -import code.name.monkey.retromusic.Result +import code.name.monkey.retromusic.Result.Success +import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Artist +import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.PresenterImpl @@ -35,14 +37,24 @@ import kotlin.coroutines.CoroutineContext */ interface ArtistDetailsView : BaseView { + fun songs(songs: List) + + fun albums(albums: List) + fun artist(artist: Artist) + fun artistInfo(lastFmArtist: LastFmArtist?) + fun complete() } interface ArtistDetailsPresenter : Presenter { - fun loadArtist(artistId: Int) + fun loadArtist(artistId: Long) + + fun loadArtistSongs(artistId: Long) + + fun loadArtistAlbums(artistId: Long) fun loadBiography( name: String, @@ -62,26 +74,35 @@ interface ArtistDetailsPresenter : Presenter { override fun loadBiography(name: String, lang: String?, cache: String?) { launch { when (val result = repository.artistInfo(name, lang, cache)) { - is Result.Success -> withContext(Dispatchers.Main) { - view?.artistInfo(result.data) - } - is Result.Error -> withContext(Dispatchers.Main) { - - } + is Success -> withContext(Dispatchers.Main) { view?.artistInfo(result.data) } + is Error -> withContext(Dispatchers.Main) {} } } } - override fun loadArtist(artistId: Int) { + override fun loadArtist(artistId: Long) { launch { when (val result = repository.artistById(artistId)) { - is Result.Success -> withContext(Dispatchers.Main) { - view?.artist(result.data) + is Success -> withContext(Dispatchers.Main) { view?.artist(result.data) } + is Error -> withContext(Dispatchers.Main) { view?.showEmptyView() } + } + } + } - } - is Result.Error -> withContext(Dispatchers.Main) { - view?.showEmptyView() - } + override fun loadArtistSongs(artistId: Long) { + launch { + when (val result = repository.artistSongsById(artistId)) { + is Success -> withContext(Dispatchers.Main) { view.songs(result.data) } + is Error -> withContext(Dispatchers.Main) {} + } + } + } + + override fun loadArtistAlbums(artistId: Long) { + launch { + when (val result = repository.artistAlbumsById(artistId)) { + is Success -> withContext(Dispatchers.Main) { view.albums(result.data) } + is Error -> withContext(Dispatchers.Main) {} } } } diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistPresenter.kt index 7af0365e5..0ed1ed893 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistPresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistPresenter.kt @@ -20,12 +20,16 @@ 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.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject import kotlin.coroutines.CoroutineContext interface ArtistsView : BaseView { - fun artists(artists: ArrayList) + fun artists(artists: List) } interface ArtistsPresenter : Presenter { @@ -33,8 +37,9 @@ interface ArtistsPresenter : Presenter { fun loadArtists() class ArtistsPresenterImpl @Inject constructor( - private val repository: Repository + private val repository: Repository ) : PresenterImpl(), ArtistsPresenter, CoroutineScope { + private val job = Job() override val coroutineContext: CoroutineContext 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 index 4fe21bf7a..786c2e248 100644 --- 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 @@ -20,26 +20,30 @@ 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 java.util.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject import kotlin.coroutines.CoroutineContext - /** * Created by hemanths on 20/08/17. */ interface GenreDetailsView : BaseView { - fun songs(songs: ArrayList) + + fun songs(songs: List) } interface GenreDetailsPresenter : Presenter { fun loadGenreSongs(genreId: Int) class GenreDetailsPresenterImpl @Inject constructor( - private val repository: Repository + private val repository: Repository ) : PresenterImpl(), GenreDetailsPresenter, CoroutineScope { + private val job = Job() override val coroutineContext: CoroutineContext @@ -50,7 +54,6 @@ interface GenreDetailsPresenter : Presenter { job.cancel() } - override fun loadGenreSongs(genreId: Int) { launch { when (val result = repository.getGenre(genreId)) { diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/GenrePresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/GenrePresenter.kt index c929ab226..5ac89fb71 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/GenrePresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/GenrePresenter.kt @@ -20,8 +20,11 @@ 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 java.util.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject import kotlin.coroutines.CoroutineContext @@ -29,15 +32,17 @@ import kotlin.coroutines.CoroutineContext * @author Hemanth S (h4h13). */ interface GenresView : BaseView { - fun genres(genres: ArrayList) + + fun genres(genres: List) } interface GenresPresenter : Presenter { fun loadGenres() class GenresPresenterImpl @Inject constructor( - private val repository: Repository + private val repository: Repository ) : PresenterImpl(), GenresPresenter, CoroutineScope { + private val job = Job() override val coroutineContext: CoroutineContext diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/PlaylistPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/PlaylistPresenter.kt index e41deeb76..e25bddd7e 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/PlaylistPresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/PlaylistPresenter.kt @@ -16,19 +16,25 @@ 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.mvp.* +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.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject import kotlin.coroutines.CoroutineContext - /** * Created by hemanths on 19/08/17. */ interface PlaylistView : BaseView { - fun playlists(playlists: ArrayList) + + fun playlists(playlists: List) } interface PlaylistsPresenter : Presenter { @@ -36,7 +42,7 @@ interface PlaylistsPresenter : Presenter { fun playlists() class PlaylistsPresenterImpl @Inject constructor( - private val repository: Repository + private val repository: Repository ) : PresenterImpl(), PlaylistsPresenter, CoroutineScope { private val job = Job() 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 index 407c4b83a..8a7234814 100644 --- 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 @@ -15,10 +15,17 @@ package code.name.monkey.retromusic.mvp.presenter import code.name.monkey.retromusic.Result -import code.name.monkey.retromusic.model.* -import code.name.monkey.retromusic.mvp.* +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.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject import kotlin.coroutines.CoroutineContext @@ -26,14 +33,15 @@ import kotlin.coroutines.CoroutineContext * Created by hemanths on 20/08/17. */ interface PlaylistSongsView : BaseView { - fun songs(songs: ArrayList) + + fun songs(songs: List) } interface PlaylistSongsPresenter : Presenter { fun loadPlaylistSongs(playlist: Playlist) class PlaylistSongsPresenterImpl @Inject constructor( - private val repository: Repository + private val repository: Repository ) : PresenterImpl(), PlaylistSongsPresenter, CoroutineScope { private var job: Job = Job() diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/SongPresenter.kt b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/SongPresenter.kt index 89ab6351d..5879de46b 100644 --- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/SongPresenter.kt +++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/SongPresenter.kt @@ -16,10 +16,14 @@ 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.mvp.* +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 java.util.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import javax.inject.Inject import kotlin.coroutines.CoroutineContext @@ -27,36 +31,37 @@ import kotlin.coroutines.CoroutineContext * Created by hemanths on 10/08/17. */ interface SongView { - fun songs(songs: ArrayList) - fun showEmptyView() + fun songs(songs: List) + + fun showEmptyView() } interface SongPresenter : Presenter { - fun loadSongs() - class SongPresenterImpl @Inject constructor( - private val repository: Repository - ) : PresenterImpl(), SongPresenter, CoroutineScope { + fun loadSongs() + class SongPresenterImpl @Inject constructor( + private val repository: Repository + ) : PresenterImpl(), SongPresenter, CoroutineScope { - private var job: Job = Job() + private var job: Job = Job() - override val coroutineContext: CoroutineContext - get() = Dispatchers.IO + job + override val coroutineContext: CoroutineContext + get() = Dispatchers.IO + job - override fun loadSongs() { - launch { - when (val songs = repository.allSongs()) { - is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) } - is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() } - } - } - } + override fun loadSongs() { + launch { + when (val songs = repository.allSongs()) { + is Result.Success -> withContext(Dispatchers.Main) { view?.songs(songs.data) } + is Result.Error -> withContext(Dispatchers.Main) { view?.showEmptyView() } + } + } + } - override fun detachView() { - super.detachView() - job.cancel(); - } - } + override fun detachView() { + super.detachView() + job.cancel(); + } + } } diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/BlacklistPreferenceDialog.kt b/app/src/main/java/code/name/monkey/retromusic/preferences/BlacklistPreferenceDialog.kt index 8271e7159..3c1c164dd 100644 --- a/app/src/main/java/code/name/monkey/retromusic/preferences/BlacklistPreferenceDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/preferences/BlacklistPreferenceDialog.kt @@ -41,7 +41,12 @@ class BlacklistPreference : ATEDialogPreference { constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super( + context, + attrs, + defStyleAttr, + defStyleRes + ) init { icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN) @@ -55,23 +60,23 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog } } - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val blacklistFolderChooserDialog = childFragmentManager.findFragmentByTag("FOLDER_CHOOSER") as BlacklistFolderChooserDialog? + val blacklistFolderChooserDialog = + childFragmentManager.findFragmentByTag("FOLDER_CHOOSER") as BlacklistFolderChooserDialog? blacklistFolderChooserDialog?.setCallback(this) refreshBlacklistData() return MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show { - title(code.name.monkey.retromusic.R.string.blacklist) + title(R.string.blacklist) cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) positiveButton(android.R.string.ok) { dismiss() } neutralButton(text = getString(R.string.clear_action)) { MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show { - title(code.name.monkey.retromusic.R.string.clear_blacklist) - message(code.name.monkey.retromusic.R.string.do_you_want_to_clear_the_blacklist) + title(R.string.clear_blacklist) + message(R.string.do_you_want_to_clear_the_blacklist) cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) - positiveButton(code.name.monkey.retromusic.R.string.clear_action) { + positiveButton(R.string.clear_action) { BlacklistStore.getInstance(context).clear() refreshBlacklistData() } @@ -81,13 +86,20 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog negativeButton(R.string.add_action) { val dialog = BlacklistFolderChooserDialog.create() dialog.setCallback(this@BlacklistPreferenceDialog) - dialog.show(childFragmentManager, "FOLDER_CHOOSER"); + dialog.show(childFragmentManager, "FOLDER_CHOOSER") } listItems(items = paths, waitForPositiveButton = false) { _, _, text -> - MaterialDialog(context, BottomSheet(LayoutMode.WRAP_CONTENT)).show { + MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show { cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) - title(code.name.monkey.retromusic.R.string.remove_from_blacklist) - message(text = Html.fromHtml(getString(code.name.monkey.retromusic.R.string.do_you_want_to_remove_from_the_blacklist, text))) + title(R.string.remove_from_blacklist) + message( + text = Html.fromHtml( + getString( + R.string.do_you_want_to_remove_from_the_blacklist, + text + ) + ) + ) positiveButton(code.name.monkey.retromusic.R.string.remove_action) { BlacklistStore.getInstance(context).removePath(File(text.toString())) refreshBlacklistData() @@ -108,7 +120,7 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog } override fun onFolderSelection(dialog: BlacklistFolderChooserDialog, folder: File) { - BlacklistStore.getInstance(context!!).addPath(folder); - refreshBlacklistData(); + BlacklistStore.getInstance(context!!).addPath(folder) + refreshBlacklistData() } } diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.kt b/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.kt index 1532c8388..05ae00ac8 100644 --- a/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.kt +++ b/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.kt @@ -16,6 +16,7 @@ package code.name.monkey.retromusic.preferences import android.app.Dialog import android.content.Context +import android.content.res.ColorStateList import android.graphics.PorterDuff import android.os.Bundle import android.util.AttributeSet @@ -30,8 +31,12 @@ import androidx.viewpager.widget.PagerAdapter import androidx.viewpager.widget.ViewPager import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference +import code.name.monkey.appthemehelper.util.ColorUtil +import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.retromusic.App import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.extensions.hide +import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.fragments.NowPlayingScreen import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.PreferenceUtil @@ -42,18 +47,23 @@ import com.bumptech.glide.Glide class NowPlayingScreenPreference : ATEDialogPreference { - constructor(context: Context) : super(context) {} + constructor(context: Context) : super(context) - constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} + constructor(context: Context, attrs: AttributeSet) : super(context, attrs) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {} + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) - constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {} + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super( + context, + attrs, + defStyleAttr, + defStyleRes + ) private val mLayoutRes = R.layout.preference_dialog_now_playing_screen override fun getDialogLayoutResource(): Int { - return mLayoutRes; + return mLayoutRes } init { @@ -66,11 +76,9 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP private var viewPagerPosition: Int = 0 override fun onPageScrollStateChanged(state: Int) { - } override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { - } override fun onPageSelected(position: Int) { @@ -78,13 +86,12 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP } override fun onDialogClosed(positiveResult: Boolean) { - } override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val view = LayoutInflater.from(activity).inflate(R.layout.preference_dialog_now_playing_screen, null) val viewPager = view.findViewById(R.id.now_playing_screen_view_pager) - ?: throw IllegalStateException("Dialog view must contain a ViewPager with id 'now_playing_screen_view_pager'") + ?: throw IllegalStateException("Dialog view must contain a ViewPager with id 'now_playing_screen_view_pager'") viewPager.adapter = NowPlayingScreenAdapter(activity!!) viewPager.addOnPageChangeListener(this) viewPager.pageMargin = ViewUtil.convertDpToPixel(32f, resources).toInt() @@ -109,24 +116,6 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP } } - private fun isNowPlayingThemes(nowPlayingScreen: NowPlayingScreen): Boolean { - if (nowPlayingScreen == NowPlayingScreen.BLUR_CARD) { - PreferenceUtil.getInstance(requireContext()).resetCarouselEffect() - PreferenceUtil.getInstance(requireContext()).resetCircularAlbumArt() - } - - return (nowPlayingScreen == NowPlayingScreen.FULL || - nowPlayingScreen == NowPlayingScreen.CARD || - nowPlayingScreen == NowPlayingScreen.PLAIN || - nowPlayingScreen == NowPlayingScreen.BLUR || - nowPlayingScreen == NowPlayingScreen.COLOR || - nowPlayingScreen == NowPlayingScreen.SIMPLE || - nowPlayingScreen == NowPlayingScreen.BLUR_CARD || - nowPlayingScreen == NowPlayingScreen.CIRCLE || - nowPlayingScreen == NowPlayingScreen.ADAPTIVE) - && !App.isProVersion() - } - companion object { fun newInstance(key: String): NowPlayingScreenPreferenceDialog { val bundle = Bundle() @@ -138,7 +127,7 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP } } -private class NowPlayingScreenAdapter internal constructor(private val context: Context) : PagerAdapter() { +private class NowPlayingScreenAdapter(private val context: Context) : PagerAdapter() { override fun instantiateItem(collection: ViewGroup, position: Int): Any { val nowPlayingScreen = NowPlayingScreen.values()[position] @@ -148,16 +137,26 @@ private class NowPlayingScreenAdapter internal constructor(private val context: collection.addView(layout) val image = layout.findViewById(R.id.image) + val proText = layout.findViewById(R.id.proText) val title = layout.findViewById(R.id.title) Glide.with(context).load(nowPlayingScreen.drawableResId).into(image) title.setText(nowPlayingScreen.titleRes) - + if (isNowPlayingThemes(nowPlayingScreen)) { + proText.show() + } else { + proText.hide() + } + val color = ThemeStore.accentColor(context) + proText.backgroundTintList = ColorStateList.valueOf(color) + proText.setTextColor(MaterialValueHelper.getPrimaryTextColor(context,ColorUtil.isColorLight(color))) return layout } - override fun destroyItem(collection: ViewGroup, - position: Int, - view: Any) { + override fun destroyItem( + collection: ViewGroup, + position: Int, + view: Any + ) { collection.removeView(view as View) } @@ -172,4 +171,19 @@ private class NowPlayingScreenAdapter internal constructor(private val context: override fun getPageTitle(position: Int): CharSequence? { return context.getString(NowPlayingScreen.values()[position].titleRes) } -} \ No newline at end of file +} + +fun isNowPlayingThemes(nowPlayingScreen: NowPlayingScreen): Boolean { + return (nowPlayingScreen == NowPlayingScreen.FULL || + nowPlayingScreen == NowPlayingScreen.CARD || + nowPlayingScreen == NowPlayingScreen.PLAIN || + nowPlayingScreen == NowPlayingScreen.BLUR || + nowPlayingScreen == NowPlayingScreen.COLOR || + nowPlayingScreen == NowPlayingScreen.SIMPLE || + nowPlayingScreen == NowPlayingScreen.BLUR_CARD || + nowPlayingScreen == NowPlayingScreen.CIRCLE || + nowPlayingScreen == NowPlayingScreen.ADAPTIVE || + nowPlayingScreen == NowPlayingScreen.MATERIAL || + nowPlayingScreen == NowPlayingScreen.PEAK) + && !App.isProVersion() +} diff --git a/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.kt b/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.kt index 20a1b3b3a..69077ba24 100644 --- a/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.kt +++ b/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.kt @@ -45,7 +45,7 @@ import javax.inject.Inject class RepositoryImpl @Inject constructor(private val context: Context) : Repository { - override suspend fun allAlbums(): Result> { + override suspend fun allAlbums(): Result> { return try { val albums = AlbumLoader.getAllAlbums(context) if (albums.isNotEmpty()) { @@ -58,14 +58,37 @@ class RepositoryImpl @Inject constructor(private val context: Context) : Reposit } } - override suspend fun albumById(albumId: Int): Result { + override suspend fun albumById(albumId: Long): Result { return try { val album = AlbumLoader.getAlbum(context, albumId) - if (album != null) { - Success(album) - } else { - Error(Throwable("No album")) - } + Success(album) + } catch (e: Exception) { + Error(e) + } + } + + override suspend fun albumSongsById(albumId: Long): Result> { + return try { + val songs = AlbumLoader.getSongsForAlbum(context, albumId) + Success(songs) + } catch (e: Exception) { + Error(e) + } + } + + override suspend fun artistSongsById(artistId: Long): Result> { + return try { + val songs = ArtistLoader.getSongsForArtist(context, artistId) + Success(songs) + } catch (e: Exception) { + Error(e) + } + } + + override suspend fun artistAlbumsById(artistId: Long): Result> { + return try { + val albums = AlbumLoader.getAlbumsForArtist(context, artistId) + Success(albums) } catch (e: Exception) { Error(e) } @@ -289,7 +312,7 @@ class RepositoryImpl @Inject constructor(private val context: Context) : Reposit errorMessage = "Error" ) - override suspend fun artistById(artistId: Int): Result { + override suspend fun artistById(artistId: Long): Result { return try { val artist = ArtistLoader.getArtist(context, artistId) return Success(artist) diff --git a/app/src/main/java/code/name/monkey/retromusic/providers/interfaces/Repository.kt b/app/src/main/java/code/name/monkey/retromusic/providers/interfaces/Repository.kt index aec8eaeab..d28d05e24 100644 --- a/app/src/main/java/code/name/monkey/retromusic/providers/interfaces/Repository.kt +++ b/app/src/main/java/code/name/monkey/retromusic/providers/interfaces/Repository.kt @@ -30,23 +30,29 @@ import code.name.monkey.retromusic.rest.model.LastFmArtist interface Repository { - suspend fun allAlbums(): Result> + suspend fun allAlbums(): Result> - suspend fun albumById(albumId: Int): Result + suspend fun albumById(albumId: Long): Result - suspend fun allSongs(): Result> + suspend fun albumSongsById(albumId: Long): Result> - suspend fun allArtists(): Result> + suspend fun artistSongsById(artistId: Long): Result> - suspend fun allPlaylists(): Result> + suspend fun artistAlbumsById(artistId: Long): Result> - suspend fun allGenres(): Result> + suspend fun allSongs(): Result> + + suspend fun allArtists(): Result> + + suspend fun allPlaylists(): Result> + + suspend fun allGenres(): Result> suspend fun search(query: String?): Result> - suspend fun getPlaylistSongs(playlist: Playlist): Result> + suspend fun getPlaylistSongs(playlist: Playlist): Result> - suspend fun getGenre(genreId: Int): Result> + suspend fun getGenre(genreId: Int): Result> suspend fun recentArtists(): Result @@ -62,5 +68,5 @@ interface Repository { suspend fun albumInfo(artist: String, album: String): Result - suspend fun artistById(artistId: Int): Result + suspend fun artistById(artistId: Long): Result } \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java index a05b9701b..983f9d46a 100644 --- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java +++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java @@ -642,7 +642,7 @@ public class MusicService extends Service implements break; case SHUFFLE_MODE_NONE: this.shuffleMode = shuffleMode; - int currentSongId = Objects.requireNonNull(getCurrentSong()).getId(); + long currentSongId = Objects.requireNonNull(getCurrentSong()).getId(); playingQueue = new ArrayList<>(originalPlayingQueue); int newPosition = 0; if (getPlayingQueue() != null) { @@ -844,7 +844,7 @@ public class MusicService extends Service implements return true; } - public void openQueue(@Nullable final ArrayList playingQueue, final int startPosition, + public void openQueue(@Nullable final List playingQueue, final int startPosition, final boolean startPlaying) { if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue .size()) { diff --git a/app/src/main/java/code/name/monkey/retromusic/service/WearBrowserService.java b/app/src/main/java/code/name/monkey/retromusic/service/WearBrowserService.java deleted file mode 100644 index 6f61630c1..000000000 --- a/app/src/main/java/code/name/monkey/retromusic/service/WearBrowserService.java +++ /dev/null @@ -1,370 +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.service; - -import android.annotation.TargetApi; -import android.content.Context; -import android.content.Intent; -import android.media.MediaDescription; -import android.media.browse.MediaBrowser; -import android.media.session.MediaSession; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Bundle; -import android.service.media.MediaBrowserService; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; - -import java.util.ArrayList; -import java.util.List; - -import code.name.monkey.retromusic.R; -import code.name.monkey.retromusic.helper.MusicPlayerRemote; -import code.name.monkey.retromusic.loaders.AlbumLoader; -import code.name.monkey.retromusic.loaders.ArtistLoader; -import code.name.monkey.retromusic.loaders.PlaylistLoader; -import code.name.monkey.retromusic.loaders.PlaylistSongsLoader; -import code.name.monkey.retromusic.loaders.SongLoader; -import code.name.monkey.retromusic.model.Album; -import code.name.monkey.retromusic.model.Artist; -import code.name.monkey.retromusic.model.Playlist; -import code.name.monkey.retromusic.model.Song; -import code.name.monkey.retromusic.util.MusicUtil; -import code.name.monkey.retromusic.util.RetroUtil; - -/** - * @author Hemanth S (h4h13). - */ -@TargetApi(21) -public class WearBrowserService extends MediaBrowserService { - - public static final String MEDIA_ID_ROOT = "__ROOT__"; - public static final int TYPE_ARTIST = 0; - public static final int TYPE_ALBUM = 1; - public static final int TYPE_SONG = 2; - public static final int TYPE_PLAYLIST = 3; - public static final int TYPE_ARTIST_SONG_ALBUMS = 4; - public static final int TYPE_ALBUM_SONGS = 5; - public static final int TYPE_ARTIST_ALL_SONGS = 6; - public static final int TYPE_PLAYLIST_ALL_SONGS = 7; - - public static WearBrowserService sInstance; - private MediaSession mSession; - private Context mContext; - private boolean mServiceStarted; - - public static WearBrowserService getInstance() { - return sInstance; - } - - @Override - public void onCreate() { - super.onCreate(); - sInstance = this; - mContext = this; - mSession = new MediaSession(this, "WearBrowserService"); - setSessionToken(mSession.getSessionToken()); - mSession.setCallback(new MediaSessionCallback()); - mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS); - } - - @Override - public int onStartCommand(Intent startIntent, int flags, int startId) { - return START_STICKY; - } - - @Override - public void onDestroy() { - mServiceStarted = false; - mSession.release(); - } - - @Nullable - @Override - public BrowserRoot onGetRoot(@NonNull String s, int i, @Nullable Bundle bundle) { - return new BrowserRoot(MEDIA_ID_ROOT, null); - } - - @Override - public void onLoadChildren(@NonNull String parentId, @NonNull Result> result) { - result.detach(); - loadChildren(parentId, result); - } - - private void setSessionActive() { - if (!mServiceStarted) { - startService(new Intent(getApplicationContext(), WearBrowserService.class)); - mServiceStarted = true; - } - - if (!mSession.isActive()) { - mSession.setActive(true); - } - } - - private void setSessionInactive() { - if (mServiceStarted) { - stopSelf(); - mServiceStarted = false; - } - - if (mSession.isActive()) { - mSession.setActive(false); - } - } - - private void fillMediaItems(List mediaItems, - String mediaId, - String title, - String subTitle, - Uri icon, - int playableOrBrowsable) { - mediaItems.add(new MediaBrowser.MediaItem( - new MediaDescription.Builder() - .setMediaId(mediaId) - .setTitle(title) - .setIconUri(icon) - .setSubtitle(subTitle) - .build(), playableOrBrowsable - )); - } - - private void addMediaRoots(List mMediaRoot) { - mMediaRoot.add(new MediaBrowser.MediaItem( - new MediaDescription.Builder() - .setMediaId(Integer.toString(TYPE_ARTIST)) - .setTitle(getString(R.string.artists)) - .setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_artist_art), 1f)) - .setSubtitle(getString(R.string.artists)) - .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE - )); - - mMediaRoot.add(new MediaBrowser.MediaItem( - new MediaDescription.Builder() - .setMediaId(Integer.toString(TYPE_ALBUM)) - .setTitle(getString(R.string.albums)) - .setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_album_art), 1f)) - .setSubtitle(getString(R.string.albums)) - .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE - )); - - mMediaRoot.add(new MediaBrowser.MediaItem( - new MediaDescription.Builder() - .setMediaId(Integer.toString(TYPE_SONG)) - .setTitle(getString(R.string.songs)) - .setIconBitmap(RetroUtil.createBitmap(ContextCompat.getDrawable(getApplicationContext(), R.drawable.default_album_art), 1f)) - .setSubtitle(getString(R.string.songs)) - .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE - )); - - - mMediaRoot.add(new MediaBrowser.MediaItem( - new MediaDescription.Builder() - .setMediaId(Integer.toString(TYPE_PLAYLIST)) - .setTitle(getString(R.string.playlists)) - .setIconUri(Uri.parse("android.resource://code.name.monkey.retromusic/drawable/ic_queue_music_white_24dp")) - .setSubtitle(getString(R.string.playlists)) - .build(), MediaBrowser.MediaItem.FLAG_BROWSABLE - )); - - } - - private void loadChildren(final String parentId, final Result> result) { - - final List mediaItems = new ArrayList<>(); - - - new AsyncTask() { - @Override - protected Void doInBackground(final Void... unused) { - - if (parentId.equals(MEDIA_ID_ROOT)) { - addMediaRoots(mediaItems); - } else { - switch (Integer.parseInt(Character.toString(parentId.charAt(0)))) { - case TYPE_ARTIST: - List artistList = ArtistLoader.INSTANCE.getAllArtists(mContext) ; - for (Artist artist : artistList) { - String albumNmber = String.format("%d %s", artist.getAlbums().size(), artist.getAlbums().size() > 1 ? "Albums" : "Album"); - String songCount = String.format("%d %s", artist.getSongs().size(), artist.getSongs().size() > 1 ? "Songs" : "Song"); - fillMediaItems(mediaItems, - Integer.toString(TYPE_ARTIST_SONG_ALBUMS) + Long.toString(artist.getId()), - artist.getName(), - albumNmber + " • " + songCount, - Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"), - MediaBrowser.MediaItem.FLAG_BROWSABLE); - } - break; - - case TYPE_ARTIST_SONG_ALBUMS: - fillMediaItems(mediaItems, - Integer.toString(TYPE_ARTIST_ALL_SONGS) + Long.parseLong(parentId.substring(1)), - "All songs", - "All songs by artist", - Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"), - MediaBrowser.MediaItem.FLAG_BROWSABLE); - - List artistAlbums = ArtistLoader.INSTANCE.getArtist(mContext, Integer.parseInt(parentId.substring(1))).getAlbums(); //ArtistAlbumLoader.getAlbumsForArtist(mContext, Long.parseLong(parentId.substring(1))); - for (Album album : artistAlbums) { - String songCount = String.format("%d %s", album.getSongs().size(), album.getSongs().size() > 1 ? "Songs" : "Song"); - fillMediaItems(mediaItems, - Integer.toString(TYPE_ALBUM_SONGS) + Long.toString(album.getId()), - album.getTitle(), - songCount, - Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_artist_art"), - MediaBrowser.MediaItem.FLAG_BROWSABLE); - } - break; - case TYPE_ALBUM: - List albumList = AlbumLoader.INSTANCE.getAllAlbums(mContext); - for (Album album : albumList) { - fillMediaItems(mediaItems, - Integer.toString(TYPE_ALBUM_SONGS) + Long.toString(album.getId()), - album.getTitle(), - album.getArtistName(), - MusicUtil.getMediaStoreAlbumCoverUri(album.getId()), - MediaBrowser.MediaItem.FLAG_BROWSABLE); - } - break; - case TYPE_SONG: - List songList = SongLoader.INSTANCE.getAllSongs(mContext); - for (Song song : songList) { - fillMediaItems(mediaItems, - String.valueOf(song.getId()), - song.getTitle(), - song.getAlbumName(), - Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"), - MediaBrowser.MediaItem.FLAG_PLAYABLE); - } - break; - - case TYPE_ALBUM_SONGS: - List albumSongList = AlbumLoader.INSTANCE.getAlbum(mContext, Integer.parseInt(parentId.substring(1))).getSongs(); - for (Song song : albumSongList) { - fillMediaItems(mediaItems, - String.valueOf(song.getId()), - song.getTitle(), - song.getAlbumName(), - Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"), - MediaBrowser.MediaItem.FLAG_PLAYABLE); - } - break; - case TYPE_ARTIST_ALL_SONGS: - List artistSongs = ArtistLoader.INSTANCE.getArtist(mContext, Integer.parseInt(parentId.substring(1))).getSongs(); - for (Song song : artistSongs) { - fillMediaItems(mediaItems, - String.valueOf(song.getId()), - song.getTitle(), - song.getAlbumName(), - Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"), - MediaBrowser.MediaItem.FLAG_PLAYABLE); - } - break; - case TYPE_PLAYLIST: - List playlistList = PlaylistLoader.INSTANCE.getAllPlaylists(mContext); - for (Playlist playlist : playlistList) { - int size = PlaylistSongsLoader.INSTANCE.getPlaylistSongList(mContext, playlist).size(); - String songCount = String.format("%d %s", size, size > 1 ? "Songs" : "Song"); - fillMediaItems(mediaItems, - Integer.toString(TYPE_PLAYLIST_ALL_SONGS) + Long.toString(playlist.id), - playlist.name, - songCount, - Uri.parse("android.resource://code.name.monkey.retromusic/drawable/ic_queue_music_white_24dp"), - MediaBrowser.MediaItem.FLAG_BROWSABLE); - } - break; - case TYPE_PLAYLIST_ALL_SONGS: - List playlistSongs = PlaylistSongsLoader.INSTANCE.getPlaylistSongList(mContext, Integer.parseInt(parentId.substring(1))); - for (Song song : playlistSongs) { - fillMediaItems(mediaItems, - String.valueOf(song.getId()), - song.getTitle(), - song.getAlbumName(), - Uri.parse("android.resource://code.name.monkey.retromusic/drawable/default_album_art"), - MediaBrowser.MediaItem.FLAG_PLAYABLE); - } - break; - - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - result.sendResult(mediaItems); - } - }.execute(); - - } - - private final class MediaSessionCallback extends MediaSession.Callback { - - @Override - public void onPlay() { - setSessionActive(); - } - - @Override - public void onSeekTo(long position) { - - } - - @Override - public void onPlayFromMediaId(final String mediaId, Bundle extras) { - long songId = Long.parseLong(mediaId); - setSessionActive(); - ArrayList songs = new ArrayList<>(); - songs.add(SongLoader.INSTANCE.getSong(mContext, Integer.parseInt(mediaId))); - MusicPlayerRemote.INSTANCE.openQueue(songs, 0, true); - } - - @Override - public void onPause() { - - } - - @Override - public void onStop() { - setSessionInactive(); - } - - @Override - public void onSkipToNext() { - - } - - @Override - public void onSkipToPrevious() { - - } - - @Override - public void onFastForward() { - - } - - @Override - public void onRewind() { - - } - - @Override - public void onCustomAction(@NonNull String action, Bundle extras) { - - } - } -} diff --git a/app/src/main/java/code/name/monkey/retromusic/util/FileUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/FileUtil.java index 9476e86d1..6243a0ca9 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/FileUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/FileUtil.java @@ -19,10 +19,11 @@ import android.database.Cursor; import android.os.Environment; import android.provider.MediaStore; import android.webkit.MimeTypeMap; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; - +import code.name.monkey.retromusic.loaders.SongLoader; +import code.name.monkey.retromusic.loaders.SortedCursor; +import code.name.monkey.retromusic.model.Song; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; @@ -37,137 +38,9 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; -import code.name.monkey.retromusic.loaders.SongLoader; -import code.name.monkey.retromusic.loaders.SortedCursor; -import code.name.monkey.retromusic.model.Song; - public final class FileUtil { - private FileUtil() { - } - - public static byte[] readBytes(InputStream stream) throws IOException { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - byte[] buffer = new byte[4096]; - int count; - while ((count = stream.read(buffer)) != -1) { - baos.write(buffer, 0, count); - } - stream.close(); - return baos.toByteArray(); - } - - @NonNull - public static ArrayList matchFilesWithMediaStore(@NonNull Context context, - @Nullable List files) { - return SongLoader.INSTANCE.getSongs(makeSongCursor(context, files)); - } - - public static String safeGetCanonicalPath(File file) { - try { - return file.getCanonicalPath(); - } catch (IOException e) { - e.printStackTrace(); - return file.getAbsolutePath(); - } - } - - @Nullable - public static SortedCursor makeSongCursor(@NonNull final Context context, - @Nullable final List files) { - String selection = null; - String[] paths = null; - - if (files != null) { - paths = toPathArray(files); - - if (files.size() > 0 - && files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle. - selection = - MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")"; - } - } - - Cursor songCursor = SongLoader.INSTANCE.makeSongCursor(context, selection, selection == null ? null : paths); - - return songCursor == null ? null - : new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA); - } - - private static String makePlaceholders(int len) { - StringBuilder sb = new StringBuilder(len * 2 - 1); - sb.append("?"); - for (int i = 1; i < len; i++) { - sb.append(",?"); - } - return sb.toString(); - } - - @Nullable - private static String[] toPathArray(@Nullable List files) { - if (files != null) { - String[] paths = new String[files.size()]; - for (int i = 0; i < files.size(); i++) { - /*try { - paths[i] = files.get(i).getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later - } catch (IOException e) { - e.printStackTrace(); - paths[i] = files.get(i).getPath(); - }*/ - paths[i] = safeGetCanonicalPath(files.get(i)); - } - return paths; - } - return null; - } - - @NonNull - public static List listFiles(@NonNull File directory, @Nullable FileFilter fileFilter) { - List fileList = new LinkedList<>(); - File[] found = directory.listFiles(fileFilter); - if (found != null) { - Collections.addAll(fileList, found); - } - return fileList; - } - - @NonNull - public static List listFilesDeep(@NonNull File directory, @Nullable FileFilter fileFilter) { - List files = new LinkedList<>(); - internalListFilesDeep(files, directory, fileFilter); - return files; - } - - @NonNull - public static List listFilesDeep(@NonNull Collection files, - @Nullable FileFilter fileFilter) { - List resFiles = new LinkedList<>(); - for (File file : files) { - if (file.isDirectory()) { - internalListFilesDeep(resFiles, file, fileFilter); - } else if (fileFilter == null || fileFilter.accept(file)) { - resFiles.add(file); - } - } - return resFiles; - } - - private static void internalListFilesDeep(@NonNull Collection files, - @NonNull File directory, @Nullable FileFilter fileFilter) { - File[] found = directory.listFiles(fileFilter); - - if (found != null) { - for (File file : found) { - if (file.isDirectory()) { - internalListFilesDeep(files, file, fileFilter); - } else { - files.add(file); - } - } - } - } - public static boolean fileIsMimeType(File file, String mimeType, MimeTypeMap mimeTypeMap) { if (mimeType == null || mimeType.equals("*/*")) { return true; @@ -209,15 +82,95 @@ public final class FileUtil { } } - public static String stripExtension(String str) { - if (str == null) { - return null; + public static boolean isExternalMemoryAvailable() { + Boolean isSDPresent = Environment.getExternalStorageState() + .equals(android.os.Environment.MEDIA_MOUNTED); + Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable(); + + if (isSDSupportedDevice && isSDPresent) { + // yes SD-card is present + return true; + } else { + return false; + // Sorry } - int pos = str.lastIndexOf('.'); - if (pos == -1) { - return str; + } + + @NonNull + public static List listFiles(@NonNull File directory, @Nullable FileFilter fileFilter) { + List fileList = new LinkedList<>(); + File[] found = directory.listFiles(fileFilter); + if (found != null) { + Collections.addAll(fileList, found); } - return str.substring(0, pos); + return fileList; + } + + @NonNull + public static List listFilesDeep(@NonNull File directory, @Nullable FileFilter fileFilter) { + List files = new LinkedList<>(); + internalListFilesDeep(files, directory, fileFilter); + return files; + } + + @NonNull + public static List listFilesDeep(@NonNull Collection files, + @Nullable FileFilter fileFilter) { + List resFiles = new LinkedList<>(); + for (File file : files) { + if (file.isDirectory()) { + internalListFilesDeep(resFiles, file, fileFilter); + } else if (fileFilter == null || fileFilter.accept(file)) { + resFiles.add(file); + } + } + return resFiles; + } + + @Nullable + public static SortedCursor makeSongCursor(@NonNull final Context context, + @Nullable final List files) { + String selection = null; + String[] paths = null; + + if (files != null) { + paths = toPathArray(files); + + if (files.size() > 0 + && files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle. + selection = + MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")"; + } + } + + Cursor songCursor = SongLoader.makeSongCursor(context, selection, selection == null ? null : paths); + + return songCursor == null ? null + : new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA); + } + + @NonNull + public static ArrayList matchFilesWithMediaStore(@NonNull Context context, + @Nullable List files) { + return SongLoader.INSTANCE.getSongs(makeSongCursor(context, files)); + } + + public static String read(File file) throws Exception { + FileInputStream fin = new FileInputStream(file); + String ret = readFromStream(fin); + fin.close(); + return ret; + } + + public static byte[] readBytes(InputStream stream) throws IOException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + byte[] buffer = new byte[4096]; + int count; + while ((count = stream.read(buffer)) != -1) { + baos.write(buffer, 0, count); + } + stream.close(); + return baos.toByteArray(); } public static String readFromStream(InputStream is) throws Exception { @@ -234,27 +187,6 @@ public final class FileUtil { return sb.toString(); } - public static String read(File file) throws Exception { - FileInputStream fin = new FileInputStream(file); - String ret = readFromStream(fin); - fin.close(); - return ret; - } - - public static boolean isExternalMemoryAvailable() { - Boolean isSDPresent = Environment.getExternalStorageState() - .equals(android.os.Environment.MEDIA_MOUNTED); - Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable(); - - if (isSDSupportedDevice && isSDPresent) { - // yes SD-card is present - return true; - } else { - return false; - // Sorry - } - } - public static File safeGetCanonicalFile(File file) { try { return file.getCanonicalFile(); @@ -264,5 +196,70 @@ public final class FileUtil { } } + public static String safeGetCanonicalPath(File file) { + try { + return file.getCanonicalPath(); + } catch (IOException e) { + e.printStackTrace(); + return file.getAbsolutePath(); + } + } + + public static String stripExtension(String str) { + if (str == null) { + return null; + } + int pos = str.lastIndexOf('.'); + if (pos == -1) { + return str; + } + return str.substring(0, pos); + } + + private FileUtil() { + } + + private static void internalListFilesDeep(@NonNull Collection files, + @NonNull File directory, @Nullable FileFilter fileFilter) { + File[] found = directory.listFiles(fileFilter); + + if (found != null) { + for (File file : found) { + if (file.isDirectory()) { + internalListFilesDeep(files, file, fileFilter); + } else { + files.add(file); + } + } + } + } + + private static String makePlaceholders(int len) { + StringBuilder sb = new StringBuilder(len * 2 - 1); + sb.append("?"); + for (int i = 1; i < len; i++) { + sb.append(",?"); + } + return sb.toString(); + } + + @Nullable + private static String[] toPathArray(@Nullable List files) { + if (files != null) { + String[] paths = new String[files.size()]; + for (int i = 0; i < files.size(); i++) { + /*try { + paths[i] = files.get(i).getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later + } catch (IOException e) { + e.printStackTrace(); + paths[i] = files.get(i).getPath(); + }*/ + paths[i] = safeGetCanonicalPath(files.get(i)); + } + return paths; + } + return null; + } + } diff --git a/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.java index 440bc6d15..fc73f94d6 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.java @@ -99,7 +99,7 @@ public class MusicUtil { } } - public static void deleteAlbumArt(@NonNull Context context, int albumId) { + public static void deleteAlbumArt(@NonNull Context context, long albumId) { ContentResolver contentResolver = context.getContentResolver(); Uri localUri = Uri.parse("content://media/external/audio/albumart"); contentResolver.delete(ContentUris.withAppendedId(localUri, albumId), null, null); @@ -262,7 +262,7 @@ public class MusicUtil { } @NonNull - public static Uri getMediaStoreAlbumCoverUri(int albumId) { + public static Uri getMediaStoreAlbumCoverUri(long albumId) { final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart"); return ContentUris.withAppendedId(sArtworkUri, albumId); } @@ -322,7 +322,7 @@ public class MusicUtil { return songCount + " " + songString; } - public static Uri getSongFileUri(int songId) { + public static Uri getSongFileUri(long songId) { return ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, songId); } @@ -348,7 +348,7 @@ public class MusicUtil { return -1; } - public static void insertAlbumArt(@NonNull Context context, int albumId, String path) { + public static void insertAlbumArt(@NonNull Context context, long albumId, String path) { ContentResolver contentResolver = context.getContentResolver(); Uri artworkUri = Uri.parse("content://media/external/audio/albumart"); 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 8ce25a27c..cfc862201 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 @@ -59,14 +59,14 @@ public class NavigationUtil { ActivityCompat.startActivity(activity, new Intent(activity, AboutActivity.class), null); } - public static void goToAlbum(@NonNull Activity activity, int albumId) { + public static void goToAlbum(@NonNull Activity activity, long albumId) { Intent intent = new Intent(activity, AlbumDetailsActivity.class); intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId); ActivityCompat.startActivity(activity, intent, null); } public static void goToAlbumOptions(@NonNull Activity activity, - int albumId, + long albumId, @NonNull ActivityOptions options) { Intent intent = new Intent(activity, AlbumDetailsActivity.class); intent.putExtra(AlbumDetailsActivity.EXTRA_ALBUM_ID, albumId); @@ -80,7 +80,7 @@ public class NavigationUtil { } public static void goToArtistOptions(@NotNull Activity activity, - int artistId, + long artistId, @NonNull ActivityOptions options) { Intent intent = new Intent(activity, ArtistDetailActivity.class); diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java index 422f9a21a..d484c3e39 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java @@ -130,7 +130,7 @@ public class PlaylistsUtil { } static boolean doPlaylistContains(@NonNull final Context context, final long playlistId, - final int songId) { + final long songId) { if (playlistId != -1) { try { Cursor c = context.getContentResolver().query( diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java index 8ca67846a..658ca2893 100644 --- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java +++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java @@ -14,6 +14,12 @@ package code.name.monkey.retromusic.util; +import static code.name.monkey.retromusic.helper.SortOrder.ArtistAlbumSortOrder; +import static code.name.monkey.retromusic.helper.SortOrder.ArtistSongSortOrder; +import static code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder; +import static code.name.monkey.retromusic.helper.SortOrder.GenreSortOrder; +import static code.name.monkey.retromusic.helper.SortOrder.SongSortOrder; + import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; @@ -33,8 +39,8 @@ import code.name.monkey.retromusic.activities.MainActivity; import code.name.monkey.retromusic.fragments.AlbumCoverStyle; import code.name.monkey.retromusic.fragments.NowPlayingScreen; import code.name.monkey.retromusic.fragments.mainactivity.folders.FoldersFragment; -import code.name.monkey.retromusic.helper.SortOrder; import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder; +import code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder; import code.name.monkey.retromusic.model.CategoryInfo; import code.name.monkey.retromusic.transform.CascadingPageTransformer; import code.name.monkey.retromusic.transform.DepthTransformation; @@ -365,6 +371,7 @@ public final class PreferenceUtil { } } + @NonNull public String getAlbumDetailSongSortOrder() { return mPreferences .getString(ALBUM_DETAIL_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST); @@ -417,8 +424,9 @@ public final class PreferenceUtil { .getString(ALBUM_SONG_SORT_ORDER, AlbumSongSortOrder.SONG_TRACK_LIST); } + @NonNull public final String getAlbumSortOrder() { - return mPreferences.getString(ALBUM_SORT_ORDER, SortOrder.AlbumSortOrder.ALBUM_A_Z); + return mPreferences.getString(ALBUM_SORT_ORDER, AlbumSortOrder.ALBUM_A_Z); } public void setAlbumSortOrder(final String sortOrder) { @@ -428,12 +436,12 @@ public final class PreferenceUtil { } public final String getArtistAlbumSortOrder() { - return mPreferences.getString(ARTIST_ALBUM_SORT_ORDER, SortOrder.ArtistAlbumSortOrder.ALBUM_YEAR); + return mPreferences.getString(ARTIST_ALBUM_SORT_ORDER, ArtistAlbumSortOrder.ALBUM_YEAR); } public String getArtistDetailSongSortOrder() { return mPreferences - .getString(ARTIST_DETAIL_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.SONG_A_Z); + .getString(ARTIST_DETAIL_SONG_SORT_ORDER, ArtistSongSortOrder.SONG_A_Z); } public void setArtistDetailSongSortOrder(String sortOrder) { @@ -462,11 +470,12 @@ public final class PreferenceUtil { } public final String getArtistSongSortOrder() { - return mPreferences.getString(ARTIST_SONG_SORT_ORDER, SortOrder.ArtistSongSortOrder.SONG_A_Z); + return mPreferences.getString(ARTIST_SONG_SORT_ORDER, ArtistSongSortOrder.SONG_A_Z); } + @NonNull public final String getArtistSortOrder() { - return mPreferences.getString(ARTIST_SORT_ORDER, SortOrder.ArtistSortOrder.ARTIST_A_Z); + return mPreferences.getString(ARTIST_SORT_ORDER, ArtistSortOrder.ARTIST_A_Z); } public void setArtistSortOrder(final String sortOrder) { @@ -536,7 +545,7 @@ public final class PreferenceUtil { } public final String getGenreSortOrder() { - return mPreferences.getString(GENRE_SORT_ORDER, SortOrder.GenreSortOrder.GENRE_A_Z); + return mPreferences.getString(GENRE_SORT_ORDER, GenreSortOrder.GENRE_A_Z); } public boolean getHeadsetPlugged() { @@ -719,7 +728,7 @@ public final class PreferenceUtil { } public final String getSongSortOrder() { - return mPreferences.getString(SONG_SORT_ORDER, SortOrder.SongSortOrder.SONG_A_Z); + return mPreferences.getString(SONG_SORT_ORDER, SongSortOrder.SONG_A_Z); } public void setSongSortOrder(final String sortOrder) { diff --git a/app/src/main/res/drawable/line_button.xml b/app/src/main/res/drawable/line_button.xml index ee063c5a4..9abfdfdfd 100644 --- a/app/src/main/res/drawable/line_button.xml +++ b/app/src/main/res/drawable/line_button.xml @@ -1,9 +1,21 @@ - - - - + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout-land/activity_album_tag_editor.xml b/app/src/main/res/layout-land/activity_album_tag_editor.xml index 3caaef6e4..b6bbd84ea 100644 --- a/app/src/main/res/layout-land/activity_album_tag_editor.xml +++ b/app/src/main/res/layout-land/activity_album_tag_editor.xml @@ -2,9 +2,9 @@ xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/gradient_background" - android:background="?attr/colorSurface" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:background="?attr/colorSurface"> + + + + + + android:layout_margin="8dp" + app:cardCornerRadius="16dp"> - - + android:layout_margin="8dp" + app:cardCornerRadius="16dp"> - - + + android:layout_margin="8dp" + app:cardCornerRadius="16dp"> - + + + + + + tools:listitem="@layout/item_song" /> @@ -18,10 +19,6 @@ android:layout_height="wrap_content" android:background="@drawable/shadow_up_full_theme" /> - - - @@ -86,5 +82,4 @@ tools:layout="@layout/fragment_card_blur_player_playback_controls" /> - \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_full_player_controls.xml b/app/src/main/res/layout/fragment_full_player_controls.xml index c6c50f6ff..6b4c52e50 100644 --- a/app/src/main/res/layout/fragment_full_player_controls.xml +++ b/app/src/main/res/layout/fragment_full_player_controls.xml @@ -12,58 +12,63 @@ android:id="@+id/playerMenu" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginEnd="16dp" android:background="?attr/roundSelector" - android:padding="12dp" - app:layout_constraintBottom_toBottomOf="@+id/text" + android:padding="8dp" + app:layout_constraintBottom_toBottomOf="@+id/titleContainer" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_more_vert_white_24dp" /> - - - + app:layout_constraintTop_toTopOf="parent"> + + + + + + @@ -95,7 +100,7 @@ android:splitTrack="false" app:layout_constraintEnd_toStartOf="@id/songTotalTime" app:layout_constraintStart_toEndOf="@id/songCurrentProgress" - app:layout_constraintTop_toBottomOf="@id/text" + app:layout_constraintTop_toBottomOf="@id/titleContainer" tools:ignore="RtlHardcoded,UnusedAttribute" tools:progress="20" /> diff --git a/app/src/main/res/layout/item_list.xml b/app/src/main/res/layout/item_list.xml index 5d15321f3..53e937035 100755 --- a/app/src/main/res/layout/item_list.xml +++ b/app/src/main/res/layout/item_list.xml @@ -47,7 +47,7 @@ android:layout_gravity="center_vertical" android:gravity="center_vertical" android:scaleType="centerCrop" - tools:srcCompat="@tools:sample/backgrounds/scenic[16]" /> + tools:srcCompat="@tools:sample/avatars" /> + tools:text="100" /> diff --git a/app/src/main/res/layout/pager_item.xml b/app/src/main/res/layout/pager_item.xml index d1a766f7a..79469fad9 100644 --- a/app/src/main/res/layout/pager_item.xml +++ b/app/src/main/res/layout/pager_item.xml @@ -22,16 +22,6 @@ android:scaleType="centerCrop" tools:src="@tools:sample/avatars" /> - + \ No newline at end of file diff --git a/app/src/main/res/values/ids.xml b/app/src/main/res/values/ids.xml index a6e2fa36f..70b7e07b5 100644 --- a/app/src/main/res/values/ids.xml +++ b/app/src/main/res/values/ids.xml @@ -8,6 +8,7 @@ + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 83ad9f3ac..b1a0ecca4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -825,4 +825,6 @@ Share to Stories Drive mode Retro Music Player + Number of songs + Pro diff --git a/app/src/main/res/xml/pref_advanced.xml b/app/src/main/res/xml/pref_advanced.xml index edfd7029a..27a62a665 100755 --- a/app/src/main/res/xml/pref_advanced.xml +++ b/app/src/main/res/xml/pref_advanced.xml @@ -7,6 +7,7 @@ - - - + \ No newline at end of file diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/TintHelper.java b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/TintHelper.java index 649ec803d..02baf53e8 100755 --- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/TintHelper.java +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/TintHelper.java @@ -35,48 +35,6 @@ import java.lang.reflect.Field; */ public final class TintHelper { - @SuppressWarnings("JavaReflectionMemberAccess") - public static void colorHandles(@NonNull TextView view, int color) { - try { - Field editorField = TextView.class.getDeclaredField("mEditor"); - if (!editorField.isAccessible()) { - editorField.setAccessible(true); - } - - Object editor = editorField.get(view); - Class editorClass = editor.getClass(); - - String[] handleNames = {"mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"}; - String[] resNames = {"mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes"}; - - for (int i = 0; i < handleNames.length; i++) { - Field handleField = editorClass.getDeclaredField(handleNames[i]); - if (!handleField.isAccessible()) { - handleField.setAccessible(true); - } - - Drawable handleDrawable = (Drawable) handleField.get(editor); - - if (handleDrawable == null) { - Field resField = TextView.class.getDeclaredField(resNames[i]); - if (!resField.isAccessible()) { - resField.setAccessible(true); - } - int resId = resField.getInt(view); - handleDrawable = view.getResources().getDrawable(resId); - } - - if (handleDrawable != null) { - Drawable drawable = handleDrawable.mutate(); - drawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); - handleField.set(editor, drawable); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - @CheckResult @NonNull public static Drawable createTintedDrawable(Context context, diff --git a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/VersionUtils.kt b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/VersionUtils.kt index 92cbbf417..ee4dd7c93 100644 --- a/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/VersionUtils.kt +++ b/appthemehelper/src/main/java/code/name/monkey/appthemehelper/util/VersionUtils.kt @@ -42,4 +42,8 @@ object VersionUtils { fun hasOreo(): Boolean { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O } + + fun hasQ(): Boolean { + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q + } }