Rolled back to old style image loading and mosaic

This commit is contained in:
h4h13 2019-09-16 23:32:40 +05:30
parent d6a961a977
commit 397f42a54a
76 changed files with 1560 additions and 1452 deletions

View file

@ -13,8 +13,8 @@ android {
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
applicationId "code.name.monkey.retromusic" applicationId "code.name.monkey.retromusic"
versionCode 365 versionCode 366
versionName '3.4.000-beta01' versionName '3.4.000-beta05'
multiDexEnabled true multiDexEnabled true
@ -120,15 +120,15 @@ dependencies {
implementation 'com.squareup.retrofit2:converter-gson:2.6.1' implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.1' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.1'
implementation 'com.afollestad.material-dialogs:core:3.0.0-alpha1' implementation 'com.afollestad.material-dialogs:core:3.1.1'
implementation 'com.afollestad.material-dialogs:input:3.0.0-alpha1' implementation 'com.afollestad.material-dialogs:input:3.1.1'
implementation 'com.afollestad.material-dialogs:color:3.0.0-alpha1' implementation 'com.afollestad.material-dialogs:color:3.1.1'
implementation 'com.afollestad.material-dialogs:bottomsheets:3.0.0-alpha1' implementation 'com.afollestad.material-dialogs:bottomsheets:3.1.1'
implementation 'com.afollestad:material-cab:0.1.12' implementation 'com.afollestad:material-cab:0.1.12'
implementation 'com.github.bumptech.glide:glide:4.8.0'
kapt 'com.github.bumptech.glide:compiler:4.8.0' implementation 'com.github.bumptech.glide:glide:3.8.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.8.0' implementation 'com.github.bumptech.glide:okhttp3-integration:1.5.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxjava:2.2.9' implementation 'io.reactivex.rxjava2:rxjava:2.2.9'
@ -158,5 +158,6 @@ dependencies {
kapt 'com.google.dagger:dagger-compiler:2.23.1' kapt 'com.google.dagger:dagger-compiler:2.23.1'
implementation project(':appthemehelper') implementation project(':appthemehelper')
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-beta-3'
} }

File diff suppressed because one or more lines are too long

View file

@ -23,7 +23,6 @@ import code.name.monkey.retromusic.Constants.TRANSLATE
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsBaseActivity import code.name.monkey.retromusic.activities.base.AbsBaseActivity
import code.name.monkey.retromusic.adapter.ContributorAdapter import code.name.monkey.retromusic.adapter.ContributorAdapter
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.model.Contributor import code.name.monkey.retromusic.model.Contributor
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog

View file

@ -28,9 +28,9 @@ import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget 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.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder
import code.name.monkey.retromusic.loaders.ArtistLoader import code.name.monkey.retromusic.loaders.ArtistLoader
@ -43,6 +43,7 @@ import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_album.* import kotlinx.android.synthetic.main.activity_album.*
@ -228,11 +229,8 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
} }
override fun loadArtistImage(artist: Artist) { override fun loadArtistImage(artist: Artist) {
GlideApp.with(this@AlbumDetailsActivity) ArtistGlideRequest.Builder.from(Glide.with(this), artist)
.asBitmapPalette() .generatePalette(this).build()
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.dontAnimate() .dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) { .into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
@ -242,13 +240,11 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsView {
} }
private fun loadAlbumCover() { private fun loadAlbumCover() {
GlideApp.with(this) SongGlideRequest.Builder.from(Glide.with(this), album.safeGetFirstSong())
.asBitmapPalette() .checkIgnoreMediaStore(this)
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong())) .generatePalette(this).build()
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate() .dontAnimate()
.into(object : RetroMusicColoredTarget(image as ImageView) { .into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColors(color) setColors(color)
} }

View file

@ -4,7 +4,6 @@ import android.app.Activity
import android.content.Intent import android.content.Intent
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.text.Html import android.text.Html
@ -29,8 +28,7 @@ import code.name.monkey.retromusic.adapter.album.AlbumAdapter
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.misc.AppBarStateChangeListener import code.name.monkey.retromusic.misc.AppBarStateChangeListener
@ -40,6 +38,7 @@ import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsView
import code.name.monkey.retromusic.rest.LastFMRestClient import code.name.monkey.retromusic.rest.LastFMRestClient
import code.name.monkey.retromusic.rest.model.LastFmArtist import code.name.monkey.retromusic.rest.model.LastFmArtist
import code.name.monkey.retromusic.util.* import code.name.monkey.retromusic.util.*
import com.bumptech.glide.Glide
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.activity_artist_content.* import kotlinx.android.synthetic.main.activity_artist_content.*
import kotlinx.android.synthetic.main.activity_artist_details.* import kotlinx.android.synthetic.main.activity_artist_details.*
@ -81,7 +80,7 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
ActivityCompat.postponeEnterTransition(this) ActivityCompat.postponeEnterTransition(this)
App.musicComponent?.inject(this) App.musicComponent.inject(this)
artistDetailsPresenter.attachView(this) artistDetailsPresenter.attachView(this)
if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) { if (intent.extras!!.containsKey(EXTRA_ARTIST_ID)) {
@ -110,6 +109,11 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
} }
} }
override fun onDestroy() {
super.onDestroy()
artistDetailsPresenter.detachView()
}
private fun setUpViews() { private fun setUpViews() {
setupRecyclerView() setupRecyclerView()
setupToolbarMarginHeight() setupToolbarMarginHeight()
@ -258,23 +262,14 @@ class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailsView {
private var lang: String? = null private var lang: String? = null
private fun loadArtistImage() { private fun loadArtistImage() {
GlideApp.with(this) ArtistGlideRequest.Builder.from(Glide.with(this), artist)
.asBitmapPalette() .generatePalette(this).build()
.load(RetroGlideExtension.getArtistModel(artist, forceDownload))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.dontAnimate() .dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) { .into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColors(color) setColors(color)
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColors(defaultFooterColor)
}
}) })
forceDownload = false
} }
private fun setColors(color: Int) { private fun setColors(color: Int) {

View file

@ -11,10 +11,11 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenPlayerControlsFragment import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenPlayerControlsFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget 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.MusicPlayerRemote
import com.bumptech.glide.Glide
import com.r0adkll.slidr.Slidr import com.r0adkll.slidr.Slidr
import com.r0adkll.slidr.model.SlidrConfig import com.r0adkll.slidr.model.SlidrConfig
import com.r0adkll.slidr.model.SlidrListener import com.r0adkll.slidr.model.SlidrListener
@ -98,15 +99,13 @@ class LockScreenActivity : AbsMusicServiceActivity() {
private fun updateSongs() { private fun updateSongs() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
GlideApp.with(this) SongGlideRequest.Builder.from(Glide.with(this), song)
.asBitmapPalette() .checkIgnoreMediaStore(this)
.load(RetroGlideExtension.getSongModel(song)) .generatePalette(this).build()
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.dontAnimate() .dontAnimate()
.into(object : RetroMusicColoredTarget(image) { .into(object : RetroMusicColoredTarget(image) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
fragment!!.setDark(color) fragment?.setDark(color)
} }
}) })
} }

View file

@ -1,7 +1,6 @@
package code.name.monkey.retromusic.activities package code.name.monkey.retromusic.activities
import android.content.* import android.content.*
import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
@ -83,7 +82,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
if (currentVersion != PreferenceUtil.getInstance(this).lastChangelogVersion) { if (currentVersion != PreferenceUtil.getInstance(this).lastChangelogVersion) {
startActivityForResult(Intent(this, WhatsNewActivity::class.java), APP_INTRO_REQUEST) startActivityForResult(Intent(this, WhatsNewActivity::class.java), APP_INTRO_REQUEST)
} }
} catch (e: PackageManager.NameNotFoundException) { } catch (e: Throwable) {
e.printStackTrace() e.printStackTrace()
} }
@ -112,16 +111,13 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
PreferenceUtil.getInstance(this).unregisterOnSharedPreferenceChangedListener(this) PreferenceUtil.getInstance(this).unregisterOnSharedPreferenceChangedListener(this)
} }
private fun setCurrentFragment(fragment: Fragment, b: Boolean = false) { private fun setCurrentFragment(fragment: Fragment, tag: String) {
val trans = supportFragmentManager.beginTransaction() println("setCurrentFragment -> $tag -> ${supportFragmentManager.findFragmentById(R.id.fragment_container)?.tag}")
trans.replace(R.id.fragment_container, fragment, null) if (tag != supportFragmentManager.findFragmentById(R.id.fragment_container)?.tag) {
if (b) { supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, tag).commit()
trans.addToBackStack(null)
}
trans.commit()
currentFragment = fragment as MainActivityFragmentCallbacks currentFragment = fragment as MainActivityFragmentCallbacks
} }
}
private fun restoreCurrentFragment() { private fun restoreCurrentFragment() {
currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as MainActivityFragmentCallbacks currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as MainActivityFragmentCallbacks
@ -275,11 +271,11 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
R.id.action_artist, R.id.action_artist,
R.id.action_playlist, R.id.action_playlist,
R.id.action_genre, R.id.action_genre,
R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), false) R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), itemId.toString())
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), false) R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
R.id.action_folder -> setCurrentFragment(FoldersFragment.newInstance(this), false) R.id.action_folder -> setCurrentFragment(FoldersFragment.newInstance(this), FoldersFragment.TAG)
else -> { else -> {
setCurrentFragment(BannerHomeFragment.newInstance(), false) setCurrentFragment(BannerHomeFragment.newInstance(), BannerHomeFragment.TAG)
} }
} }
} }

View file

@ -5,6 +5,7 @@ import android.content.res.ColorStateList
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.text.Editable import android.text.Editable
@ -19,8 +20,7 @@ import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.appHandleColor import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.loaders.AlbumLoader import code.name.monkey.retromusic.loaders.AlbumLoader
import code.name.monkey.retromusic.rest.LastFMRestClient import code.name.monkey.retromusic.rest.LastFMRestClient
@ -30,10 +30,10 @@ import code.name.monkey.retromusic.util.LastFMUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
import code.name.monkey.retromusic.util.RetroColorUtil.getColor import code.name.monkey.retromusic.util.RetroColorUtil.getColor
import com.bumptech.glide.GenericTransitionOptions import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.request.target.SimpleTarget
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
@ -46,23 +46,54 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
override val contentViewLayout: Int override val contentViewLayout: Int
get() = R.layout.activity_album_tag_editor get() = R.layout.activity_album_tag_editor
override fun loadImageFromFile(selectedFile: Uri?) { override fun loadImageFromFile(selectedFileUri: Uri?) {
GlideApp.with(this).`as`(BitmapPaletteWrapper::class.java)
.load(selectedFile) Glide.with(this@AlbumTagEditorActivity)
.transition(GenericTransitionOptions<BitmapPaletteWrapper>().transition(android.R.anim.fade_in)) .load(selectedFileUri)
.apply(RequestOptions() .asBitmap()
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)) .skipMemoryCache(true)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>() { .into(object : SimpleTarget<BitmapPaletteWrapper>() {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) { override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT) RetroColorUtil.getColor(resource?.palette, Color.TRANSPARENT);
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048) albumArtBitmap = resource?.bitmap?.let { ImageUtil.resizeBitmap(it, 2048) }
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor))) setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource?.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
deleteAlbumArt = false deleteAlbumArt = false
dataChanged() dataChanged()
setResult(Activity.RESULT_OK) setResult(Activity.RESULT_OK)
} }
override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG).show()
}
}) })
/*Glide.with(AlbumTagEditorActivity.this)
.load(selectedFileUri)
.asBitmap()
.transcode(new BitmapPaletteTranscoder(AlbumTagEditorActivity.this), BitmapPaletteWrapper.class)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(new SimpleTarget<BitmapPaletteWrapper>() {
@Override
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
e.printStackTrace();
Toast.makeText(AlbumTagEditorActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
@Override
public void onResourceReady(BitmapPaletteWrapper resource, GlideAnimation<? super BitmapPaletteWrapper> glideAnimation) {
PhonographColorUtil.getColor(resource.getPalette(), Color.TRANSPARENT);
albumArtBitmap = ImageUtil.resizeBitmap(resource.getBitmap(), 2048);
setImageBitmap(albumArtBitmap, PhonographColorUtil.getColor(resource.getPalette(), ATHUtil.resolveColor(AlbumTagEditorActivity.this, R.attr.defaultFooterColor)));
deleteAlbumArt = false;
dataChanged();
setResult(RESULT_OK);
}
});*/
} }
private var albumArtBitmap: Bitmap? = null private var albumArtBitmap: Bitmap? = null
@ -141,22 +172,26 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image) val url = LastFMUtil.getLargestAlbumImageUrl(lastFmAlbum.album.image)
if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) { if (!TextUtils.isEmpty(url) && url.trim { it <= ' ' }.isNotEmpty()) {
GlideApp.with(this) Glide.with(this@AlbumTagEditorActivity)
.`as`(BitmapPaletteWrapper::class.java)
.load(url) .load(url)
.apply(RequestOptions() .asBitmap()
.diskCacheStrategy(DiskCacheStrategy.RESOURCE) .transcode( BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
.error(R.drawable.default_album_art)) .diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>() { .error(R.drawable.default_album_art)
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) { .into( object: SimpleTarget<BitmapPaletteWrapper>() {
albumArtBitmap = ImageUtil.resizeBitmap(resource.bitmap, 2048) override fun onLoadFailed(e: java.lang.Exception?, errorDrawable: Drawable?) {
setImageBitmap(albumArtBitmap, getColor(resource.palette, super.onLoadFailed(e, errorDrawable)
ContextCompat.getColor(this@AlbumTagEditorActivity, R.color.md_grey_500))) Toast.makeText(this@AlbumTagEditorActivity, e.toString(), Toast.LENGTH_LONG).show()
}
override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
albumArtBitmap = resource?.bitmap?.let { ImageUtil.resizeBitmap(it, 2048) }
setImageBitmap(albumArtBitmap, RetroColorUtil.getColor(resource?.palette, ATHUtil.resolveColor(this@AlbumTagEditorActivity, R.attr.defaultFooterColor)))
deleteAlbumArt = false deleteAlbumArt = false
dataChanged() dataChanged()
setResult(Activity.RESULT_OK) setResult(RESULT_OK)
} }
}) });
return return
} }
if (lastFmAlbum.album.tags.tag.size > 0) { if (lastFmAlbum.album.tags.tag.size > 0) {

View file

@ -7,10 +7,10 @@ import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.model.Contributor import code.name.monkey.retromusic.model.Contributor
import code.name.monkey.retromusic.util.RetroUtil.openUrl import code.name.monkey.retromusic.util.RetroUtil.openUrl
import code.name.monkey.retromusic.views.CircularImageView import code.name.monkey.retromusic.views.CircularImageView
import com.bumptech.glide.Glide
class ContributorAdapter( class ContributorAdapter(
private var contributors: List<Contributor> private var contributors: List<Contributor>
@ -56,7 +56,7 @@ class ContributorAdapter(
internal fun bindData(contributor: Contributor) { internal fun bindData(contributor: Contributor) {
title.text = contributor.name title.text = contributor.name
text.text = contributor.summary text.text = contributor.summary
GlideApp.with(image.context) Glide.with(image.context)
.load(contributor.profileImage) .load(contributor.profileImage)
.error(R.drawable.ic_account_white_24dp) .error(R.drawable.ic_account_white_24dp)
.placeholder(R.drawable.ic_account_white_24dp) .placeholder(R.drawable.ic_account_white_24dp)

View file

@ -9,8 +9,8 @@ import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.menu.SongMenuHelper import code.name.monkey.retromusic.helper.menu.SongMenuHelper
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
@ -18,6 +18,7 @@ import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide
import java.util.* import java.util.*
@ -44,35 +45,28 @@ class SearchAdapter(
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
when (getItemViewType(position)) { when (getItemViewType(position)) {
ALBUM -> { ALBUM -> {
val album = dataSet!![position] as Album val album = dataSet?.get(position) as Album
holder.title!!.text = album.title holder.title?.text = album.title
holder.text!!.text = album.artistName holder.text?.text = album.artistName
GlideApp.with(activity) SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.asDrawable() .checkIgnoreMediaStore(activity).build()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong())) .into(holder.image)
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.into(holder.image!!)
} }
ARTIST -> { ARTIST -> {
val artist = dataSet!![position] as Artist val artist = dataSet?.get(position) as Artist
holder.title!!.text = artist.name holder.title?.text = artist.name
holder.text!!.text = MusicUtil.getArtistInfoString(activity, artist) holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
GlideApp.with(activity) ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
.asBitmap() .build().into(holder.image);
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.into(holder.image!!)
} }
SONG -> { SONG -> {
val song = dataSet!![position] as Song val song = dataSet?.get(position) as Song
holder.title!!.text = song.title holder.title?.text = song.title
holder.text!!.text = song.albumName holder.text?.text = song.albumName
} }
else -> { else -> {
holder.title!!.text = dataSet!![position].toString() holder.title?.text = dataSet?.get(position).toString()
holder.title!!.setTextColor(ThemeStore.accentColor(activity)) holder.title?.setTextColor(ThemeStore.accentColor(activity))
} }
} }
} }

View file

@ -1,7 +1,6 @@
package code.name.monkey.retromusic.adapter package code.name.monkey.retromusic.adapter
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -9,16 +8,13 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.GenericTransitionOptions import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.signature.MediaStoreSignature import com.bumptech.glide.signature.MediaStoreSignature
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.io.File import java.io.File
@ -32,7 +28,7 @@ class SongFileAdapter(
private val itemLayoutRes: Int, private val itemLayoutRes: Int,
private val callbacks: Callbacks?, private val callbacks: Callbacks?,
cabHolder: CabHolder? cabHolder: CabHolder?
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(activity, cabHolder, R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter { ) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(activity, cabHolder, code.name.monkey.retromusic.R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter {
init { init {
this.setHasStableIds(true) this.setHasStableIds(true)
@ -85,25 +81,24 @@ class SongFileAdapter(
} }
private fun loadFileImage(file: File, holder: ViewHolder) { private fun loadFileImage(file: File, holder: ViewHolder) {
val iconColor = ATHUtil.resolveColor(activity, R.attr.iconColor) val iconColor = ATHUtil.resolveColor(activity, code.name.monkey.retromusic.R.attr.iconColor)
if (file.isDirectory) { if (file.isDirectory) {
holder.image?.let { holder.image?.let {
it.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN) it.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN)
it.setImageResource(R.drawable.ic_folder_white_24dp) it.setImageResource(code.name.monkey.retromusic.R.drawable.ic_folder_white_24dp)
} }
holder.imageTextContainer?.setCardBackgroundColor(ThemeStore.primaryColor(activity)) holder.imageTextContainer?.setCardBackgroundColor(ThemeStore.primaryColor(activity))
} else { } else {
val error = RetroUtil.getTintedVectorDrawable(activity, R.drawable.ic_file_music_white_24dp, iconColor) val error = RetroUtil.getTintedVectorDrawable(activity, code.name.monkey.retromusic.R.drawable.ic_file_music_white_24dp, iconColor)
GlideApp.with(activity) Glide.with(activity)
.load(AudioFileCover(file.path)) .load(AudioFileCover(file.path))
.transition(GenericTransitionOptions.with<Drawable>(android.R.anim.fade_in))
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.error(error) .error(error)
.placeholder(error) .placeholder(error)
.signature(MediaStoreSignature("", file.lastModified(), 0))) .animate(android.R.anim.fade_in)
.into(holder.image!!) .signature(MediaStoreSignature("", file.lastModified(), 0))
.into(holder.image)
} }
} }

View file

@ -11,12 +11,10 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.util.Pair import androidx.core.util.Pair
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper 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.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget 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.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
@ -26,6 +24,7 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
@ -33,7 +32,7 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
dataSet: ArrayList<Album>, dataSet: ArrayList<Album>,
@param:LayoutRes protected var itemLayoutRes: Int, @param:LayoutRes protected var itemLayoutRes: Int,
usePalette: Boolean, usePalette: Boolean,
cabHolder: CabHolder?) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(activity, cabHolder, R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter { cabHolder: CabHolder?) : AbsMultiSelectAdapter<AlbumAdapter.ViewHolder, Album>(activity, cabHolder, code.name.monkey.retromusic.R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter {
var dataSet: ArrayList<Album> var dataSet: ArrayList<Album>
protected set protected set
@ -97,18 +96,13 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
} }
protected open fun setColors(color: Int, holder: ViewHolder) { protected open fun setColors(color: Int, holder: ViewHolder) {
if (holder.paletteColorContainer != null) { holder.paletteColorContainer?.let {
holder.paletteColorContainer!!.setBackgroundColor(color) it.setBackgroundColor(color)
if (holder.title != null) { holder.title?.setTextColor(
holder.title!!.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color))) MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
} holder.text?.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
if (holder.text != null) {
holder.text!!.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
}
}
if (holder.mask != null) {
holder.mask!!.backgroundTintList = ColorStateList.valueOf(color)
} }
holder.mask?.backgroundTintList = ColorStateList.valueOf(color)
} }
protected open fun loadAlbumCover(album: Album, holder: ViewHolder) { protected open fun loadAlbumCover(album: Album, holder: ViewHolder) {
@ -116,20 +110,19 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
return return
} }
GlideApp.with(activity) SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.asBitmapPalette() .checkIgnoreMediaStore(activity)
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong())) .generatePalette(activity).build()
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) { override fun onLoadCleared(placeholder: Drawable?) {
setColors(color, holder) super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onColorReady(color: Int) {
super.onLoadFailed(errorDrawable) if (usePalette)
setColors(color, holder)
else
setColors(defaultFooterColor, holder) setColors(defaultFooterColor, holder)
} }
}) })
@ -178,7 +171,7 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) { inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init { init {
setImageTransitionName(activity.getString(R.string.transition_album_art)) setImageTransitionName(activity.getString(code.name.monkey.retromusic.R.string.transition_album_art))
if (menu != null) { if (menu != null) {
menu!!.visibility = View.GONE menu!!.visibility = View.GONE
} }
@ -189,7 +182,7 @@ open class AlbumAdapter(protected val activity: AppCompatActivity,
if (isInQuickSelectMode) { if (isInQuickSelectMode) {
toggleChecked(adapterPosition) toggleChecked(adapterPosition)
} else { } else {
val pairImageView = Pair.create<View, String>(image, activity.resources.getString(R.string.transition_album_art)) val pairImageView = Pair.create<View, String>(image, activity.resources.getString(code.name.monkey.retromusic.R.string.transition_album_art))
val pairs = ArrayList<Pair<View, String>>() val pairs = ArrayList<Pair<View, String>>()
pairs.add(pairImageView) pairs.add(pairImageView)
val albumPairs: Array<Pair<View, String>> = pairs.toTypedArray() val albumPairs: Array<Pair<View, String>> = pairs.toTypedArray()

View file

@ -1,7 +1,6 @@
package code.name.monkey.retromusic.adapter.album package code.name.monkey.retromusic.adapter.album
import android.content.Intent import android.content.Intent
import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -9,16 +8,15 @@ import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.LyricsActivity import code.name.monkey.retromusic.activities.LyricsActivity
import code.name.monkey.retromusic.fragments.AlbumCoverStyle import code.name.monkey.retromusic.fragments.AlbumCoverStyle
import code.name.monkey.retromusic.fragments.NowPlayingScreen import code.name.monkey.retromusic.fragments.NowPlayingScreen
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import java.util.* import java.util.*
@ -72,14 +70,14 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
private val layout: Int private val layout: Int
get() { get() {
return when (PreferenceUtil.getInstance(activity).albumCoverStyle) { return when (PreferenceUtil.getInstance(activity).albumCoverStyle) {
AlbumCoverStyle.NORMAL -> R.layout.fragment_album_cover AlbumCoverStyle.NORMAL -> code.name.monkey.retromusic.R.layout.fragment_album_cover
AlbumCoverStyle.FLAT -> R.layout.fragment_album_flat_cover AlbumCoverStyle.FLAT -> code.name.monkey.retromusic.R.layout.fragment_album_flat_cover
AlbumCoverStyle.CIRCLE -> R.layout.fragment_album_circle_cover AlbumCoverStyle.CIRCLE -> code.name.monkey.retromusic.R.layout.fragment_album_circle_cover
AlbumCoverStyle.CARD -> R.layout.fragment_album_card_cover AlbumCoverStyle.CARD -> code.name.monkey.retromusic.R.layout.fragment_album_card_cover
AlbumCoverStyle.MATERIAL -> R.layout.fragment_album_material_cover AlbumCoverStyle.MATERIAL -> code.name.monkey.retromusic.R.layout.fragment_album_material_cover
AlbumCoverStyle.FULL -> R.layout.fragment_album_full_cover AlbumCoverStyle.FULL -> code.name.monkey.retromusic.R.layout.fragment_album_full_cover
AlbumCoverStyle.FULL_CARD -> R.layout.fragment_album_full_card_cover AlbumCoverStyle.FULL_CARD -> code.name.monkey.retromusic.R.layout.fragment_album_full_card_cover
else -> R.layout.fragment_album_cover else -> code.name.monkey.retromusic.R.layout.fragment_album_cover
} }
} }
@ -92,12 +90,12 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val finalLayout = when { val finalLayout = when {
PreferenceUtil.getInstance(activity).nowPlayingScreen == NowPlayingScreen.CLASSIC -> R.layout.fragment_album_full_cover PreferenceUtil.getInstance(activity).nowPlayingScreen == NowPlayingScreen.CLASSIC -> code.name.monkey.retromusic.R.layout.fragment_album_full_cover
PreferenceUtil.getInstance(activity).carouselEffect() -> R.layout.fragment_album_carousel_cover PreferenceUtil.getInstance(activity).carouselEffect() -> code.name.monkey.retromusic.R.layout.fragment_album_carousel_cover
else -> layout else -> layout
} }
val view = inflater.inflate(finalLayout, container, false) val view = inflater.inflate(finalLayout, container, false)
albumCover = view.findViewById(R.id.player_image) albumCover = view.findViewById(code.name.monkey.retromusic.R.id.player_image)
albumCover.setOnClickListener { startActivity(Intent(context, LyricsActivity::class.java)) } albumCover.setOnClickListener { startActivity(Intent(context, LyricsActivity::class.java)) }
return view return view
} }
@ -114,21 +112,13 @@ class AlbumCoverPagerAdapter(fm: FragmentManager, private val dataSet: ArrayList
} }
private fun loadAlbumCover() { private fun loadAlbumCover() {
GlideApp.with(context!!) SongGlideRequest.Builder.from(Glide.with(requireContext()), song)
.asBitmapPalette() .checkIgnoreMediaStore(activity)
.load(RetroGlideExtension.getSongModel(song!!)) .generatePalette(activity).build()
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.dontAnimate()
.into(object : RetroMusicColoredTarget(albumCover) { .into(object : RetroMusicColoredTarget(albumCover) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
setColor(color) setColor(color)
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColor(defaultFooterColor)
}
}) })
} }

View file

@ -22,13 +22,13 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.util.Pair import androidx.core.util.Pair
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget 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.MusicPlayerRemote
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.views.MetalRecyclerViewPager import code.name.monkey.retromusic.views.MetalRecyclerViewPager
import com.bumptech.glide.Glide
class AlbumFullWidthAdapter(private val activity: Activity, private val dataSet: ArrayList<Album>, metrics: DisplayMetrics) : class AlbumFullWidthAdapter(private val activity: Activity, private val dataSet: ArrayList<Album>, metrics: DisplayMetrics) :
MetalRecyclerViewPager.MetalAdapter<AlbumFullWidthAdapter.FullMetalViewHolder>(metrics) { MetalRecyclerViewPager.MetalAdapter<AlbumFullWidthAdapter.FullMetalViewHolder>(metrics) {
@ -67,12 +67,9 @@ class AlbumFullWidthAdapter(private val activity: Activity, private val dataSet:
if (holder.image == null) { if (holder.image == null) {
return return
} }
GlideApp.with(activity) SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.asBitmapPalette() .checkIgnoreMediaStore(activity)
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong())) .generatePalette(activity).build()
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {

View file

@ -6,17 +6,28 @@ import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget 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.helper.HorizontalAdapterHelper
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Album import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import com.bumptech.glide.Glide
import java.util.* import java.util.*
class HorizontalAlbumAdapter(activity: AppCompatActivity, dataSet: ArrayList<Album>, usePalette: Boolean, cabHolder: CabHolder?) : AlbumAdapter(activity, dataSet, HorizontalAdapterHelper.LAYOUT_RES, usePalette, cabHolder) { class HorizontalAlbumAdapter(
activity: AppCompatActivity,
dataSet: ArrayList<Album>,
usePalette: Boolean,
cabHolder: CabHolder?
) : AlbumAdapter(
activity,
dataSet,
HorizontalAdapterHelper.LAYOUT_RES,
usePalette,
cabHolder
) {
override fun createViewHolder(view: View, viewType: Int): ViewHolder { override fun createViewHolder(view: View, viewType: Int): ViewHolder {
val params = view.layoutParams as ViewGroup.MarginLayoutParams val params = view.layoutParams as ViewGroup.MarginLayoutParams
@ -25,35 +36,28 @@ class HorizontalAlbumAdapter(activity: AppCompatActivity, dataSet: ArrayList<Alb
} }
override fun setColors(color: Int, holder: ViewHolder) { override fun setColors(color: Int, holder: ViewHolder) {
if (holder.title != null) { holder.title?.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
holder.title!!.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color))) holder.text?.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
}
if (holder.text != null) {
holder.text!!.setTextColor(MaterialValueHelper.getSecondaryTextColor(activity, ColorUtil.isColorLight(color)))
}
} }
override fun loadAlbumCover(album: Album, holder: ViewHolder) { override fun loadAlbumCover(album: Album, holder: ViewHolder) {
if (holder.image == null) return if (holder.image == null) return
GlideApp.with(activity) SongGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
.asBitmapPalette() .checkIgnoreMediaStore(activity)
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong())) .generatePalette(activity).build()
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(album.safeGetFirstSong())
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
setColors(albumArtistFooterColor, holder)
}
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
if (usePalette) if (usePalette)
setColors(color, holder) setColors(color, holder)
else else
setColors(albumArtistFooterColor, holder) setColors(albumArtistFooterColor, holder)
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
setColors(albumArtistFooterColor, holder)
}
}) })
} }

View file

@ -1,6 +1,7 @@
package code.name.monkey.retromusic.adapter.artist package code.name.monkey.retromusic.adapter.artist
import android.content.res.ColorStateList import android.content.res.ColorStateList
import android.graphics.drawable.Drawable
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
@ -11,18 +12,17 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.util.Pair import androidx.core.util.Pair
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper 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.glide.GlideApp import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.RetroGlideExtension import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.util.* import java.util.*
@ -31,7 +31,8 @@ class ArtistAdapter(val activity: AppCompatActivity,
var dataSet: ArrayList<Artist>, var dataSet: ArrayList<Artist>,
@LayoutRes var itemLayoutRes: Int, @LayoutRes var itemLayoutRes: Int,
var usePalette: Boolean, var usePalette: Boolean,
cabHolder: CabHolder?) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(activity, cabHolder, R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter { cabHolder: CabHolder?
) : AbsMultiSelectAdapter<ArtistAdapter.ViewHolder, Artist>(activity, cabHolder, code.name.monkey.retromusic.R.menu.menu_media_selection), FastScrollRecyclerView.SectionedAdapter {
fun swapDataSet(dataSet: ArrayList<Artist>) { fun swapDataSet(dataSet: ArrayList<Artist>) {
this.dataSet = dataSet this.dataSet = dataSet
@ -58,46 +59,38 @@ class ArtistAdapter(val activity: AppCompatActivity,
override fun onBindViewHolder(holder: ViewHolder, position: Int) { override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val artist = dataSet[position] val artist = dataSet[position]
val isChecked = isChecked(artist) val isChecked = isChecked(artist)
holder.itemView.isActivated = isChecked holder.itemView.isActivated = isChecked
holder.title?.text = artist.name
if (holder.title != null) { holder.text?.visibility = View.GONE
holder.title!!.text = artist.name
}
if (holder.text != null) {
holder.text!!.visibility = View.GONE
}
loadArtistImage(artist, holder) loadArtistImage(artist, holder)
} }
fun setColors(color: Int, holder: ViewHolder) { fun setColors(color: Int, holder: ViewHolder) {
if (holder.paletteColorContainer != null) { holder.paletteColorContainer?.let {
holder.paletteColorContainer!!.setBackgroundColor(color) it.setBackgroundColor(color)
if (holder.title != null) { holder.title?.setTextColor(MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
holder.title!!.setTextColor(
MaterialValueHelper.getPrimaryTextColor(activity, ColorUtil.isColorLight(color)))
}
}
if (holder.mask != null) {
holder.mask!!.backgroundTintList = ColorStateList.valueOf(color)
} }
holder.mask?.backgroundTintList = ColorStateList.valueOf(color)
} }
private fun loadArtistImage(artist: Artist, holder: ViewHolder) { private fun loadArtistImage(artist: Artist, holder: ViewHolder) {
if (holder.image == null) { if (holder.image == null) {
return return
} }
GlideApp.with(activity) ArtistGlideRequest.Builder.from(Glide.with(activity), artist)
.asBitmapPalette() .generatePalette(activity).build()
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(artist)
.dontAnimate()
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onLoadCleared(placeholder: Drawable?) {
super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
}
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
if (usePalette)
setColors(color, holder) setColors(color, holder)
else
setColors(defaultFooterColor, holder)
} }
}) })
} }
@ -134,7 +127,7 @@ class ArtistAdapter(val activity: AppCompatActivity,
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) { inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init { init {
setImageTransitionName(activity.getString(R.string.transition_artist_image)) setImageTransitionName(activity.getString(code.name.monkey.retromusic.R.string.transition_artist_image))
if (menu != null) { if (menu != null) {
menu!!.visibility = View.GONE menu!!.visibility = View.GONE
} }
@ -146,7 +139,7 @@ class ArtistAdapter(val activity: AppCompatActivity,
toggleChecked(adapterPosition) toggleChecked(adapterPosition)
} else { } else {
val artistPairs = arrayOf<Pair<*, *>>(Pair.create<ImageView, String>(image, val artistPairs = arrayOf<Pair<*, *>>(Pair.create<ImageView, String>(image,
activity.resources.getString(R.string.transition_artist_image))) activity.resources.getString(code.name.monkey.retromusic.R.string.transition_artist_image)))
NavigationUtil.goToArtist(activity, dataSet[adapterPosition].id, *artistPairs) NavigationUtil.goToArtist(activity, dataSet[adapterPosition].id, *artistPairs)
} }
} }

View file

@ -10,33 +10,32 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.util.Pair import androidx.core.util.Pair
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget 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.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.helper.menu.SongMenuHelper import code.name.monkey.retromusic.helper.menu.SongMenuHelper
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.CabHolder import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialcab.MaterialCab import com.afollestad.materialcab.MaterialCab
import com.bumptech.glide.Glide
import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView
import java.util.* import java.util.*
/** /**
* Created by hemanths on 13/08/17. * Created by hemanths on 13/08/17.
*/ */
open class SongAdapter @JvmOverloads constructor(protected val activity: AppCompatActivity, dataSet: ArrayList<Song>, open class SongAdapter @JvmOverloads constructor(protected val activity: AppCompatActivity, dataSet: ArrayList<Song>,
@param:LayoutRes protected var itemLayoutRes: Int, usePalette: Boolean, cabHolder: CabHolder?, @param:LayoutRes protected var itemLayoutRes: Int, usePalette: Boolean, cabHolder: CabHolder?,
showSectionName: Boolean = true) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>(activity, cabHolder, R.menu.menu_media_selection), MaterialCab.Callback, FastScrollRecyclerView.SectionedAdapter { showSectionName: Boolean = true) : AbsMultiSelectAdapter<SongAdapter.ViewHolder, Song>(activity, cabHolder, code.name.monkey.retromusic.R.menu.menu_media_selection), MaterialCab.Callback, FastScrollRecyclerView.SectionedAdapter {
var dataSet: ArrayList<Song> var dataSet: ArrayList<Song>
protected var usePalette = false protected var usePalette = false
@ -105,17 +104,19 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
if (holder.image == null) { if (holder.image == null) {
return return
} }
GlideApp.with(activity).asBitmapPalette() SongGlideRequest.Builder.from(Glide.with(activity), song)
.load(RetroGlideExtension.getSongModel(song)) .checkIgnoreMediaStore(activity)
.transition(RetroGlideExtension.getDefaultTransition()) .generatePalette(activity).build()
.songOptions(song)
.into(object : RetroMusicColoredTarget(holder.image!!) { .into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(color: Int) { override fun onLoadCleared(placeholder: Drawable?) {
setColors(color, holder) super.onLoadCleared(placeholder)
setColors(defaultFooterColor, holder)
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onColorReady(color: Int) {
super.onLoadFailed(errorDrawable) if (usePalette)
setColors(color, holder)
else
setColors(defaultFooterColor, holder) setColors(defaultFooterColor, holder)
} }
}) })
@ -172,7 +173,7 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
get() = dataSet[adapterPosition] get() = dataSet[adapterPosition]
init { init {
setImageTransitionName(activity.getString(R.string.transition_album_art)) setImageTransitionName(activity.getString(code.name.monkey.retromusic.R.string.transition_album_art))
if (menu != null) { if (menu != null) {
menu!!.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) { menu!!.setOnClickListener(object : SongMenuHelper.OnClickSongMenu(activity) {
override val song: Song override val song: Song
@ -191,9 +192,9 @@ open class SongAdapter @JvmOverloads constructor(protected val activity: AppComp
protected open fun onSongMenuItemClick(item: MenuItem): Boolean { protected open fun onSongMenuItemClick(item: MenuItem): Boolean {
if (image != null && image!!.visibility == View.VISIBLE) { if (image != null && image!!.visibility == View.VISIBLE) {
when (item.itemId) { when (item.itemId) {
R.id.action_go_to_album -> { code.name.monkey.retromusic.R.id.action_go_to_album -> {
val albumPairs = arrayOf<Pair<*, *>>(Pair.create(imageContainer, val albumPairs = arrayOf<Pair<*, *>>(Pair.create(imageContainer,
activity.resources.getString(R.string.transition_album_art))) activity.resources.getString(code.name.monkey.retromusic.R.string.transition_album_art)))
NavigationUtil.goToAlbum(activity, song.albumId, *albumPairs) NavigationUtil.goToAlbum(activity, song.albumId, *albumPairs)
return true return true
} }

View file

@ -27,14 +27,14 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.* import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class AppWidgetBig : BaseAppWidget() { class AppWidgetBig : BaseAppWidget() {
@ -46,18 +46,18 @@ class AppWidgetBig : BaseAppWidget() {
*/ */
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) { override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
val appWidgetView = RemoteViews(context.packageName, val appWidgetView = RemoteViews(context.packageName,
R.layout.app_widget_big) code.name.monkey.retromusic.R.layout.app_widget_big)
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(code.name.monkey.retromusic.R.id.media_titles, View.INVISIBLE)
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art) appWidgetView.setImageViewResource(R.id.image, R.drawable.default_album_art)
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_next_white_24dp, RetroUtil.getTintedVectorDrawable(context, code.name.monkey.retromusic.R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f)) MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_skip_previous_white_24dp, RetroUtil.getTintedVectorDrawable(context, code.name.monkey.retromusic.R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f)) MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(context, R.drawable.ic_play_arrow_white_32dp, RetroUtil.getTintedVectorDrawable(context, code.name.monkey.retromusic.R.drawable.ic_play_arrow_white_32dp,
MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f)) MaterialValueHelper.getPrimaryTextColor(context, false))!!, 1f))
linkButtons(context, appWidgetView) linkButtons(context, appWidgetView)
@ -69,32 +69,32 @@ class AppWidgetBig : BaseAppWidget() {
*/ */
override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) { override fun performUpdate(service: MusicService, appWidgetIds: IntArray?) {
val appWidgetView = RemoteViews(service.packageName, val appWidgetView = RemoteViews(service.packageName,
R.layout.app_widget_big) code.name.monkey.retromusic.R.layout.app_widget_big)
val isPlaying = service.isPlaying val isPlaying = service.isPlaying
val song = service.currentSong val song = service.currentSong
// Set the titles and artwork // Set the titles and artwork
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) { if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
appWidgetView.setViewVisibility(R.id.media_titles, View.INVISIBLE) appWidgetView.setViewVisibility(code.name.monkey.retromusic.R.id.media_titles, View.INVISIBLE)
} else { } else {
appWidgetView.setViewVisibility(R.id.media_titles, View.VISIBLE) appWidgetView.setViewVisibility(code.name.monkey.retromusic.R.id.media_titles, View.VISIBLE)
appWidgetView.setTextViewText(R.id.title, song.title) appWidgetView.setTextViewText(code.name.monkey.retromusic.R.id.title, song.title)
appWidgetView.setTextViewText(R.id.text, getSongArtistAndAlbum(song)) appWidgetView.setTextViewText(code.name.monkey.retromusic.R.id.text, getSongArtistAndAlbum(song))
} }
// Set correct drawable for pause state // Set correct drawable for pause state
val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_32dp val playPauseRes = if (isPlaying) code.name.monkey.retromusic.R.drawable.ic_pause_white_24dp else code.name.monkey.retromusic.R.drawable.ic_play_arrow_white_32dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.createBitmap(
RetroUtil.getTintedVectorDrawable(service, playPauseRes, RetroUtil.getTintedVectorDrawable(service, playPauseRes,
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f)) MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f))
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, RetroUtil.getTintedVectorDrawable(service, code.name.monkey.retromusic.R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f)) MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, RetroUtil.getTintedVectorDrawable(service, code.name.monkey.retromusic.R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f)) MaterialValueHelper.getPrimaryTextColor(service, false))!!, 1f))
// Link actions buttons to intents // Link actions buttons to intents
@ -106,19 +106,18 @@ class AppWidgetBig : BaseAppWidget() {
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
GlideApp.with(appContext).clear(target) Glide.clear(target)
} }
target = GlideApp.with(appContext) target = SongGlideRequest.Builder.from(Glide.with(appContext), song)
.asBitmap() .checkIgnoreMediaStore(appContext)
.load(RetroGlideExtension.getSongModel(song)) .asBitmap().build()
.transition(RetroGlideExtension.getDefaultTransition()) .into(object : SimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
.songOptions(song) override fun onResourceReady(resource: Bitmap, glideAnimation: GlideAnimation<in Bitmap>) {
.into(object : RetroSimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
update(resource) update(resource)
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null) update(null)
} }
@ -130,7 +129,7 @@ class AppWidgetBig : BaseAppWidget() {
} }
pushUpdate(appContext, appWidgetIds, appWidgetView) pushUpdate(appContext, appWidgetIds, appWidgetView)
} }
}) });
} }
} }
@ -165,9 +164,7 @@ class AppWidgetBig : BaseAppWidget() {
companion object { companion object {
const val NAME: String = "app_widget_big" const val NAME: String = "app_widget_big"
private var mInstance: AppWidgetBig? = null private var mInstance: AppWidgetBig? = null
val instance: AppWidgetBig val instance: AppWidgetBig

View file

@ -27,15 +27,17 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.* import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class AppWidgetCard : BaseAppWidget() { class AppWidgetCard : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -79,15 +81,15 @@ class AppWidgetCard : BaseAppWidget() {
// Set correct drawable for pause state // Set correct drawable for pause state
val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_32dp val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_32dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(
RetroUtil.getTintedVectorDrawable(service, playPauseRes, RetroUtil.getTintedVectorDrawable(service, playPauseRes,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f)) MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f))
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f)) MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap( appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f)) MaterialValueHelper.getSecondaryTextColor(service, true))!!, 1f))
@ -95,46 +97,42 @@ class AppWidgetCard : BaseAppWidget() {
linkButtons(service, appWidgetView) linkButtons(service, appWidgetView)
if (imageSize == 0) { if (imageSize == 0) {
imageSize = service.resources.getDimensionPixelSize(R.dimen.app_widget_card_image_size) imageSize = service.resources.getDimensionPixelSize(code.name.monkey.retromusic.R.dimen.app_widget_card_image_size)
} }
if (cardRadius == 0f) { if (cardRadius == 0f) {
cardRadius = service.resources.getDimension(R.dimen.app_widget_card_radius) cardRadius = service.resources.getDimension(code.name.monkey.retromusic.R.dimen.app_widget_card_radius)
} }
val appContext = service.applicationContext val appContext = service.applicationContext
// Load the album cover async and push the update on completion // Load the album cover async and push the update on completion
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
GlideApp.with(appContext).clear(target) Glide.clear(target)
} }
GlideApp.with(appContext) target = SongGlideRequest.Builder.from(Glide.with(service), song)
.asBitmapPalette() .checkIgnoreMediaStore(service)
.load(RetroGlideExtension.getSongModel(song)) .generatePalette(service).build()
.transition(RetroGlideExtension.getDefaultTransition()) .centerCrop()
.songOptions(song) .into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(service, true)) update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
} }
private fun update(bitmap: Bitmap?, color: Int) { private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state // Set correct drawable for pause state
val playPauseRest = if (isPlaying) R.drawable.ic_pause_white_24dp appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, playPauseRes, color)))
else
R.drawable.ic_play_arrow_white_32dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRest, color)!!, 1f))
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_next, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)))
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_prev, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)))
val image = getAlbumArtDrawable(service.resources, bitmap) val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = BaseAppWidget.Companion.createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0f, cardRadius, 0f) val roundedBitmap = createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap) appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(service, appWidgetIds, appWidgetView) pushUpdate(service, appWidgetIds, appWidgetView)

View file

@ -24,19 +24,20 @@ import android.text.TextUtils
import android.view.View import android.view.View
import android.widget.RemoteViews import android.widget.RemoteViews
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.service.MusicService.* import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class AppWidgetClassic : BaseAppWidget() { class AppWidgetClassic : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -92,40 +93,35 @@ class AppWidgetClassic : BaseAppWidget() {
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
GlideApp.with(appContext).clear(target) Glide.clear(target)
} }
GlideApp.with(appContext) target = SongGlideRequest.Builder.from(Glide.with(service), song)
.asBitmapPalette() .checkIgnoreMediaStore(service)
.load(RetroGlideExtension.getSongModel(song)) .generatePalette(service).build()
.transition(RetroGlideExtension.getDefaultTransition()) .centerCrop()
.songOptions(song) .into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true)))) update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true)) update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
} }
private fun update(bitmap: Bitmap?, color: Int) { private fun update(bitmap: Bitmap?, color: Int) {
// Set correct drawable for pause state // Set correct drawable for pause state
val playPauseRes = if (isPlaying) val playPauseRes = if (isPlaying) R.drawable.ic_pause_white_24dp else R.drawable.ic_play_arrow_white_24dp
R.drawable.ic_pause_white_24dp appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, playPauseRes, color)))
else
R.drawable.ic_play_arrow_white_32dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause,
createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color)!!, 1f))
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_next, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)))
appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_prev, ImageUtil.createBitmap(ImageUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)))
val image = getAlbumArtDrawable(service.resources, bitmap) val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = BaseAppWidget.createRoundedBitmap(image, imageSize, imageSize, val roundedBitmap = createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F)
cardRadius, 0f, cardRadius, 0f)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap) appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(appContext, appWidgetIds, appWidgetView) pushUpdate(appContext, appWidgetIds, appWidgetView)

View file

@ -27,15 +27,15 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.* import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class AppWidgetSmall : BaseAppWidget() { class AppWidgetSmall : BaseAppWidget() {
private var target: Target<BitmapPaletteWrapper>? = null // for cancellation private var target: Target<BitmapPaletteWrapper>? = null // for cancellation
@ -96,23 +96,21 @@ class AppWidgetSmall : BaseAppWidget() {
val appContext = service.applicationContext val appContext = service.applicationContext
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
GlideApp.with(appContext).clear(target); Glide.clear(target)
} }
target = GlideApp.with(appContext) target = SongGlideRequest.Builder.from(Glide.with(service), song)
.asBitmapPalette() .checkIgnoreMediaStore(service)
.load(RetroGlideExtension.getSongModel(song)) .generatePalette(service).build()
.transition(RetroGlideExtension.getDefaultTransition()) .centerCrop()
.songOptions(song) .into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) { override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val palette = resource.palette val palette = resource.palette
update(resource.bitmap, palette.getVibrantColor(palette update(resource.bitmap, palette.getVibrantColor(palette.getMutedColor(MaterialValueHelper.getSecondaryTextColor(service, true))))
.getMutedColor(MaterialValueHelper.getSecondaryTextColor(appContext, true))))
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null, MaterialValueHelper.getSecondaryTextColor(appContext, true)) update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
} }
private fun update(bitmap: Bitmap?, color: Int) { private fun update(bitmap: Bitmap?, color: Int) {
@ -121,14 +119,14 @@ class AppWidgetSmall : BaseAppWidget() {
R.drawable.ic_pause_white_24dp R.drawable.ic_pause_white_24dp
else else
R.drawable.ic_play_arrow_white_32dp R.drawable.ic_play_arrow_white_32dp
appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color)!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_toggle_play_pause, createBitmap(RetroUtil.getTintedVectorDrawable(service, playPauseRes, color)!!, 1f))
// Set prev/next button drawables // Set prev/next button drawables
appWidgetView.setImageViewBitmap(R.id.button_next, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_next, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp, color)!!, 1f))
appWidgetView.setImageViewBitmap(R.id.button_prev, BaseAppWidget.Companion.createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f)) appWidgetView.setImageViewBitmap(R.id.button_prev, createBitmap(RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp, color)!!, 1f))
val image = getAlbumArtDrawable(service.resources, bitmap) val image = getAlbumArtDrawable(service.resources, bitmap)
val roundedBitmap = BaseAppWidget.createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0f, 0f, 0f) val roundedBitmap = createRoundedBitmap(image, imageSize, imageSize, cardRadius, 0f, 0f, 0f)
appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap) appWidgetView.setImageViewBitmap(R.id.image, roundedBitmap)
pushUpdate(appContext, appWidgetIds, appWidgetView) pushUpdate(appContext, appWidgetIds, appWidgetView)

View file

@ -19,10 +19,12 @@ import code.name.monkey.retromusic.dagger.module.*
import code.name.monkey.retromusic.fragments.mainactivity.* import code.name.monkey.retromusic.fragments.mainactivity.*
import code.name.monkey.retromusic.fragments.mainactivity.home.BannerHomeFragment import code.name.monkey.retromusic.fragments.mainactivity.home.BannerHomeFragment
import dagger.Component import dagger.Component
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
*/ */
@Singleton
@Component(modules = [ @Component(modules = [
RepositoryModule::class, RepositoryModule::class,
AlbumModule::class, AlbumModule::class,

View file

@ -18,6 +18,7 @@ import android.app.Activity
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -26,6 +27,7 @@ import dagger.Provides
class ActivityModule(private val activity: Activity) { class ActivityModule(private val activity: Activity) {
@Provides @Provides
@Singleton
fun provideActivity(): Activity { fun provideActivity(): Activity {
return activity return activity
} }

View file

@ -20,6 +20,7 @@ import code.name.monkey.retromusic.mvp.presenter.AlbumsPresenter
import code.name.monkey.retromusic.mvp.presenter.AlbumsPresenter.AlbumsPresenterImpl import code.name.monkey.retromusic.mvp.presenter.AlbumsPresenter.AlbumsPresenterImpl
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -28,11 +29,13 @@ import dagger.Provides
class AlbumModule { class AlbumModule {
@Provides @Provides
@Singleton
fun providesAlbumsPresenter(presenter: AlbumsPresenterImpl): AlbumsPresenter { fun providesAlbumsPresenter(presenter: AlbumsPresenterImpl): AlbumsPresenter {
return presenter return presenter
} }
@Provides @Provides
@Singleton
fun providesAlbumDetailsPresenter(presenter: AlbumDetailsPresenterImpl): AlbumDetailsPresenter { fun providesAlbumDetailsPresenter(presenter: AlbumDetailsPresenterImpl): AlbumDetailsPresenter {
return presenter return presenter
} }

View file

@ -18,6 +18,7 @@ import android.content.Context
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -26,6 +27,7 @@ import dagger.Provides
class AppModule(private val context: Context) { class AppModule(private val context: Context) {
@Provides @Provides
@Singleton
fun provideContext(): Context { fun provideContext(): Context {
return context return context
} }

View file

@ -21,6 +21,7 @@ import dagger.Provides
import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter.* import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter.*
import code.name.monkey.retromusic.mvp.presenter.ArtistsPresenter.* import code.name.monkey.retromusic.mvp.presenter.ArtistsPresenter.*
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -29,11 +30,13 @@ import code.name.monkey.retromusic.mvp.presenter.ArtistsPresenter.*
class ArtistModule { class ArtistModule {
@Provides @Provides
@Singleton
fun providesArtistDetailsPresenter(presenter: ArtistDetailsPresenterImpl): ArtistDetailsPresenter { fun providesArtistDetailsPresenter(presenter: ArtistDetailsPresenterImpl): ArtistDetailsPresenter {
return presenter return presenter
} }
@Provides @Provides
@Singleton
fun providesArtistsPresenter(presenter: ArtistsPresenterImpl): ArtistsPresenter { fun providesArtistsPresenter(presenter: ArtistsPresenterImpl): ArtistsPresenter {
return presenter return presenter
} }

View file

@ -20,6 +20,7 @@ import code.name.monkey.retromusic.mvp.presenter.GenresPresenter
import code.name.monkey.retromusic.mvp.presenter.GenresPresenter.GenresPresenterImpl import code.name.monkey.retromusic.mvp.presenter.GenresPresenter.GenresPresenterImpl
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -28,12 +29,14 @@ import dagger.Provides
class GenreModule { class GenreModule {
@Provides @Provides
@Singleton
fun providesGenresPresenter(presenter: GenresPresenterImpl): GenresPresenter { fun providesGenresPresenter(presenter: GenresPresenterImpl): GenresPresenter {
return presenter return presenter
} }
@Provides @Provides
@Singleton
fun providesGenreDetailsPresenter(presenter: GenreDetailsPresenterImpl): GenreDetailsPresenter { fun providesGenreDetailsPresenter(presenter: GenreDetailsPresenterImpl): GenreDetailsPresenter {
return presenter return presenter
} }

View file

@ -18,6 +18,7 @@ import code.name.monkey.retromusic.mvp.presenter.HomePresenter
import code.name.monkey.retromusic.mvp.presenter.HomePresenter.HomePresenterImpl import code.name.monkey.retromusic.mvp.presenter.HomePresenter.HomePresenterImpl
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -26,6 +27,7 @@ import dagger.Provides
class HomeModule { class HomeModule {
@Provides @Provides
@Singleton
fun providesHomePresenter(presenter: HomePresenterImpl): HomePresenter { fun providesHomePresenter(presenter: HomePresenterImpl): HomePresenter {
return presenter return presenter
} }

View file

@ -20,6 +20,7 @@ import code.name.monkey.retromusic.mvp.presenter.PlaylistsPresenter
import code.name.monkey.retromusic.mvp.presenter.PlaylistsPresenter.PlaylistsPresenterImpl import code.name.monkey.retromusic.mvp.presenter.PlaylistsPresenter.PlaylistsPresenterImpl
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -27,11 +28,13 @@ import dagger.Provides
@Module @Module
class PlaylistModule { class PlaylistModule {
@Provides @Provides
@Singleton
fun providesPlaylistSongPresenter(presenter: PlaylistSongsPresenterImpl): PlaylistSongsPresenter { fun providesPlaylistSongPresenter(presenter: PlaylistSongsPresenterImpl): PlaylistSongsPresenter {
return presenter return presenter
} }
@Provides @Provides
@Singleton
fun providesPlaylistsPresenter(presenter: PlaylistsPresenterImpl): PlaylistsPresenter { fun providesPlaylistsPresenter(presenter: PlaylistsPresenterImpl): PlaylistsPresenter {
return presenter return presenter
} }

View file

@ -20,6 +20,7 @@ import code.name.monkey.retromusic.providers.RepositoryImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -28,6 +29,7 @@ import dagger.Provides
class RepositoryModule { class RepositoryModule {
@Provides @Provides
@Singleton
fun providesRepository(context: Context): Repository { fun providesRepository(context: Context): Repository {
return RepositoryImpl(context) return RepositoryImpl(context)
} }

View file

@ -18,6 +18,7 @@ import code.name.monkey.retromusic.mvp.presenter.SearchPresenter
import code.name.monkey.retromusic.mvp.presenter.SearchPresenter.SearchPresenterImpl import code.name.monkey.retromusic.mvp.presenter.SearchPresenter.SearchPresenterImpl
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -26,6 +27,7 @@ import dagger.Provides
class SearchModule { class SearchModule {
@Provides @Provides
@Singleton
fun providesSearchPresenter(presenter: SearchPresenterImpl): SearchPresenter { fun providesSearchPresenter(presenter: SearchPresenterImpl): SearchPresenter {
return presenter return presenter
} }

View file

@ -18,6 +18,7 @@ import code.name.monkey.retromusic.mvp.presenter.SongPresenter
import code.name.monkey.retromusic.mvp.presenter.SongPresenter.SongPresenterImpl import code.name.monkey.retromusic.mvp.presenter.SongPresenter.SongPresenterImpl
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import javax.inject.Singleton
/** /**
* Created by hemanths on 2019-09-04. * Created by hemanths on 2019-09-04.
@ -25,6 +26,7 @@ import dagger.Provides
@Module @Module
class SongModule { class SongModule {
@Provides @Provides
@Singleton
fun providesSongPresenter(presenter: SongPresenterImpl): SongPresenter { fun providesSongPresenter(presenter: SongPresenterImpl): SongPresenter {
return presenter return presenter
} }

View file

@ -13,6 +13,26 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import javax.inject.Inject import javax.inject.Inject
open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager>(), AlbumsView { open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridLayoutManager>(), AlbumsView {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
App.musicComponent.inject(this)
albumsPresenter.attachView(this)
}
override fun onResume() {
super.onResume()
if (adapter!!.dataSet.isEmpty()) {
albumsPresenter.loadAlbums()
}
}
override fun onDestroyView() {
super.onDestroyView()
albumsPresenter.detachView()
}
override fun albums(albums: java.util.ArrayList<Album>) { override fun albums(albums: java.util.ArrayList<Album>) {
adapter?.swapDataSet(albums) adapter?.swapDataSet(albums)
} }
@ -86,20 +106,6 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
PreferenceUtil.getInstance(requireContext()).setAlbumColoredFooters(usePalette) PreferenceUtil.getInstance(requireContext()).setAlbumColoredFooters(usePalette)
} }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
App.musicComponent?.inject(this)
albumsPresenter.attachView(this)
}
override fun onResume() {
super.onResume()
if (adapter!!.dataSet.isEmpty()) {
albumsPresenter.loadAlbums()
}
}
override fun onMediaStoreChanged() { override fun onMediaStoreChanged() {
albumsPresenter.loadAlbums() albumsPresenter.loadAlbums()
} }
@ -108,19 +114,14 @@ open class AlbumsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Al
albumsPresenter.loadAlbums() albumsPresenter.loadAlbums()
} }
override fun onDestroyView() {
super.onDestroyView()
albumsPresenter.detachView()
}
override fun showEmptyView() { override fun showEmptyView() {
adapter?.swapDataSet(ArrayList()) adapter?.swapDataSet(ArrayList())
} }
companion object { companion object {
@JvmField
val TAG: String = AlbumsFragment::class.java.simpleName var TAG: String = AlbumsFragment::class.java.simpleName
fun newInstance(): AlbumsFragment { fun newInstance(): AlbumsFragment {
val args = Bundle() val args = Bundle()

View file

@ -25,7 +25,7 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
App.musicComponent?.inject(this) App.musicComponent.inject(this)
artistsPresenter.attachView(this) artistsPresenter.attachView(this)
} }
@ -36,6 +36,11 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
} }
} }
override fun onDestroyView() {
super.onDestroyView()
artistsPresenter.detachView()
}
override fun onMediaStoreChanged() { override fun onMediaStoreChanged() {
artistsPresenter.loadArtists() artistsPresenter.loadArtists()
} }
@ -101,17 +106,13 @@ class ArtistsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<Artist
PreferenceUtil.getInstance(requireContext()).artistSortOrder = sortOrder PreferenceUtil.getInstance(requireContext()).artistSortOrder = sortOrder
} }
override fun onDestroyView() {
super.onDestroyView()
artistsPresenter.detachView()
}
override fun showEmptyView() { override fun showEmptyView() {
adapter?.swapDataSet(ArrayList()) adapter?.swapDataSet(ArrayList())
} }
companion object { companion object {
@JvmField
val TAG = ArtistsFragment::class.java.simpleName val TAG = ArtistsFragment::class.java.simpleName
fun newInstance(): ArtistsFragment { fun newInstance(): ArtistsFragment {

View file

@ -54,7 +54,7 @@ class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearL
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
App.musicComponent?.inject(this) App.musicComponent.inject(this)
genresPresenter.attachView(this) genresPresenter.attachView(this)
} }
@ -75,6 +75,8 @@ class GenresFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearL
} }
companion object { companion object {
@JvmField
val TAG = GenresFragment::class.java.simpleName
fun newInstance(): GenresFragment { fun newInstance(): GenresFragment {
return GenresFragment() return GenresFragment()

View file

@ -183,9 +183,8 @@ public class LibraryFragment extends AbsMainActivityFragment implements CabHolde
private void selectedFragment(Fragment fragment) { private void selectedFragment(Fragment fragment) {
fragmentManager = getChildFragmentManager(); fragmentManager = getChildFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction fragmentTransaction
.replace(R.id.fragmentContainer, fragment, TAG) .replace(R.id.fragmentContainer, fragment, LibraryFragment.TAG)
.commit(); .commit();
} }

View file

@ -71,6 +71,8 @@ class PlaylistsFragment : AbsLibraryPagerRecyclerViewFragment<PlaylistAdapter, L
} }
companion object { companion object {
@JvmField
val TAG = PlaylistsFragment::class.java.simpleName
fun newInstance(): PlaylistsFragment { fun newInstance(): PlaylistsFragment {
val args = Bundle() val args = Bundle()

View file

@ -25,8 +25,7 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
App.musicComponent?.inject(this) App.musicComponent.inject(this)
songPresenter.attachView(this) songPresenter.attachView(this)
} }
@ -117,6 +116,9 @@ class SongsFragment : AbsLibraryPagerRecyclerViewCustomGridSizeFragment<SongAdap
companion object { companion object {
@JvmField
var TAG: String = SongsFragment::class.java.simpleName
fun newInstance(): SongsFragment { fun newInstance(): SongsFragment {
val args = Bundle() val args = Bundle()
val fragment = SongsFragment() val fragment = SongsFragment()

View file

@ -22,7 +22,6 @@ import code.name.monkey.retromusic.dialogs.OptionsSheetDialogFragment
import code.name.monkey.retromusic.extensions.hide import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
import code.name.monkey.retromusic.loaders.SongLoader import code.name.monkey.retromusic.loaders.SongLoader
@ -33,6 +32,7 @@ import code.name.monkey.retromusic.model.smartplaylist.MyTopTracksPlaylist
import code.name.monkey.retromusic.mvp.presenter.HomePresenter import code.name.monkey.retromusic.mvp.presenter.HomePresenter
import code.name.monkey.retromusic.mvp.presenter.HomeView import code.name.monkey.retromusic.mvp.presenter.HomeView
import code.name.monkey.retromusic.util.* import code.name.monkey.retromusic.util.*
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
@ -101,15 +101,14 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
App.musicComponent?.inject(this) App.musicComponent.inject(this)
homePresenter.attachView(this)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
toolbar = view.findViewById(R.id.toolbar) toolbar = view.findViewById(R.id.toolbar)
bannerImage?.setOnClickListener { bannerImage?.setOnClickListener {
@ -146,7 +145,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
} }
titleWelcome.setTextColor(ThemeStore.textColorPrimary(requireContext())) titleWelcome.setTextColor(ThemeStore.textColorPrimary(requireContext()))
titleWelcome.text = String.format("%s", PreferenceUtil.getInstance(requireContext()).userName) titleWelcome.text = String.format("%s", PreferenceUtil.getInstance(requireContext()).userName)
homePresenter.attachView(this)
homePresenter.loadSections() homePresenter.loadSections()
} }
@ -254,7 +253,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
private fun loadTimeImage(day: String) { private fun loadTimeImage(day: String) {
if (bannerImage != null) { if (bannerImage != null) {
if (PreferenceUtil.getInstance(requireContext()).bannerImage.isEmpty()) { if (PreferenceUtil.getInstance(requireContext()).bannerImage.isEmpty()) {
GlideApp.with(requireActivity()) Glide.with(requireActivity())
.load(day) .load(day)
.placeholder(R.drawable.material_design_default) .placeholder(R.drawable.material_design_default)
.diskCacheStrategy(DiskCacheStrategy.ALL) .diskCacheStrategy(DiskCacheStrategy.ALL)
@ -277,10 +276,7 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
const val TAG: String = "BannerHomeFragment" const val TAG: String = "BannerHomeFragment"
fun newInstance(): BannerHomeFragment { fun newInstance(): BannerHomeFragment {
val args = Bundle() return BannerHomeFragment()
val fragment = BannerHomeFragment()
fragment.arguments = args
return fragment
} }
} }
} }

View file

@ -1,23 +1,22 @@
package code.name.monkey.retromusic.fragments.player.blur package code.name.monkey.retromusic.fragments.player.blur
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.preference.PreferenceManager
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.glide.BlurTransformation
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.Song
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_blur.* import kotlinx.android.synthetic.main.fragment_blur.*
class BlurPlayerFragment : AbsPlayerFragment() { class BlurPlayerFragment : AbsPlayerFragment() {
@ -97,12 +96,11 @@ class BlurPlayerFragment : AbsPlayerFragment() {
val activity = activity ?: return val activity = activity ?: return
val blurAmount = PreferenceManager.getDefaultSharedPreferences(context).getInt("new_blur_amount", 25) val blurAmount = PreferenceManager.getDefaultSharedPreferences(context).getInt("new_blur_amount", 25)
colorBackground!!.clearColorFilter() colorBackground!!.clearColorFilter()
GlideApp.with(activity) SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
.asBitmapPalette() .checkIgnoreMediaStore(requireContext())
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong)) .generatePalette(requireContext()).build()
.transition(RetroGlideExtension.getDefaultTransition())
.transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build()) .transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build())
.songOptions(MusicPlayerRemote.currentSong) .centerCrop()
.override(320, 480) .override(320, 480)
.into(object : RetroMusicColoredTarget(colorBackground) { .into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
@ -110,11 +108,6 @@ class BlurPlayerFragment : AbsPlayerFragment() {
colorBackground!!.setColorFilter(color) colorBackground!!.setColorFilter(color)
} }
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
}) })
} }

View file

@ -1,24 +1,23 @@
package code.name.monkey.retromusic.fragments.player.cardblur package code.name.monkey.retromusic.fragments.player.cardblur
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Bundle import android.os.Bundle
import android.preference.PreferenceManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.preference.PreferenceManager
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
import code.name.monkey.retromusic.glide.BlurTransformation
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.Song
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_card_blur_player.* import kotlinx.android.synthetic.main.fragment_card_blur_player.*
class CardBlurFragment : AbsPlayerFragment() { class CardBlurFragment : AbsPlayerFragment() {
@ -125,17 +124,13 @@ class CardBlurFragment : AbsPlayerFragment() {
private fun updateBlur() { private fun updateBlur() {
val activity = activity ?: return val activity = activity ?: return
val blurAmount = PreferenceManager.getDefaultSharedPreferences(context) val blurAmount = PreferenceManager.getDefaultSharedPreferences(context).getInt("new_blur_amount", 25)
.getInt("new_blur_amount", 25)
colorBackground!!.clearColorFilter() colorBackground!!.clearColorFilter()
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
GlideApp.with(activity) .checkIgnoreMediaStore(requireContext())
.asBitmapPalette() .generatePalette(requireContext()).build()
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.transition(RetroGlideExtension.getDefaultTransition())
.transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build()) .transform(BlurTransformation.Builder(activity).blurRadius(blurAmount.toFloat()).build())
.songOptions(MusicPlayerRemote.currentSong) .centerCrop()
.override(320, 480) .override(320, 480)
.into(object : RetroMusicColoredTarget(colorBackground) { .into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
@ -143,11 +138,6 @@ class CardBlurFragment : AbsPlayerFragment() {
colorBackground!!.setColorFilter(color) colorBackground!!.setColorFilter(color)
} }
} }
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
}
}) })
} }

View file

@ -21,9 +21,8 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.LyricsActivity import code.name.monkey.retromusic.activities.LyricsActivity
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
@ -31,7 +30,8 @@ import code.name.monkey.retromusic.model.lyrics.Lyrics
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import kotlinx.android.synthetic.main.fragment_color_player.* import kotlinx.android.synthetic.main.fragment_color_player.*
class ColorFragment : AbsPlayerFragment() { class ColorFragment : AbsPlayerFragment() {
@ -133,21 +133,20 @@ class ColorFragment : AbsPlayerFragment() {
private fun updateSong() { private fun updateSong() {
GlideApp.with(activity!!)
.asBitmapPalette() SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong)) .checkIgnoreMediaStore(requireContext())
.songOptions(MusicPlayerRemote.currentSong) .generatePalette(requireContext())
.transition(RetroGlideExtension.getDefaultTransition()) .build()
.into(object : RetroMusicColoredTarget(playerImage) { .into(object : RetroMusicColoredTarget(playerImage) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
} }
override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: Transition<in BitmapPaletteWrapper>?) { override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation) super.onResourceReady(resource, glideAnimation)
val background = resource.palette.getColor() val background = resource.palette.getColor()
val accentColor = resource.palette.getContrastColor(background)
val palette = resource.palette val palette = resource.palette
val swatch = RetroColorUtil.getSwatch(palette) val swatch = RetroColorUtil.getSwatch(palette)
@ -158,8 +157,8 @@ class ColorFragment : AbsPlayerFragment() {
setColors(backgroundColor, textColor) setColors(backgroundColor, textColor)
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception, errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable) super.onLoadFailed(e, errorDrawable)
val backgroundColor = defaultFooterColor val backgroundColor = defaultFooterColor
val textColor = if (ColorUtil.isColorLight(defaultFooterColor)) val textColor = if (ColorUtil.isColorLight(defaultFooterColor))
MaterialValueHelper.getPrimaryTextColor(context, true) MaterialValueHelper.getPrimaryTextColor(context, true)
@ -265,10 +264,6 @@ class ColorFragment : AbsPlayerFragment() {
} }
} }
fun Palette.getContrastColor(background: Int): Int {
return 0
}
fun Palette.getColor(): Int { fun Palette.getColor(): Int {
return when { return when {

View file

@ -13,10 +13,10 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import code.name.monkey.retromusic.views.DrawableGradient import code.name.monkey.retromusic.views.DrawableGradient

View file

@ -14,8 +14,7 @@ import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
@ -24,6 +23,7 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics
import code.name.monkey.retromusic.model.lyrics.Lyrics import code.name.monkey.retromusic.model.lyrics.Lyrics
import code.name.monkey.retromusic.util.NavigationUtil import code.name.monkey.retromusic.util.NavigationUtil
import com.bumptech.glide.Glide
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
@ -217,13 +217,9 @@ class FullPlayerFragment : AbsPlayerFragment() , MusicProgressViewUpdateHelper.C
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe { .subscribe {
GlideApp.with(activity!!) ArtistGlideRequest.Builder.from(Glide.with(requireContext()), it)
.asBitmapPalette() .generatePalette(requireContext())
.load(RetroGlideExtension.getArtistModel(it)) .build().into(object : RetroMusicColoredTarget(artistImage) {
.transition(RetroGlideExtension.getDefaultTransition())
.artistOptions(it)
.dontAnimate()
.into(object : RetroMusicColoredTarget(artistImage) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
} }
@ -238,7 +234,6 @@ class FullPlayerFragment : AbsPlayerFragment() , MusicProgressViewUpdateHelper.C
private fun updateLabel() { private fun updateLabel() {
(MusicPlayerRemote.playingQueue.size - 1).apply { (MusicPlayerRemote.playingQueue.size - 1).apply {
println("Log Position $this ${MusicPlayerRemote.position}")
if (this == (MusicPlayerRemote.position)) { if (this == (MusicPlayerRemote.position)) {
nextSongLabel.setText(R.string.last_song) nextSongLabel.setText(R.string.last_song)
nextSong.hide() nextSong.hide()

View file

@ -77,7 +77,7 @@ class TinyPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
ThemeStore.accentColor(requireContext()) ThemeStore.accentColor(requireContext())
} }
if (ColorUtil.isColorLight(color)) { if (ColorUtil.isColorLight(colorFinal)) {
textColorPrimary = MaterialValueHelper.getSecondaryTextColor(requireContext(), true) textColorPrimary = MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
textColorPrimaryDisabled = MaterialValueHelper.getSecondaryTextColor(requireContext(), true) textColorPrimaryDisabled = MaterialValueHelper.getSecondaryTextColor(requireContext(), true)
} else { } else {

View file

@ -0,0 +1,155 @@
/*
* 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.glide;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import com.bumptech.glide.BitmapRequestBuilder;
import com.bumptech.glide.DrawableRequestBuilder;
import com.bumptech.glide.DrawableTypeRequest;
import com.bumptech.glide.Priority;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.target.Target;
import java.util.ArrayList;
import java.util.List;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.artistimage.AlbumCover;
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
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.ArtistSignatureUtil;
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistGlideRequest {
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.ALL;
private static final int DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art;
public static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist, boolean noCustomImage) {
boolean hasCustomImage = CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist);
if (noCustomImage || !hasCustomImage) {
final List<AlbumCover> songs = new ArrayList<>();
for (final Album album : artist.getAlbums()) {
final Song song = album.safeGetFirstSong();
songs.add(new AlbumCover(album.getYear(), song.getData()));
}
return requestManager.load(new ArtistImage(artist.getName(), songs));
} else {
return requestManager.load(CustomArtistImageUtil.getFile(artist));
}
}
private static Key createSignature(Artist artist) {
return ArtistSignatureUtil.getInstance(App.Companion.getContext()).getArtistSignature(artist.getName());
}
public static class Builder {
final RequestManager requestManager;
final Artist artist;
boolean noCustomImage;
private Builder(@NonNull RequestManager requestManager, Artist artist) {
this.requestManager = requestManager;
this.artist = artist;
}
public static Builder from(@NonNull RequestManager requestManager, Artist artist) {
return new Builder(requestManager, artist);
}
public PaletteBuilder generatePalette(Context context) {
return new PaletteBuilder(this, context);
}
public BitmapBuilder asBitmap() {
return new BitmapBuilder(this);
}
public Builder noCustomImage(boolean noCustomImage) {
this.noCustomImage = noCustomImage;
return this;
}
public DrawableRequestBuilder<GlideDrawable> build() {
//noinspection unchecked
return createBaseRequest(requestManager, artist, noCustomImage)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(artist));
}
}
public static class BitmapBuilder {
private final Builder builder;
public BitmapBuilder(Builder builder) {
this.builder = builder;
}
public BitmapRequestBuilder<?, Bitmap> build() {
//noinspection unchecked
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage)
.asBitmap()
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(builder.artist));
}
}
public static class PaletteBuilder {
final Context context;
private final Builder builder;
public PaletteBuilder(Builder builder, Context context) {
this.builder = builder;
this.context = context;
}
public BitmapRequestBuilder<?, BitmapPaletteWrapper> build() {
//noinspection unchecked
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage)
.asBitmap()
.transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(builder.artist));
}
}
}

View file

@ -26,28 +26,67 @@ import code.name.monkey.retromusic.helper.StackBlur
import code.name.monkey.retromusic.util.ImageUtil import code.name.monkey.retromusic.util.ImageUtil
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import java.security.MessageDigest
class BlurTransformation : BitmapTransformation { class BlurTransformation : BitmapTransformation {
private var context: Context? = null private var context: Context? = null
private var blurRadius: Float = 0.toFloat() private var blurRadius: Float = 0.toFloat()
private var sampling: Int = 0 private var sampling: Int = 0
private constructor(builder: Builder) : super() {
init(builder)
}
private constructor(builder: Builder, bitmapPool: BitmapPool) : super() {
init(builder)
}
private fun init(builder: Builder) { private fun init(builder: Builder) {
this.context = builder.context this.context = builder.context
this.blurRadius = builder.blurRadius this.blurRadius = builder.blurRadius
this.sampling = builder.sampling this.sampling = builder.sampling
} }
private constructor(builder: Builder) : super(builder.context) {
init(builder)
}
private constructor(builder: Builder, bitmapPool: BitmapPool) : super(bitmapPool) {
init(builder)
}
class Builder(val context: Context) {
private var bitmapPool: BitmapPool? = null
var blurRadius = DEFAULT_BLUR_RADIUS
var sampling: Int = 0
/**
* @param blurRadius The radius to use. Must be between 0 and 25. Default is 5.
* @return the same Builder
*/
fun blurRadius(@FloatRange(from = 0.0, to = 25.0) blurRadius: Float): Builder {
this.blurRadius = blurRadius
return this
}
/**
* @param sampling The inSampleSize to use. Must be a power of 2, or 1 for no down sampling or 0 for auto detect sampling. Default is 0.
* @return the same Builder
*/
fun sampling(sampling: Int): Builder {
this.sampling = sampling
return this
}
/**
* @param bitmapPool The BitmapPool to use.
* @return the same Builder
*/
fun bitmapPool(bitmapPool: BitmapPool): Builder {
this.bitmapPool = bitmapPool
return this
}
fun build(): BlurTransformation {
return if (bitmapPool != null) {
BlurTransformation(this, bitmapPool!!)
} else BlurTransformation(this)
}
}
override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? { override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? {
val sampling: Int val sampling: Int
if (this.sampling == 0) { if (this.sampling == 0) {
@ -99,60 +138,11 @@ class BlurTransformation : BitmapTransformation {
return StackBlur.blur(out, blurRadius) return StackBlur.blur(out, blurRadius)
} }
override fun equals(other: Any?): Boolean { override fun getId(): String {
return other is BlurTransformation return "BlurTransformation(radius=$blurRadius, sampling=$sampling)"
}
override fun hashCode(): Int {
return ID.hashCode()
}
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update("BlurTransformation(radius=$blurRadius, sampling=$sampling)".toByteArray(CHARSET))
}
class Builder(val context: Context) {
var bitmapPool: BitmapPool? = null
var blurRadius = DEFAULT_BLUR_RADIUS
var sampling: Int = 0
/**
* @param blurRadius The radius to use. Must be between 0 and 25. Default is 5.
* @return the same Builder
*/
fun blurRadius(@FloatRange(from = 0.0, to = 25.0) blurRadius: Float): Builder {
this.blurRadius = blurRadius
return this
}
/**
* @param sampling The inSampleSize to use. Must be a power of 2, or 1 for no down sampling or 0 for auto detect sampling. Default is 0.
* @return the same Builder
*/
fun sampling(sampling: Int): Builder {
this.sampling = sampling
return this
}
/**
* @param bitmapPool The BitmapPool to use.
* @return the same Builder
*/
fun bitmapPool(bitmapPool: BitmapPool): Builder {
this.bitmapPool = bitmapPool
return this
}
fun build(): BlurTransformation {
return if (bitmapPool != null) {
BlurTransformation(this, bitmapPool!!)
} else BlurTransformation(this)
}
} }
companion object { companion object {
val DEFAULT_BLUR_RADIUS = 5f
const val DEFAULT_BLUR_RADIUS = 5f
private const val ID = "code.name.monkey.retromusic.glide.BlurTransformation"
} }
} }

View file

@ -1,123 +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.glide;
import androidx.annotation.NonNull;
import com.bumptech.glide.GenericTransitionOptions;
import com.bumptech.glide.Priority;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.annotation.GlideExtension;
import com.bumptech.glide.annotation.GlideOption;
import com.bumptech.glide.annotation.GlideType;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.signature.MediaStoreSignature;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.ArtistSignatureUtil;
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
import code.name.monkey.retromusic.util.MusicUtil;
import code.name.monkey.retromusic.util.PreferenceUtil;
@GlideExtension
public final class RetroGlideExtension {
private RetroGlideExtension() {
}
@NonNull
@GlideType(BitmapPaletteWrapper.class)
public static void asBitmapPalette(@NonNull RequestBuilder<BitmapPaletteWrapper> requestBuilder) {
}
@NonNull
@GlideOption
public static RequestOptions artistOptions(@NonNull RequestOptions requestOptions, @NonNull Artist artist) {
return requestOptions
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.error(R.drawable.default_artist_art)
.placeholder(R.drawable.default_artist_art)
.priority(Priority.LOW)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.signature(createSignature(artist));
}
@GlideOption
@NonNull
public static RequestOptions songOptions(@NonNull RequestOptions requestOptions, @NonNull Song song) {
return requestOptions
.diskCacheStrategy(DiskCacheStrategy.NONE)
.error(R.drawable.default_album_art)
//.placeholder(R.drawable.default_album_art)
.signature(createSignature(song));
}
@NonNull
public static Key createSignature(@NonNull Artist artist) {
return ArtistSignatureUtil.getInstance().getArtistSignature(artist.getName());
}
@NonNull
public static Key createSignature(@NonNull Song song) {
return new MediaStoreSignature("", song.getDateModified(), 0);
}
@NonNull
public static Object getArtistModel(@NonNull Artist artist) {
return getArtistModel(artist, CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist), false);
}
@NonNull
public static Object getArtistModel(@NonNull Artist artist, boolean forceDownload) {
return getArtistModel(artist, CustomArtistImageUtil.Companion.getInstance(App.Companion.getContext()).hasCustomArtistImage(artist), forceDownload);
}
@NonNull
public static Object getArtistModel(@NonNull Artist artist, boolean hasCustomImage, boolean forceDownload) {
if (!hasCustomImage) {
return new ArtistImage(artist.getName(), forceDownload);
} else {
return CustomArtistImageUtil.getFile(artist);
}
}
@NonNull
public static Object getSongModel(@NonNull Song song) {
return getSongModel(song, PreferenceUtil.getInstance(App.Companion.getContext()).ignoreMediaStoreArtwork());
}
@NonNull
public static Object getSongModel(@NonNull Song song, boolean ignoreMediaStore) {
if (ignoreMediaStore) {
return new AudioFileCover(song.getData());
} else {
return MusicUtil.getMediaStoreAlbumCoverUri(song.getAlbumId());
}
}
@NonNull
public static <TranscodeType> GenericTransitionOptions<TranscodeType> getDefaultTransition() {
return new GenericTransitionOptions<TranscodeType>().transition(android.R.anim.fade_in);
}
}

View file

@ -23,7 +23,7 @@ import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil.getColor import code.name.monkey.retromusic.util.RetroColorUtil.getColor
import code.name.monkey.retromusic.util.RetroColorUtil.getDominantColor import code.name.monkey.retromusic.util.RetroColorUtil.getDominantColor
import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.request.animation.GlideAnimation
abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) { abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) {
@ -34,13 +34,13 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
protected val albumArtistFooterColor: Int protected val albumArtistFooterColor: Int
get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor) get() = ATHUtil.resolveColor(getView().context, R.attr.cardBackgroundColor)
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception, errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable) super.onLoadFailed(e, errorDrawable)
onColorReady(defaultFooterColor) onColorReady(defaultFooterColor)
} }
override fun onResourceReady(resource: BitmapPaletteWrapper, override fun onResourceReady(resource: BitmapPaletteWrapper,
glideAnimation: Transition<in BitmapPaletteWrapper>?) { glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) {
super.onResourceReady(resource, glideAnimation) super.onResourceReady(resource, glideAnimation)
val defaultColor = defaultFooterColor val defaultColor = defaultFooterColor

View file

@ -15,29 +15,22 @@
package code.name.monkey.retromusic.glide package code.name.monkey.retromusic.glide
import android.content.Context import android.content.Context
import android.graphics.Bitmap
import code.name.monkey.retromusic.glide.artistimage.ArtistImage import code.name.monkey.retromusic.glide.artistimage.ArtistImage
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.Registry import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.annotation.GlideModule import com.bumptech.glide.module.GlideModule
import com.bumptech.glide.module.AppGlideModule
import java.io.InputStream import java.io.InputStream
@GlideModule class RetroMusicGlideModule : GlideModule {
class RetroMusicGlideModule : AppGlideModule() { override fun applyOptions(context: Context, builder: GlideBuilder) {
override fun registerComponents(context: Context, glide: Glide,
registry: Registry) {
registry.append(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory())
registry.append(ArtistImage::class.java, InputStream::class.java, ArtistImageLoader.Factory(context))
registry.register(Bitmap::class.java, BitmapPaletteWrapper::class.java, BitmapPaletteTranscoder())
} }
override fun isManifestParsingEnabled(): Boolean { override fun registerComponents(context: Context, glide: Glide) {
return false glide.register(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory())
glide.register(ArtistImage::class.java, InputStream::class.java, ArtistImageLoader.Factory())
} }
} }

View file

@ -1,78 +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.glide
import android.graphics.drawable.Drawable
import com.bumptech.glide.request.Request
import com.bumptech.glide.request.target.SizeReadyCallback
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
import com.bumptech.glide.util.Util
open class RetroSimpleTarget<T> @JvmOverloads constructor(private val width: Int = Target.SIZE_ORIGINAL, private val height: Int = Target.SIZE_ORIGINAL) : Target<T> {
private var request: Request? = null
override fun getRequest(): Request? {
return request
}
override fun setRequest(request: Request?) {
this.request = request
}
override fun onLoadStarted(placeholder: Drawable?) {
}
override fun onLoadFailed(errorDrawable: Drawable?) {
}
override fun onResourceReady(resource: T, transition: Transition<in T>?) {
}
override fun onLoadCleared(placeholder: Drawable?) {
}
override fun getSize(cb: SizeReadyCallback) {
if (!Util.isValidDimensions(width, height)) {
throw IllegalArgumentException(
"Width and height must both be > 0 or Target#SIZE_ORIGINAL, but given" + " width: "
+ width + " and height: " + height + ", either provide dimensions in the constructor"
+ " or call override()")
}
cb.onSizeReady(width, height)
}
override fun removeCallback(cb: SizeReadyCallback) {
}
override fun onStart() {
}
override fun onStop() {
}
override fun onDestroy() {
}
}

View file

@ -0,0 +1,139 @@
/*
* 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.glide;
import android.content.Context;
import android.graphics.Bitmap;
import androidx.annotation.NonNull;
import com.bumptech.glide.BitmapRequestBuilder;
import com.bumptech.glide.DrawableRequestBuilder;
import com.bumptech.glide.DrawableTypeRequest;
import com.bumptech.glide.RequestManager;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.signature.MediaStoreSignature;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.util.MusicUtil;
import code.name.monkey.retromusic.util.PreferenceUtil;
/**
* Created by hemanths on 2019-09-15.
*/
public class SongGlideRequest {
public static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.NONE;
public static final int DEFAULT_ERROR_IMAGE = R.drawable.default_album_art;
public static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
public static class Builder {
final RequestManager requestManager;
final Song song;
boolean ignoreMediaStore;
public static Builder from(@NonNull RequestManager requestManager, Song song) {
return new Builder(requestManager, song);
}
private Builder(@NonNull RequestManager requestManager, Song song) {
this.requestManager = requestManager;
this.song = song;
}
public PaletteBuilder generatePalette(Context context) {
return new PaletteBuilder(this, context);
}
public BitmapBuilder asBitmap() {
return new BitmapBuilder(this);
}
public Builder checkIgnoreMediaStore(Context context) {
return ignoreMediaStore(PreferenceUtil.getInstance(context).ignoreMediaStoreArtwork());
}
public Builder ignoreMediaStore(boolean ignoreMediaStore) {
this.ignoreMediaStore = ignoreMediaStore;
return this;
}
public DrawableRequestBuilder<GlideDrawable> build() {
//noinspection unchecked
return createBaseRequest(requestManager, song, ignoreMediaStore)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.signature(createSignature(song));
}
}
public static class BitmapBuilder {
private final Builder builder;
public BitmapBuilder(Builder builder) {
this.builder = builder;
}
public BitmapRequestBuilder<?, Bitmap> build() {
//noinspection unchecked
return createBaseRequest(builder.requestManager, builder.song, builder.ignoreMediaStore)
.asBitmap()
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.signature(createSignature(builder.song));
}
}
public static class PaletteBuilder {
final Context context;
private final Builder builder;
public PaletteBuilder(Builder builder, Context context) {
this.builder = builder;
this.context = context;
}
public BitmapRequestBuilder<?, BitmapPaletteWrapper> build() {
//noinspection unchecked
return createBaseRequest(builder.requestManager, builder.song, builder.ignoreMediaStore)
.asBitmap()
.transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class)
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(DEFAULT_ERROR_IMAGE)
.animate(DEFAULT_ANIMATION)
.signature(createSignature(builder.song));
}
}
public static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Song song, boolean ignoreMediaStore) {
if (ignoreMediaStore) {
return requestManager.load(new AudioFileCover(song.getData()));
} else {
return requestManager.loadFromMediaStore(MusicUtil.getMediaStoreAlbumCoverUri(song.getAlbumId()));
}
}
public static Key createSignature(Song song) {
return new MediaStoreSignature("", song.getDateModified(), 0);
}
}

View file

@ -15,29 +15,201 @@
package code.name.monkey.retromusic.glide.artistimage package code.name.monkey.retromusic.glide.artistimage
import android.content.Context import android.content.Context
import code.name.monkey.retromusic.deezer.Data import android.graphics.Bitmap
import code.name.monkey.retromusic.deezer.DeezerApiService import android.graphics.Canvas
import code.name.monkey.retromusic.deezer.DeezerResponse import android.media.MediaMetadataRetriever
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverUtils
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Priority import com.bumptech.glide.Priority
import com.bumptech.glide.integration.okhttp3.OkHttpStreamFetcher
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.data.DataFetcher import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.GlideUrl import com.bumptech.glide.load.model.GenericLoaderFactory
import com.bumptech.glide.load.model.ModelLoader import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.MultiModelLoaderFactory import com.bumptech.glide.load.model.stream.StreamModelLoader
import com.bumptech.glide.signature.ObjectKey import java.io.ByteArrayInputStream
import okhttp3.OkHttpClient import java.io.ByteArrayOutputStream
import retrofit2.Call import java.io.IOException
import retrofit2.Callback
import retrofit2.Response
import java.io.InputStream import java.io.InputStream
import java.util.concurrent.TimeUnit
class AlbumCover(
var year: Int,
var filePath: String?)
class ArtistImage(val artistName: String, // filePath to get the image of the artist
val albumCovers: List<AlbumCover>
) {
fun toIdString(): String {
val id = StringBuilder(artistName)
for (albumCover in albumCovers) {
id.append(albumCover.year).append(albumCover.filePath)
}
return id.toString()
}
}
class ArtistImageFetcher(
val artistImage: ArtistImage,
val ignoreMediaStore: Boolean
) : DataFetcher<InputStream> {
private var stream: InputStream? = null
override fun cleanup() {
if (stream != null) {
try {
stream?.close()
} catch (ignore: IOException) {
// can't do much about it
}
}
}
override fun cancel() {
}
override fun loadData(priority: Priority?): InputStream {
println("MOSAIC load data for" + artistImage.artistName)
stream = getMosaic(artistImage.albumCovers)?.let {
it
}
return stream as InputStream
}
private fun getMosaic(albumCovers: List<AlbumCover>): InputStream? {
val retriever = MediaMetadataRetriever()
val artistBitMapSize = 512
val images = HashMap<InputStream, Int>()
var result: InputStream? = null
var streams = ArrayList<InputStream>()
try {
for (albumCover in albumCovers) {
var picture: ByteArray? = null
if (!ignoreMediaStore) {
retriever.setDataSource(albumCover.filePath)
picture = retriever.embeddedPicture
}
val stream: InputStream? = if (picture != null) {
ByteArrayInputStream(picture)
} else {
AudioFileCoverUtils.fallback(albumCover.filePath)
}
if (stream != null) {
images[stream] = albumCover.year
}
val nbImages = images.size
if (nbImages > 3) {
streams = ArrayList(images.keys)
var divisor = 1
var i = 1
while (i < nbImages && Math.pow(i.toDouble(), 2.0) <= nbImages) {
divisor = i
++i
}
divisor += 1
var nbTiles = Math.pow(divisor.toDouble(), 2.0)
if (nbImages < nbTiles) {
divisor -= 1;
nbTiles = Math.pow(divisor.toDouble(), 2.0)
}
val resize = (artistBitMapSize / divisor) + 1
val bitmap = Bitmap.createBitmap(artistBitMapSize, artistBitMapSize, Bitmap.Config.RGB_565)
val canvas = Canvas(bitmap)
var x = 0F
var y = 0F
var j = 0
while (j < streams.size && j < nbTiles) {
val tempBitmap = ImageUtil.resize(streams[j], resize, resize)
canvas.drawBitmap(tempBitmap, x, y, null)
x += resize
if (x >= artistBitMapSize) {
x = 0F
y += resize
}
++j
}
val bos = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 0, bos)
result = ByteArrayInputStream(bos.toByteArray())
} else if (nbImages > 0) {
var maxEntryYear: Map.Entry<InputStream, Int>? = null
for (entry in images.entries) {
if (maxEntryYear == null || entry.value
.compareTo(maxEntryYear.value) > 0) {
maxEntryYear = entry
}
}
result = if (maxEntryYear != null) {
maxEntryYear.key
} else {
images.entries
.iterator()
.next()
.key
}
}
}
} finally {
retriever.release()
try {
for (stream in streams) {
stream.close()
}
} catch (e: IOException) {
e.printStackTrace()
}
}
return result
}
override fun getId(): String {
println("MOSAIC get id for" + artistImage.artistName)
// never return NULL here!
// this id is used to determine whether the image is already cached
// we use the artist name as well as the album years + file paths
return artistImage.toIdString() + "ignoremediastore:" + ignoreMediaStore
}
}
class ArtistImageLoader(
private val context: Context
) : StreamModelLoader<ArtistImage> {
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
return ArtistImageFetcher(model, PreferenceUtil.getInstance(context).ignoreMediaStoreArtwork())
}
class Factory : ModelLoaderFactory<ArtistImage, InputStream> {
override fun build(context: Context, factories: GenericLoaderFactory): ModelLoader<ArtistImage, InputStream> {
return ArtistImageLoader(context)
}
override fun teardown() {
}
}
}
/*
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean) class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
class ArtistImageFetcher(private val context: Context, class ArtistImageFetcher(private val context: Context,
@ -158,4 +330,4 @@ class ArtistImageLoader(private val context: Context,
// we need these very low values to make sure our artist image loading calls doesn't block the image loading queue // we need these very low values to make sure our artist image loading calls doesn't block the image loading queue
private const val TIMEOUT = 700 private const val TIMEOUT = 700
} }
} }*/

View file

@ -0,0 +1,26 @@
/*
* 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.glide.audiocover;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class AudioFileCover {
public final String filePath;
public AudioFileCover(String filePath) {
this.filePath = filePath;
}
}

View file

@ -0,0 +1,78 @@
/*
* 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.glide.audiocover;
import android.media.MediaMetadataRetriever;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.data.DataFetcher;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
public class AudioFileCoverFetcher implements DataFetcher<InputStream> {
private final AudioFileCover model;
private InputStream stream;
public AudioFileCoverFetcher(AudioFileCover model) {
this.model = model;
}
@Override
public String getId() {
// makes sure we never ever return null here
return String.valueOf(model.filePath);
}
@Override
public InputStream loadData(final Priority priority) throws Exception {
final MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(model.filePath);
byte[] picture = retriever.getEmbeddedPicture();
if (picture != null) {
stream = new ByteArrayInputStream(picture);
} else {
stream = AudioFileCoverUtils.fallback(model.filePath);
}
} finally {
retriever.release();
}
return stream;
}
@Override
public void cleanup() {
// already cleaned up in loadData and ByteArrayInputStream will be GC'd
if (stream != null) {
try {
stream.close();
} catch (IOException ignore) {
// can't do much about it
}
}
}
@Override
public void cancel() {
// cannot cancel
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.glide.audiocover;
import android.content.Context;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GenericLoaderFactory;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.stream.StreamModelLoader;
import java.io.InputStream;
public class AudioFileCoverLoader implements StreamModelLoader<AudioFileCover> {
@Override
public DataFetcher<InputStream> getResourceFetcher(AudioFileCover model, int width, int height) {
return new AudioFileCoverFetcher(model);
}
public static class Factory implements ModelLoaderFactory<AudioFileCover, InputStream> {
@Override
public ModelLoader<AudioFileCover, InputStream> build(Context context, GenericLoaderFactory factories) {
return new AudioFileCoverLoader();
}
@Override
public void teardown() {
}
}
}

View file

@ -1,133 +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.glide.audiocover
import android.media.MediaMetadataRetriever
import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.data.DataFetcher
import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoader.LoadData
import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.MultiModelLoaderFactory
import com.bumptech.glide.signature.ObjectKey
import org.jaudiotagger.audio.mp3.MP3File
import java.io.*
class AudioFileCover(val filePath: String)
class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<InputStream> {
private var stream: FileInputStream? = null
override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
val retriever = MediaMetadataRetriever()
val data: InputStream?
try {
retriever.setDataSource(model.filePath)
val picture = retriever.embeddedPicture
if (picture != null) {
data = ByteArrayInputStream(picture)
} else {
data = fallback(model.filePath)
}
callback.onDataReady(data)
} catch (e: FileNotFoundException) {
callback.onLoadFailed(e)
} finally {
retriever.release()
}
}
override fun getDataClass(): Class<InputStream> {
return InputStream::class.java
}
override fun getDataSource(): DataSource {
return DataSource.LOCAL
}
@Throws(FileNotFoundException::class)
private fun fallback(path: String): InputStream? {
try {
val mp3File = MP3File(path)
if (mp3File.hasID3v2Tag()) {
val art = mp3File.tag.firstArtwork
if (art != null) {
val imageData = art.binaryData
return ByteArrayInputStream(imageData)
}
}
// If there are any exceptions, we ignore them and continue to the other fallback method
} catch (ignored: Exception) {
}
// Method 2: look for album art in external files
val parent = File(path).parentFile
for (fallback in FALLBACKS) {
val cover = File(parent, fallback)
if (cover.exists()) {
stream = FileInputStream(cover)
return stream
}
}
return null
}
override fun cleanup() {
// already cleaned up in loadData and ByteArrayInputStream will be GC'd
if (stream != null) {
try {
stream!!.close()
} catch (ignore: IOException) {
// can't do much about it
}
}
}
override fun cancel() {
// cannot cancel
}
companion object {
private val FALLBACKS = arrayOf("cover.jpg", "album.jpg", "folder.jpg", "cover.png", "album.png", "folder.png")
}
}
class AudioFileCoverLoader : ModelLoader<AudioFileCover, InputStream> {
override fun buildLoadData(model: AudioFileCover, width: Int, height: Int,
options: Options): LoadData<InputStream>? {
return LoadData(ObjectKey(model.filePath), AudioFileCoverFetcher(model))
}
override fun handles(model: AudioFileCover): Boolean {
return true
}
class Factory : ModelLoaderFactory<AudioFileCover, InputStream> {
override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<AudioFileCover, InputStream> {
return AudioFileCoverLoader()
}
override fun teardown() {}
}
}

View file

@ -0,0 +1,63 @@
/*
* 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.glide.audiocover;
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
import org.jaudiotagger.audio.mp3.MP3File;
import org.jaudiotagger.tag.TagException;
import org.jaudiotagger.tag.images.Artwork;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
public class AudioFileCoverUtils {
public static final String[] FALLBACKS = {"cover.jpg", "album.jpg", "folder.jpg", "cover.png", "album.png", "folder.png"};
public static InputStream fallback(String path) throws FileNotFoundException {
// Method 1: use embedded high resolution album art if there is any
try {
MP3File mp3File = new MP3File(path);
if (mp3File.hasID3v2Tag()) {
Artwork art = mp3File.getTag().getFirstArtwork();
if (art != null) {
byte[] imageData = art.getBinaryData();
return new ByteArrayInputStream(imageData);
}
}
// If there are any exceptions, we ignore them and continue to the other fallback method
} catch (ReadOnlyFileException ignored) {
} catch (InvalidAudioFrameException ignored) {
} catch (TagException ignored) {
} catch (IOException ignored) {
}
// Method 2: look for album art in external files
final File parent = new File(path).getParentFile();
for (String fallback : FALLBACKS) {
File cover = new File(parent, fallback);
if (cover.exists()) {
return new FileInputStream(cover);
}
}
return null;
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.glide.palette;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.util.Util;
public class BitmapPaletteResource implements Resource<BitmapPaletteWrapper> {
private final BitmapPaletteWrapper bitmapPaletteWrapper;
private final BitmapPool bitmapPool;
public BitmapPaletteResource(BitmapPaletteWrapper bitmapPaletteWrapper, BitmapPool bitmapPool) {
this.bitmapPaletteWrapper = bitmapPaletteWrapper;
this.bitmapPool = bitmapPool;
}
@Override
public BitmapPaletteWrapper get() {
return bitmapPaletteWrapper;
}
@Override
public int getSize() {
return Util.getBitmapByteSize(bitmapPaletteWrapper.getBitmap());
}
@Override
public void recycle() {
if (!bitmapPool.put(bitmapPaletteWrapper.getBitmap())) {
bitmapPaletteWrapper.getBitmap().recycle();
}
}
}

View file

@ -1,63 +0,0 @@
/*
* Copyright (c) 2019 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.glide.palette
import android.graphics.Bitmap
import android.widget.ImageView
import androidx.palette.graphics.Palette
import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder
import com.bumptech.glide.request.target.ImageViewTarget
import com.bumptech.glide.util.Util
class BitmapPaletteTranscoder : ResourceTranscoder<Bitmap, BitmapPaletteWrapper> {
override fun transcode(bitmapResource: Resource<Bitmap>, options: Options): Resource<BitmapPaletteWrapper>? {
val bitmap = bitmapResource.get()
val bitmapPaletteWrapper = BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap)!!)
return BitmapPaletteResource(bitmapPaletteWrapper)
}
}
class BitmapPaletteWrapper(val bitmap: Bitmap, val palette: Palette)
open class BitmapPaletteTarget(view: ImageView) : ImageViewTarget<BitmapPaletteWrapper>(view) {
override fun setResource(bitmapPaletteWrapper: BitmapPaletteWrapper?) {
if (bitmapPaletteWrapper != null) {
view.setImageBitmap(bitmapPaletteWrapper.bitmap)
}
}
}
class BitmapPaletteResource(private val bitmapPaletteWrapper: BitmapPaletteWrapper) : Resource<BitmapPaletteWrapper> {
override fun get(): BitmapPaletteWrapper {
return bitmapPaletteWrapper
}
override fun getResourceClass(): Class<BitmapPaletteWrapper> {
return BitmapPaletteWrapper::class.java
}
override fun getSize(): Int {
return Util.getBitmapByteSize(bitmapPaletteWrapper.bitmap)
}
override fun recycle() {
bitmapPaletteWrapper.bitmap.recycle()
}
}

View file

@ -0,0 +1,30 @@
/*
* 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.glide.palette;
import android.widget.ImageView;
import com.bumptech.glide.request.target.ImageViewTarget;
public class BitmapPaletteTarget extends ImageViewTarget<BitmapPaletteWrapper> {
public BitmapPaletteTarget(ImageView view) {
super(view);
}
@Override
protected void setResource(BitmapPaletteWrapper bitmapPaletteWrapper) {
view.setImageBitmap(bitmapPaletteWrapper.getBitmap());
}
}

View file

@ -0,0 +1,49 @@
/*
* 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.glide.palette;
import android.content.Context;
import android.graphics.Bitmap;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
import code.name.monkey.retromusic.util.RetroColorUtil;
public class BitmapPaletteTranscoder implements ResourceTranscoder<Bitmap, BitmapPaletteWrapper> {
private final BitmapPool bitmapPool;
public BitmapPaletteTranscoder(Context context) {
this(Glide.get(context).getBitmapPool());
}
public BitmapPaletteTranscoder(BitmapPool bitmapPool) {
this.bitmapPool = bitmapPool;
}
@Override
public Resource<BitmapPaletteWrapper> transcode(Resource<Bitmap> bitmapResource) {
Bitmap bitmap = bitmapResource.get();
BitmapPaletteWrapper bitmapPaletteWrapper = new BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap));
return new BitmapPaletteResource(bitmapPaletteWrapper, bitmapPool);
}
@Override
public String getId() {
return "BitmapPaletteTranscoder.com.kabouzeid.gramophone.glide.palette";
}
}

View file

@ -0,0 +1,36 @@
/*
* 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.glide.palette;
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) {
mBitmap = bitmap;
mPalette = palette;
}
public Bitmap getBitmap() {
return mBitmap;
}
public Palette getPalette() {
return mPalette;
}
}

View file

@ -19,7 +19,7 @@ import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.disposables.Disposable import io.reactivex.disposables.CompositeDisposable
import javax.inject.Inject import javax.inject.Inject
@ -48,7 +48,7 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
private lateinit var album: Album private lateinit var album: Album
override fun loadMore(artistId: Int) { override fun loadMore(artistId: Int) {
disposable = repository.getArtistByIdFlowable(artistId) disposable += repository.getArtistByIdFlowable(artistId)
.map { .map {
view.loadArtistImage(it) view.loadArtistImage(it)
return@map it.albums return@map it.albums
@ -64,10 +64,10 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
} }
} }
private var disposable: Disposable? = null private var disposable: CompositeDisposable = CompositeDisposable()
override fun loadAlbum(albumId: Int) { override fun loadAlbum(albumId: Int) {
disposable = repository.getAlbumFlowable(albumId) disposable += repository.getAlbumFlowable(albumId)
.doOnComplete { .doOnComplete {
view.complete() view.complete()
} }
@ -79,7 +79,7 @@ interface AlbumDetailsPresenter : Presenter<AlbumDetailsView> {
override fun detachView() { override fun detachView() {
super.detachView() super.detachView()
disposable?.dispose() disposable.dispose()
} }
} }
} }

View file

@ -20,7 +20,7 @@ import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import code.name.monkey.retromusic.rest.model.LastFmArtist import code.name.monkey.retromusic.rest.model.LastFmArtist
import io.reactivex.disposables.Disposable import io.reactivex.disposables.CompositeDisposable
import java.util.* import java.util.*
import javax.inject.Inject import javax.inject.Inject
@ -49,16 +49,16 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
override fun loadBiography(name: String, override fun loadBiography(name: String,
lang: String?, lang: String?,
cache: String?) { cache: String?) {
disposable = repository.artistInfoFloable(name, lang, cache) disposable += repository.artistInfoFloable(name, lang, cache)
.subscribe { .subscribe {
view.artistInfo(it) view.artistInfo(it)
} }
} }
private var disposable: Disposable? = null private var disposable = CompositeDisposable()
override fun loadArtist(artistId: Int) { override fun loadArtist(artistId: Int) {
disposable = repository.getArtistByIdFlowable(artistId) disposable += repository.getArtistByIdFlowable(artistId)
.doOnComplete { .doOnComplete {
view.complete() view.complete()
} }
@ -67,6 +67,10 @@ interface ArtistDetailsPresenter : Presenter<ArtistDetailsView> {
} }
} }
override fun detachView() {
super.detachView()
disposable.dispose()
}
private fun showArtist(artist: Artist) { private fun showArtist(artist: Artist) {
view.artist(artist) view.artist(artist)

View file

@ -20,11 +20,15 @@ import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.RECENT_ALBUMS
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.RECENT_ARTISTS import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.RECENT_ARTISTS
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.TOP_ALBUMS import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.TOP_ALBUMS
import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.TOP_ARTISTS import code.name.monkey.retromusic.adapter.HomeAdapter.Companion.TOP_ARTISTS
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Home import code.name.monkey.retromusic.model.Home
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.mvp.BaseView import code.name.monkey.retromusic.mvp.BaseView
import code.name.monkey.retromusic.mvp.Presenter import code.name.monkey.retromusic.mvp.Presenter
import code.name.monkey.retromusic.mvp.PresenterImpl import code.name.monkey.retromusic.mvp.PresenterImpl
import code.name.monkey.retromusic.providers.interfaces.Repository import code.name.monkey.retromusic.providers.interfaces.Repository
import io.reactivex.Observable
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import javax.inject.Inject import javax.inject.Inject
@ -44,15 +48,16 @@ interface HomePresenter : Presenter<HomeView> {
private val repository: Repository private val repository: Repository
) : PresenterImpl<HomeView>(), HomePresenter { ) : PresenterImpl<HomeView>(), HomePresenter {
override fun loadSections() { override fun loadSections() {
loadRecentArtists() /*loadRecentArtists()
loadRecentAlbums() loadRecentAlbums()
loadTopArtists() loadTopArtists()
loadATopAlbums() loadATopAlbums()
loadFavorite() loadFavorite()*/
loadHomeSection()
} }
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
private val hashSet: HashSet<Home> = HashSet()
private fun showData(sections: ArrayList<Home>) { private fun showData(sections: ArrayList<Home>) {
if (sections.isEmpty()) { if (sections.isEmpty()) {
@ -62,7 +67,7 @@ interface HomePresenter : Presenter<HomeView> {
} }
} }
private fun loadRecentArtists() { /*private fun loadRecentArtists() {
disposable += repository.recentArtistsFlowable disposable += repository.recentArtistsFlowable
.subscribe { .subscribe {
if (it.isNotEmpty()) hashSet.add( if (it.isNotEmpty()) hashSet.add(
@ -135,8 +140,67 @@ interface HomePresenter : Presenter<HomeView> {
)) ))
showData(ArrayList(hashSet)) showData(ArrayList(hashSet))
} }
} }*/
private fun loadHomeSection() {
val ob = listOf(repository.recentArtistsFlowable,
repository.recentAlbumsFlowable,
repository.topArtistsFlowable,
repository.topAlbumsFlowable,
repository.favoritePlaylistFlowable)
disposable += Observable.combineLatest(ob) {
val hashSet: HashSet<Home> = HashSet()
val recentArtist = it[0] as ArrayList<Artist>
if (recentArtist.isNotEmpty()) hashSet.add(
Home(0,
R.string.recent_artists,
0,
recentArtist,
RECENT_ARTISTS,
R.drawable.ic_artist_white_24dp
))
val recentAlbums = it[1] as ArrayList<Album>
if (recentAlbums.isNotEmpty()) hashSet.add(
Home(1,
R.string.recent_albums,
0,
recentAlbums,
RECENT_ALBUMS,
R.drawable.ic_album_white_24dp
))
val topArtists = it[2] as ArrayList<Artist>
if (topArtists.isNotEmpty()) hashSet.add(
Home(2,
R.string.top_artists,
0,
topArtists,
TOP_ARTISTS,
R.drawable.ic_artist_white_24dp
))
val topAlbums = it[3] as ArrayList<Album>
if (topAlbums.isNotEmpty()) hashSet.add(
Home(3,
R.string.top_albums,
0,
topAlbums,
TOP_ALBUMS,
R.drawable.ic_album_white_24dp
))
val playlists = it[4] as ArrayList<Playlist>
if (playlists.isNotEmpty()) hashSet.add(
Home(4,
R.string.favorites,
0,
playlists,
PLAYLISTS,
R.drawable.ic_favorite_white_24dp
))
return@combineLatest hashSet
}.subscribe {
view.sections(ArrayList(it))
}
}
} }
} }

View file

@ -84,7 +84,7 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
title(code.name.monkey.retromusic.R.string.remove_from_blacklist) 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))) message(text = Html.fromHtml(getString(code.name.monkey.retromusic.R.string.do_you_want_to_remove_from_the_blacklist, text)))
positiveButton(code.name.monkey.retromusic.R.string.remove_action) { positiveButton(code.name.monkey.retromusic.R.string.remove_action) {
BlacklistStore.getInstance(context).removePath(File(text)) BlacklistStore.getInstance(context).removePath(File(text.toString()))
refreshBlacklistData() refreshBlacklistData()
} }
negativeButton(android.R.string.cancel) negativeButton(android.R.string.cancel)

View file

@ -51,7 +51,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media.MediaBrowserServiceCompat; import androidx.media.MediaBrowserServiceCompat;
import com.bumptech.glide.request.transition.Transition; import com.bumptech.glide.BitmapRequestBuilder;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -66,10 +69,7 @@ import code.name.monkey.retromusic.appwidgets.AppWidgetText;
import code.name.monkey.retromusic.auto.AutoMediaIDHelper; import code.name.monkey.retromusic.auto.AutoMediaIDHelper;
import code.name.monkey.retromusic.auto.AutoMusicProvider; import code.name.monkey.retromusic.auto.AutoMusicProvider;
import code.name.monkey.retromusic.glide.BlurTransformation; import code.name.monkey.retromusic.glide.BlurTransformation;
import code.name.monkey.retromusic.glide.GlideApp; import code.name.monkey.retromusic.glide.SongGlideRequest;
import code.name.monkey.retromusic.glide.GlideRequest;
import code.name.monkey.retromusic.glide.RetroGlideExtension;
import code.name.monkey.retromusic.glide.RetroSimpleTarget;
import code.name.monkey.retromusic.helper.ShuffleHelper; import code.name.monkey.retromusic.helper.ShuffleHelper;
import code.name.monkey.retromusic.model.Playlist; import code.name.monkey.retromusic.model.Playlist;
import code.name.monkey.retromusic.model.Song; import code.name.monkey.retromusic.model.Song;
@ -747,27 +747,25 @@ public class MusicService extends MediaBrowserServiceCompat implements SharedPre
if (PreferenceUtil.getInstance(this).albumArtOnLockscreen()) { if (PreferenceUtil.getInstance(this).albumArtOnLockscreen()) {
final Point screenSize = RetroUtil.getScreenSize(MusicService.this); final Point screenSize = RetroUtil.getScreenSize(MusicService.this);
GlideRequest request = GlideApp.with(MusicService.this) final BitmapRequestBuilder<?, Bitmap> request = SongGlideRequest.Builder.from(Glide.with(MusicService.this), song)
.asBitmap() .checkIgnoreMediaStore(MusicService.this)
.load(RetroGlideExtension.getSongModel(song)) .asBitmap().build();
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song);
if (PreferenceUtil.getInstance(this).blurredAlbumArt()) { if (PreferenceUtil.getInstance(this).blurredAlbumArt()) {
request.transform(new BlurTransformation.Builder(MusicService.this).build()); request.transform(new BlurTransformation.Builder(MusicService.this).build());
} }
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
request.into(new RetroSimpleTarget<Bitmap>(screenSize.x, screenSize.y) { request.into(new SimpleTarget<Bitmap>(screenSize.x, screenSize.y) {
@Override @Override
public void onLoadFailed(@Nullable Drawable errorDrawable) { public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {
super.onLoadFailed(errorDrawable); metaData.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, copy(resource));
mediaSession.setMetadata(metaData.build()); mediaSession.setMetadata(metaData.build());
} }
@Override @Override
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> glideAnimation) { public void onLoadFailed(Exception e, Drawable errorDrawable) {
metaData.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, copy(resource)); super.onLoadFailed(e, errorDrawable);
mediaSession.setMetadata(metaData.build()); mediaSession.setMetadata(metaData.build());
} }
}); });

View file

@ -1,227 +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.notification
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.view.View
import android.widget.RemoteViews
import androidx.core.app.NotificationCompat
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget.Companion.createBitmap
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class PlayingNotificationImpl : PlayingNotification() {
private var target: Target<BitmapPaletteWrapper>? = null
@Synchronized
override fun update() {
stopped = false
val song = service.currentSong
val isPlaying = service.isPlaying
val notificationLayout = RemoteViews(service.packageName, R.layout.notification)
val notificationLayoutBig = RemoteViews(service.packageName, R.layout.notification_big)
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName)) {
notificationLayout.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
notificationLayout.setViewVisibility(R.id.media_titles, View.VISIBLE)
notificationLayout.setTextViewText(R.id.title, song.title)
notificationLayout.setTextViewText(R.id.text, song.artistName)
}
if (TextUtils.isEmpty(song.title) && TextUtils.isEmpty(song.artistName) && TextUtils.isEmpty(song.albumName)) {
notificationLayoutBig.setViewVisibility(R.id.media_titles, View.INVISIBLE)
} else {
notificationLayoutBig.setViewVisibility(R.id.media_titles, View.VISIBLE)
notificationLayoutBig.setTextViewText(R.id.title, song.title)
notificationLayoutBig.setTextViewText(R.id.text, song.artistName)
notificationLayoutBig.setTextViewText(R.id.text2, song.albumName)
}
linkButtons(notificationLayout, notificationLayoutBig)
val action = Intent(service, MainActivity::class.java)
action.putExtra("expand", true)
action.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP
val clickIntent = PendingIntent
.getActivity(service, 0, action, PendingIntent.FLAG_UPDATE_CURRENT)
val deleteIntent = buildPendingIntent(service, ACTION_QUIT, null)
val notification = NotificationCompat.Builder(service, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentIntent(clickIntent)
.setDeleteIntent(deleteIntent)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContent(notificationLayout)
.setCustomBigContentView(notificationLayoutBig)
.setOngoing(isPlaying)
.build()
val bigNotificationImageSize = service.resources
.getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread {
if (target != null) {
GlideApp.with(service).clear(target);
}
target = GlideApp.with(service)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songOptions(song)
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize,
bigNotificationImageSize) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
update(resource.bitmap,
if (PreferenceUtil.getInstance(service).isDominantColor)
RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT)
else
RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT))
}
override fun onLoadFailed(errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable)
update(null, Color.WHITE)
}
private fun update(bitmap: Bitmap?, bgColor: Int) {
var bgColorFinal = bgColor
if (bitmap != null) {
notificationLayout.setImageViewBitmap(R.id.image, bitmap)
notificationLayoutBig.setImageViewBitmap(R.id.image, bitmap)
} else {
notificationLayout.setImageViewResource(R.id.image, R.drawable.default_album_art)
notificationLayoutBig
.setImageViewResource(R.id.image, R.drawable.default_album_art)
}
if (!PreferenceUtil.getInstance(service).coloredNotification()) {
bgColorFinal = Color.WHITE
}
setBackgroundColor(bgColorFinal)
setNotificationContent(ColorUtil.isColorLight(bgColorFinal))
if (stopped) {
return // notification has been stopped before loading was finished
}
updateNotifyModeAndPostNotification(notification)
}
private fun setBackgroundColor(color: Int) {
notificationLayout.setInt(R.id.root, "setBackgroundColor", color)
notificationLayoutBig.setInt(R.id.root, "setBackgroundColor", color)
}
private fun setNotificationContent(dark: Boolean) {
val primary = MaterialValueHelper.getPrimaryTextColor(service, dark)
val secondary = MaterialValueHelper.getSecondaryTextColor(service, dark)
val close = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_close_white_24dp, primary)!!,
1.5f)
val prev = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_previous_white_24dp,
primary)!!, 1.5f)
val next = createBitmap(
RetroUtil.getTintedVectorDrawable(service, R.drawable.ic_skip_next_white_24dp,
primary)!!, 1.5f)
val playPause = createBitmap(RetroUtil.getTintedVectorDrawable(service,
if (isPlaying)
R.drawable.ic_pause_white_24dp
else
R.drawable.ic_play_arrow_white_32dp, primary)!!, 1.5f)
notificationLayout.setTextColor(R.id.title, primary)
notificationLayout.setTextColor(R.id.text, secondary)
notificationLayout.setImageViewBitmap(R.id.action_prev, prev)
notificationLayout.setImageViewBitmap(R.id.action_next, next)
notificationLayout.setImageViewBitmap(R.id.action_play_pause, playPause)
notificationLayoutBig.setTextColor(R.id.title, primary)
notificationLayoutBig.setTextColor(R.id.text, secondary)
notificationLayoutBig.setTextColor(R.id.text2, secondary)
notificationLayoutBig.setImageViewBitmap(R.id.action_quit, close)
notificationLayoutBig.setImageViewBitmap(R.id.action_prev, prev)
notificationLayoutBig.setImageViewBitmap(R.id.action_next, next)
notificationLayoutBig.setImageViewBitmap(R.id.action_play_pause, playPause)
}
})
}
}
private fun linkButtons(notificationLayout: RemoteViews,
notificationLayoutBig: RemoteViews) {
var pendingIntent: PendingIntent
val serviceName = ComponentName(service, MusicService::class.java)
// Previous track
pendingIntent = buildPendingIntent(service, ACTION_REWIND, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_prev, pendingIntent)
notificationLayoutBig.setOnClickPendingIntent(R.id.action_prev, pendingIntent)
// Play and pause
pendingIntent = buildPendingIntent(service, ACTION_TOGGLE_PAUSE, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_play_pause, pendingIntent)
notificationLayoutBig.setOnClickPendingIntent(R.id.action_play_pause, pendingIntent)
// Next track
pendingIntent = buildPendingIntent(service, ACTION_SKIP, serviceName)
notificationLayout.setOnClickPendingIntent(R.id.action_next, pendingIntent)
notificationLayoutBig.setOnClickPendingIntent(R.id.action_next, pendingIntent)
// Close
pendingIntent = buildPendingIntent(service, ACTION_QUIT, serviceName)
notificationLayoutBig.setOnClickPendingIntent(R.id.action_quit, pendingIntent)
}
private fun buildPendingIntent(context: Context, action: String,
serviceName: ComponentName?): PendingIntent {
val intent = Intent(action)
intent.component = serviceName
return PendingIntent.getService(context, 0, intent, 0)
}
}

View file

@ -24,20 +24,20 @@ import android.graphics.drawable.Drawable
import android.os.Build import android.os.Build
import android.text.Html import android.text.Html
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.media.app.NotificationCompat.* import androidx.media.app.NotificationCompat.MediaStyle
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.* import code.name.monkey.retromusic.service.MusicService.*
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
class PlayingNotificationImpl24 : PlayingNotification() { class PlayingNotificationImpl24 : PlayingNotification() {
private var target: Target<BitmapPaletteWrapper>? = null private var target: Target<BitmapPaletteWrapper>? = null
@ -74,22 +74,22 @@ class PlayingNotificationImpl24 : PlayingNotification() {
.getDimensionPixelSize(R.dimen.notification_big_image_size) .getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
GlideApp.with(service).clear(target); Glide.clear(target)
} }
target = GlideApp.with(service) target = SongGlideRequest.Builder.from(Glide.with(service), song)
.asBitmapPalette() .checkIgnoreMediaStore(service)
.load(RetroGlideExtension.getSongModel(song)) .generatePalette(service).build()
.transition(RetroGlideExtension.getDefaultTransition()) .centerCrop()
.songOptions(song) .into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) { override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
update(resource.bitmap, when { update(resource.bitmap, when {
PreferenceUtil.getInstance(service).isDominantColor -> RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT) PreferenceUtil.getInstance(service).isDominantColor -> RetroColorUtil.getDominantColor(resource.bitmap, Color.TRANSPARENT)
else -> RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT) else -> RetroColorUtil.getColor(resource.palette, Color.TRANSPARENT)
}) })
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
update(null, Color.TRANSPARENT) update(null, Color.TRANSPARENT)
} }

View file

@ -27,9 +27,7 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.glide.GlideApp import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
@ -38,8 +36,10 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.RetroUtil.createBitmap import code.name.monkey.retromusic.util.RetroUtil.createBitmap
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
/** /**
* @author Hemanth S (h4h13). * @author Hemanth S (h4h13).
@ -99,22 +99,21 @@ class PlayingNotificationOreo : PlayingNotification() {
.getDimensionPixelSize(R.dimen.notification_big_image_size) .getDimensionPixelSize(R.dimen.notification_big_image_size)
service.runOnUiThread { service.runOnUiThread {
if (target != null) { if (target != null) {
GlideApp.with(service).clear(target); Glide.clear(target)
} }
target = GlideApp.with(service) target = SongGlideRequest.Builder.from(Glide.with(service), song)
.asBitmapPalette() .checkIgnoreMediaStore(service)
.load(RetroGlideExtension.getSongModel(song)) .generatePalette(service).build()
.transition(RetroGlideExtension.getDefaultTransition()) .centerCrop()
.songOptions(song) .into(object : SimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) {
.into(object : RetroSimpleTarget<BitmapPaletteWrapper>(bigNotificationImageSize, bigNotificationImageSize) { override fun onResourceReady(resource: BitmapPaletteWrapper, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>) {
override fun onResourceReady(resource: BitmapPaletteWrapper, transition: Transition<in BitmapPaletteWrapper>?) {
val mediaNotificationProcessor = MediaNotificationProcessor(service, service) { i, _ -> update(resource.bitmap, i) } val mediaNotificationProcessor = MediaNotificationProcessor(service, service) { i, _ -> update(resource.bitmap, i) }
mediaNotificationProcessor.processNotification(resource.bitmap) mediaNotificationProcessor.processNotification(resource.bitmap)
} }
override fun onLoadFailed(errorDrawable: Drawable?) { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(errorDrawable) super.onLoadFailed(e, errorDrawable)
update(null, Color.WHITE) update(null, Color.TRANSPARENT)
} }
private fun update(bitmap: Bitmap?, bgColor: Int) { private fun update(bitmap: Bitmap?, bgColor: Int) {

View file

@ -17,13 +17,13 @@ package code.name.monkey.retromusic.util;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.bumptech.glide.signature.ObjectKey; import com.bumptech.glide.signature.StringSignature;
import code.name.monkey.retromusic.App;
/**
* @author Karim Abou Zeid (kabouzeid)
*/
public class ArtistSignatureUtil { public class ArtistSignatureUtil {
private static final String ARTIST_SIGNATURE_PREFS = "artist_signatures"; private static final String ARTIST_SIGNATURE_PREFS = "artist_signatures";
@ -35,23 +35,23 @@ public class ArtistSignatureUtil {
mPreferences = context.getSharedPreferences(ARTIST_SIGNATURE_PREFS, Context.MODE_PRIVATE); mPreferences = context.getSharedPreferences(ARTIST_SIGNATURE_PREFS, Context.MODE_PRIVATE);
} }
public static ArtistSignatureUtil getInstance() { public static ArtistSignatureUtil getInstance(@NonNull final Context context) {
if (sInstance == null) { if (sInstance == null) {
sInstance = new ArtistSignatureUtil(App.Companion.getContext()); sInstance = new ArtistSignatureUtil(context.getApplicationContext());
} }
return sInstance; return sInstance;
} }
@SuppressLint("CommitPrefEdits") @SuppressLint("CommitPrefEdits")
public void updateArtistSignature(String artistName) { public void updateArtistSignature(String artistName) {
mPreferences.edit().putLong(artistName, System.currentTimeMillis()).apply(); mPreferences.edit().putLong(artistName, System.currentTimeMillis()).commit();
} }
public long getArtistSignatureRaw(String artistName) { public long getArtistSignatureRaw(String artistName) {
return mPreferences.getLong(artistName, 0); return mPreferences.getLong(artistName, 0);
} }
public ObjectKey getArtistSignature(String artistName) { public StringSignature getArtistSignature(String artistName) {
return new ObjectKey(String.valueOf(getArtistSignatureRaw(artistName))); return new StringSignature(String.valueOf(getArtistSignatureRaw(artistName)));
} }
} }

View file

@ -23,18 +23,18 @@ import android.net.Uri
import android.os.AsyncTask import android.os.AsyncTask
import android.widget.Toast import android.widget.Toast
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroSimpleTarget
import code.name.monkey.retromusic.model.Artist import code.name.monkey.retromusic.model.Artist
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.animation.GlideAnimation
import com.bumptech.glide.request.transition.Transition import com.bumptech.glide.request.target.SimpleTarget
import java.io.BufferedOutputStream import java.io.BufferedOutputStream
import java.io.File import java.io.File
import java.io.FileOutputStream import java.io.FileOutputStream
import java.io.IOException import java.io.IOException
import java.util.* import java.util.*
class CustomArtistImageUtil private constructor(context: Context) { class CustomArtistImageUtil private constructor(context: Context) {
private val mPreferences: SharedPreferences private val mPreferences: SharedPreferences
@ -44,21 +44,23 @@ class CustomArtistImageUtil private constructor(context: Context) {
} }
fun setCustomArtistImage(artist: Artist, uri: Uri) { fun setCustomArtistImage(artist: Artist, uri: Uri) {
GlideApp.with(App.getContext()) Glide.with(App.getContext())
.asBitmap()
.load(uri) .load(uri)
.apply(RequestOptions() .asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true) .skipMemoryCache(true)
) .into(object : SimpleTarget<Bitmap>() {
.into(object : RetroSimpleTarget<Bitmap>() { override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
super.onLoadFailed(e, errorDrawable)
e!!.printStackTrace()
Toast.makeText(App.getContext(), e.toString(), Toast.LENGTH_LONG).show()
}
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) { override fun onResourceReady(resource: Bitmap, glideAnimation: GlideAnimation<in Bitmap>) {
object : AsyncTask<Void, Void, Void>() { object : AsyncTask<Void, Void, Void>() {
@SuppressLint("ApplySharedPref") @SuppressLint("ApplySharedPref")
override fun doInBackground(vararg params: Void): Void? { override fun doInBackground(vararg params: Void): Void? {
val dir = File(App.getContext().filesDir, FOLDER_NAME) val dir = File(App.getContext().filesDir, FOLDER_NAME)
println(dir.absolutePath)
if (!dir.exists()) { if (!dir.exists()) {
if (!dir.mkdirs()) { // create the folder if (!dir.mkdirs()) { // create the folder
return null return null
@ -77,8 +79,8 @@ class CustomArtistImageUtil private constructor(context: Context) {
if (succesful) { if (succesful) {
mPreferences.edit().putBoolean(getFileName(artist), true).commit() mPreferences.edit().putBoolean(getFileName(artist), true).commit()
ArtistSignatureUtil.getInstance().updateArtistSignature(artist.name) ArtistSignatureUtil.getInstance(App.getContext()).updateArtistSignature(artist.name)
App.getContext().contentResolver.notifyChange(Uri.parse("content://media"), null) // trigger media store changed to force artist image reload App.getContext().getContentResolver().notifyChange(Uri.parse("content://media"), null) // trigger media store changed to force artist image reload
} }
return null return null
} }
@ -92,7 +94,7 @@ class CustomArtistImageUtil private constructor(context: Context) {
@SuppressLint("ApplySharedPref") @SuppressLint("ApplySharedPref")
override fun doInBackground(vararg params: Void): Void? { override fun doInBackground(vararg params: Void): Void? {
mPreferences.edit().putBoolean(getFileName(artist), false).commit() mPreferences.edit().putBoolean(getFileName(artist), false).commit()
ArtistSignatureUtil.getInstance().updateArtistSignature(artist.name) ArtistSignatureUtil.getInstance(App.getContext()).updateArtistSignature(artist.name)
App.getContext().contentResolver.notifyChange(Uri.parse("content://media"), null) // trigger media store changed to force artist image reload App.getContext().contentResolver.notifyChange(Uri.parse("content://media"), null) // trigger media store changed to force artist image reload
val file = getFile(artist) val file = getFile(artist)

View file

@ -36,6 +36,7 @@ import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import code.name.monkey.appthemehelper.util.TintHelper; import code.name.monkey.appthemehelper.util.TintHelper;
@ -277,4 +278,10 @@ public class ImageUtil {
} }
return Bitmap.createScaledBitmap(image, width, height, true); return Bitmap.createScaledBitmap(image, width, height, true);
} }
public static Bitmap resize(InputStream stream, int scaledWidth, int scaledHeight) {
final Bitmap bitmap = BitmapFactory.decodeStream(stream);
return Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
}
} }

View file

@ -21,8 +21,9 @@ import android.util.AttributeSet;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.bumptech.glide.Glide;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.GlideApp;
/** /**
* @author Hemanth S (h4h13). * @author Hemanth S (h4h13).
@ -49,7 +50,7 @@ public class NetworkImageView extends CircularImageView {
} }
public void setImageUrl(@NonNull Context context, @NonNull String imageUrl) { public void setImageUrl(@NonNull Context context, @NonNull String imageUrl) {
GlideApp.with(context) Glide.with(context)
.load(imageUrl) .load(imageUrl)
.error(R.drawable.ic_account_white_24dp) .error(R.drawable.ic_account_white_24dp)
.placeholder(R.drawable.ic_account_white_24dp) .placeholder(R.drawable.ic_account_white_24dp)

View file

@ -1,147 +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.views;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.util.AttributeSet;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.bumptech.glide.request.Request;
import com.bumptech.glide.request.target.SizeReadyCallback;
import com.bumptech.glide.request.target.Target;
import com.bumptech.glide.request.transition.Transition;
import java.io.File;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.glide.GlideApp;
import code.name.monkey.retromusic.util.PreferenceUtil;
import static code.name.monkey.retromusic.Constants.USER_PROFILE;
public class UserImageView extends CircularImageView implements SharedPreferences.OnSharedPreferenceChangeListener {
public UserImageView(@NonNull Context context) {
super(context);
init(context);
}
public UserImageView(@NonNull Context context, @NonNull AttributeSet attrs) {
super(context, attrs);
init(context);
}
public UserImageView(@NonNull Context context, @NonNull AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
void init(@NonNull Context context) {
resetImage(context);
}
private void resetImage(@NonNull Context context) {
GlideApp.with(context)
.asDrawable()
.placeholder(R.drawable.ic_account_white_24dp)
.fallback(R.drawable.ic_account_white_24dp)
.load(new File(PreferenceUtil.getInstance(context).getProfileImage(), USER_PROFILE))
.into(new Target<Drawable>() {
@Override
public void onLoadStarted(@Nullable Drawable placeholder) {
setImageDrawable(placeholder);
setBackgroundColor(Color.TRANSPARENT);
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
setImageDrawable(errorDrawable);
setBackgroundColor(Color.TRANSPARENT);
}
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
setImageDrawable(resource);
setBackgroundColor(Color.TRANSPARENT);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
@Override
public void getSize(@NonNull SizeReadyCallback cb) {
cb.onSizeReady(96, 96);
}
@Override
public void removeCallback(@NonNull SizeReadyCallback cb) {
}
@Nullable
@Override
public Request getRequest() {
return null;
}
@Override
public void setRequest(@Nullable Request request) {
}
@Override
public void onStart() {
}
@Override
public void onStop() {
}
@Override
public void onDestroy() {
}
});
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
PreferenceManager.getDefaultSharedPreferences(getContext()).registerOnSharedPreferenceChangeListener(this);
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
PreferenceManager.getDefaultSharedPreferences(getContext()).unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(@NonNull SharedPreferences sharedPreferences, @NonNull String key) {
if (key.equals(PreferenceUtil.PROFILE_IMAGE_PATH)) {
resetImage(getContext());
}
}
}